Merge
authorprr
Tue, 17 Nov 2015 10:29:28 -0800
changeset 33866 e4b2a5f4dea0
parent 33865 d5d2d1a08a71 (current diff)
parent 33849 17a6b70090b3 (diff)
child 33867 c07b6cc0c61d
child 34405 d152b09f62ba
Merge
jdk/test/java/util/stream/bootlib/java/util/stream/CollectorOps.java
jdk/test/java/util/stream/bootlib/java/util/stream/DefaultMethodStreams.java
jdk/test/java/util/stream/bootlib/java/util/stream/DoubleStreamTestDataProvider.java
jdk/test/java/util/stream/bootlib/java/util/stream/DoubleStreamTestScenario.java
jdk/test/java/util/stream/bootlib/java/util/stream/FlagDeclaringOp.java
jdk/test/java/util/stream/bootlib/java/util/stream/IntStreamTestDataProvider.java
jdk/test/java/util/stream/bootlib/java/util/stream/IntStreamTestScenario.java
jdk/test/java/util/stream/bootlib/java/util/stream/IntermediateTestOp.java
jdk/test/java/util/stream/bootlib/java/util/stream/LambdaTestHelpers.java
jdk/test/java/util/stream/bootlib/java/util/stream/LambdaTestMode.java
jdk/test/java/util/stream/bootlib/java/util/stream/LoggingTestCase.java
jdk/test/java/util/stream/bootlib/java/util/stream/LongStreamTestDataProvider.java
jdk/test/java/util/stream/bootlib/java/util/stream/LongStreamTestScenario.java
jdk/test/java/util/stream/bootlib/java/util/stream/OpTestCase.java
jdk/test/java/util/stream/bootlib/java/util/stream/SpliteratorTestHelper.java
jdk/test/java/util/stream/bootlib/java/util/stream/StatefulTestOp.java
jdk/test/java/util/stream/bootlib/java/util/stream/StatelessTestOp.java
jdk/test/java/util/stream/bootlib/java/util/stream/StreamOpFlagTestHelper.java
jdk/test/java/util/stream/bootlib/java/util/stream/StreamTestDataProvider.java
jdk/test/java/util/stream/bootlib/java/util/stream/StreamTestScenario.java
jdk/test/java/util/stream/bootlib/java/util/stream/TestData.java
jdk/test/java/util/stream/bootlib/java/util/stream/TestFlagExpectedOp.java
jdk/test/java/util/stream/bootlib/java/util/stream/ThowableHelper.java
jdk/test/java/util/stream/boottest/java/util/stream/DoubleNodeTest.java
jdk/test/java/util/stream/boottest/java/util/stream/FlagOpTest.java
jdk/test/java/util/stream/boottest/java/util/stream/IntNodeTest.java
jdk/test/java/util/stream/boottest/java/util/stream/LongNodeTest.java
jdk/test/java/util/stream/boottest/java/util/stream/NodeBuilderTest.java
jdk/test/java/util/stream/boottest/java/util/stream/NodeTest.java
jdk/test/java/util/stream/boottest/java/util/stream/SliceSpliteratorTest.java
jdk/test/java/util/stream/boottest/java/util/stream/SpinedBufferTest.java
jdk/test/java/util/stream/boottest/java/util/stream/StreamFlagsTest.java
jdk/test/java/util/stream/boottest/java/util/stream/StreamOpFlagsTest.java
jdk/test/java/util/stream/boottest/java/util/stream/StreamReuseTest.java
--- a/jdk/.hgtags	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/.hgtags	Tue Nov 17 10:29:28 2015 -0800
@@ -334,3 +334,4 @@
 0d0a63b325592607974612f9cfb48590975aa2d6 jdk9-b89
 b433e4dfb830fea60e5187e4580791b62cc362d2 jdk9-b90
 97624df5026a2fb191793697dbd2c604c4d5c66e jdk9-b91
+6a5c99506f44538b879d8635a3979849ed587130 jdk9-b92
--- a/jdk/make/Import.gmk	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/make/Import.gmk	Tue Nov 17 10:29:28 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
@@ -45,8 +45,16 @@
 #
 # Import hotspot
 #
+
+# Don't import jsig library for static builds
+ifneq ($(STATIC_BUILD), true)
+  JSIG_IMPORT = jsig.*
+else
+  JSIG_IMPORT = 
+endif
+
 HOTSPOT_BASE_IMPORT_FILES := \
-    $(addprefix $(LIBRARY_PREFIX), jvm.* jsig.* jvm_db.* jvm_dtrace.*) \
+    $(addprefix $(LIBRARY_PREFIX), jvm.* $(JSIG_IMPORT) jvm_db.* jvm_dtrace.*) \
     Xusage.txt \
     #
 
@@ -79,32 +87,34 @@
 
 ################################################################################
 
-ifeq ($(OPENJDK_TARGET_OS), macosx)
-  JSIG_DEBUGINFO := $(strip $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig$(SHARED_LIBRARY_SUFFIX).dSYM) \
-      $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.diz) )
-else
-  JSIG_DEBUGINFO := $(strip $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.debuginfo) \
-      $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.diz) )
-endif
+ifneq ($(STATIC_BUILD), true)
+  ifeq ($(OPENJDK_TARGET_OS), macosx)
+    JSIG_DEBUGINFO := $(strip $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig$(SHARED_LIBRARY_SUFFIX).dSYM) \
+        $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.diz) )
+  else
+    JSIG_DEBUGINFO := $(strip $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.debuginfo) \
+        $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.diz) )
+  endif
 
-ifneq ($(OPENJDK_TARGET_OS), windows)
-  ifeq ($(JVM_VARIANT_SERVER), true)
-    BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/server/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX)
-    ifneq (, $(JSIG_DEBUGINFO))
-      BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/server/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I))
+  ifneq ($(OPENJDK_TARGET_OS), windows)
+    ifeq ($(JVM_VARIANT_SERVER), true)
+      BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/server/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX)
+      ifneq (, $(JSIG_DEBUGINFO))
+        BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/server/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I))
+      endif
     endif
-  endif
-  ifeq ($(JVM_VARIANT_CLIENT), true)
-    BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/client/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX)
-    ifneq (, $(JSIG_DEBUGINFO))
-      BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/client/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I))
+    ifeq ($(JVM_VARIANT_CLIENT), true)
+      BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/client/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX)
+      ifneq (, $(JSIG_DEBUGINFO))
+        BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/client/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I))
+      endif
     endif
-  endif
-  ifneq ($(OPENJDK_TARGET_OS), macosx)
-    ifeq ($(JVM_VARIANT_MINIMAL1), true)
-      BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/minimal/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX)
-      ifneq (,$(JSIG_DEBUGINFO))
-        BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/minimal/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I))
+    ifneq ($(OPENJDK_TARGET_OS), macosx)
+      ifeq ($(JVM_VARIANT_MINIMAL1), true)
+        BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/minimal/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX)
+        ifneq (,$(JSIG_DEBUGINFO))
+          BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/minimal/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I))
+        endif
       endif
     endif
   endif
--- a/jdk/make/data/charsetmapping/DoubleByte-X.java.template	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/make/data/charsetmapping/DoubleByte-X.java.template	Tue Nov 17 10:29:28 2015 -0800
@@ -50,12 +50,12 @@
 
     public CharsetDecoder newDecoder() {
         initb2c();
-        return new  DoubleByte.Decoder$DECTYPE$(this, b2c, b2cSB, $B2MIN$, $B2MAX$);
+        return new  DoubleByte.Decoder$DECTYPE$(this, b2c, b2cSB, $B2MIN$, $B2MAX$, $ASCIICOMPATIBLE$);
     }
 
     public CharsetEncoder newEncoder() {
         initc2b();
-        return new DoubleByte.Encoder$ENCTYPE$(this, $ENC_REPLACEMENT$ c2b, c2bIndex); 
+        return new DoubleByte.Encoder$ENCTYPE$(this, $ENC_REPLACEMENT$ c2b, c2bIndex, $ASCIICOMPATIBLE$);
     }
 
     $B2C$
--- a/jdk/make/data/charsetmapping/SingleByte-X.java.template	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/make/data/charsetmapping/SingleByte-X.java.template	Tue Nov 17 10:29:28 2015 -0800
@@ -48,11 +48,11 @@
     }
 
     public CharsetDecoder newDecoder() {
-        return new SingleByte.Decoder(this, b2c);
+        return new SingleByte.Decoder(this, b2c, $ASCIICOMPATIBLE$);
     }
 
     public CharsetEncoder newEncoder() {
-        return new SingleByte.Encoder(this, c2b, c2bIndex);
+        return new SingleByte.Encoder(this, c2b, c2bIndex, $ASCIICOMPATIBLE$);
     }
 
     private final static String b2cTable = $B2CTABLE$
--- a/jdk/make/gensrc/Gensrc-java.base.gmk	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/make/gensrc/Gensrc-java.base.gmk	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
@@ -38,15 +38,15 @@
 
 include GensrcProperties.gmk
 
-$(eval $(call SetupCompileProperties,LIST_RESOURCE_BUNDLE, \
-    $(filter %.properties, \
-        $(call CacheFind, $(JDK_TOPDIR)/src/java.base/share/classes/sun/launcher/resources)), \
-    ListResourceBundle))
+$(eval $(call SetupCompileProperties, LIST_RESOURCE_BUNDLE, \
+    SRC_DIRS := $(JDK_TOPDIR)/src/java.base/share/classes/sun/launcher/resources, \
+    CLASS := ListResourceBundle, \
+))
 
-$(eval $(call SetupCompileProperties,SUN_UTIL, \
-    $(filter %.properties, \
-        $(call CacheFind, $(JDK_TOPDIR)/src/java.base/share/classes/sun/util/resources)), \
-    sun.util.resources.LocaleNamesBundle))
+$(eval $(call SetupCompileProperties, SUN_UTIL, \
+    SRC_DIRS := $(JDK_TOPDIR)/src/java.base/share/classes/sun/util/resources, \
+    CLASS := sun.util.resources.LocaleNamesBundle, \
+))
 
 GENSRC_JAVA_BASE += $(LIST_RESOURCE_BUNDLE) $(SUN_UTIL)
 
--- a/jdk/make/gensrc/Gensrc-java.desktop.gmk	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/make/gensrc/Gensrc-java.desktop.gmk	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
@@ -66,11 +66,11 @@
   PROP_SRC_DIRS += $(JDK_TOPDIR)/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/resources
 endif
 
-PROP_SRC_FILES := $(filter-out %cursors.properties, \
-    $(filter %.properties, $(call CacheFind, $(PROP_SRC_DIRS))))
-
-$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \
-    $(PROP_SRC_FILES), ListResourceBundle))
+$(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \
+    SRC_DIRS := $(PROP_SRC_DIRS), \
+    EXCLUDE := %cursors.properties, \
+    CLASS := ListResourceBundle, \
+))
 
 GENSRC_JAVA_DESKTOP += $(COMPILE_PROPERTIES)
 
--- a/jdk/make/gensrc/Gensrc-java.logging.gmk	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/make/gensrc/Gensrc-java.logging.gmk	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 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,10 +29,10 @@
 
 include GensrcProperties.gmk
 
-$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \
-    $(filter %.properties, \
-        $(call CacheFind, $(JDK_TOPDIR)/src/java.logging/share/classes/sun/util/logging/resources)), \
-    ListResourceBundle))
+$(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \
+    SRC_DIRS := $(JDK_TOPDIR)/src/java.logging/share/classes/sun/util/logging/resources, \
+    CLASS := ListResourceBundle, \
+))
 
 TARGETS += $(COMPILE_PROPERTIES)
 
--- a/jdk/make/gensrc/Gensrc-java.management.gmk	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/make/gensrc/Gensrc-java.management.gmk	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
@@ -32,10 +32,10 @@
 
 include GensrcProperties.gmk
 
-$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \
-    $(filter %.properties, \
-        $(call CacheFind, $(JDK_TOPDIR)/src/java.management/share/classes/sun/management/resources)), \
-    ListResourceBundle))
+$(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \
+    SRC_DIRS := $(JDK_TOPDIR)/src/java.management/share/classes/sun/management/resources, \
+    CLASS := ListResourceBundle, \
+))
 
 TARGETS += $(COMPILE_PROPERTIES)
 
--- a/jdk/make/gensrc/Gensrc-jdk.dev.gmk	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/make/gensrc/Gensrc-jdk.dev.gmk	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 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,11 +29,10 @@
 
 include GensrcProperties.gmk
 
-$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \
-    $(filter %.properties, \
-        $(call CacheFind, \
-            $(JDK_TOPDIR)/src/jdk.dev/share/classes/jdk/tools/jimage/resources)), \
-    ListResourceBundle))
+$(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \
+    SRC_DIRS := $(JDK_TOPDIR)/src/jdk.dev/share/classes/jdk/tools/jimage/resources, \
+    CLASS := ListResourceBundle, \
+))
 
 TARGETS += $(COMPILE_PROPERTIES)
 
--- a/jdk/make/gensrc/Gensrc-jdk.jartool.gmk	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/make/gensrc/Gensrc-jdk.jartool.gmk	Tue Nov 17 10:29:28 2015 -0800
@@ -29,11 +29,10 @@
 
 include GensrcProperties.gmk
 
-$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \
-    $(filter %.properties, \
-        $(call CacheFind, \
-            $(JDK_TOPDIR)/src/jdk.jartool/share/classes/sun/tools/jar/resources)), \
-    ListResourceBundle))
+$(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \
+    SRC_DIRS := $(JDK_TOPDIR)/src/jdk.jartool/share/classes/sun/tools/jar/resources, \
+    CLASS := ListResourceBundle, \
+))
 
 TARGETS += $(COMPILE_PROPERTIES)
 
--- a/jdk/make/gensrc/Gensrc-jdk.jdi.gmk	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/make/gensrc/Gensrc-jdk.jdi.gmk	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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,7 +34,7 @@
 JAVA_FILE := $(SUPPORT_OUTPUTDIR)/gensrc/jdk.jdi/com/sun/tools/jdi/JDWP.java
 
 # Both the header and java file are created using the same recipe. By declaring
-# this rule and adding header file to dependencies for java file, both are 
+# this rule and adding header file to dependencies for java file, both are
 # rebuilt if either is missing
 $(HEADER_FILE): $(JDWP_SPEC_FILE) $(BUILD_TOOLS_JDK)
 
@@ -90,10 +90,10 @@
 
 include GensrcProperties.gmk
 
-$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \
-    $(filter %.properties, \
-        $(call CacheFind, $(JDK_TOPDIR)/src/jdk.jdi/share/classes/com/sun/tools/jdi/resources)), \
-    ListResourceBundle))
+$(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \
+    SRC_DIRS := $(JDK_TOPDIR)/src/jdk.jdi/share/classes/com/sun/tools/jdi/resources, \
+    CLASS := ListResourceBundle, \
+))
 
 GENSRC_JDK_JDI += $(COMPILE_PROPERTIES)
 
--- a/jdk/make/gensrc/Gensrc-jdk.localedata.gmk	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/make/gensrc/Gensrc-jdk.localedata.gmk	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 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
@@ -35,10 +35,10 @@
 
 include GensrcProperties.gmk
 
-$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \
-    $(filter %.properties, \
-        $(call CacheFind, $(JDK_TOPDIR)/src/jdk.localedata/share/classes/sun/util/resources)), \
-    sun.util.resources.LocaleNamesBundle))
+$(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \
+    SRC_DIRS := $(JDK_TOPDIR)/src/jdk.localedata/share/classes/sun/util/resources, \
+    CLASS := sun.util.resources.LocaleNamesBundle, \
+))
 
 # Skip generating zh_HK from zh_TW for this module.
 GENSRC_JDK_LOCALEDATA += $(filter-out %_zh_HK.java, $(COMPILE_PROPERTIES))
--- a/jdk/make/gensrc/GensrcProperties.gmk	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/make/gensrc/GensrcProperties.gmk	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
@@ -49,30 +49,40 @@
 endef
 
 ################################################################################
-# Creates a rule that runs CompileProperties on a set of properties files.
-# Param 1 - Variable to add targets to, must not contain space
-# Param 2 - Properties files to process
-# Param 3 - The super class for the generated classes
-# Param 4 - Module path root, defaults to $(JDK_TOPDIR)/src
-define SetupCompileProperties
-  $1_SRCS := $2
-  $1_CLASS := $3
-  $1_MODULE_PATH_ROOT := $4
-
+# Setup make rules that runs CompileProperties on a set of properties files.
+#
+# Parameter 1 is the name of the rule. This name is used as variable prefix,
+# and the targets generated are listed in a variable by that name.
+#
+# Remaining parameters are named arguments. These include:
+# SRC_DIRS   Directories containing properties files to process.
+# EXCLUDE   Exclude files matching this pattern.
+# CLASS   The super class for the generated classes.
+# MODULE_PATH_ROOT   Module path root, defaults to $(JDK_TOPDIR)/src.
+SetupCompileProperties = $(NamedParamsMacroTemplate)
+define SetupCompilePropertiesBody
+  # Set default value unless overridden
   ifeq ($$($1_MODULE_PATH_ROOT), )
     $1_MODULE_PATH_ROOT := $(JDK_TOPDIR)/src
   endif
 
+  # Locate all properties files in the given source dirs.
+  $1_SRC_FILES := $$(filter %.properties, $$(call CacheFind, $$($1_SRC_DIRS)))
+
+  ifneq ($$($1_EXCLUDE), )
+    $1_SRC_FILES := $$(filter-out $$($1_EXCLUDE), $$($1_SRC_FILES))
+  endif
+
   # Convert .../src/<module>/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties
   # to .../support/gensrc/<module>/com/sun/tools/javac/resources/javac_zh_CN.java
-  # Strip away prefix and suffix, leaving for example only: 
+  # Strip away prefix and suffix, leaving for example only:
   # "<module>/share/classes/com/sun/tools/javac/resources/javac_zh_CN"
   $1_JAVAS := $$(patsubst $$($1_MODULE_PATH_ROOT)/%, \
       $(SUPPORT_OUTPUTDIR)/gensrc/%, \
       $$(patsubst %.properties, %.java, \
       $$(subst /$(OPENJDK_TARGET_OS)/classes,, \
       $$(subst /$(OPENJDK_TARGET_OS_TYPE)/classes,, \
-      $$(subst /share/classes,, $$($1_SRCS))))))
+      $$(subst /share/classes,, $$($1_SRC_FILES))))))
 
   # Generate the package dirs for the to be generated java files. Sort to remove
   # duplicates.
@@ -82,22 +92,22 @@
   # "-compile ...javac_zh_CN.properties ...javac_zh_CN.java java.util.ListResourceBundle"
   # suitable to be fed into the CompileProperties command.
   $1_CMDLINE := $$(subst _SPACE_, $(SPACE), \
-      $$(join $$(addprefix -compile_SPACE_, $$($1_SRCS)), \
+      $$(join $$(addprefix -compile_SPACE_, $$($1_SRC_FILES)), \
       $$(addsuffix _SPACE_$$($1_CLASS), \
       $$(addprefix _SPACE_, $$($1_JAVAS)))))
 
-  $1_TARGET := $(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/_the.$1.done
+  $1_TARGET := $(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/_the.$1.marker
   $1_CMDLINE_FILE := $(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/_the.$1.cmdline
 
 # Now setup the rule for the generation of the resource bundles.
-  $$($1_TARGET): $$($1_SRCS) $$($1_JAVAS) $(BUILD_TOOLS_JDK)
+  $$($1_TARGET): $$($1_SRC_FILES) $$($1_JAVAS) $(BUILD_TOOLS_JDK)
 	$(MKDIR) -p $$(@D) $$($1_DIRS)
-	$(ECHO) Compiling $$(words $$($1_SRCS)) properties into resource bundles for $(MODULE)
+	$(ECHO) Compiling $$(words $$($1_SRC_FILES)) properties into resource bundles for $(MODULE)
 	$$(eval $$(call ListPathsSafely, $1_CMDLINE, $$($1_CMDLINE_FILE)))
 	$(TOOL_COMPILEPROPERTIES) -quiet @$$($1_CMDLINE_FILE)
 	$(TOUCH) $$@
 
-  $$($1_JAVAS): $$($1_SRCS)
+  $$($1_JAVAS): $$($1_SRC_FILES)
 
   # Create zh_HK versions of all zh_TW files created above
   $$(eval $$(call SetupCopy-zh_HK,$1_HK,$$(filter %_zh_TW.java, $$($1_JAVAS))))
--- a/jdk/make/launcher/LauncherCommon.gmk	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/make/launcher/LauncherCommon.gmk	Tue Nov 17 10:29:28 2015 -0800
@@ -122,8 +122,23 @@
     endif
 
     $1_CFLAGS += -DPACKAGE_PATH='"$(PACKAGE_PATH)"'
-    $1_LDFLAGS += -Wl,-all_load $(SUPPORT_OUTPUTDIR)/native/java.base/libjli_static.a \
+    $1_LDFLAGS += -Wl,-all_load \
         -sectcreate __TEXT __info_plist $(MACOSX_PLIST_DIR)/$$($1_PLIST_FILE)
+    ifeq ($(STATIC_BUILD), true)
+      $1_LDFLAGS += -exported_symbols_list \
+              $(SUPPORT_OUTPUTDIR)/build-static/exported.symbols
+      $1_LIBS += \
+          $(shell $(FIND) $(SUPPORT_OUTPUTDIR)/modules_libs/java.base -name "*.a") \
+          $(SUPPORT_OUTPUTDIR)/modules_libs/jdk.jdwp.agent/libdt_socket.a \
+          $(SUPPORT_OUTPUTDIR)/modules_libs/jdk.jdwp.agent/libjdwp.a \
+          $(SUPPORT_OUTPUTDIR)/native/java.base/$(LIBRARY_PREFIX)fdlibm$(STATIC_LIBRARY_SUFFIX) \
+          -framework CoreFoundation \
+          -framework Foundation \
+          -framework SystemConfiguration \
+          -lstdc++ -liconv
+    else
+      $1_LIBS += $(SUPPORT_OUTPUTDIR)/native/java.base/libjli_static.a
+    endif
     $1_LIBS += -framework Cocoa -framework Security \
         -framework ApplicationServices
   endif
--- a/jdk/make/lib/CoreLibraries.gmk	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/make/lib/CoreLibraries.gmk	Tue Nov 17 10:29:28 2015 -0800
@@ -435,10 +435,14 @@
       OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjli_static, \
       DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
 
-  $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjli_static.a: $(BUILD_LIBJLI_STATIC)
+  ifeq ($(STATIC_BUILD), true)
+    TARGETS += $(BUILD_LIBJLI_STATIC)
+  else
+    $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjli_static.a: $(BUILD_LIBJLI_STATIC)
 	$(call install-file)
 
-  TARGETS += $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjli_static.a
+    TARGETS += $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjli_static.a
+  endif
 
 else ifeq ($(OPENJDK_TARGET_OS), aix)
   # AIX also requires a static libjli because the compiler doesn't support '-rpath'
--- a/jdk/make/lib/Lib-java.base.gmk	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/make/lib/Lib-java.base.gmk	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 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
@@ -33,3 +33,29 @@
 include NetworkingLibraries.gmk
 include NioLibraries.gmk
 include SecurityLibraries.gmk
+
+ifeq ($(STATIC_BUILD), true)
+  JAVA_BASE_EXPORT_SYMBOLS_SRC := \
+      $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/jli/$(LIBRARY_PREFIX)jli.symbols \
+      $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/$(LIBRARY_PREFIX)java.symbols \
+      $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/$(LIBRARY_PREFIX)net.symbols \
+      $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/$(LIBRARY_PREFIX)nio.symbols \
+      $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/$(LIBRARY_PREFIX)verify.symbols \
+      $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/$(LIBRARY_PREFIX)zip.symbols \
+      $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/$(LIBRARY_PREFIX)jimage.symbols \
+      $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/server/$(LIBRARY_PREFIX)jvm.symbols \
+      #
+
+  JAVA_BASE_EXPORT_SYMBOL_FILE := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/java.base.symbols
+
+  $(JAVA_BASE_EXPORT_SYMBOL_FILE): $(JAVA_BASE_EXPORT_SYMBOLS_SRC)
+	$(ECHO) $(LOG_INFO) "Generating java.base.symbols file"
+	$(CAT) $^ > $@
+
+  # The individual symbol files is generated when the respective lib is built
+  $(JAVA_BASE_EXPORT_SYMBOLS_SRC): $(BUILD_LIBJLI) $(BUILD_LIBJAVA) \
+      $(BUILD_LIBNET) $(BUILD_LIBNIO) $(BUILD_LIBVERIFY) $(BUILD_LIBZIP) \
+      $(BUILD_LIBJIMAGE)
+
+  TARGETS += $(JAVA_BASE_EXPORT_SYMBOL_FILE)
+endif
--- a/jdk/make/lib/Lib-jdk.jdwp.agent.gmk	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/make/lib/Lib-jdk.jdwp.agent.gmk	Tue Nov 17 10:29:28 2015 -0800
@@ -102,3 +102,23 @@
 TARGETS += $(BUILD_LIBJDWP)
 
 ################################################################################
+
+ifeq ($(STATIC_BUILD), true)
+  JDK_JDWP_AGENT_EXPORT_SYMBOLS_SRC := \
+      $(SUPPORT_OUTPUTDIR)/modules_libs/jdk.jdwp.agent/$(LIBRARY_PREFIX)dt_socket.symbols \
+      $(SUPPORT_OUTPUTDIR)/modules_libs/jdk.jdwp.agent/$(LIBRARY_PREFIX)jdwp.symbols
+
+  JDK_JDWP_AGENT_EXPORT_SYMBOL_FILE := $(SUPPORT_OUTPUTDIR)/modules_libs/jdk.jdwp.agent/jdk.jdwp.agent.symbols
+
+  $(JDK_JDWP_AGENT_EXPORT_SYMBOL_FILE): $(JDK_JDWP_AGENT_EXPORT_SYMBOLS_SRC)
+	$(ECHO) $(LOG_INFO) "Generating jdk.jdwp.agent symbols file"
+	$(CAT) $^ > $@
+
+  # The individual symbol files is generated when the respective lib is built
+  $(JDK_JDWP_AGENT_EXPORT_SYMBOLS_SRC): $(BUILD_LIBDT_SOCKET) $(BUILD_LIBJDWP)
+
+  TARGETS += $(JDK_JDWP_AGENT_EXPORT_SYMBOL_FILE)
+
+endif
+
+################################################################################
--- a/jdk/make/lib/SecurityLibraries.gmk	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/make/lib/SecurityLibraries.gmk	Tue Nov 17 10:29:28 2015 -0800
@@ -26,38 +26,41 @@
 include LibCommon.gmk
 
 ifeq ($(OPENJDK_TARGET_OS), macosx)
+  # JavaNativeFoundation framework not supported in static builds 
+  ifneq ($(STATIC_BUILD), true)
 
   ################################################################################
 
-  LIBOSXSECURITY_DIRS := $(JDK_TOPDIR)/src/java.base/macosx/native/libosxsecurity
-  LIBOSXSECURITY_CFLAGS := -I$(LIBOSXSECURITY_DIRS) \
-      $(LIBJAVA_HEADER_FLAGS) \
-      -I$(SUPPORT_OUTPUTDIR)/headers/java.base \
+    LIBOSXSECURITY_DIRS := $(JDK_TOPDIR)/src/java.base/macosx/native/libosxsecurity
+    LIBOSXSECURITY_CFLAGS := -I$(LIBOSXSECURITY_DIRS) \
+        $(LIBJAVA_HEADER_FLAGS) \
+        -I$(SUPPORT_OUTPUTDIR)/headers/java.base \
 
-  $(eval $(call SetupNativeCompilation,BUILD_LIBOSXSECURITY, \
-      LIBRARY := osxsecurity, \
-      OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
-      SRC := $(LIBOSXSECURITY_DIRS), \
-      OPTIMIZATION := LOW, \
-      CFLAGS := $(CFLAGS_JDKLIB) \
-          $(LIBOSXSECURITY_CFLAGS), \
-      DISABLED_WARNINGS_clang := deprecated-declarations, \
-      LDFLAGS := $(LDFLAGS_JDKLIB) \
-          -L$(SUPPORT_OUTPUTDIR)/modules_libs/java.base \
-          $(call SET_SHARED_LIBRARY_ORIGIN) \
-          -fobjc-link-runtime, \
-      LIBS := \
-          -framework JavaNativeFoundation \
-          -framework CoreServices \
-          -framework Security \
-          $(JDKLIB_LIBS), \
-      OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libosxsecurity, \
-      DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
+    $(eval $(call SetupNativeCompilation,BUILD_LIBOSXSECURITY, \
+        LIBRARY := osxsecurity, \
+        OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+        SRC := $(LIBOSXSECURITY_DIRS), \
+        OPTIMIZATION := LOW, \
+        CFLAGS := $(CFLAGS_JDKLIB) \
+            $(LIBOSXSECURITY_CFLAGS), \
+        DISABLED_WARNINGS_clang := deprecated-declarations, \
+        LDFLAGS := $(LDFLAGS_JDKLIB) \
+            -L$(SUPPORT_OUTPUTDIR)/modules_libs/java.base \
+            $(call SET_SHARED_LIBRARY_ORIGIN) \
+            -fobjc-link-runtime, \
+        LIBS := \
+            -framework JavaNativeFoundation \
+            -framework CoreServices \
+            -framework Security \
+            $(JDKLIB_LIBS), \
+        OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libosxsecurity, \
+        DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
 
-  $(BUILD_LIBOSXSECURITY): $(BUILD_LIBJAVA)
+    $(BUILD_LIBOSXSECURITY): $(BUILD_LIBJAVA)
 
-  TARGETS += $(BUILD_LIBOSXSECURITY)
+    TARGETS += $(BUILD_LIBOSXSECURITY)
 
   ################################################################################
 
+  endif
 endif
--- a/jdk/make/mapfiles/libjava/mapfile-vers	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/make/mapfiles/libjava/mapfile-vers	Tue Nov 17 10:29:28 2015 -0800
@@ -211,6 +211,7 @@
 		Java_java_lang_SecurityManager_getClassContext;
 		Java_java_lang_Shutdown_halt0;
 		Java_java_lang_String_intern;
+		Java_java_lang_StringUTF16_isBigEndian;
 		Java_java_lang_System_identityHashCode;
 		Java_java_lang_System_initProperties;
 		Java_java_lang_System_mapLibraryName;
--- a/jdk/make/mapfiles/libjava/reorder-sparc	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/make/mapfiles/libjava/reorder-sparc	Tue Nov 17 10:29:28 2015 -0800
@@ -57,6 +57,7 @@
 text: .text%JNU_ClassString;
 text: .text%JNU_CopyObjectArray;
 text: .text%Java_java_lang_String_intern;
+text: .text%Java_java_lang_StringUTF16_isBigEndian;
 text: .text%Java_java_lang_ClassLoader_findLoadedClass0;
 text: .text%Java_java_lang_ClassLoader_findBootstrapClass;
 text: .text%Java_java_lang_Throwable_fillInStackTrace;
--- a/jdk/make/mapfiles/libjava/reorder-sparcv9	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/make/mapfiles/libjava/reorder-sparcv9	Tue Nov 17 10:29:28 2015 -0800
@@ -29,6 +29,7 @@
 text: .text%Java_sun_reflect_Reflection_getCallerClass__I;
 text: .text%Java_java_lang_Class_forName0;
 text: .text%Java_java_lang_String_intern;
+text: .text%Java_java_lang_StringUTF16_isBigEndian;
 text: .text%Java_java_lang_Float_floatToRawIntBits;
 text: .text%Java_java_lang_Double_doubleToRawLongBits;
 text: .text%Java_java_lang_ClassLoader_findLoadedClass0;
--- a/jdk/make/mapfiles/libjava/reorder-x86	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/make/mapfiles/libjava/reorder-x86	Tue Nov 17 10:29:28 2015 -0800
@@ -31,6 +31,7 @@
 text: .text%Java_sun_reflect_Reflection_getCallerClass__I;
 text: .text%Java_java_lang_Class_forName0;
 text: .text%Java_java_lang_String_intern;
+text: .text%Java_java_lang_StringUTF16_isBigEndian;
 text: .text%Java_sun_reflect_NativeConstructorAccessorImpl_newInstance0;
 text: .text%Java_java_lang_Throwable_fillInStackTrace;
 text: .text%Java_java_lang_System_setOut0;
--- a/jdk/make/mapfiles/libnio/mapfile-macosx	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/make/mapfiles/libnio/mapfile-macosx	Tue Nov 17 10:29:28 2015 -0800
@@ -75,6 +75,7 @@
                 Java_sun_nio_ch_IOUtil_makePipe;
                 Java_sun_nio_ch_IOUtil_randomBytes;
                 Java_sun_nio_ch_IOUtil_setfdVal;
+                Java_sun_nio_ch_IOUtil_iovMax;
 		Java_sun_nio_ch_KQueue_kqueue;
 		Java_sun_nio_ch_KQueue_keventRegister;
 		Java_sun_nio_ch_KQueue_keventPoll;
--- a/jdk/make/src/classes/build/tools/charsetmapping/DBCS.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/make/src/classes/build/tools/charsetmapping/DBCS.java	Tue Nov 17 10:29:28 2015 -0800
@@ -197,6 +197,7 @@
                        .replace("$B1MAX$"   , "0x" + Integer.toString(b1Max, 16))
                        .replace("$B2MIN$"   , "0x" + Integer.toString(b2Min, 16))
                        .replace("$B2MAX$"   , "0x" + Integer.toString(b2Max, 16))
+                       .replace("$ASCIICOMPATIBLE$", isASCII ? "true" : "false")
                        .replace("$B2C$", b2c)
                        .replace("$C2BLENGTH$", "0x" + Integer.toString(c2bOff, 16))
                        .replace("$NONROUNDTRIP_B2C$", b2cNR)
--- a/jdk/make/src/classes/build/tools/charsetmapping/SBCS.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/make/src/classes/build/tools/charsetmapping/SBCS.java	Tue Nov 17 10:29:28 2015 -0800
@@ -175,6 +175,9 @@
                 else
                     line = "        return (cs instanceof " + clzName + ");";
             }
+            if (line.indexOf("$ASCIICOMPATIBLE$") != -1) {
+                line = line.replace("$ASCIICOMPATIBLE$", isASCII ? "true" : "false");
+            }
             if (line.indexOf("$B2CTABLE$") != -1) {
                 line = line.replace("$B2CTABLE$", b2c);
             }
--- a/jdk/make/src/classes/build/tools/x11wrappergen/WrapperGenerator.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/make/src/classes/build/tools/x11wrappergen/WrapperGenerator.java	Tue Nov 17 10:29:28 2015 -0800
@@ -841,7 +841,7 @@
                 pw.println("// This file is an automatically generated file, please do not edit this file, modify the WrapperGenerator.java file instead !\n" );
 
                 pw.println("package "+package_name+";\n");
-                pw.println("import sun.misc.*;\n");
+                pw.println("import jdk.internal.misc.Unsafe;\n");
                 pw.println("import sun.util.logging.PlatformLogger;");
                 String baseClass = stp.getBaseClass();
                 if (baseClass == null) {
@@ -941,7 +941,7 @@
             pw.println("// This file is an automatically generated file, please do not edit this file, modify the WrapperGenerator.java file instead !\n" );
 
             pw.println("package "+package_name+";\n");
-            pw.println("import sun.misc.Unsafe;\n");
+            pw.println("import jdk.internal.misc.Unsafe;\n");
             pw.println("class " + ft.getName() + " {");
             pw.println("\tprivate static Unsafe unsafe = XlibWrapper.unsafe;");
             pw.println("\tprivate boolean __executed = false;");
--- a/jdk/src/demo/share/jvmti/agent_util/agent_util.h	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/demo/share/jvmti/agent_util/agent_util.h	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -65,6 +65,51 @@
 void *allocate(jvmtiEnv *jvmti, jint len);
 void  add_demo_jar_to_bootclasspath(jvmtiEnv *jvmti, char *demo_name);
 
+#ifdef STATIC_BUILD
+/* Macros for handling declaration of static/dynamic
+ * Agent library Load/Attach/Unload functions
+ *
+ * DEF_Agent_OnLoad, DEF_Agent_OnAttach or DEF_Agent_OnUnload
+ * generate the appropriate entrypoint names based on static
+ * versus dynamic builds.
+ *
+ * STATIC_BUILD must be defined to build static versions of these libraries.
+ * LIBRARY_NAME must be set to the name of the library for static builds.
+ */
+#define ADD_LIB_NAME3(name, lib) name ## lib
+#define ADD_LIB_NAME2(name, lib) ADD_LIB_NAME3(name, lib)
+#define ADD_LIB_NAME(entry) ADD_LIB_NAME2(entry, LIBRARY_NAME)
+
+#define DEF_Agent_OnLoad \
+ADD_LIB_NAME(Agent_OnLoad_)(JavaVM *vm, char *options, void *reserved) \
+{ \
+  jint JNICALL ADD_LIB_NAME(Agent_OnLoad_dynamic_)(JavaVM *vm, char *options, void *reserved); \
+  return ADD_LIB_NAME(Agent_OnLoad_dynamic_)(vm, options, reserved); \
+} \
+jint JNICALL ADD_LIB_NAME(Agent_OnLoad_dynamic_)
+
+#define DEF_Agent_OnAttach \
+ADD_LIB_NAME(Agent_OnAttach_)(JavaVM *vm, char *options, void *reserved) \
+{ \
+  jint JNICALL ADD_LIB_NAME(Agent_OnAttach_dynamic_)(JavaVM *vm, char *options, void *reserved); \
+  return ADD_LIB_NAME(Agent_OnAttach_dynamic_)(vm, options, reserved); \
+} \
+jint JNICALL ADD_LIB_NAME(Agent_OnAttach_dynamic_)
+
+#define DEF_Agent_OnUnload \
+ADD_LIB_NAME(Agent_OnUnload_)(JavaVM *vm) \
+{ \
+  void JNICALL ADD_LIB_NAME(Agent_OnUnload_dynamic_)(JavaVM *vm); \
+  ADD_LIB_NAME(Agent_OnUnload_dynamic_)(vm); \
+} \
+void JNICALL ADD_LIB_NAME(Agent_OnUnload_dynamic_)
+
+#else
+#define DEF_Agent_OnLoad Agent_OnLoad
+#define DEF_Agent_OnAttach Agent_OnAttach
+#define DEF_Agent_OnUnload Agent_OnUnload
+#endif
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif /* __cplusplus */
--- a/jdk/src/demo/share/jvmti/compiledMethodLoad/compiledMethodLoad.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/demo/share/jvmti/compiledMethodLoad/compiledMethodLoad.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -225,7 +225,7 @@
  * event here.
  */
 JNIEXPORT jint JNICALL
-Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
+DEF_Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
 {
     jint                rc;
     jvmtiError          err;
@@ -272,6 +272,6 @@
 
 /* Agent_OnUnload() is called last */
 JNIEXPORT void JNICALL
-Agent_OnUnload(JavaVM *vm)
+DEF_Agent_OnUnload(JavaVM *vm)
 {
 }
--- a/jdk/src/demo/share/jvmti/gctest/gctest.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/demo/share/jvmti/gctest/gctest.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -148,7 +148,7 @@
 
 /* Agent_OnLoad() is called first, we prepare for a VM_INIT event here. */
 JNIEXPORT jint JNICALL
-Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
+DEF_Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
 {
     jint                rc;
     jvmtiError          err;
@@ -193,6 +193,6 @@
 
 /* Agent_OnUnload() is called last */
 JNIEXPORT void JNICALL
-Agent_OnUnload(JavaVM *vm)
+DEF_Agent_OnUnload(JavaVM *vm)
 {
 }
--- a/jdk/src/demo/share/jvmti/heapTracker/heapTracker.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/demo/share/jvmti/heapTracker/heapTracker.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -894,7 +894,7 @@
  *   loaded. This is the first code executed.
  */
 JNIEXPORT jint JNICALL
-Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
+DEF_Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
 {
     static GlobalAgentData data;
     jvmtiEnv              *jvmti;
@@ -1010,7 +1010,7 @@
  *   unloaded. This is the last code executed.
  */
 JNIEXPORT void JNICALL
-Agent_OnUnload(JavaVM *vm)
+DEF_Agent_OnUnload(JavaVM *vm)
 {
     /* Skip any cleanup, VM is about to die anyway */
 }
--- a/jdk/src/demo/share/jvmti/heapTracker/heapTracker.h	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/demo/share/jvmti/heapTracker/heapTracker.h	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -64,9 +64,4 @@
 
 #include "agent_util.h"
 
-/* Agent library externals to export. */
-
-JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved);
-JNIEXPORT void JNICALL Agent_OnUnload(JavaVM *vm);
-
 #endif
--- a/jdk/src/demo/share/jvmti/heapViewer/heapViewer.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/demo/share/jvmti/heapViewer/heapViewer.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -235,7 +235,7 @@
 
 /* Agent_OnLoad() is called first, we prepare for a VM_INIT event here. */
 JNIEXPORT jint JNICALL
-Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
+DEF_Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
 {
     jint                rc;
     jvmtiError          err;
@@ -283,6 +283,6 @@
 
 /* Agent_OnUnload() is called last */
 JNIEXPORT void JNICALL
-Agent_OnUnload(JavaVM *vm)
+DEF_Agent_OnUnload(JavaVM *vm)
 {
 }
--- a/jdk/src/demo/share/jvmti/minst/minst.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/demo/share/jvmti/minst/minst.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -373,7 +373,7 @@
  *   loaded. This is the first code executed.
  */
 JNIEXPORT jint JNICALL
-Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
+DEF_Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
 {
     static GlobalAgentData data;
     jvmtiEnv              *jvmti;
@@ -467,7 +467,7 @@
  *   unloaded. This is the last code executed.
  */
 JNIEXPORT void JNICALL
-Agent_OnUnload(JavaVM *vm)
+DEF_Agent_OnUnload(JavaVM *vm)
 {
     /* Make sure all malloc/calloc/strdup space is freed */
     if ( gdata->include != NULL ) {
--- a/jdk/src/demo/share/jvmti/minst/minst.h	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/demo/share/jvmti/minst/minst.h	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -64,9 +64,4 @@
 
 #include "agent_util.h"
 
-/* Agent library externals to export. */
-
-JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved);
-JNIEXPORT void JNICALL Agent_OnUnload(JavaVM *vm);
-
 #endif
--- a/jdk/src/demo/share/jvmti/mtrace/mtrace.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/demo/share/jvmti/mtrace/mtrace.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -697,7 +697,7 @@
  *   loaded. This is the first code executed.
  */
 JNIEXPORT jint JNICALL
-Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
+DEF_Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
 {
     static GlobalAgentData data;
     jvmtiEnv              *jvmti;
@@ -795,7 +795,7 @@
  *   unloaded. This is the last code executed.
  */
 JNIEXPORT void JNICALL
-Agent_OnUnload(JavaVM *vm)
+DEF_Agent_OnUnload(JavaVM *vm)
 {
     /* Make sure all malloc/calloc/strdup space is freed */
     if ( gdata->include != NULL ) {
--- a/jdk/src/demo/share/jvmti/mtrace/mtrace.h	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/demo/share/jvmti/mtrace/mtrace.h	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -64,9 +64,4 @@
 
 #include "agent_util.h"
 
-/* Agent library externals to export. */
-
-JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved);
-JNIEXPORT void JNICALL Agent_OnUnload(JavaVM *vm);
-
 #endif
--- a/jdk/src/demo/share/jvmti/versionCheck/versionCheck.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/demo/share/jvmti/versionCheck/versionCheck.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -89,7 +89,7 @@
 
 /* Agent_OnLoad() is called first, we prepare for a VM_INIT event here. */
 JNIEXPORT jint JNICALL
-Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
+DEF_Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
 {
     jint                rc;
     jvmtiError          err;
@@ -116,6 +116,6 @@
 
 /* Agent_OnUnload() is called last */
 JNIEXPORT void JNICALL
-Agent_OnUnload(JavaVM *vm)
+DEF_Agent_OnUnload(JavaVM *vm)
 {
 }
--- a/jdk/src/demo/share/jvmti/waiters/Monitor.hpp	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/demo/share/jvmti/waiters/Monitor.hpp	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,6 +37,10 @@
  * this sample code.
  */
 
+#ifdef STATIC_BUILD
+#define Monitor WaiterMonitor
+#endif
+
 
 /* C++ Monitor class */
 
--- a/jdk/src/demo/share/jvmti/waiters/Thread.cpp	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/demo/share/jvmti/waiters/Thread.cpp	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,6 +37,9 @@
  * this sample code.
  */
 
+#ifdef STATIC_BUILD
+#define Thread WaiterThread
+#endif
 
 #include <stdio.h>
 #include <stdlib.h>
--- a/jdk/src/demo/share/jvmti/waiters/waiters.cpp	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/demo/share/jvmti/waiters/waiters.cpp	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -243,7 +243,7 @@
 
     /* Agent_OnLoad() is called first, we prepare for a VM_INIT event here. */
     JNIEXPORT jint JNICALL
-    Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
+    DEF_Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
     {
         jvmtiEnv           *jvmti;
         jint                rc;
@@ -288,7 +288,7 @@
 
     /* Agent_OnUnload() is called last */
     JNIEXPORT void JNICALL
-    Agent_OnUnload(JavaVM *vm)
+    DEF_Agent_OnUnload(JavaVM *vm)
     {
     }
 
--- a/jdk/src/java.base/aix/classes/sun/nio/ch/AixPollPort.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/aix/classes/sun/nio/ch/AixPollPort.java	Tue Nov 17 10:29:28 2015 -0800
@@ -34,7 +34,7 @@
 import java.util.concurrent.RejectedExecutionException;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.locks.ReentrantLock;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 /**
  * AsynchronousChannelGroup implementation based on the AIX pollset framework.
--- a/jdk/src/java.base/linux/classes/sun/nio/ch/EPoll.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/linux/classes/sun/nio/ch/EPoll.java	Tue Nov 17 10:29:28 2015 -0800
@@ -26,7 +26,7 @@
 package sun.nio.ch;
 
 import java.io.IOException;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 /**
  * Provides access to the Linux epoll facility.
--- a/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxDosFileAttributeView.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxDosFileAttributeView.java	Tue Nov 17 10:29:28 2015 -0800
@@ -29,7 +29,7 @@
 import java.util.Map;
 import java.util.Set;
 import java.io.IOException;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 import static sun.nio.fs.UnixNativeDispatcher.*;
 import static sun.nio.fs.UnixConstants.*;
--- a/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxUserDefinedFileAttributeView.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxUserDefinedFileAttributeView.java	Tue Nov 17 10:29:28 2015 -0800
@@ -29,7 +29,7 @@
 import java.nio.ByteBuffer;
 import java.io.IOException;
 import java.util.*;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 import static sun.nio.fs.UnixConstants.*;
 import static sun.nio.fs.LinuxNativeDispatcher.*;
--- a/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxWatchService.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxWatchService.java	Tue Nov 17 10:29:28 2015 -0800
@@ -30,7 +30,7 @@
 import java.security.PrivilegedAction;
 import java.util.*;
 import java.io.IOException;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 import static sun.nio.fs.UnixNativeDispatcher.*;
 import static sun.nio.fs.UnixConstants.*;
--- a/jdk/src/java.base/macosx/classes/sun/nio/ch/KQueue.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/macosx/classes/sun/nio/ch/KQueue.java	Tue Nov 17 10:29:28 2015 -0800
@@ -26,7 +26,7 @@
 package sun.nio.ch;
 
 import java.io.IOException;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 /**
  * Provides access to the BSD kqueue facility.
--- a/jdk/src/java.base/macosx/native/libjava/java_props_macosx.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/macosx/native/libjava/java_props_macosx.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -35,13 +35,15 @@
 
 #include "java_props_macosx.h"
 
-
 // need dlopen/dlsym trick to avoid pulling in JavaRuntimeSupport before libjava.dylib is loaded
 static void *getJRSFramework() {
     static void *jrsFwk = NULL;
+#ifndef STATIC_BUILD
+// JavaRuntimeSupport doesn't support static Java runtimes
     if (jrsFwk == NULL) {
        jrsFwk = dlopen("/System/Library/Frameworks/JavaVM.framework/Frameworks/JavaRuntimeSupport.framework/JavaRuntimeSupport", RTLD_LAZY | RTLD_LOCAL);
     }
+#endif
     return jrsFwk;
 }
 
--- a/jdk/src/java.base/macosx/native/libjli/java_md_macosx.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/macosx/native/libjli/java_md_macosx.c	Tue Nov 17 10:29:28 2015 -0800
@@ -245,6 +245,8 @@
     return sExportedJNIFunctions = fxns;
 }
 
+#ifndef STATIC_BUILD
+
 JNIEXPORT jint JNICALL
 JNI_GetDefaultJavaVMInitArgs(void *args) {
     InvocationFunctions *ifn = GetExportedJNIFunctions();
@@ -265,6 +267,7 @@
     if (ifn == NULL) return JNI_ERR;
     return ifn->GetCreatedJavaVMs(vmBuf, bufLen, nVMs);
 }
+#endif
 
 /*
  * Allow JLI-aware launchers to specify a client/server preference
@@ -303,7 +306,12 @@
     objc_registerThreadWithCollector();
 
     if (main_fptr == NULL) {
+#ifdef STATIC_BUILD
+        extern int main(int argc, char **argv);
+        main_fptr = &main;
+#else
         main_fptr = (int (*)())dlsym(RTLD_DEFAULT, "main");
+#endif
         if (main_fptr == NULL) {
             JLI_ReportErrorMessageSys("error locating main entrypoint\n");
             exit(1);
@@ -588,6 +596,9 @@
 
     JLI_TraceLauncher("Does `%s' exist ... ", jvmpath);
 
+#ifdef STATIC_BUILD
+    return JNI_TRUE;
+#else
     if (stat(jvmpath, &s) == 0) {
         JLI_TraceLauncher("yes.\n");
         return JNI_TRUE;
@@ -595,6 +606,7 @@
         JLI_TraceLauncher("no.\n");
         return JNI_FALSE;
     }
+#endif
 }
 
 /*
@@ -607,10 +619,18 @@
 
     if (GetApplicationHome(path, pathsize)) {
         /* Is JRE co-located with the application? */
+#ifdef STATIC_BUILD
+        char jvm_cfg[MAXPATHLEN];
+        JLI_Snprintf(jvm_cfg, sizeof(jvm_cfg), "%s/lib/jvm.cfg", path);
+        if (access(jvm_cfg, F_OK) == 0) {
+            return JNI_TRUE;
+        }
+#else
         JLI_Snprintf(libjava, sizeof(libjava), "%s/lib/" JAVA_DLL, path);
         if (access(libjava, F_OK) == 0) {
             return JNI_TRUE;
         }
+#endif
         /* ensure storage for path + /jre + NULL */
         if ((JLI_StrLen(path) + 4 + 1) > (size_t) pathsize) {
             JLI_TraceLauncher("Insufficient space to store JRE path\n");
@@ -629,6 +649,24 @@
     Dl_info selfInfo;
     dladdr(&GetJREPath, &selfInfo);
 
+#ifdef STATIC_BUILD
+    char jvm_cfg[MAXPATHLEN];
+    char *p = NULL;
+    strncpy(jvm_cfg, selfInfo.dli_fname, MAXPATHLEN);
+    p = strrchr(jvm_cfg, '/'); *p = '\0';
+    p = strrchr(jvm_cfg, '/');
+    if (strcmp(p, "/.") == 0) {
+      *p = '\0';
+      p = strrchr(jvm_cfg, '/'); *p = '\0';
+    }
+    else *p = '\0';
+    strncpy(path, jvm_cfg, pathsize);
+    strncat(jvm_cfg, "/lib/jvm.cfg", MAXPATHLEN);
+    if (access(jvm_cfg, F_OK) == 0) {
+      return JNI_TRUE;
+    }
+#endif
+
     char *realPathToSelf = realpath(selfInfo.dli_fname, path);
     if (realPathToSelf != path) {
         return JNI_FALSE;
@@ -664,7 +702,11 @@
 
     JLI_TraceLauncher("JVM path is %s\n", jvmpath);
 
+#ifndef STATIC_BUILD
     libjvm = dlopen(jvmpath, RTLD_NOW + RTLD_GLOBAL);
+#else
+    libjvm = dlopen(NULL, RTLD_FIRST);
+#endif
     if (libjvm == NULL) {
         JLI_ReportErrorMessage(DLL_ERROR1, __LINE__);
         JLI_ReportErrorMessage(DLL_ERROR2, jvmpath, dlerror());
@@ -714,9 +756,14 @@
     char* exec_path = NULL;
     {
         Dl_info dlinfo;
+
+#ifdef STATIC_BUILD
+        void *fptr;
+        fptr = (void *)&SetExecname;
+#else
         int (*fptr)();
-
         fptr = (int (*)())dlsym(RTLD_DEFAULT, "main");
+#endif
         if (fptr == NULL) {
             JLI_ReportErrorMessage(DLL_ERROR3, dlerror());
             return JNI_FALSE;
--- a/jdk/src/java.base/share/classes/java/io/File.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/io/File.java	Tue Nov 17 10:29:28 2015 -0800
@@ -2184,10 +2184,10 @@
 
     private static final long PATH_OFFSET;
     private static final long PREFIX_LENGTH_OFFSET;
-    private static final sun.misc.Unsafe UNSAFE;
+    private static final jdk.internal.misc.Unsafe UNSAFE;
     static {
         try {
-            sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
+            jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe();
             PATH_OFFSET = unsafe.objectFieldOffset(
                     File.class.getDeclaredField("path"));
             PREFIX_LENGTH_OFFSET = unsafe.objectFieldOffset(
--- a/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java	Tue Nov 17 10:29:28 2015 -0800
@@ -40,7 +40,7 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import static java.io.ObjectStreamClass.processQueue;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 import sun.reflect.misc.ReflectUtil;
 
 /**
--- a/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java	Tue Nov 17 10:29:28 2015 -0800
@@ -48,7 +48,7 @@
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 import sun.reflect.CallerSensitive;
 import sun.reflect.Reflection;
 import sun.reflect.ReflectionFactory;
--- a/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java	Tue Nov 17 10:29:28 2015 -0800
@@ -31,6 +31,12 @@
 import java.util.stream.IntStream;
 import java.util.stream.StreamSupport;
 
+import static java.lang.String.COMPACT_STRINGS;
+import static java.lang.String.UTF16;
+import static java.lang.String.LATIN1;
+import static java.lang.String.checkIndex;
+import static java.lang.String.checkOffset;
+
 /**
  * A mutable sequence of characters.
  * <p>
@@ -51,7 +57,12 @@
     /**
      * The value is used for character storage.
      */
-    char[] value;
+    byte[] value;
+
+    /**
+     * The id of the encoding used to encode the bytes in {@code value}.
+     */
+    byte coder;
 
     /**
      * The count is the number of characters used.
@@ -68,7 +79,13 @@
      * Creates an AbstractStringBuilder of the specified capacity.
      */
     AbstractStringBuilder(int capacity) {
-        value = new char[capacity];
+        if (COMPACT_STRINGS) {
+            value = new byte[capacity];
+            coder = LATIN1;
+        } else {
+            value = StringUTF16.newBytesFor(capacity);
+            coder = UTF16;
+        }
     }
 
     /**
@@ -90,7 +107,7 @@
      * @return  the current capacity
      */
     public int capacity() {
-        return value.length;
+        return value.length >> coder;
     }
 
     /**
@@ -110,8 +127,9 @@
      * @param   minimumCapacity   the minimum desired capacity.
      */
     public void ensureCapacity(int minimumCapacity) {
-        if (minimumCapacity > 0)
+        if (minimumCapacity > 0) {
             ensureCapacityInternal(minimumCapacity);
+        }
     }
 
     /**
@@ -120,24 +138,48 @@
      */
     private void ensureCapacityInternal(int minimumCapacity) {
         // overflow-conscious code
-        if (minimumCapacity - value.length > 0)
+        int capacity = value.length >> coder;
+        if (minimumCapacity - capacity > 0) {
             expandCapacity(minimumCapacity);
+        }
     }
 
     /**
      * This implements the expansion semantics of ensureCapacity with no
      * size check or synchronization.
      */
-    void expandCapacity(int minimumCapacity) {
-        int newCapacity = value.length * 2 + 2;
-        if (newCapacity - minimumCapacity < 0)
+    private void expandCapacity(int minimumCapacity) {
+        int newCapacity = (value.length >> coder) * 2 + 2;
+        if (newCapacity - minimumCapacity < 0) {
             newCapacity = minimumCapacity;
+        }
         if (newCapacity < 0) {
-            if (minimumCapacity < 0) // overflow
+            if (minimumCapacity < 0) {// overflow
                 throw new OutOfMemoryError();
+            }
             newCapacity = Integer.MAX_VALUE;
         }
-        value = Arrays.copyOf(value, newCapacity);
+        if (coder != LATIN1 && newCapacity > StringUTF16.MAX_LENGTH) {
+            if (minimumCapacity >= StringUTF16.MAX_LENGTH) {
+                throw new OutOfMemoryError();
+            }
+            newCapacity = StringUTF16.MAX_LENGTH;
+        }
+        this.value = Arrays.copyOf(value, newCapacity << coder);
+    }
+
+    /**
+     * If the coder is "isLatin1", this inflates the internal 8-bit storage
+     * to 16-bit <hi=0, low> pair storage.
+     */
+    private void inflate() {
+        if (!isLatin1()) {
+            return;
+        }
+        byte[] buf = StringUTF16.newBytesFor(value.length);
+        StringLatin1.inflateSB(value, buf, 0, count);
+        this.value = buf;
+        this.coder = UTF16;
     }
 
     /**
@@ -148,8 +190,9 @@
      * returned by a subsequent call to the {@link #capacity()} method.
      */
     public void trimToSize() {
-        if (count < value.length) {
-            value = Arrays.copyOf(value, count);
+        int length = count << coder;
+        if (length < value.length) {
+            value = Arrays.copyOf(value, length);
         }
     }
 
@@ -179,14 +222,17 @@
      *               {@code newLength} argument is negative.
      */
     public void setLength(int newLength) {
-        if (newLength < 0)
+        if (newLength < 0) {
             throw new StringIndexOutOfBoundsException(newLength);
+        }
         ensureCapacityInternal(newLength);
-
         if (count < newLength) {
-            Arrays.fill(value, count, newLength, '\0');
+            if (isLatin1()) {
+                StringLatin1.fillNull(value, count, newLength);
+            } else {
+                StringUTF16.fillNull(value, count, newLength);
+            }
         }
-
         count = newLength;
     }
 
@@ -209,9 +255,11 @@
      */
     @Override
     public char charAt(int index) {
-        if ((index < 0) || (index >= count))
-            throw new StringIndexOutOfBoundsException(index);
-        return value[index];
+        checkIndex(index, count);
+        if (isLatin1()) {
+            return (char)(value[index] & 0xff);
+        }
+        return StringUTF16.charAt(value, index);
     }
 
     /**
@@ -236,10 +284,11 @@
      *             sequence.
      */
     public int codePointAt(int index) {
-        if ((index < 0) || (index >= count)) {
-            throw new StringIndexOutOfBoundsException(index);
+        checkIndex(index, count);
+        if (isLatin1()) {
+            return value[index] & 0xff;
         }
-        return Character.codePointAtImpl(value, index, count);
+        return StringUTF16.codePointAtSB(value, index, count);
     }
 
     /**
@@ -265,10 +314,13 @@
      */
     public int codePointBefore(int index) {
         int i = index - 1;
-        if ((i < 0) || (i >= count)) {
+        if (i < 0 || i >= count) {
             throw new StringIndexOutOfBoundsException(index);
         }
-        return Character.codePointBeforeImpl(value, index, 0);
+        if (isLatin1()) {
+            return value[i] & 0xff;
+        }
+        return StringUTF16.codePointBeforeSB(value, index);
     }
 
     /**
@@ -295,7 +347,10 @@
         if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) {
             throw new IndexOutOfBoundsException();
         }
-        return Character.codePointCountImpl(value, beginIndex, endIndex - beginIndex);
+        if (isLatin1()) {
+            return endIndex - beginIndex;
+        }
+        return StringUTF16.codePointCountSB(value, beginIndex, endIndex);
     }
 
     /**
@@ -321,8 +376,8 @@
         if (index < 0 || index > count) {
             throw new IndexOutOfBoundsException();
         }
-        return Character.offsetByCodePointsImpl(value, 0, count,
-                                                index, codePointOffset);
+        return Character.offsetByCodePoints(this,
+                                            index, codePointOffset);
     }
 
     /**
@@ -355,13 +410,14 @@
      */
     public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
     {
-        if (srcBegin < 0)
-            throw new StringIndexOutOfBoundsException(srcBegin);
-        if ((srcEnd < 0) || (srcEnd > count))
-            throw new StringIndexOutOfBoundsException(srcEnd);
-        if (srcBegin > srcEnd)
-            throw new StringIndexOutOfBoundsException("srcBegin > srcEnd");
-        System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
+        checkRangeSIOOBE(srcBegin, srcEnd, count);  // compatible to old version
+        int n = srcEnd - srcBegin;
+        checkRange(dstBegin, dstBegin + n, dst.length);
+        if (isLatin1()) {
+            StringLatin1.getCharsSB(value, srcBegin, srcEnd, dst, dstBegin);
+        } else {
+            StringUTF16.getCharsSB(value, srcBegin, srcEnd, dst, dstBegin);
+        }
     }
 
     /**
@@ -379,9 +435,15 @@
      *             negative or greater than or equal to {@code length()}.
      */
     public void setCharAt(int index, char ch) {
-        if ((index < 0) || (index >= count))
-            throw new StringIndexOutOfBoundsException(index);
-        value[index] = ch;
+        checkIndex(index, count);
+        if (isLatin1() && StringLatin1.canEncode(ch)) {
+            value[index] = (byte)ch;
+        } else {
+            if (isLatin1()) {
+                inflate();
+            }
+            StringUTF16.putCharSB(value, index, ch);
+        }
     }
 
     /**
@@ -418,35 +480,34 @@
      * @return  a reference to this object.
      */
     public AbstractStringBuilder append(String str) {
-        if (str == null)
+        if (str == null) {
             return appendNull();
+        }
         int len = str.length();
         ensureCapacityInternal(count + len);
-        str.getChars(0, len, value, count);
+        putStringAt(count, str);
         count += len;
         return this;
     }
 
     // Documentation in subclasses because of synchro difference
     public AbstractStringBuilder append(StringBuffer sb) {
-        if (sb == null)
-            return appendNull();
-        int len = sb.length();
-        ensureCapacityInternal(count + len);
-        sb.getChars(0, len, value, count);
-        count += len;
-        return this;
+        return this.append((AbstractStringBuilder)sb);
     }
 
     /**
      * @since 1.8
      */
     AbstractStringBuilder append(AbstractStringBuilder asb) {
-        if (asb == null)
+        if (asb == null) {
             return appendNull();
+        }
         int len = asb.length();
         ensureCapacityInternal(count + len);
-        asb.getChars(0, len, value, count);
+        if (getCoder() != asb.getCoder()) {
+            inflate();
+        }
+        asb.getBytes(value, count, coder);
         count += len;
         return this;
     }
@@ -454,25 +515,35 @@
     // Documentation in subclasses because of synchro difference
     @Override
     public AbstractStringBuilder append(CharSequence s) {
-        if (s == null)
+        if (s == null) {
             return appendNull();
-        if (s instanceof String)
+        }
+        if (s instanceof String) {
             return this.append((String)s);
-        if (s instanceof AbstractStringBuilder)
+        }
+        if (s instanceof AbstractStringBuilder) {
             return this.append((AbstractStringBuilder)s);
-
+        }
         return this.append(s, 0, s.length());
     }
 
     private AbstractStringBuilder appendNull() {
-        int c = count;
-        ensureCapacityInternal(c + 4);
-        final char[] value = this.value;
-        value[c++] = 'n';
-        value[c++] = 'u';
-        value[c++] = 'l';
-        value[c++] = 'l';
-        count = c;
+        ensureCapacityInternal(count + 4);
+        int count = this.count;
+        byte[] val = this.value;
+        if (isLatin1()) {
+            val[count++] = 'n';
+            val[count++] = 'u';
+            val[count++] = 'l';
+            val[count++] = 'l';
+        } else {
+            checkOffset(count + 4, val.length >> 1);
+            StringUTF16.putChar(val, count++, 'n');
+            StringUTF16.putChar(val, count++, 'u');
+            StringUTF16.putChar(val, count++, 'l');
+            StringUTF16.putChar(val, count++, 'l');
+        }
+        this.count = count;
         return this;
     }
 
@@ -507,21 +578,13 @@
      */
     @Override
     public AbstractStringBuilder append(CharSequence s, int start, int end) {
-        if (s == null)
+        if (s == null) {
             s = "null";
-        if ((start < 0) || (start > end) || (end > s.length()))
-            throw new IndexOutOfBoundsException(
-                "start " + start + ", end " + end + ", s.length() "
-                + s.length());
+        }
+        checkRange(start, end, s.length());
         int len = end - start;
         ensureCapacityInternal(count + len);
-        if (s instanceof String) {
-            ((String)s).getChars(start, end, value, count);
-        } else {
-            for (int i = start, j = count; i < end; i++, j++)
-                value[j] = s.charAt(i);
-        }
-        count += len;
+        appendChars(s, start, end);
         return this;
     }
 
@@ -544,8 +607,7 @@
     public AbstractStringBuilder append(char[] str) {
         int len = str.length;
         ensureCapacityInternal(count + len);
-        System.arraycopy(str, 0, value, count, len);
-        count += len;
+        appendChars(str, 0, len);
         return this;
     }
 
@@ -572,10 +634,10 @@
      *         or {@code offset+len > str.length}
      */
     public AbstractStringBuilder append(char str[], int offset, int len) {
-        if (len > 0)                // let arraycopy report AIOOBE for len < 0
-            ensureCapacityInternal(count + len);
-        System.arraycopy(str, offset, value, count, len);
-        count += len;
+        int end = offset + len;
+        checkRange(offset, end, str.length);
+        ensureCapacityInternal(count + len);
+        appendChars(str, offset, end);
         return this;
     }
 
@@ -592,20 +654,39 @@
      * @return  a reference to this object.
      */
     public AbstractStringBuilder append(boolean b) {
-        if (b) {
-            ensureCapacityInternal(count + 4);
-            value[count++] = 't';
-            value[count++] = 'r';
-            value[count++] = 'u';
-            value[count++] = 'e';
+        ensureCapacityInternal(count + (b ? 4 : 5));
+        int count = this.count;
+        byte[] val = this.value;
+        if (isLatin1()) {
+            if (b) {
+                val[count++] = 't';
+                val[count++] = 'r';
+                val[count++] = 'u';
+                val[count++] = 'e';
+            } else {
+                val[count++] = 'f';
+                val[count++] = 'a';
+                val[count++] = 'l';
+                val[count++] = 's';
+                val[count++] = 'e';
+            }
         } else {
-            ensureCapacityInternal(count + 5);
-            value[count++] = 'f';
-            value[count++] = 'a';
-            value[count++] = 'l';
-            value[count++] = 's';
-            value[count++] = 'e';
+            if (b) {
+                checkOffset(count + 4, val.length >> 1);
+                StringUTF16.putChar(val, count++, 't');
+                StringUTF16.putChar(val, count++, 'r');
+                StringUTF16.putChar(val, count++, 'u');
+                StringUTF16.putChar(val, count++, 'e');
+            } else {
+                checkOffset(count + 5, val.length >> 1);
+                StringUTF16.putChar(val, count++, 'f');
+                StringUTF16.putChar(val, count++, 'a');
+                StringUTF16.putChar(val, count++, 'l');
+                StringUTF16.putChar(val, count++, 's');
+                StringUTF16.putChar(val, count++, 'e');
+            }
         }
+        this.count = count;
         return this;
     }
 
@@ -627,7 +708,14 @@
     @Override
     public AbstractStringBuilder append(char c) {
         ensureCapacityInternal(count + 1);
-        value[count++] = c;
+        if (isLatin1() && StringLatin1.canEncode(c)) {
+            value[count++] = (byte)c;
+        } else {
+            if (isLatin1()) {
+                inflate();
+            }
+            StringUTF16.putCharSB(value, count++, c);
+        }
         return this;
     }
 
@@ -652,7 +740,13 @@
                                      : Integer.stringSize(i);
         int spaceNeeded = count + appendedLength;
         ensureCapacityInternal(spaceNeeded);
-        Integer.getChars(i, spaceNeeded, value);
+        if (isLatin1()) {
+            Integer.getChars(i, spaceNeeded, value);
+        } else {
+            byte[] val = this.value;
+            checkOffset(spaceNeeded, val.length >> 1);
+            Integer.getCharsUTF16(i, spaceNeeded, val);
+        }
         count = spaceNeeded;
         return this;
     }
@@ -678,7 +772,13 @@
                                      : Long.stringSize(l);
         int spaceNeeded = count + appendedLength;
         ensureCapacityInternal(spaceNeeded);
-        Long.getChars(l, spaceNeeded, value);
+        if (isLatin1()) {
+            Long.getChars(l, spaceNeeded, value);
+        } else {
+            byte[] val = this.value;
+            checkOffset(spaceNeeded, val.length >> 1);
+            Long.getCharsUTF16(l, spaceNeeded, val);
+        }
         count = spaceNeeded;
         return this;
     }
@@ -732,15 +832,13 @@
      *             greater than {@code end}.
      */
     public AbstractStringBuilder delete(int start, int end) {
-        if (start < 0)
-            throw new StringIndexOutOfBoundsException(start);
-        if (end > count)
+        if (end > count) {
             end = count;
-        if (start > end)
-            throw new StringIndexOutOfBoundsException();
+        }
+        checkRangeSIOOBE(start, end, count);
         int len = end - start;
         if (len > 0) {
-            System.arraycopy(value, start+len, value, start, count-end);
+            shift(end, -len);
             count -= len;
         }
         return this;
@@ -766,20 +864,10 @@
      * {@code codePoint} isn't a valid Unicode code point
      */
     public AbstractStringBuilder appendCodePoint(int codePoint) {
-        final int count = this.count;
-
         if (Character.isBmpCodePoint(codePoint)) {
-            ensureCapacityInternal(count + 1);
-            value[count] = (char) codePoint;
-            this.count = count + 1;
-        } else if (Character.isValidCodePoint(codePoint)) {
-            ensureCapacityInternal(count + 2);
-            Character.toSurrogates(codePoint, value, count);
-            this.count = count + 2;
-        } else {
-            throw new IllegalArgumentException();
+            return append((char)codePoint);
         }
-        return this;
+        return append(Character.toChars(codePoint));
     }
 
     /**
@@ -800,9 +888,8 @@
      *              {@code length()}.
      */
     public AbstractStringBuilder deleteCharAt(int index) {
-        if ((index < 0) || (index >= count))
-            throw new StringIndexOutOfBoundsException(index);
-        System.arraycopy(value, index+1, value, index, count-index-1);
+        checkIndex(index, count);
+        shift(index + 1, -1);
         count--;
         return this;
     }
@@ -827,22 +914,16 @@
      *             greater than {@code end}.
      */
     public AbstractStringBuilder replace(int start, int end, String str) {
-        if (start < 0)
-            throw new StringIndexOutOfBoundsException(start);
-        if (start > count)
-            throw new StringIndexOutOfBoundsException("start > length()");
-        if (start > end)
-            throw new StringIndexOutOfBoundsException("start > end");
-
-        if (end > count)
+        if (end > count) {
             end = count;
+        }
+        checkRangeSIOOBE(start, end, count);
         int len = str.length();
         int newCount = count + len - (end - start);
         ensureCapacityInternal(newCount);
-
-        System.arraycopy(value, end, value, start + len, count - end);
-        str.getChars(value, start);
+        shift(end, newCount - count);
         count = newCount;
+        putStringAt(start, str);
         return this;
     }
 
@@ -907,13 +988,16 @@
      *             greater than {@code end}.
      */
     public String substring(int start, int end) {
-        if (start < 0)
-            throw new StringIndexOutOfBoundsException(start);
-        if (end > count)
-            throw new StringIndexOutOfBoundsException(end);
-        if (start > end)
-            throw new StringIndexOutOfBoundsException(end - start);
-        return new String(value, start, end - start);
+        checkRangeSIOOBE(start, end, count);
+        if (isLatin1()) {
+            return StringLatin1.newString(value, start, end - start);
+        }
+        return StringUTF16.newStringSB(value, start, end - start);
+    }
+
+    private void shift(int offset, int n) {
+        System.arraycopy(value, offset << coder,
+                         value, (offset + n) << coder, (count - offset) << coder);
     }
 
     /**
@@ -940,16 +1024,12 @@
     public AbstractStringBuilder insert(int index, char[] str, int offset,
                                         int len)
     {
-        if ((index < 0) || (index > length()))
-            throw new StringIndexOutOfBoundsException(index);
-        if ((offset < 0) || (len < 0) || (offset > str.length - len))
-            throw new StringIndexOutOfBoundsException(
-                "offset " + offset + ", len " + len + ", str.length "
-                + str.length);
+        checkOffset(index, count);
+        checkRangeSIOOBE(offset, offset + len, str.length);
         ensureCapacityInternal(count + len);
-        System.arraycopy(value, index, value, index + len, count - index);
-        System.arraycopy(str, offset, value, index, len);
+        shift(index, len);
         count += len;
+        putCharsAt(index, str, offset, offset + len);
         return this;
     }
 
@@ -1008,15 +1088,15 @@
      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
      */
     public AbstractStringBuilder insert(int offset, String str) {
-        if ((offset < 0) || (offset > length()))
-            throw new StringIndexOutOfBoundsException(offset);
-        if (str == null)
+        checkOffset(offset, count);
+        if (str == null) {
             str = "null";
+        }
         int len = str.length();
         ensureCapacityInternal(count + len);
-        System.arraycopy(value, offset, value, offset + len, count - offset);
-        str.getChars(value, offset);
+        shift(offset, len);
         count += len;
+        putStringAt(offset, str);
         return this;
     }
 
@@ -1045,13 +1125,12 @@
      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
      */
     public AbstractStringBuilder insert(int offset, char[] str) {
-        if ((offset < 0) || (offset > length()))
-            throw new StringIndexOutOfBoundsException(offset);
+        checkOffset(offset, count);
         int len = str.length;
         ensureCapacityInternal(count + len);
-        System.arraycopy(value, offset, value, offset + len, count - offset);
-        System.arraycopy(str, 0, value, offset, len);
+        shift(offset, len);
         count += len;
+        putCharsAt(offset, str, 0, len);
         return this;
     }
 
@@ -1077,10 +1156,12 @@
      * @throws     IndexOutOfBoundsException  if the offset is invalid.
      */
     public AbstractStringBuilder insert(int dstOffset, CharSequence s) {
-        if (s == null)
+        if (s == null) {
             s = "null";
-        if (s instanceof String)
+        }
+        if (s instanceof String) {
             return this.insert(dstOffset, (String)s);
+        }
         return this.insert(dstOffset, s, 0, s.length());
     }
 
@@ -1128,23 +1209,19 @@
      *              {@code start} is greater than {@code end} or
      *              {@code end} is greater than {@code s.length()}
      */
-     public AbstractStringBuilder insert(int dstOffset, CharSequence s,
-                                         int start, int end) {
-        if (s == null)
+    public AbstractStringBuilder insert(int dstOffset, CharSequence s,
+                                        int start, int end)
+    {
+        if (s == null) {
             s = "null";
-        if ((dstOffset < 0) || (dstOffset > this.length()))
-            throw new IndexOutOfBoundsException("dstOffset "+dstOffset);
-        if ((start < 0) || (end < 0) || (start > end) || (end > s.length()))
-            throw new IndexOutOfBoundsException(
-                "start " + start + ", end " + end + ", s.length() "
-                + s.length());
+        }
+        checkOffset(dstOffset, count);
+        checkRange(start, end, s.length());
         int len = end - start;
         ensureCapacityInternal(count + len);
-        System.arraycopy(value, dstOffset, value, dstOffset + len,
-                         count - dstOffset);
-        for (int i=start; i<end; i++)
-            value[dstOffset++] = s.charAt(i);
+        shift(dstOffset, len);
         count += len;
+        putCharsAt(dstOffset, s, start, end);
         return this;
     }
 
@@ -1191,10 +1268,18 @@
      * @throws     IndexOutOfBoundsException  if the offset is invalid.
      */
     public AbstractStringBuilder insert(int offset, char c) {
+        checkOffset(offset, count);
         ensureCapacityInternal(count + 1);
-        System.arraycopy(value, offset, value, offset + 1, count - offset);
-        value[offset] = c;
+        shift(offset, 1);
         count += 1;
+        if (isLatin1() && StringLatin1.canEncode(c)) {
+            value[offset] = (byte)c;
+        } else {
+            if (isLatin1()) {
+                inflate();
+            }
+            StringUTF16.putCharSB(value, offset, c);
+        }
         return this;
     }
 
@@ -1326,7 +1411,7 @@
      *          or {@code -1} if there is no such occurrence.
      */
     public int indexOf(String str, int fromIndex) {
-        return String.indexOf(value, 0, count, str, fromIndex);
+        return String.indexOf(value, coder, count, str, fromIndex);
     }
 
     /**
@@ -1366,7 +1451,7 @@
      *          or {@code -1} if there is no such occurrence.
      */
     public int lastIndexOf(String str, int fromIndex) {
-        return String.lastIndexOf(value, 0, count, str, fromIndex);
+        return String.lastIndexOf(value, coder, count, str, fromIndex);
     }
 
     /**
@@ -1392,34 +1477,47 @@
      * @return  a reference to this object.
      */
     public AbstractStringBuilder reverse() {
-        boolean hasSurrogates = false;
+        byte[] val = this.value;
+        int count = this.count;
+        int coder = this.coder;
         int n = count - 1;
-        for (int j = (n-1) >> 1; j >= 0; j--) {
-            int k = n - j;
-            char cj = value[j];
-            char ck = value[k];
-            value[j] = ck;
-            value[k] = cj;
-            if (Character.isSurrogate(cj) ||
-                Character.isSurrogate(ck)) {
-                hasSurrogates = true;
+        if (COMPACT_STRINGS && coder == LATIN1) {
+            for (int j = (n-1) >> 1; j >= 0; j--) {
+                int k = n - j;
+                byte cj = val[j];
+                val[j] = val[k];
+                val[k] = cj;
             }
-        }
-        if (hasSurrogates) {
-            reverseAllValidSurrogatePairs();
+        } else {
+            checkOffset(count, val.length >> 1);
+            boolean hasSurrogates = false;
+            for (int j = (n-1) >> 1; j >= 0; j--) {
+                int k = n - j;
+                char cj = StringUTF16.getChar(val, j);
+                char ck = StringUTF16.getChar(val, k);
+                StringUTF16.putChar(val, j, ck);
+                StringUTF16.putChar(val, k, cj);
+                if (Character.isSurrogate(cj) ||
+                    Character.isSurrogate(ck)) {
+                    hasSurrogates = true;
+                }
+            }
+            if (hasSurrogates) {
+                reverseAllValidSurrogatePairs(val, count);
+            }
         }
         return this;
     }
 
     /** Outlined helper method for reverse() */
-    private void reverseAllValidSurrogatePairs() {
+    private void reverseAllValidSurrogatePairs(byte[] val, int count) {
         for (int i = 0; i < count - 1; i++) {
-            char c2 = value[i];
+            char c2 = StringUTF16.getChar(val, i);
             if (Character.isLowSurrogate(c2)) {
-                char c1 = value[i + 1];
+                char c1 = StringUTF16.getChar(val, i + 1);
                 if (Character.isHighSurrogate(c1)) {
-                    value[i++] = c1;
-                    value[i] = c2;
+                    StringUTF16.putChar(val, i++, c1);
+                    StringUTF16.putChar(val, i, c2);
                 }
             }
         }
@@ -1444,10 +1542,13 @@
      */
     @Override
     public IntStream chars() {
+        byte[] val = this.value; int count = this.count; byte coder = this.coder;
+        checkOffset(count, val.length >> coder);
         // Reuse String-based spliterator. This requires a supplier to
         // capture the value and count when the terminal operation is executed
         return StreamSupport.intStream(
-                () -> new String.IntCharArraySpliterator(value, 0, count, 0),
+                () -> coder == LATIN1 ? new StringLatin1.CharsSpliterator(val, 0, count, 0)
+                                      : new StringUTF16.CharsSpliterator(val, 0, count, 0),
                 Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED,
                 false);
     }
@@ -1458,10 +1559,13 @@
      */
     @Override
     public IntStream codePoints() {
+        byte[] val = this.value; int count = this.count; byte coder = this.coder;
+        checkOffset(count, val.length >> coder);
         // Reuse String-based spliterator. This requires a supplier to
         // capture the value and count when the terminal operation is executed
         return StreamSupport.intStream(
-                () -> new String.CodePointsSpliterator(value, 0, count, 0),
+                () -> coder == LATIN1 ? new StringLatin1.CharsSpliterator(val, 0, count, 0)
+                                      : new StringUTF16.CodePointsSpliterator(val, 0, count, 0),
                 Spliterator.ORDERED,
                 false);
     }
@@ -1469,8 +1573,147 @@
     /**
      * Needed by {@code String} for the contentEquals method.
      */
-    final char[] getValue() {
+    final byte[] getValue() {
         return value;
     }
 
+    /*
+     * Invoker guarantees it is in UTF16 (inflate itself for asb), if two
+     * coders are different and the dstBegin has enough space
+     *
+     * @param dstBegin  the char index, not offset of byte[]
+     * @param coder     the coder of dst[]
+     */
+    protected void getBytes(byte dst[], int dstBegin, byte coder) {
+        if (this.coder == coder) {
+            System.arraycopy(value, 0, dst, dstBegin << coder, count << coder);
+        } else {        // this.coder == LATIN && coder == UTF16
+            StringLatin1.inflateSB(value, dst, dstBegin, count);
+        }
+    }
+
+    /* for readObject() */
+    protected void initBytes(char[] value, int off, int len) {
+        if (String.COMPACT_STRINGS) {
+            this.value = StringUTF16.compress(value, off, len);
+            if (this.value != null) {
+                this.coder = LATIN1;
+                return;
+            }
+        }
+        this.coder = UTF16;
+        this.value = StringUTF16.toBytes(value, off, len);
+    }
+
+    final byte getCoder() {
+        return COMPACT_STRINGS ? coder : UTF16;
+    }
+
+    final boolean isLatin1() {
+        return COMPACT_STRINGS && coder == LATIN1;
+    }
+
+    private final void putCharsAt(int index, char[] s, int off, int end) {
+        if (isLatin1()) {
+            byte[] val = this.value;
+            for (int i = off, j = index; i < end; i++) {
+                char c = s[i];
+                if (StringLatin1.canEncode(c)) {
+                    val[j++] = (byte)c;
+                } else {
+                    inflate();
+                    StringUTF16.putCharsSB(this.value, j, s, i, end);
+                    return;
+                }
+            }
+        } else {
+            StringUTF16.putCharsSB(this.value, index, s, off, end);
+        }
+    }
+
+    private final void putCharsAt(int index, CharSequence s, int off, int end) {
+        if (isLatin1()) {
+            byte[] val = this.value;
+            for (int i = off, j = index; i < end; i++) {
+                char c = s.charAt(i);
+                if (StringLatin1.canEncode(c)) {
+                    val[j++] = (byte)c;
+                } else {
+                    inflate();
+                    StringUTF16.putCharsSB(this.value, j, s, i, end);
+                    return;
+                }
+            }
+        } else {
+            StringUTF16.putCharsSB(this.value, index, s, off, end);
+        }
+    }
+
+    private final void putStringAt(int index, String str) {
+        if (getCoder() != str.coder()) {
+            inflate();
+        }
+        byte[] val = this.value;
+        byte coder = this.coder;
+        checkOffset(index + str.length(), val.length >> coder);
+        str.getBytes(val, index, coder);
+    }
+
+    private final void appendChars(char[] s, int off, int end) {
+        if (isLatin1()) {
+            byte[] val = this.value;
+            for (int i = off, j = count; i < end; i++) {
+                char c = s[i];
+                if (StringLatin1.canEncode(c)) {
+                    val[j++] = (byte)c;
+                } else {
+                    count = j;
+                    inflate();
+                    StringUTF16.putCharsSB(this.value, j, s, i, end);
+                    count += end - i;
+                    return;
+                }
+            }
+        } else {
+            StringUTF16.putCharsSB(this.value, count, s, off, end);
+        }
+        count += end - off;
+    }
+
+    private final void appendChars(CharSequence s, int off, int end) {
+        if (isLatin1()) {
+            byte[] val = this.value;
+            for (int i = off, j = count; i < end; i++) {
+                char c = s.charAt(i);
+                if (StringLatin1.canEncode(c)) {
+                    val[j++] = (byte)c;
+                } else {
+                    count = j;
+                    inflate();
+                    StringUTF16.putCharsSB(this.value, j, s, i, end);
+                    count += end - i;
+                    return;
+                }
+            }
+        } else {
+            StringUTF16.putCharsSB(this.value, count, s, off, end);
+        }
+        count += end - off;
+    }
+
+    /* IndexOutOfBoundsException, if out of bounds */
+    private static void checkRange(int start, int end, int len) {
+        if (start < 0 || start > end || end > len) {
+            throw new IndexOutOfBoundsException(
+                "start " + start + ", end " + end + ", length " + len);
+        }
+    }
+
+    /* StringIndexOutOfBoundsException, if out of bounds */
+    private static void checkRangeSIOOBE(int start, int end, int len) {
+        if (start < 0 || start > end || end > len) {
+            throw new StringIndexOutOfBoundsException(
+                "start " + start + ", end " + end + ", length " + len);
+        }
+    }
 }
--- a/jdk/src/java.base/share/classes/java/lang/Class.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/Class.java	Tue Nov 17 10:29:28 2015 -0800
@@ -55,7 +55,7 @@
 import java.util.HashMap;
 import java.util.Objects;
 import java.util.StringJoiner;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 import jdk.internal.HotSpotIntrinsicCandidate;
 import sun.reflect.CallerSensitive;
 import sun.reflect.ConstantPool;
--- a/jdk/src/java.base/share/classes/java/lang/Integer.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/Integer.java	Tue Nov 17 10:29:28 2015 -0800
@@ -29,6 +29,10 @@
 import java.util.Objects;
 import jdk.internal.HotSpotIntrinsicCandidate;
 
+import static java.lang.String.COMPACT_STRINGS;
+import static java.lang.String.LATIN1;
+import static java.lang.String.UTF16;
+
 /**
  * The {@code Integer} class wraps a value of the primitive type
  * {@code int} in an object. An object of type {@code Integer}
@@ -138,25 +142,47 @@
             return toString(i);
         }
 
-        char buf[] = new char[33];
+        if (COMPACT_STRINGS) {
+            byte[] buf = new byte[33];
+            boolean negative = (i < 0);
+            int charPos = 32;
+
+            if (!negative) {
+                i = -i;
+            }
+
+            while (i <= -radix) {
+                buf[charPos--] = (byte)digits[-(i % radix)];
+                i = i / radix;
+            }
+            buf[charPos] = (byte)digits[-i];
+
+            if (negative) {
+                buf[--charPos] = '-';
+            }
+
+            return StringLatin1.newString(buf, charPos, (33 - charPos));
+        }
+        return toStringUTF16(i, radix);
+    }
+
+    private static String toStringUTF16(int i, int radix) {
+        byte[] buf = new byte[33 * 2];
         boolean negative = (i < 0);
         int charPos = 32;
-
         if (!negative) {
             i = -i;
         }
-
         while (i <= -radix) {
-            buf[charPos--] = digits[-(i % radix)];
+            StringUTF16.putChar(buf, charPos--, digits[-(i % radix)]);
             i = i / radix;
         }
-        buf[charPos] = digits[-i];
+        StringUTF16.putChar(buf, charPos, digits[-i]);
 
         if (negative) {
-            buf[--charPos] = '-';
+            StringUTF16.putChar(buf, --charPos, '-');
         }
-
-        return new String(buf, charPos, (33 - charPos));
+        return StringUTF16.newString(buf, charPos, (33 - charPos));
     }
 
     /**
@@ -312,12 +338,16 @@
         // assert shift > 0 && shift <=5 : "Illegal shift value";
         int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val);
         int chars = Math.max(((mag + (shift - 1)) / shift), 1);
-        char[] buf = new char[chars];
 
-        formatUnsignedInt(val, shift, buf, 0, chars);
-
-        // Use special constructor which takes over "buf".
-        return new String(buf, true);
+        if (COMPACT_STRINGS) {
+            byte[] buf = new byte[chars];
+            formatUnsignedInt(val, shift, buf, 0, chars);
+            return new String(buf, LATIN1);
+        } else {
+            byte[] buf = new byte[chars * 2];
+            formatUnsignedIntUTF16(val, shift, buf, 0, chars);
+            return new String(buf, UTF16);
+        }
     }
 
     /**
@@ -331,7 +361,7 @@
      * @param offset the offset in the destination buffer to start at
      * @param len the number of characters to write
      */
-     static void formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {
+    static void formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {
         // assert shift > 0 && shift <=5 : "Illegal shift value";
         // assert offset >= 0 && offset < buf.length : "illegal offset";
         // assert len > 0 && (offset + len) <= buf.length : "illegal length";
@@ -344,6 +374,28 @@
         } while (charPos > offset);
     }
 
+    /** byte[]/LATIN1 version    */
+    static void formatUnsignedInt(int val, int shift, byte[] buf, int offset, int len) {
+        int charPos = offset + len;
+        int radix = 1 << shift;
+        int mask = radix - 1;
+        do {
+            buf[--charPos] = (byte)Integer.digits[val & mask];
+            val >>>= shift;
+        } while (charPos > offset);
+    }
+
+    /** byte[]/UTF16 version    */
+    static void formatUnsignedIntUTF16(int val, int shift, byte[] buf, int offset, int len) {
+        int charPos = offset + len;
+        int radix = 1 << shift;
+        int mask = radix - 1;
+        do {
+            StringUTF16.putChar(buf, --charPos, Integer.digits[val & mask]);
+            val >>>= shift;
+        } while (charPos > offset);
+    }
+
     static final char [] DigitTens = {
         '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
         '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
@@ -401,9 +453,15 @@
         if (i == Integer.MIN_VALUE)
             return "-2147483648";
         int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
-        char[] buf = new char[size];
-        getChars(i, size, buf);
-        return new String(buf, true);
+        if (COMPACT_STRINGS) {
+            byte[] buf = new byte[size];
+            getChars(i, size, buf);
+            return new String(buf, LATIN1);
+        } else {
+            byte[] buf = new byte[size * 2];
+            getCharsUTF16(i, size, buf);
+            return new String(buf, UTF16);
+        }
     }
 
     /**
@@ -433,7 +491,7 @@
      *
      * Will fail if i == Integer.MIN_VALUE
      */
-    static void getChars(int i, int index, char[] buf) {
+    static void getChars(int i, int index, byte[] buf) {
         int q, r;
         int charPos = index;
         char sign = 0;
@@ -449,8 +507,8 @@
         // really: r = i - (q * 100);
             r = i - ((q << 6) + (q << 5) + (q << 2));
             i = q;
-            buf [--charPos] = DigitOnes[r];
-            buf [--charPos] = DigitTens[r];
+            buf [--charPos] = (byte)DigitOnes[r];
+            buf [--charPos] = (byte)DigitTens[r];
         }
 
         // Fall thru to fast mode for smaller numbers
@@ -458,12 +516,46 @@
         for (;;) {
             q = (i * 52429) >>> (16+3);
             r = i - ((q << 3) + (q << 1));  // r = i-(q*10) ...
-            buf [--charPos] = digits [r];
+            buf [--charPos] = (byte)digits [r];
             i = q;
             if (i == 0) break;
         }
         if (sign != 0) {
-            buf [--charPos] = sign;
+            buf [--charPos] = (byte)sign;
+        }
+    }
+
+    static void getCharsUTF16(int i, int index, byte[] buf) {
+        int q, r;
+        int charPos = index;
+        char sign = 0;
+
+        if (i < 0) {
+            sign = '-';
+            i = -i;
+        }
+
+        // Generate two digits per iteration
+        while (i >= 65536) {
+            q = i / 100;
+        // really: r = i - (q * 100);
+            r = i - ((q << 6) + (q << 5) + (q << 2));
+            i = q;
+            StringUTF16.putChar(buf, --charPos, DigitOnes[r]);
+            StringUTF16.putChar(buf, --charPos, DigitTens[r]);
+        }
+
+        // Fall thru to fast mode for smaller numbers
+        // assert(i <= 65536, i);
+        for (;;) {
+            q = (i * 52429) >>> (16+3);
+            r = i - ((q << 3) + (q << 1));  // r = i-(q*10) ...
+            StringUTF16.putChar(buf, --charPos, Integer.digits[r]);
+            i = q;
+            if (i == 0) break;
+        }
+        if (sign != 0) {
+            StringUTF16.putChar(buf, --charPos, sign);
         }
     }
 
--- a/jdk/src/java.base/share/classes/java/lang/Long.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/Long.java	Tue Nov 17 10:29:28 2015 -0800
@@ -30,6 +30,9 @@
 import java.util.Objects;
 import jdk.internal.HotSpotIntrinsicCandidate;
 
+import static java.lang.String.COMPACT_STRINGS;
+import static java.lang.String.LATIN1;
+import static java.lang.String.UTF16;
 
 /**
  * The {@code Long} class wraps a value of the primitive type {@code
@@ -124,25 +127,46 @@
             radix = 10;
         if (radix == 10)
             return toString(i);
-        char[] buf = new char[65];
+
+        if (COMPACT_STRINGS) {
+            byte[] buf = new byte[65];
+            int charPos = 64;
+            boolean negative = (i < 0);
+
+            if (!negative) {
+                i = -i;
+            }
+
+            while (i <= -radix) {
+                buf[charPos--] = (byte)Integer.digits[(int)(-(i % radix))];
+                i = i / radix;
+            }
+            buf[charPos] = (byte)Integer.digits[(int)(-i)];
+
+            if (negative) {
+                buf[--charPos] = '-';
+            }
+            return StringLatin1.newString(buf, charPos, (65 - charPos));
+        }
+        return toStringUTF16(i, radix);
+    }
+
+    private static String toStringUTF16(long i, int radix) {
+        byte[] buf = new byte[65 * 2];
         int charPos = 64;
         boolean negative = (i < 0);
-
         if (!negative) {
             i = -i;
         }
-
         while (i <= -radix) {
-            buf[charPos--] = Integer.digits[(int)(-(i % radix))];
+            StringUTF16.putChar(buf, charPos--, Integer.digits[(int)(-(i % radix))]);
             i = i / radix;
         }
-        buf[charPos] = Integer.digits[(int)(-i)];
-
+        StringUTF16.putChar(buf, charPos, Integer.digits[(int)(-i)]);
         if (negative) {
-            buf[--charPos] = '-';
+            StringUTF16.putChar(buf, --charPos, '-');
         }
-
-        return new String(buf, charPos, (65 - charPos));
+        return StringUTF16.newString(buf, charPos, (65 - charPos));
     }
 
     /**
@@ -355,10 +379,16 @@
         // assert shift > 0 && shift <=5 : "Illegal shift value";
         int mag = Long.SIZE - Long.numberOfLeadingZeros(val);
         int chars = Math.max(((mag + (shift - 1)) / shift), 1);
-        char[] buf = new char[chars];
 
-        formatUnsignedLong(val, shift, buf, 0, chars);
-        return new String(buf, true);
+        if (COMPACT_STRINGS) {
+            byte[] buf = new byte[chars];
+            formatUnsignedLong0(val, shift, buf, 0, chars);
+            return new String(buf, LATIN1);
+        } else {
+            byte[] buf = new byte[chars * 2];
+            formatUnsignedLong0UTF16(val, shift, buf, 0, chars);
+            return new String(buf, UTF16);
+        }
     }
 
     /**
@@ -385,6 +415,28 @@
         } while (charPos > offset);
     }
 
+    /** byte[]/LATIN1 version    */
+    static void formatUnsignedLong0(long val, int shift, byte[] buf, int offset, int len) {
+        int charPos = offset + len;
+        int radix = 1 << shift;
+        int mask = radix - 1;
+        do {
+            buf[--charPos] = (byte)Integer.digits[((int) val) & mask];
+            val >>>= shift;
+        } while (charPos > offset);
+    }
+
+    /** byte[]/UTF16 version    */
+    static void formatUnsignedLong0UTF16(long val, int shift, byte[] buf, int offset, int len) {
+        int charPos = offset + len;
+        int radix = 1 << shift;
+        int mask = radix - 1;
+        do {
+            StringUTF16.putChar(buf, --charPos, Integer.digits[((int) val) & mask]);
+            val >>>= shift;
+        } while (charPos > offset);
+    }
+
     /**
      * Returns a {@code String} object representing the specified
      * {@code long}.  The argument is converted to signed decimal
@@ -399,9 +451,15 @@
         if (i == Long.MIN_VALUE)
             return "-9223372036854775808";
         int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
-        char[] buf = new char[size];
-        getChars(i, size, buf);
-        return new String(buf, true);
+        if (COMPACT_STRINGS) {
+            byte[] buf = new byte[size];
+            getChars(i, size, buf);
+            return new String(buf, LATIN1);
+        } else {
+            byte[] buf = new byte[size * 2];
+            getCharsUTF16(i, size, buf);
+            return new String(buf, UTF16);
+        }
     }
 
     /**
@@ -431,7 +489,7 @@
      *
      * Will fail if i == Long.MIN_VALUE
      */
-    static void getChars(long i, int index, char[] buf) {
+    static void getChars(long i, int index, byte[] buf) {
         long q;
         int r;
         int charPos = index;
@@ -448,8 +506,8 @@
             // really: r = i - (q * 100);
             r = (int)(i - ((q << 6) + (q << 5) + (q << 2)));
             i = q;
-            buf[--charPos] = Integer.DigitOnes[r];
-            buf[--charPos] = Integer.DigitTens[r];
+            buf[--charPos] = (byte)Integer.DigitOnes[r];
+            buf[--charPos] = (byte)Integer.DigitTens[r];
         }
 
         // Get 2 digits/iteration using ints
@@ -460,8 +518,8 @@
             // really: r = i2 - (q * 100);
             r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2));
             i2 = q2;
-            buf[--charPos] = Integer.DigitOnes[r];
-            buf[--charPos] = Integer.DigitTens[r];
+            buf[--charPos] = (byte)Integer.DigitOnes[r];
+            buf[--charPos] = (byte)Integer.DigitTens[r];
         }
 
         // Fall thru to fast mode for smaller numbers
@@ -469,12 +527,59 @@
         for (;;) {
             q2 = (i2 * 52429) >>> (16+3);
             r = i2 - ((q2 << 3) + (q2 << 1));  // r = i2-(q2*10) ...
-            buf[--charPos] = Integer.digits[r];
+            buf[--charPos] = (byte)Integer.digits[r];
             i2 = q2;
             if (i2 == 0) break;
         }
         if (sign != 0) {
-            buf[--charPos] = sign;
+            buf[--charPos] = (byte)sign;
+        }
+    }
+
+    static void getCharsUTF16(long i, int index, byte[] buf) {
+        long q;
+        int r;
+        int charPos = index;
+        char sign = 0;
+
+        if (i < 0) {
+            sign = '-';
+            i = -i;
+        }
+
+        // Get 2 digits/iteration using longs until quotient fits into an int
+        while (i > Integer.MAX_VALUE) {
+            q = i / 100;
+            // really: r = i - (q * 100);
+            r = (int)(i - ((q << 6) + (q << 5) + (q << 2)));
+            i = q;
+            StringUTF16.putChar(buf, --charPos, Integer.DigitOnes[r]);
+            StringUTF16.putChar(buf, --charPos, Integer.DigitTens[r]);
+        }
+
+        // Get 2 digits/iteration using ints
+        int q2;
+        int i2 = (int)i;
+        while (i2 >= 65536) {
+            q2 = i2 / 100;
+            // really: r = i2 - (q * 100);
+            r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2));
+            i2 = q2;
+            StringUTF16.putChar(buf, --charPos, Integer.DigitOnes[r]);
+            StringUTF16.putChar(buf, --charPos, Integer.DigitTens[r]);
+        }
+
+        // Fall thru to fast mode for smaller numbers
+        // assert(i2 <= 65536, i2);
+        for (;;) {
+            q2 = (i2 * 52429) >>> (16+3);
+            r = i2 - ((q2 << 3) + (q2 << 1));  // r = i2-(q2*10) ...
+            StringUTF16.putChar(buf, --charPos, Integer.digits[r]);
+            i2 = q2;
+            if (i2 == 0) break;
+        }
+        if (sign != 0) {
+            StringUTF16.putChar(buf, --charPos, sign);
         }
     }
 
--- a/jdk/src/java.base/share/classes/java/lang/ProcessBuilder.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/ProcessBuilder.java	Tue Nov 17 10:29:28 2015 -0800
@@ -26,9 +26,11 @@
 package java.lang;
 
 import java.io.File;
+import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.channels.Pipe;
 import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.List;
@@ -43,6 +45,11 @@
  * {@link Process} instance with those attributes.  The {@link
  * #start()} method can be invoked repeatedly from the same instance
  * to create new subprocesses with identical or related attributes.
+ * <p>
+ * The {@link #startPipeline startPipeline} method can be invoked to create
+ * a pipeline of new processes that send the output of each process
+ * directly to the next process.  Each process has the attributes of
+ * its respective ProcessBuilder.
  *
  * <p>Each process builder manages these process attributes:
  *
@@ -696,11 +703,37 @@
         private Redirect() {}
     }
 
+    /**
+     * Private implementation subclass of Redirect that holds a FileDescriptor for the
+     * output of a previously started Process.
+     * The FileDescriptor is used as the standard input of the next Process
+     * to be started.
+     */
+    static class RedirectPipeImpl extends Redirect {
+        final FileDescriptor fd;
+
+        RedirectPipeImpl() {
+            this.fd = new FileDescriptor();
+        }
+        @Override
+        public Type type() { return Type.PIPE; }
+
+        @Override
+        public String toString() { return type().toString();}
+
+        FileDescriptor getFd() { return fd; }
+    }
+
+    /**
+     * Return the array of redirects, creating the default as needed.
+     * @return the array of redirects
+     */
     private Redirect[] redirects() {
-        if (redirects == null)
+        if (redirects == null) {
             redirects = new Redirect[] {
-                Redirect.PIPE, Redirect.PIPE, Redirect.PIPE
+                    Redirect.PIPE, Redirect.PIPE, Redirect.PIPE
             };
+        }
         return redirects;
     }
 
@@ -1039,6 +1072,18 @@
      * @see Runtime#exec(String[], String[], java.io.File)
      */
     public Process start() throws IOException {
+        return start(redirects);
+    }
+
+    /**
+     * Start a new Process using an explicit array of redirects.
+     * See {@link #start} for details of starting each Process.
+     *
+     * @param redirect array of redirects for stdin, stdout, stderr
+     * @return the new Process
+     * @throws IOException if an I/O error occurs
+     */
+    private Process start(Redirect[] redirects) throws IOException {
         // Must convert to array first -- a malicious user-supplied
         // list might try to circumvent the security check.
         String[] cmdarray = command.toArray(new String[command.size()]);
@@ -1089,4 +1134,171 @@
                 cause);
         }
     }
+
+    /**
+     * Starts a Process for each ProcessBuilder, creating a pipeline of
+     * processes linked by their standard output and standard input streams.
+     * The attributes of each ProcessBuilder are used to start the respective
+     * process except that as each process is started, its standard output
+     * is directed to the standard input of the next.  The redirects for standard
+     * input of the first process and standard output of the last process are
+     * initialized using the redirect settings of the respective ProcessBuilder.
+     * All other {@code ProcessBuilder} redirects should be
+     * {@link Redirect#PIPE Redirect.PIPE}.
+     * <p>
+     * All input and output streams between the intermediate processes are
+     * not accessible.
+     * The {@link Process#getOutputStream standard input} of all processes
+     * except the first process are <i>null output streams</i>
+     * The {@link Process#getInputStream standard output} of all processes
+     * except the last process are <i>null input streams</i>.
+     * <p>
+     * The {@link #redirectErrorStream} of each ProcessBuilder applies to the
+     * respective process.  If set to {@code true}, the error stream is written
+     * to the same stream as standard output.
+     * <p>
+     * If starting any of the processes throws an Exception, all processes
+     * are forcibly destroyed.
+     * <p>
+     * The {@code startPipeline} method performs the same checks on
+     * each ProcessBuilder as does the {@link #start} method. The new process
+     * will invoke the command and arguments given by {@link #command()},
+     * in a working directory as given by {@link #directory()},
+     * with a process environment as given by {@link #environment()}.
+     * <p>
+     * This method checks that the command is a valid operating
+     * system command.  Which commands are valid is system-dependent,
+     * but at the very least the command must be a non-empty list of
+     * non-null strings.
+     * <p>
+     * A minimal set of system dependent environment variables may
+     * be required to start a process on some operating systems.
+     * As a result, the subprocess may inherit additional environment variable
+     * settings beyond those in the process builder's {@link #environment()}.
+     * <p>
+     * If there is a security manager, its
+     * {@link SecurityManager#checkExec checkExec}
+     * method is called with the first component of this object's
+     * {@code command} array as its argument. This may result in
+     * a {@link SecurityException} being thrown.
+     * <p>
+     * Starting an operating system process is highly system-dependent.
+     * Among the many things that can go wrong are:
+     * <ul>
+     * <li>The operating system program file was not found.
+     * <li>Access to the program file was denied.
+     * <li>The working directory does not exist.
+     * <li>Invalid character in command argument, such as NUL.
+     * </ul>
+     * <p>
+     * In such cases an exception will be thrown.  The exact nature
+     * of the exception is system-dependent, but it will always be a
+     * subclass of {@link IOException}.
+     * <p>
+     * If the operating system does not support the creation of
+     * processes, an {@link UnsupportedOperationException} will be thrown.
+     * <p>
+     * Subsequent modifications to this process builder will not
+     * affect the returned {@link Process}.
+     * @apiNote
+     * For example to count the unique imports for all the files in a file hierarchy
+     * on a Unix compatible platform:
+     * <pre>{@code
+     * String directory = "/home/duke/src";
+     * ProcessBuilder[] builders = {
+     *              new ProcessBuilder("find", directory, "-type", "f"),
+                    new ProcessBuilder("xargs", "grep", "-h", "^import "),
+                    new ProcessBuilder("awk", "{print $2;}"),
+                    new ProcessBuilder("sort", "-u")};
+     * List<Process> processes = ProcessBuilder.startPipeline(
+     *         Arrays.asList(builders));
+     * Process last = processes.get(processes.size()-1);
+     * try (InputStream is = last.getInputStream();
+     *         Reader isr = new InputStreamReader(is);
+     *         BufferedReader r = new BufferedReader(isr)) {
+     *     long count = r.lines().count();
+     * }
+     * }</pre>
+     *
+     * @param builders a List of ProcessBuilders
+     * @return a {@code List<Process>}es started from the corresponding
+     *         ProcessBuilder
+     * @throws IllegalArgumentException any of the redirects except the
+     *          standard input of the first builder and the standard output of
+     *          the last builder are not {@link Redirect#PIPE}.
+     * @throws NullPointerException
+     *         if an element of the command list is null or
+     *         if an element of the ProcessBuilder list is null or
+     *         the builders argument is null
+     * @throws IndexOutOfBoundsException
+     *         if the command is an empty list (has size {@code 0})
+     * @throws SecurityException
+     *         if a security manager exists and
+     *         <ul>
+     *         <li>its
+     *         {@link SecurityManager#checkExec checkExec}
+     *         method doesn't allow creation of the subprocess, or
+     *         <li>the standard input to the subprocess was
+     *         {@linkplain #redirectInput redirected from a file}
+     *         and the security manager's
+     *         {@link SecurityManager#checkRead(String) checkRead} method
+     *         denies read access to the file, or
+     *         <li>the standard output or standard error of the
+     *         subprocess was
+     *         {@linkplain #redirectOutput redirected to a file}
+     *         and the security manager's
+     *         {@link SecurityManager#checkWrite(String) checkWrite} method
+     *         denies write access to the file
+     *         </ul>
+     *
+     * @throws  UnsupportedOperationException
+     *          If the operating system does not support the creation of processes
+     *
+     * @throws IOException if an I/O error occurs
+     */
+    public static List<Process> startPipeline(List<ProcessBuilder> builders) throws IOException {
+        // Accumulate and check the builders
+        final int numBuilders = builders.size();
+        List<Process> processes = new ArrayList<>(numBuilders);
+        try {
+            Redirect prevOutput = null;
+            for (int index = 0; index < builders.size(); index++) {
+                ProcessBuilder builder = builders.get(index);
+                Redirect[] redirects = builder.redirects();
+                if (index > 0) {
+                    // check the current Builder to see if it can take input from the previous
+                    if (builder.redirectInput() != Redirect.PIPE) {
+                        throw new IllegalArgumentException("builder redirectInput()" +
+                                " must be PIPE except for the first builder: "
+                                + builder.redirectInput());
+                    }
+                    redirects[0] = prevOutput;
+                }
+                if (index < numBuilders - 1) {
+                    // check all but the last stage has output = PIPE
+                    if (builder.redirectOutput() != Redirect.PIPE) {
+                        throw new IllegalArgumentException("builder redirectOutput()" +
+                                " must be PIPE except for the last builder: "
+                                + builder.redirectOutput());
+                    }
+                    redirects[1] = new RedirectPipeImpl();  // placeholder for new output
+                }
+                processes.add(builder.start(redirects));
+                prevOutput = redirects[1];
+            }
+        } catch (Exception ex) {
+            // Cleanup processes already started
+            processes.forEach(Process::destroyForcibly);
+            processes.forEach(p -> {
+                try {
+                    p.waitFor();        // Wait for it to exit
+                } catch (InterruptedException ie) {
+                    // If interrupted; continue with next Process
+                    Thread.currentThread().interrupt();
+                }
+            });
+            throw ex;
+        }
+        return processes;
+    }
 }
--- a/jdk/src/java.base/share/classes/java/lang/String.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/String.java	Tue Nov 17 10:29:28 2015 -0800
@@ -36,7 +36,6 @@
 import java.util.Objects;
 import java.util.Spliterator;
 import java.util.StringJoiner;
-import java.util.function.IntConsumer;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
@@ -119,8 +118,19 @@
 
 public final class String
     implements java.io.Serializable, Comparable<String>, CharSequence {
+
     /** The value is used for character storage. */
-    private final char value[];
+    private final byte[] value;
+
+    /**
+     * The identifier of the encoding used to encode the bytes in
+     * {@code value}. The supported values in this implementation are
+     *
+     * LATIN1
+     * UTF16
+     *
+     */
+    private final byte coder;
 
     /** Cache the hash code for the string */
     private int hash; // Default to 0
@@ -129,6 +139,49 @@
     private static final long serialVersionUID = -6849794470754667710L;
 
     /**
+     * If String compaction is disabled, the bytes in {@code value} are
+     * always encoded in UTF16.
+     *
+     * For methods with several possible implementation paths, when String
+     * compaction is disabled, only one code path is taken.
+     *
+     * The instance field value is generally opaque to optimizing JIT
+     * compilers. Therefore, in performance-sensitive place, an explicit
+     * check of the static boolean {@code COMPACT_STRINGS} is done first
+     * before checking the {@code coder} field since the static boolean
+     * {@code COMPACT_STRINGS} would be constant folded away by an
+     * optimizing JIT compiler. The idioms for these cases are as follows.
+     *
+     * For code such as:
+     *
+     *    if (coder == LATIN1) { ... }
+     *
+     * can be written more optimally as
+     *
+     *    if (coder() == LATIN1) { ... }
+     *
+     * or:
+     *
+     *    if (COMPACT_STRINGS && coder == LATIN1) { ... }
+     *
+     * An optimizing JIT compiler can fold the above conditional as:
+     *
+     *    COMPACT_STRINGS == true  => if (coder == LATIN1) { ... }
+     *    COMPACT_STRINGS == false => if (false)           { ... }
+     *
+     * @implNote
+     * The actual value for this field is injected by JVM. The static
+     * initialization block is used to set the value here to communicate
+     * that this static final field is not statically foldable, and to
+     * avoid any possible circular dependency during vm initialization.
+     */
+    static final boolean COMPACT_STRINGS;
+
+    static {
+        COMPACT_STRINGS = true;
+    }
+
+    /**
      * Class String is special cased within the Serialization Stream Protocol.
      *
      * A String instance is written into an ObjectOutputStream according to
@@ -145,6 +198,7 @@
      */
     public String() {
         this.value = "".value;
+        this.coder = "".coder;
     }
 
     /**
@@ -160,6 +214,7 @@
     @HotSpotIntrinsicCandidate
     public String(String original) {
         this.value = original.value;
+        this.coder = original.coder;
         this.hash = original.hash;
     }
 
@@ -173,7 +228,7 @@
      *         The initial value of the string
      */
     public String(char value[]) {
-        this.value = Arrays.copyOf(value, value.length);
+        this(value, 0, value.length, null);
     }
 
     /**
@@ -198,23 +253,12 @@
      *          {@code offset} is greater than {@code value.length - count}
      */
     public String(char value[], int offset, int count) {
-        if (offset < 0) {
-            throw new StringIndexOutOfBoundsException(offset);
-        }
-        if (count <= 0) {
-            if (count < 0) {
-                throw new StringIndexOutOfBoundsException(count);
-            }
-            if (offset <= value.length) {
-                this.value = "".value;
-                return;
-            }
-        }
-        // Note: offset or count might be near -1>>>1.
-        if (offset > value.length - count) {
-            throw new StringIndexOutOfBoundsException(offset + count);
-        }
-        this.value = Arrays.copyOfRange(value, offset, offset + count);
+        this(value, offset, count, rangeCheck(value, offset, count));
+    }
+
+    private static Void rangeCheck(char[] value, int offset, int count) {
+        checkBoundsOffCount(offset, count, value.length);
+        return null;
     }
 
     /**
@@ -246,48 +290,22 @@
      * @since  1.5
      */
     public String(int[] codePoints, int offset, int count) {
-        if (offset < 0) {
-            throw new StringIndexOutOfBoundsException(offset);
+        checkBoundsOffCount(offset, count, codePoints.length);
+        if (count == 0) {
+            this.value = "".value;
+            this.coder = "".coder;
+            return;
         }
-        if (count <= 0) {
-            if (count < 0) {
-                throw new StringIndexOutOfBoundsException(count);
-            }
-            if (offset <= codePoints.length) {
-                this.value = "".value;
+        if (COMPACT_STRINGS) {
+            byte[] val = StringLatin1.toBytes(codePoints, offset, count);
+            if (val != null) {
+                this.coder = LATIN1;
+                this.value = val;
                 return;
             }
         }
-        // Note: offset or count might be near -1>>>1.
-        if (offset > codePoints.length - count) {
-            throw new StringIndexOutOfBoundsException(offset + count);
-        }
-
-        final int end = offset + count;
-
-        // Pass 1: Compute precise size of char[]
-        int n = count;
-        for (int i = offset; i < end; i++) {
-            int c = codePoints[i];
-            if (Character.isBmpCodePoint(c))
-                continue;
-            else if (Character.isValidCodePoint(c))
-                n++;
-            else throw new IllegalArgumentException(Integer.toString(c));
-        }
-
-        // Pass 2: Allocate and fill in char[]
-        final char[] v = new char[n];
-
-        for (int i = offset, j = 0; i < end; i++, j++) {
-            int c = codePoints[i];
-            if (Character.isBmpCodePoint(c))
-                v[j] = (char)c;
-            else
-                Character.toSurrogates(c, v, j++);
-        }
-
-        this.value = v;
+        this.coder = UTF16;
+        this.value = StringUTF16.toBytes(codePoints, offset, count);
     }
 
     /**
@@ -332,20 +350,24 @@
      */
     @Deprecated
     public String(byte ascii[], int hibyte, int offset, int count) {
-        checkBounds(ascii, offset, count);
-        char[] value = new char[count];
-
-        if (hibyte == 0) {
-            for (int i = count; i-- > 0;) {
-                value[i] = (char)(ascii[i + offset] & 0xff);
-            }
+        checkBoundsOffCount(offset, count, ascii.length);
+        if (count == 0) {
+            this.value = "".value;
+            this.coder = "".coder;
+            return;
+        }
+        if (COMPACT_STRINGS && (byte)hibyte == 0) {
+            this.value = Arrays.copyOfRange(ascii, offset, offset + count);
+            this.coder = LATIN1;
         } else {
             hibyte <<= 8;
-            for (int i = count; i-- > 0;) {
-                value[i] = (char)(hibyte | (ascii[i + offset] & 0xff));
+            byte[] val = StringUTF16.newBytesFor(count);
+            for (int i = 0; i < count; i++) {
+                StringUTF16.putChar(val, i, hibyte | (ascii[offset++] & 0xff));
             }
+            this.value = val;
+            this.coder = UTF16;
         }
-        this.value = value;
     }
 
     /**
@@ -383,19 +405,6 @@
         this(ascii, hibyte, 0, ascii.length);
     }
 
-    /* Common private utility method used to bounds check the byte array
-     * and requested offset & length values used by the String(byte[],..)
-     * constructors.
-     */
-    private static void checkBounds(byte[] bytes, int offset, int length) {
-        if (length < 0)
-            throw new StringIndexOutOfBoundsException(length);
-        if (offset < 0)
-            throw new StringIndexOutOfBoundsException(offset);
-        if (offset > bytes.length - length)
-            throw new StringIndexOutOfBoundsException(offset + length);
-    }
-
     /**
      * Constructs a new {@code String} by decoding the specified subarray of
      * bytes using the specified charset.  The length of the new {@code String}
@@ -433,8 +442,11 @@
             throws UnsupportedEncodingException {
         if (charsetName == null)
             throw new NullPointerException("charsetName");
-        checkBounds(bytes, offset, length);
-        this.value = StringCoding.decode(charsetName, bytes, offset, length);
+        checkBoundsOffCount(offset, length, bytes.length);
+        StringCoding.Result ret =
+            StringCoding.decode(charsetName, bytes, offset, length);
+        this.value = ret.value;
+        this.coder = ret.coder;
     }
 
     /**
@@ -470,8 +482,11 @@
     public String(byte bytes[], int offset, int length, Charset charset) {
         if (charset == null)
             throw new NullPointerException("charset");
-        checkBounds(bytes, offset, length);
-        this.value = StringCoding.decode(charset, bytes, offset, length);
+        checkBoundsOffCount(offset, length, bytes.length);
+        StringCoding.Result ret =
+            StringCoding.decode(charset, bytes, offset, length);
+        this.value = ret.value;
+        this.coder = ret.coder;
     }
 
     /**
@@ -553,8 +568,10 @@
      * @since  1.1
      */
     public String(byte bytes[], int offset, int length) {
-        checkBounds(bytes, offset, length);
-        this.value = StringCoding.decode(bytes, offset, length);
+        checkBoundsOffCount(offset, length, bytes.length);
+        StringCoding.Result ret = StringCoding.decode(bytes, offset, length);
+        this.value = ret.value;
+        this.coder = ret.coder;
     }
 
     /**
@@ -587,9 +604,7 @@
      *         A {@code StringBuffer}
      */
     public String(StringBuffer buffer) {
-        synchronized(buffer) {
-            this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
-        }
+        this(buffer.toString());
     }
 
     /**
@@ -608,18 +623,20 @@
      * @since  1.5
      */
     public String(StringBuilder builder) {
-        this.value = Arrays.copyOf(builder.getValue(), builder.length());
+        this(builder, null);
     }
 
-    /*
+   /*
     * Package private constructor which shares value array for speed.
     * this constructor is always expected to be called with share==true.
     * a separate constructor is needed because we already have a public
     * String(char[]) constructor that makes a copy of the given char[].
     */
-    String(char[] value, boolean share) {
+    // TBD: this is kept for package internal use (Thread/System),
+    // should be removed if they all have a byte[] version
+    String(char[] val, boolean share) {
         // assert share : "unshared not supported";
-        this.value = value;
+        this(val, 0, val.length, null);
     }
 
     /**
@@ -631,7 +648,7 @@
      *          object.
      */
     public int length() {
-        return value.length;
+        return value.length >> coder();
     }
 
     /**
@@ -665,10 +682,11 @@
      *             string.
      */
     public char charAt(int index) {
-        if ((index < 0) || (index >= value.length)) {
-            throw new StringIndexOutOfBoundsException(index);
+        if (isLatin1()) {
+            return StringLatin1.charAt(value, index);
+        } else {
+            return StringUTF16.charAt(value, index);
         }
-        return value[index];
     }
 
     /**
@@ -694,10 +712,13 @@
      * @since      1.5
      */
     public int codePointAt(int index) {
-        if ((index < 0) || (index >= value.length)) {
-            throw new StringIndexOutOfBoundsException(index);
+        if (isLatin1()) {
+            checkIndex(index, value.length);
+            return value[index] & 0xff;
         }
-        return Character.codePointAtImpl(value, index, value.length);
+        int length = value.length >> 1;
+        checkIndex(index, length);
+        return StringUTF16.codePointAt(value, index, length);
     }
 
     /**
@@ -724,10 +745,13 @@
      */
     public int codePointBefore(int index) {
         int i = index - 1;
-        if ((i < 0) || (i >= value.length)) {
+        if (i < 0 || i >= length()) {
             throw new StringIndexOutOfBoundsException(index);
         }
-        return Character.codePointBeforeImpl(value, index, 0);
+        if (isLatin1()) {
+            return (value[i] & 0xff);
+        }
+        return StringUTF16.codePointBefore(value, index);
     }
 
     /**
@@ -752,10 +776,14 @@
      * @since  1.5
      */
     public int codePointCount(int beginIndex, int endIndex) {
-        if (beginIndex < 0 || endIndex > value.length || beginIndex > endIndex) {
+        if (beginIndex < 0 || beginIndex > endIndex ||
+            endIndex > length()) {
             throw new IndexOutOfBoundsException();
         }
-        return Character.codePointCountImpl(value, beginIndex, endIndex - beginIndex);
+        if (isLatin1()) {
+            return endIndex - beginIndex;
+        }
+        return StringUTF16.codePointCount(value, beginIndex, endIndex);
     }
 
     /**
@@ -779,19 +807,10 @@
      * @since 1.5
      */
     public int offsetByCodePoints(int index, int codePointOffset) {
-        if (index < 0 || index > value.length) {
+        if (index < 0 || index > length()) {
             throw new IndexOutOfBoundsException();
         }
-        return Character.offsetByCodePointsImpl(value, 0, value.length,
-                index, codePointOffset);
-    }
-
-    /**
-     * Copy characters from this string into dst starting at dstBegin.
-     * This method doesn't perform any range checking.
-     */
-    void getChars(char dst[], int dstBegin) {
-        System.arraycopy(value, 0, dst, dstBegin, value.length);
+        return Character.offsetByCodePoints(this, index, codePointOffset);
     }
 
     /**
@@ -825,16 +844,13 @@
      *                {@code dst.length}</ul>
      */
     public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
-        if (srcBegin < 0) {
-            throw new StringIndexOutOfBoundsException(srcBegin);
+        checkBoundsBeginEnd(srcBegin, srcEnd, length());
+        checkBoundsOffCount(dstBegin, srcEnd - srcBegin, dst.length);
+        if (isLatin1()) {
+            StringLatin1.getChars(value, srcBegin, srcEnd, dst, dstBegin);
+        } else {
+            StringUTF16.getChars(value, srcBegin, srcEnd, dst, dstBegin);
         }
-        if (srcEnd > value.length) {
-            throw new StringIndexOutOfBoundsException(srcEnd);
-        }
-        if (srcBegin > srcEnd) {
-            throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
-        }
-        System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
     }
 
     /**
@@ -882,24 +898,13 @@
      */
     @Deprecated
     public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin) {
-        if (srcBegin < 0) {
-            throw new StringIndexOutOfBoundsException(srcBegin);
-        }
-        if (srcEnd > value.length) {
-            throw new StringIndexOutOfBoundsException(srcEnd);
-        }
-        if (srcBegin > srcEnd) {
-            throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
-        }
+        checkBoundsBeginEnd(srcBegin, srcEnd, length());
         Objects.requireNonNull(dst);
-
-        int j = dstBegin;
-        int n = srcEnd;
-        int i = srcBegin;
-        char[] val = value;   /* avoid getfield opcode */
-
-        while (i < n) {
-            dst[j++] = (byte)val[i++];
+        checkBoundsOffCount(dstBegin, srcEnd - srcBegin, dst.length);
+        if (isLatin1()) {
+            StringLatin1.getBytes(value, srcBegin, srcEnd, dst, dstBegin);
+        } else {
+            StringUTF16.getBytes(value, srcBegin, srcEnd, dst, dstBegin);
         }
     }
 
@@ -926,7 +931,7 @@
     public byte[] getBytes(String charsetName)
             throws UnsupportedEncodingException {
         if (charsetName == null) throw new NullPointerException();
-        return StringCoding.encode(charsetName, value, 0, value.length);
+        return StringCoding.encode(charsetName, coder(), value);
     }
 
     /**
@@ -949,8 +954,8 @@
      */
     public byte[] getBytes(Charset charset) {
         if (charset == null) throw new NullPointerException();
-        return StringCoding.encode(charset, value, 0, value.length);
-    }
+        return StringCoding.encode(charset, coder(), value);
+     }
 
     /**
      * Encodes this {@code String} into a sequence of bytes using the
@@ -966,7 +971,7 @@
      * @since      1.1
      */
     public byte[] getBytes() {
-        return StringCoding.encode(value, 0, value.length);
+        return StringCoding.encode(coder(), value);
     }
 
     /**
@@ -987,23 +992,15 @@
      * @see  #compareTo(String)
      * @see  #equalsIgnoreCase(String)
      */
-    @HotSpotIntrinsicCandidate
     public boolean equals(Object anObject) {
         if (this == anObject) {
             return true;
         }
         if (anObject instanceof String) {
-            char[] v1 = value;
-            char[] v2 = ((String)anObject).value;
-            int n = v1.length;
-            if (n == v2.length) {
-                int i = 0;
-                while (n-- != 0) {
-                    if (v1[i] != v2[i])
-                        return false;
-                    i++;
-                }
-                return true;
+            String aString = (String)anObject;
+            if (coder() == aString.coder()) {
+                return isLatin1() ? StringLatin1.equals(value, aString.value)
+                                  : StringUTF16.equals(value, aString.value);
             }
         }
         return false;
@@ -1032,16 +1029,28 @@
     }
 
     private boolean nonSyncContentEquals(AbstractStringBuilder sb) {
-        char[] v1 = value;
-        char[] v2 = sb.getValue();
-        int n = v1.length;
-        if (n != sb.length()) {
+        int len = length();
+        if (len != sb.length()) {
             return false;
         }
-        for (int i = 0; i < n; i++) {
-            if (v1[i] != v2[i]) {
+        byte v1[] = value;
+        byte v2[] = sb.getValue();
+        if (coder() == sb.getCoder()) {
+            int n = v1.length;
+            for (int i = 0; i < n; i++) {
+                if (v1[i] != v2[i]) {
+                    return false;
+                }
+            }
+        } else {
+            if (!isLatin1()) {  // utf16 str and latin1 abs can never be "equal"
                 return false;
             }
+            for (int i = 0; i < len; i++) {
+                if ((char)(v1[i] & 0xff) != StringUTF16.getChar(v2, i)) {
+                    return false;
+                }
+            }
         }
         return true;
     }
@@ -1081,14 +1090,22 @@
             return equals(cs);
         }
         // Argument is a generic CharSequence
-        char[] v1 = value;
-        int n = v1.length;
-        if (n != cs.length()) {
+        int n = cs.length();
+        if (n != length()) {
             return false;
         }
-        for (int i = 0; i < n; i++) {
-            if (v1[i] != cs.charAt(i)) {
-                return false;
+        byte[] val = this.value;
+        if (isLatin1()) {
+            for (int i = 0; i < n; i++) {
+                if ((val[i] & 0xff) != cs.charAt(i)) {
+                    return false;
+                }
+            }
+        } else {
+            for (int i = 0; i < n; i++) {
+                if (StringUTF16.getChar(val, i) != cs.charAt(i)) {
+                    return false;
+                }
             }
         }
         return true;
@@ -1125,8 +1142,8 @@
     public boolean equalsIgnoreCase(String anotherString) {
         return (this == anotherString) ? true
                 : (anotherString != null)
-                && (anotherString.value.length == value.length)
-                && regionMatches(true, 0, anotherString, 0, value.length);
+                && (anotherString.length() == length())
+                && regionMatches(true, 0, anotherString, 0, length());
     }
 
     /**
@@ -1173,23 +1190,16 @@
      *          value greater than {@code 0} if this string is
      *          lexicographically greater than the string argument.
      */
-    @HotSpotIntrinsicCandidate
     public int compareTo(String anotherString) {
-        char[] v1 = value;
-        char[] v2 = anotherString.value;
-        int len1 = v1.length;
-        int len2 = v2.length;
-        int lim = Math.min(len1, len2);
-
-        for (int k = 0; k < lim; k++) {
-            char c1 = v1[k];
-            char c2 = v2[k];
-            if (c1 != c2) {
-                return c1 - c2;
-            }
+        byte v1[] = value;
+        byte v2[] = anotherString.value;
+        if (coder() == anotherString.coder()) {
+            return isLatin1() ? StringLatin1.compareTo(v1, v2)
+                              : StringUTF16.compareTo(v1, v2);
         }
-        return len1 - len2;
-    }
+        return isLatin1() ? StringLatin1.compareToUTF16(v1, v2)
+                          : StringUTF16.compareToLatin1(v1, v2);
+     }
 
     /**
      * A Comparator that orders {@code String} objects as by
@@ -1210,12 +1220,18 @@
         private static final long serialVersionUID = 8575799808933029326L;
 
         public int compare(String s1, String s2) {
+            byte v1[] = s1.value;
+            byte v2[] = s2.value;
             int n1 = s1.length();
             int n2 = s2.length();
+            boolean s1IsLatin1 = s1.isLatin1();
+            boolean s2IsLatin1 = s2.isLatin1();
             int min = Math.min(n1, n2);
             for (int i = 0; i < min; i++) {
-                char c1 = s1.charAt(i);
-                char c2 = s2.charAt(i);
+                char c1 = s1IsLatin1 ? StringLatin1.getChar(v1, i)
+                                     : StringUTF16.getChar(v1, i);
+                char c2 = s2IsLatin1 ? StringLatin1.getChar(v2, i)
+                                     : StringUTF16.getChar(v2, i);
                 if (c1 != c2) {
                     c1 = Character.toUpperCase(c1);
                     c2 = Character.toUpperCase(c2);
@@ -1294,21 +1310,41 @@
      *          exactly matches the specified subregion of the string argument;
      *          {@code false} otherwise.
      */
-    public boolean regionMatches(int toffset, String other, int ooffset,
-            int len) {
-        char[] ta = value;
-        int to = toffset;
-        char[] pa = other.value;
-        int po = ooffset;
+    public boolean regionMatches(int toffset, String other, int ooffset, int len) {
+        byte tv[] = value;
+        byte ov[] = other.value;
         // Note: toffset, ooffset, or len might be near -1>>>1.
-        if ((ooffset < 0) || (toffset < 0)
-                || (toffset > (long)ta.length - len)
-                || (ooffset > (long)pa.length - len)) {
+        if ((ooffset < 0) || (toffset < 0) ||
+             (toffset > (long)length() - len) ||
+             (ooffset > (long)other.length() - len)) {
             return false;
         }
-        while (len-- > 0) {
-            if (ta[to++] != pa[po++]) {
-                return false;
+        if (coder() == other.coder()) {
+            if (!isLatin1() && (len > 0)) {
+                toffset = toffset << 1;
+                ooffset = ooffset << 1;
+                len = len << 1;
+            }
+            while (len-- > 0) {
+                if (tv[toffset++] != ov[ooffset++]) {
+                    return false;
+                }
+            }
+        } else {
+            if (coder() == LATIN1) {
+                while (len-- > 0) {
+                    if (StringLatin1.getChar(tv, toffset++) !=
+                        StringUTF16.getChar(ov, ooffset++)) {
+                        return false;
+                    }
+                }
+            } else {
+                while (len-- > 0) {
+                    if (StringUTF16.getChar(tv, toffset++) !=
+                        StringLatin1.getChar(ov, ooffset++)) {
+                        return false;
+                    }
+                }
             }
         }
         return true;
@@ -1366,43 +1402,25 @@
      */
     public boolean regionMatches(boolean ignoreCase, int toffset,
             String other, int ooffset, int len) {
-        char[] ta = value;
-        int to = toffset;
-        char[] pa = other.value;
-        int po = ooffset;
+        if (!ignoreCase) {
+            return regionMatches(toffset, other, ooffset, len);
+        }
         // Note: toffset, ooffset, or len might be near -1>>>1.
         if ((ooffset < 0) || (toffset < 0)
-                || (toffset > (long)ta.length - len)
-                || (ooffset > (long)pa.length - len)) {
+                || (toffset > (long)length() - len)
+                || (ooffset > (long)other.length() - len)) {
             return false;
         }
-        while (len-- > 0) {
-            char c1 = ta[to++];
-            char c2 = pa[po++];
-            if (c1 == c2) {
-                continue;
-            }
-            if (ignoreCase) {
-                // If characters don't match but case may be ignored,
-                // try converting both characters to uppercase.
-                // If the results match, then the comparison scan should
-                // continue.
-                char u1 = Character.toUpperCase(c1);
-                char u2 = Character.toUpperCase(c2);
-                if (u1 == u2) {
-                    continue;
-                }
-                // Unfortunately, conversion to uppercase does not work properly
-                // for the Georgian alphabet, which has strange rules about case
-                // conversion.  So we need to make one last check before
-                // exiting.
-                if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
-                    continue;
-                }
-            }
-            return false;
+        byte tv[] = value;
+        byte ov[] = other.value;
+        if (coder() == other.coder()) {
+            return isLatin1()
+              ? StringLatin1.regionMatchesCI(tv, toffset, ov, ooffset, len)
+              : StringUTF16.regionMatchesCI(tv, toffset, ov, ooffset, len);
         }
-        return true;
+        return isLatin1()
+              ? StringLatin1.regionMatchesCI_UTF16(tv, toffset, ov, ooffset, len)
+              : StringUTF16.regionMatchesCI_Latin1(tv, toffset, ov, ooffset, len);
     }
 
     /**
@@ -1423,19 +1441,31 @@
      *          </pre>
      */
     public boolean startsWith(String prefix, int toffset) {
-        char[] ta = value;
-        int to = toffset;
-        char[] pa = prefix.value;
+        // Note: toffset might be near -1>>>1.
+        if (toffset < 0 || toffset > length() - prefix.length()) {
+            return false;
+        }
+        byte ta[] = value;
+        byte pa[] = prefix.value;
         int po = 0;
         int pc = pa.length;
-        // Note: toffset might be near -1>>>1.
-        if ((toffset < 0) || (toffset > ta.length - pc)) {
-            return false;
-        }
-        while (--pc >= 0) {
-            if (ta[to++] != pa[po++]) {
+        if (coder() == prefix.coder()) {
+            int to = isLatin1() ? toffset : toffset << 1;
+            while (po < pc) {
+                if (ta[to++] != pa[po++]) {
+                    return false;
+                }
+            }
+        } else {
+            if (isLatin1()) {  // && pcoder == UTF16
                 return false;
             }
+            // coder == UTF16 && pcoder == LATIN1)
+            while (po < pc) {
+                if (StringUTF16.getChar(ta, toffset++) != (pa[po++] & 0xff)) {
+                    return false;
+               }
+            }
         }
         return true;
     }
@@ -1469,7 +1499,7 @@
      *          as determined by the {@link #equals(Object)} method.
      */
     public boolean endsWith(String suffix) {
-        return startsWith(suffix, value.length - suffix.value.length);
+        return startsWith(suffix, length() - suffix.length());
     }
 
     /**
@@ -1486,16 +1516,11 @@
      * @return  a hash code value for this object.
      */
     public int hashCode() {
-        int h = hash;
-        if (h == 0) {
-            for (char v : value) {
-                h = 31 * h + v;
-            }
-            if (h != 0) {
-                hash = h;
-            }
+        if (hash == 0 && value.length > 0) {
+            hash = isLatin1() ? StringLatin1.hashCode(value)
+                              : StringUTF16.hashCode(value);
         }
-        return h;
+        return hash;
     }
 
     /**
@@ -1566,45 +1591,8 @@
      *          if the character does not occur.
      */
     public int indexOf(int ch, int fromIndex) {
-        final int max = value.length;
-        if (fromIndex < 0) {
-            fromIndex = 0;
-        } else if (fromIndex >= max) {
-            // Note: fromIndex might be near -1>>>1.
-            return -1;
-        }
-
-        if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
-            // handle most cases here (ch is a BMP code point or a
-            // negative value (invalid code point))
-            final char[] value = this.value;
-            for (int i = fromIndex; i < max; i++) {
-                if (value[i] == ch) {
-                    return i;
-                }
-            }
-            return -1;
-        } else {
-            return indexOfSupplementary(ch, fromIndex);
-        }
-    }
-
-    /**
-     * Handles (rare) calls of indexOf with a supplementary character.
-     */
-    private int indexOfSupplementary(int ch, int fromIndex) {
-        if (Character.isValidCodePoint(ch)) {
-            final char[] value = this.value;
-            final char hi = Character.highSurrogate(ch);
-            final char lo = Character.lowSurrogate(ch);
-            final int max = value.length - 1;
-            for (int i = fromIndex; i < max; i++) {
-                if (value[i] == hi && value[i + 1] == lo) {
-                    return i;
-                }
-            }
-        }
-        return -1;
+        return isLatin1() ? StringLatin1.indexOf(value, ch, fromIndex)
+                          : StringUTF16.indexOf(value, ch, fromIndex);
     }
 
     /**
@@ -1631,7 +1619,7 @@
      *          {@code -1} if the character does not occur.
      */
     public int lastIndexOf(int ch) {
-        return lastIndexOf(ch, value.length - 1);
+        return lastIndexOf(ch, length() - 1);
     }
 
     /**
@@ -1669,38 +1657,8 @@
      *          if the character does not occur before that point.
      */
     public int lastIndexOf(int ch, int fromIndex) {
-        if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
-            // handle most cases here (ch is a BMP code point or a
-            // negative value (invalid code point))
-            final char[] value = this.value;
-            int i = Math.min(fromIndex, value.length - 1);
-            for (; i >= 0; i--) {
-                if (value[i] == ch) {
-                    return i;
-                }
-            }
-            return -1;
-        } else {
-            return lastIndexOfSupplementary(ch, fromIndex);
-        }
-    }
-
-    /**
-     * Handles (rare) calls of lastIndexOf with a supplementary character.
-     */
-    private int lastIndexOfSupplementary(int ch, int fromIndex) {
-        if (Character.isValidCodePoint(ch)) {
-            final char[] value = this.value;
-            char hi = Character.highSurrogate(ch);
-            char lo = Character.lowSurrogate(ch);
-            int i = Math.min(fromIndex, value.length - 2);
-            for (; i >= 0; i--) {
-                if (value[i] == hi && value[i + 1] == lo) {
-                    return i;
-                }
-            }
-        }
-        return -1;
+        return isLatin1() ? StringLatin1.lastIndexOf(value, ch, fromIndex)
+                          : StringUTF16.lastIndexOf(value, ch, fromIndex);
     }
 
     /**
@@ -1717,9 +1675,15 @@
      * @return  the index of the first occurrence of the specified substring,
      *          or {@code -1} if there is no such occurrence.
      */
-    @HotSpotIntrinsicCandidate
     public int indexOf(String str) {
-        return indexOf(str, 0);
+        if (coder() == str.coder()) {
+            return isLatin1() ? StringLatin1.indexOf(value, str.value)
+                              : StringUTF16.indexOf(value, str.value);
+        }
+        if (coder() == LATIN1) {  // str.coder == UTF16
+            return -1;
+        }
+        return StringUTF16.indexOfLatin1(value, str.value);
     }
 
     /**
@@ -1740,8 +1704,7 @@
      *          or {@code -1} if there is no such occurrence.
      */
     public int indexOf(String str, int fromIndex) {
-        return indexOf(value, 0, value.length,
-                str.value, 0, str.value.length, fromIndex);
+        return indexOf(value, coder(), length(), str, fromIndex);
     }
 
     /**
@@ -1749,68 +1712,38 @@
      * source is the character array being searched, and the target
      * is the string being searched for.
      *
-     * @param   source       the characters being searched.
-     * @param   sourceOffset offset of the source string.
-     * @param   sourceCount  count of the source string.
-     * @param   target       the characters being searched for.
-     * @param   fromIndex    the index to begin searching from.
+     * @param   src       the characters being searched.
+     * @param   srcCoder  the coder of the source string.
+     * @param   srcCount  length of the source string.
+     * @param   tgtStr    the characters being searched for.
+     * @param   fromIndex the index to begin searching from.
      */
-    static int indexOf(char[] source, int sourceOffset, int sourceCount,
-            String target, int fromIndex) {
-        return indexOf(source, sourceOffset, sourceCount,
-                       target.value, 0, target.value.length,
-                       fromIndex);
-    }
+    static int indexOf(byte[] src, byte srcCoder, int srcCount,
+                       String tgtStr, int fromIndex) {
 
-    /**
-     * Code shared by String and StringBuffer to do searches. The
-     * source is the character array being searched, and the target
-     * is the string being searched for.
-     *
-     * @param   source       the characters being searched.
-     * @param   sourceOffset offset of the source string.
-     * @param   sourceCount  count of the source string.
-     * @param   target       the characters being searched for.
-     * @param   targetOffset offset of the target string.
-     * @param   targetCount  count of the target string.
-     * @param   fromIndex    the index to begin searching from.
-     */
-    static int indexOf(char[] source, int sourceOffset, int sourceCount,
-            char[] target, int targetOffset, int targetCount,
-            int fromIndex) {
-        if (fromIndex >= sourceCount) {
-            return (targetCount == 0 ? sourceCount : -1);
+        byte[] tgt    = tgtStr.value;
+        byte tgtCoder = tgtStr.coder();
+        int tgtCount  = tgtStr.length();
+
+        if (fromIndex >= srcCount) {
+            return (tgtCount == 0 ? srcCount : -1);
         }
         if (fromIndex < 0) {
             fromIndex = 0;
         }
-        if (targetCount == 0) {
+        if (tgtCount == 0) {
             return fromIndex;
         }
-
-        char first = target[targetOffset];
-        int max = sourceOffset + (sourceCount - targetCount);
-
-        for (int i = sourceOffset + fromIndex; i <= max; i++) {
-            /* Look for first character. */
-            if (source[i] != first) {
-                while (++i <= max && source[i] != first);
-            }
-
-            /* Found first character, now look at the rest of v2 */
-            if (i <= max) {
-                int j = i + 1;
-                int end = j + targetCount - 1;
-                for (int k = targetOffset + 1; j < end && source[j]
-                        == target[k]; j++, k++);
-
-                if (j == end) {
-                    /* Found whole string. */
-                    return i - sourceOffset;
-                }
-            }
+        if (srcCoder == tgtCoder) {
+            return srcCoder == LATIN1
+                ? StringLatin1.indexOf(src, srcCount, tgt, tgtCount, fromIndex)
+                : StringUTF16.indexOf(src, srcCount, tgt, tgtCount, fromIndex);
         }
-        return -1;
+        if (srcCoder == LATIN1) {    //  && tgtCoder == UTF16
+            return -1;
+        }
+        // srcCoder == UTF16 && tgtCoder == LATIN1) {
+        return StringUTF16.indexOfLatin1(src, srcCount, tgt, tgtCount, fromIndex);
     }
 
     /**
@@ -1829,7 +1762,7 @@
      *          or {@code -1} if there is no such occurrence.
      */
     public int lastIndexOf(String str) {
-        return lastIndexOf(str, value.length);
+        return lastIndexOf(str, length());
     }
 
     /**
@@ -1850,8 +1783,7 @@
      *          or {@code -1} if there is no such occurrence.
      */
     public int lastIndexOf(String str, int fromIndex) {
-        return lastIndexOf(value, 0, value.length,
-                str.value, 0, str.value.length, fromIndex);
+        return lastIndexOf(value, coder(), length(), str, fromIndex);
     }
 
     /**
@@ -1859,40 +1791,22 @@
      * source is the character array being searched, and the target
      * is the string being searched for.
      *
-     * @param   source       the characters being searched.
-     * @param   sourceOffset offset of the source string.
-     * @param   sourceCount  count of the source string.
-     * @param   target       the characters being searched for.
-     * @param   fromIndex    the index to begin searching from.
+     * @param   src         the characters being searched.
+     * @param   srcCoder  coder handles the mapping between bytes/chars
+     * @param   srcCount    count of the source string.
+     * @param   tgt         the characters being searched for.
+     * @param   fromIndex   the index to begin searching from.
      */
-    static int lastIndexOf(char[] source, int sourceOffset, int sourceCount,
-            String target, int fromIndex) {
-        return lastIndexOf(source, sourceOffset, sourceCount,
-                       target.value, 0, target.value.length,
-                       fromIndex);
-    }
-
-    /**
-     * Code shared by String and StringBuffer to do searches. The
-     * source is the character array being searched, and the target
-     * is the string being searched for.
-     *
-     * @param   source       the characters being searched.
-     * @param   sourceOffset offset of the source string.
-     * @param   sourceCount  count of the source string.
-     * @param   target       the characters being searched for.
-     * @param   targetOffset offset of the target string.
-     * @param   targetCount  count of the target string.
-     * @param   fromIndex    the index to begin searching from.
-     */
-    static int lastIndexOf(char[] source, int sourceOffset, int sourceCount,
-            char[] target, int targetOffset, int targetCount,
-            int fromIndex) {
+    static int lastIndexOf(byte[] src, byte srcCoder, int srcCount,
+                           String tgtStr, int fromIndex) {
+        byte[] tgt = tgtStr.value;
+        byte tgtCoder = tgtStr.coder();
+        int tgtCount = tgtStr.length();
         /*
          * Check arguments; return immediately where possible. For
          * consistency, don't check for null str.
          */
-        int rightIndex = sourceCount - targetCount;
+        int rightIndex = srcCount - tgtCount;
         if (fromIndex < 0) {
             return -1;
         }
@@ -1900,34 +1814,41 @@
             fromIndex = rightIndex;
         }
         /* Empty string always matches. */
-        if (targetCount == 0) {
+        if (tgtCount == 0) {
             return fromIndex;
         }
+        if (srcCoder == tgtCoder) {
+            return srcCoder == LATIN1
+                ? StringLatin1.lastIndexOf(src, srcCount, tgt, tgtCount, fromIndex)
+                : StringUTF16.lastIndexOf(src, srcCount, tgt, tgtCount, fromIndex);
+        }
+        if (srcCoder == LATIN1) {    // && tgtCoder == UTF16
+            return -1;
+        }
+                                     // srcCoder == UTF16 && tgtCoder == LATIN1
+        int min = tgtCount - 1;
+        int i = min + fromIndex;
+        int strLastIndex = tgtCount - 1;
 
-        int strLastIndex = targetOffset + targetCount - 1;
-        char strLastChar = target[strLastIndex];
-        int min = sourceOffset + targetCount - 1;
-        int i = min + fromIndex;
-
+        char strLastChar = (char)(tgt[strLastIndex] & 0xff);
     startSearchForLastChar:
         while (true) {
-            while (i >= min && source[i] != strLastChar) {
+            while (i >= min && StringUTF16.getChar(src, i) != strLastChar) {
                 i--;
             }
             if (i < min) {
                 return -1;
             }
             int j = i - 1;
-            int start = j - (targetCount - 1);
+            int start = j - strLastIndex;
             int k = strLastIndex - 1;
-
             while (j > start) {
-                if (source[j--] != target[k--]) {
+                if (StringUTF16.getChar(src, j--) != (tgt[k--] & 0xff)) {
                     i--;
                     continue startSearchForLastChar;
                 }
             }
-            return start - sourceOffset + 1;
+            return start + 1;
         }
     }
 
@@ -1949,17 +1870,18 @@
      *             length of this {@code String} object.
      */
     public String substring(int beginIndex) {
-        if (beginIndex <= 0) {
-            if (beginIndex < 0) {
-                throw new StringIndexOutOfBoundsException(beginIndex);
-            }
-            return this;
+        if (beginIndex < 0) {
+            throw new StringIndexOutOfBoundsException(beginIndex);
         }
-        int subLen = value.length - beginIndex;
+        int subLen = length() - beginIndex;
         if (subLen < 0) {
             throw new StringIndexOutOfBoundsException(subLen);
         }
-        return new String(value, beginIndex, subLen);
+        if (beginIndex == 0) {
+            return this;
+        }
+        return isLatin1() ? StringLatin1.newString(value, beginIndex, subLen)
+                          : StringUTF16.newString(value, beginIndex, subLen);
     }
 
     /**
@@ -1985,22 +1907,14 @@
      *             {@code endIndex}.
      */
     public String substring(int beginIndex, int endIndex) {
-        if (beginIndex <= 0) {
-            if (beginIndex < 0) {
-                throw new StringIndexOutOfBoundsException(beginIndex);
-            }
-            if (endIndex == value.length) {
-                return this;
-            }
+        int length = length();
+        checkBoundsBeginEnd(beginIndex, endIndex, length);
+        int subLen = endIndex - beginIndex;
+        if (beginIndex == 0 && endIndex == length) {
+            return this;
         }
-        if (endIndex > value.length) {
-            throw new StringIndexOutOfBoundsException(endIndex);
-        }
-        int subLen = endIndex - beginIndex;
-        if (subLen < 0) {
-            throw new StringIndexOutOfBoundsException(subLen);
-        }
-        return new String(value, beginIndex, subLen);
+        return isLatin1() ? StringLatin1.newString(value, beginIndex, subLen)
+                          : StringUTF16.newString(value, beginIndex, subLen);
     }
 
     /**
@@ -2057,14 +1971,23 @@
      *          characters followed by the string argument's characters.
      */
     public String concat(String str) {
-        int otherLen = str.length();
-        if (otherLen == 0) {
+        int olen = str.length();
+        if (olen == 0) {
             return this;
         }
-        int len = value.length;
-        char[] buf = Arrays.copyOf(value, len + otherLen);
-        str.getChars(buf, len);
-        return new String(buf, true);
+        if (coder() == str.coder()) {
+            byte[] val = this.value;
+            byte[] oval = str.value;
+            int len = val.length + oval.length;
+            byte[] buf = Arrays.copyOf(val, len);
+            System.arraycopy(oval, 0, buf, val.length, oval.length);
+            return new String(buf, coder);
+        }
+        int len = length();
+        byte[] buf = StringUTF16.newBytesFor(len + olen);
+        getBytes(buf, 0, UTF16);
+        str.getBytes(buf, len, UTF16);
+        return new String(buf, UTF16);
     }
 
     /**
@@ -2098,26 +2021,10 @@
      */
     public String replace(char oldChar, char newChar) {
         if (oldChar != newChar) {
-            char[] val = value; /* avoid getfield opcode */
-            int len = val.length;
-            int i = -1;
-
-            while (++i < len) {
-                if (val[i] == oldChar) {
-                    break;
-                }
-            }
-            if (i < len) {
-                char[] buf = new char[len];
-                for (int j = 0; j < i; j++) {
-                    buf[j] = val[j];
-                }
-                while (i < len) {
-                    char c = val[i];
-                    buf[i] = (c == oldChar) ? newChar : c;
-                    i++;
-                }
-                return new String(buf, true);
+            String ret = isLatin1() ? StringLatin1.replace(value, oldChar, newChar)
+                                    : StringUTF16.replace(value, oldChar, newChar);
+            if (ret != null) {
+                return ret;
             }
         }
         return this;
@@ -2269,29 +2176,27 @@
      * @since 1.5
      */
     public String replace(CharSequence target, CharSequence replacement) {
-        String starget = target.toString();
-        String srepl = replacement.toString();
-        int j = indexOf(starget);
+        String tgtStr = target.toString();
+        String replStr = replacement.toString();
+        int j = indexOf(tgtStr);
         if (j < 0) {
             return this;
         }
-        int targLen = starget.length();
-        int targLen1 = Math.max(targLen, 1);
-        final char[] value = this.value;
-        final char[] replValue = srepl.value;
-        int newLenHint = value.length - targLen + replValue.length;
+        int tgtLen = tgtStr.length();
+        int tgtLen1 = Math.max(tgtLen, 1);
+        int thisLen = length();
+
+        int newLenHint = thisLen - tgtLen + replStr.length();
         if (newLenHint < 0) {
             throw new OutOfMemoryError();
         }
         StringBuilder sb = new StringBuilder(newLenHint);
         int i = 0;
         do {
-            sb.append(value, i, j - i)
-                    .append(replValue);
-            i = j + targLen;
-        } while (j < value.length && (j = indexOf(starget, j + targLen1)) > 0);
-
-        return sb.append(value, i, value.length - i).toString();
+            sb.append(this, i, j).append(replStr);
+            i = j + tgtLen;
+        } while (j < thisLen && (j = indexOf(tgtStr, j + tgtLen1)) > 0);
+        return sb.append(this, i, thisLen).toString();
     }
 
     /**
@@ -2388,7 +2293,7 @@
             the second is not the ascii digit or ascii letter.
          */
         char ch = 0;
-        if (((regex.value.length == 1 &&
+        if (((regex.length() == 1 &&
              ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||
              (regex.length() == 2 &&
               regex.charAt(0) == '\\' &&
@@ -2408,8 +2313,9 @@
                     off = next + 1;
                 } else {    // last one
                     //assert (list.size() == limit - 1);
-                    list.add(substring(off, value.length));
-                    off = value.length;
+                    int last = length();
+                    list.add(substring(off, last));
+                    off = last;
                     break;
                 }
             }
@@ -2419,7 +2325,7 @@
 
             // Add remaining segment
             if (!limited || list.size() < limit)
-                list.add(substring(off, value.length));
+                list.add(substring(off, length()));
 
             // Construct result
             int resultSize = list.size();
@@ -2613,95 +2519,8 @@
      * @since   1.1
      */
     public String toLowerCase(Locale locale) {
-        if (locale == null) {
-            throw new NullPointerException();
-        }
-        int first;
-        boolean hasSurr = false;
-        final int len = value.length;
-
-        // Now check if there are any characters that need to be changed, or are surrogate
-        for (first = 0 ; first < len; first++) {
-            int cp = (int)value[first];
-            if (Character.isSurrogate((char)cp)) {
-                hasSurr = true;
-                break;
-            }
-            if (cp != Character.toLowerCase(cp)) {  // no need to check Character.ERROR
-                break;
-            }
-        }
-        if (first == len)
-            return this;
-        char[] result = new char[len];
-        System.arraycopy(value, 0, result, 0, first);  // Just copy the first few
-                                                       // lowerCase characters.
-        String lang = locale.getLanguage();
-        if (lang == "tr" || lang == "az" || lang == "lt") {
-            return toLowerCaseEx(result, first, locale, true);
-        }
-        if (hasSurr) {
-            return toLowerCaseEx(result, first, locale, false);
-        }
-        for (int i = first; i < len; i++) {
-            int cp = (int)value[i];
-            if (cp == '\u03A3' ||                       // GREEK CAPITAL LETTER SIGMA
-                Character.isSurrogate((char)cp)) {
-                return toLowerCaseEx(result, i, locale, false);
-            }
-            if (cp == '\u0130') {                       // LATIN CAPITAL LETTER I WITH DOT ABOVE
-                return toLowerCaseEx(result, i, locale, true);
-            }
-            cp = Character.toLowerCase(cp);
-            if (!Character.isBmpCodePoint(cp)) {
-                return toLowerCaseEx(result, i, locale, false);
-            }
-            result[i] = (char)cp;
-        }
-        return new String(result, true);
-    }
-
-    private String toLowerCaseEx(char[] result, int first, Locale locale, boolean localeDependent) {
-        int resultOffset = first;
-        int srcCount;
-        for (int i = first; i < value.length; i += srcCount) {
-            int srcChar = (int)value[i];
-            int lowerChar;
-            char[] lowerCharArray;
-            srcCount = 1;
-            if (Character.isSurrogate((char)srcChar)) {
-                srcChar = codePointAt(i);
-                srcCount = Character.charCount(srcChar);
-            }
-            if (localeDependent || srcChar == '\u03A3') { // GREEK CAPITAL LETTER SIGMA
-                lowerChar = ConditionalSpecialCasing.toLowerCaseEx(this, i, locale);
-            } else {
-                lowerChar = Character.toLowerCase(srcChar);
-            }
-            if (Character.isBmpCodePoint(lowerChar)) {    // Character.ERROR is not a bmp
-                result[resultOffset++] = (char)lowerChar;
-            } else {
-                if (lowerChar == Character.ERROR) {
-                    lowerCharArray = ConditionalSpecialCasing.toLowerCaseCharArray(this, i, locale);
-                } else if (srcCount == 2) {
-                    resultOffset += Character.toChars(lowerChar, result, resultOffset);
-                    continue;
-                } else {
-                    lowerCharArray = Character.toChars(lowerChar);
-                }
-                /* Grow result if needed */
-                int mapLen = lowerCharArray.length;
-                if (mapLen > srcCount) {
-                    char[] result2 = new char[result.length + mapLen - srcCount];
-                    System.arraycopy(result, 0, result2, 0, resultOffset);
-                    result = result2;
-                }
-                for (int x = 0; x < mapLen; ++x) {
-                    result[resultOffset++] = lowerCharArray[x];
-                }
-            }
-        }
-        return new String(result, 0, resultOffset);
+        return isLatin1() ? StringLatin1.toLowerCase(this, value, locale)
+                          : StringUTF16.toLowerCase(this, value, locale);
     }
 
     /**
@@ -2776,98 +2595,8 @@
      * @since   1.1
      */
     public String toUpperCase(Locale locale) {
-        if (locale == null) {
-            throw new NullPointerException();
-        }
-        int first;
-        boolean hasSurr = false;
-        final int len = value.length;
-
-        // Now check if there are any characters that need to be changed, or are surrogate
-        for (first = 0 ; first < len; first++ ) {
-            int cp = (int)value[first];
-            if (Character.isSurrogate((char)cp)) {
-                hasSurr = true;
-                break;
-            }
-            if (cp != Character.toUpperCaseEx(cp)) {   // no need to check Character.ERROR
-                break;
-            }
-        }
-        if (first == len) {
-            return this;
-        }
-        char[] result = new char[len];
-        System.arraycopy(value, 0, result, 0, first);  // Just copy the first few
-                                                       // upperCase characters.
-        String lang = locale.getLanguage();
-        if (lang == "tr" || lang == "az" || lang == "lt") {
-            return toUpperCaseEx(result, first, locale, true);
-        }
-        if (hasSurr) {
-            return toUpperCaseEx(result, first, locale, false);
-        }
-        for (int i = first; i < len; i++) {
-            int cp = (int)value[i];
-            if (Character.isSurrogate((char)cp)) {
-                return toUpperCaseEx(result, i, locale, false);
-            }
-            cp = Character.toUpperCaseEx(cp);
-            if (!Character.isBmpCodePoint(cp)) {    // Character.ERROR is not bmp
-                return toUpperCaseEx(result, i, locale, false);
-            }
-            result[i] = (char)cp;
-        }
-        return new String(result, true);
-    }
-
-    private String toUpperCaseEx(char[] result, int first, Locale locale,
-                                 boolean localeDependent) {
-        int resultOffset = first;
-        int srcCount;
-        for (int i = first; i < value.length; i += srcCount) {
-            int srcChar = (int)value[i];
-            int upperChar;
-            char[] upperCharArray;
-            srcCount = 1;
-            if (Character.isSurrogate((char)srcChar)) {
-                srcChar = codePointAt(i);
-                srcCount = Character.charCount(srcChar);
-            }
-            if (localeDependent) {
-                upperChar = ConditionalSpecialCasing.toUpperCaseEx(this, i, locale);
-            } else {
-                upperChar = Character.toUpperCaseEx(srcChar);
-            }
-            if (Character.isBmpCodePoint(upperChar)) {
-                result[resultOffset++] = (char)upperChar;
-            } else {
-                if (upperChar == Character.ERROR) {
-                    if (localeDependent) {
-                        upperCharArray =
-                            ConditionalSpecialCasing.toUpperCaseCharArray(this, i, locale);
-                    } else {
-                        upperCharArray = Character.toUpperCaseCharArray(srcChar);
-                    }
-                } else if (srcCount == 2) {
-                    resultOffset += Character.toChars(upperChar, result, resultOffset);
-                    continue;
-                } else {
-                    upperCharArray = Character.toChars(upperChar);
-                }
-                /* Grow result if needed */
-                int mapLen = upperCharArray.length;
-                if (mapLen > srcCount) {
-                    char[] result2 = new char[result.length + mapLen - srcCount];
-                    System.arraycopy(result, 0, result2, 0, resultOffset);
-                    result = result2;
-                 }
-                 for (int x = 0; x < mapLen; ++x) {
-                    result[resultOffset++] = upperCharArray[x];
-                 }
-            }
-        }
-        return new String(result, 0, resultOffset);
+        return isLatin1() ? StringLatin1.toUpperCase(this, value, locale)
+                          : StringUTF16.toUpperCase(this, value, locale);
     }
 
     /**
@@ -2925,17 +2654,9 @@
      *          trailing white space.
      */
     public String trim() {
-        char[] val = value;    /* avoid getfield opcode */
-        int end = val.length;
-        int beg = 0;
-
-        while ((beg < end) && (val[beg] <= ' ')) {
-            beg++;
-        }
-        while ((beg < end) && (val[end - 1] <= ' ')) {
-            end--;
-        }
-        return substring(beg, end);
+        String ret = isLatin1() ? StringLatin1.trim(value)
+                                : StringUTF16.trim(value);
+        return ret == null ? this : ret;
     }
 
     /**
@@ -2947,63 +2668,6 @@
         return this;
     }
 
-    static class IntCharArraySpliterator implements Spliterator.OfInt {
-        private final char[] array;
-        private int index;        // current index, modified on advance/split
-        private final int fence;  // one past last index
-        private final int cs;
-
-        IntCharArraySpliterator(char[] array, int acs) {
-            this(array, 0, array.length, acs);
-        }
-
-        IntCharArraySpliterator(char[] array, int origin, int fence, int acs) {
-            this.array = array;
-            this.index = origin;
-            this.fence = fence;
-            this.cs = acs | Spliterator.ORDERED | Spliterator.SIZED
-                      | Spliterator.SUBSIZED;
-        }
-
-        @Override
-        public OfInt trySplit() {
-            int lo = index, mid = (lo + fence) >>> 1;
-            return (lo >= mid)
-                   ? null
-                   : new IntCharArraySpliterator(array, lo, index = mid, cs);
-        }
-
-        @Override
-        public void forEachRemaining(IntConsumer action) {
-            char[] a; int i, hi; // hoist accesses and checks from loop
-            if (action == null)
-                throw new NullPointerException();
-            if ((a = array).length >= (hi = fence) &&
-                (i = index) >= 0 && i < (index = hi)) {
-                do { action.accept(a[i]); } while (++i < hi);
-            }
-        }
-
-        @Override
-        public boolean tryAdvance(IntConsumer action) {
-            if (action == null)
-                throw new NullPointerException();
-            if (index >= 0 && index < fence) {
-                action.accept(array[index++]);
-                return true;
-            }
-            return false;
-        }
-
-        @Override
-        public long estimateSize() { return (long)(fence - index); }
-
-        @Override
-        public int characteristics() {
-            return cs;
-        }
-    }
-
     /**
      * Returns a stream of {@code int} zero-extending the {@code char} values
      * from this sequence.  Any char which maps to a <a
@@ -3016,93 +2680,11 @@
     @Override
     public IntStream chars() {
         return StreamSupport.intStream(
-                new IntCharArraySpliterator(value, Spliterator.IMMUTABLE), false);
+            isLatin1() ? new StringLatin1.CharsSpliterator(value, Spliterator.IMMUTABLE)
+                       : new StringUTF16.CharsSpliterator(value, Spliterator.IMMUTABLE),
+            false);
     }
 
-    static class CodePointsSpliterator implements Spliterator.OfInt {
-        private final char[] array;
-        private int index;        // current index, modified on advance/split
-        private final int fence;  // one past last index
-        private final int cs;
-
-        CodePointsSpliterator(char[] array, int acs) {
-            this(array, 0, array.length, acs);
-        }
-
-        CodePointsSpliterator(char[] array, int origin, int fence, int acs) {
-            this.array = array;
-            this.index = origin;
-            this.fence = fence;
-            this.cs = acs | Spliterator.ORDERED;
-        }
-
-        @Override
-        public OfInt trySplit() {
-            int lo = index, mid = (lo + fence) >>> 1;
-            if (lo >= mid)
-                return null;
-
-            int midOneLess;
-            // If the mid-point intersects a surrogate pair
-            if (Character.isLowSurrogate(array[mid]) &&
-                Character.isHighSurrogate(array[midOneLess = (mid -1)])) {
-                // If there is only one pair it cannot be split
-                if (lo >= midOneLess)
-                    return null;
-                // Shift the mid-point to align with the surrogate pair
-                return new CodePointsSpliterator(array, lo, index = midOneLess, cs);
-            }
-            return new CodePointsSpliterator(array, lo, index = mid, cs);
-        }
-
-        @Override
-        public void forEachRemaining(IntConsumer action) {
-            char[] a; int i, hi; // hoist accesses and checks from loop
-            if (action == null)
-                throw new NullPointerException();
-            if ((a = array).length >= (hi = fence) &&
-                (i = index) >= 0 && i < (index = hi)) {
-                do {
-                    i = advance(a, i, hi, action);
-                } while (i < hi);
-            }
-        }
-
-        @Override
-        public boolean tryAdvance(IntConsumer action) {
-            if (action == null)
-                throw new NullPointerException();
-            if (index >= 0 && index < fence) {
-                index = advance(array, index, fence, action);
-                return true;
-            }
-            return false;
-        }
-
-        // Advance one code point from the index, i, and return the next
-        // index to advance from
-        private static int advance(char[] a, int i, int hi, IntConsumer action) {
-            char c1 = a[i++];
-            int cp = c1;
-            if (Character.isHighSurrogate(c1) && i < hi) {
-                char c2 = a[i];
-                if (Character.isLowSurrogate(c2)) {
-                    i++;
-                    cp = Character.toCodePoint(c1, c2);
-                }
-            }
-            action.accept(cp);
-            return i;
-        }
-
-        @Override
-        public long estimateSize() { return (long)(fence - index); }
-
-        @Override
-        public int characteristics() {
-            return cs;
-        }
-    }
 
     /**
      * Returns a stream of code point values from this sequence.  Any surrogate
@@ -3118,7 +2700,9 @@
     @Override
     public IntStream codePoints() {
         return StreamSupport.intStream(
-                new CodePointsSpliterator(value, Spliterator.IMMUTABLE), false);
+            isLatin1() ? new StringLatin1.CharsSpliterator(value, Spliterator.IMMUTABLE)
+                       : new StringUTF16.CodePointsSpliterator(value, Spliterator.IMMUTABLE),
+            false);
     }
 
     /**
@@ -3129,10 +2713,8 @@
      *          the character sequence represented by this string.
      */
     public char[] toCharArray() {
-        // Cannot use Arrays.copyOf because of class initialization order issues
-        char[] result = new char[value.length];
-        System.arraycopy(value, 0, result, 0, value.length);
-        return result;
+        return isLatin1() ? StringLatin1.toChars(value)
+                          : StringUTF16.toChars(value);
     }
 
     /**
@@ -3315,7 +2897,10 @@
      *          as its single character the argument {@code c}.
      */
     public static String valueOf(char c) {
-        return new String(new char[]{c}, true);
+        if (COMPACT_STRINGS && StringLatin1.canEncode(c)) {
+            return new String(StringLatin1.toBytes(c), LATIN1);
+        }
+        return new String(StringUTF16.toBytes(c), UTF16);
     }
 
     /**
@@ -3398,4 +2983,145 @@
      *          guaranteed to be from a pool of unique strings.
      */
     public native String intern();
+
+    ////////////////////////////////////////////////////////////////
+
+    /**
+     * Copy character bytes from this string into dst starting at dstBegin.
+     * This method doesn't perform any range checking.
+     *
+     * Invoker guarantees: dst is in UTF16 (inflate itself for asb), if two
+     * coders are different, and dst is big enough (range check)
+     *
+     * @param dstBegin  the char index, not offset of byte[]
+     * @param coder     the coder of dst[]
+     */
+    void getBytes(byte dst[], int dstBegin, byte coder) {
+        if (coder() == coder) {
+            System.arraycopy(value, 0, dst, dstBegin << coder, value.length);
+        } else {    // this.coder == LATIN && coder == UTF16
+            StringLatin1.inflate(value, 0, dst, dstBegin, value.length);
+        }
+    }
+
+    /*
+     * Package private constructor. Trailing Void argument is there for
+     * disambiguating it against other (public) constructors.
+     *
+     * Stores the char[] value into a byte[] that each byte represents
+     * the8 low-order bits of the corresponding character, if the char[]
+     * contains only latin1 character. Or a byte[] that stores all
+     * characters in their byte sequences defined by the {@code StringUTF16}.
+     */
+    String(char[] value, int off, int len, Void sig) {
+        if (len == 0) {
+            this.value = "".value;
+            this.coder = "".coder;
+            return;
+        }
+        if (COMPACT_STRINGS) {
+            byte[] val = StringUTF16.compress(value, off, len);
+            if (val != null) {
+                this.value = val;
+                this.coder = LATIN1;
+                return;
+            }
+        }
+        this.coder = UTF16;
+        this.value = StringUTF16.toBytes(value, off, len);
+    }
+
+    /*
+     * Package private constructor. Trailing Void argument is there for
+     * disambiguating it against other (public) constructors.
+     */
+    String(AbstractStringBuilder asb, Void sig) {
+        byte[] val = asb.getValue();
+        int length = asb.length();
+        if (asb.isLatin1()) {
+            this.coder = LATIN1;
+            this.value = Arrays.copyOfRange(val, 0, length);
+        } else {
+            if (COMPACT_STRINGS) {
+                byte[] buf = StringUTF16.compress(val, 0, length);
+                if (buf != null) {
+                    this.coder = LATIN1;
+                    this.value = buf;
+                    return;
+                }
+            }
+            this.coder = UTF16;
+            this.value = Arrays.copyOfRange(val, 0, length << 1);
+        }
+    }
+
+   /*
+    * Package private constructor which shares value array for speed.
+    */
+    String(byte[] value, byte coder) {
+        this.value = value;
+        this.coder = coder;
+    }
+
+    byte coder() {
+        return COMPACT_STRINGS ? coder : UTF16;
+    }
+
+    private boolean isLatin1() {
+        return COMPACT_STRINGS && coder == LATIN1;
+    }
+
+    static final byte LATIN1 = 0;
+    static final byte UTF16  = 1;
+
+    /*
+     * StringIndexOutOfBoundsException  if {@code index} is
+     * negative or greater than or equal to {@code length}.
+     */
+    static void checkIndex(int index, int length) {
+        if (index < 0 || index >= length) {
+            throw new StringIndexOutOfBoundsException("index " + index);
+        }
+    }
+
+    /*
+     * StringIndexOutOfBoundsException  if {@code offset}
+     * is negative or greater than {@code length}.
+     */
+    static void checkOffset(int offset, int length) {
+        if (offset < 0 || offset > length) {
+            throw new StringIndexOutOfBoundsException("offset " + offset +
+                                                      ",length " + length);
+        }
+    }
+
+    /*
+     * Check {@code offset}, {@code count} against {@code 0} and {@code length}
+     * bounds.
+     *
+     * @throws  StringIndexOutOfBoundsException
+     *          If {@code offset} is negative, {@code count} is negative,
+     *          or {@code offset} is greater than {@code length - count}
+     */
+    private static void checkBoundsOffCount(int offset, int count, int length) {
+        if (offset < 0 || count < 0 || offset > length - count) {
+            throw new StringIndexOutOfBoundsException(
+                "offset " + offset + ", count " + count + ", length " + length);
+        }
+    }
+
+    /*
+     * Check {@code begin}, {@code end} against {@code 0} and {@code length}
+     * bounds.
+     *
+     * @throws  StringIndexOutOfBoundsException
+     *          If {@code begin} is negative, {@code begin} is greater than
+     *          {@code end}, or {@code end} is greater than {@code length}.
+     */
+    private static void checkBoundsBeginEnd(int begin, int end, int length) {
+        if (begin < 0 || begin > end || end > length) {
+            throw new StringIndexOutOfBoundsException(
+                "begin " + begin + ", end " + end + ", length " + length);
+        }
+    }
 }
--- a/jdk/src/java.base/share/classes/java/lang/StringBuffer.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/StringBuffer.java	Tue Nov 17 10:29:28 2015 -0800
@@ -104,7 +104,7 @@
      * A cache of the last value returned by toString. Cleared
      * whenever the StringBuffer is modified.
      */
-    private transient char[] toStringCache;
+    private transient String toStringCache;
 
     /** use serialVersionUID from JDK 1.0.2 for interoperability */
     static final long serialVersionUID = 3388685877147921107L;
@@ -169,15 +169,13 @@
 
     @Override
     public synchronized int capacity() {
-        return value.length;
+        return super.capacity();
     }
 
 
     @Override
     public synchronized void ensureCapacity(int minimumCapacity) {
-        if (minimumCapacity > value.length) {
-            expandCapacity(minimumCapacity);
-        }
+        super.ensureCapacity(minimumCapacity);
     }
 
     /**
@@ -204,9 +202,7 @@
      */
     @Override
     public synchronized char charAt(int index) {
-        if ((index < 0) || (index >= count))
-            throw new StringIndexOutOfBoundsException(index);
-        return value[index];
+        return super.charAt(index);
     }
 
     /**
@@ -261,10 +257,8 @@
      */
     @Override
     public synchronized void setCharAt(int index, char ch) {
-        if ((index < 0) || (index >= count))
-            throw new StringIndexOutOfBoundsException(index);
         toStringCache = null;
-        value[index] = ch;
+        super.setCharAt(index, ch);
     }
 
     @Override
@@ -680,9 +674,11 @@
     @HotSpotIntrinsicCandidate
     public synchronized String toString() {
         if (toStringCache == null) {
-            toStringCache = Arrays.copyOfRange(value, 0, count);
+            return toStringCache =
+                    isLatin1() ? StringLatin1.newString(value, 0, count)
+                               : StringUTF16.newString(value, 0, count);
         }
-        return new String(toStringCache, true);
+        return new String(toStringCache);
     }
 
     /**
@@ -710,7 +706,13 @@
     private synchronized void writeObject(java.io.ObjectOutputStream s)
         throws java.io.IOException {
         java.io.ObjectOutputStream.PutField fields = s.putFields();
-        fields.put("value", value);
+        char[] val = new char[capacity()];
+        if (isLatin1()) {
+            StringLatin1.getChars(value, 0, count, val, 0);
+        } else {
+            StringUTF16.getChars(value, 0, count, val, 0);
+        }
+        fields.put("value", val);
         fields.put("count", count);
         fields.put("shared", false);
         s.writeFields();
@@ -723,7 +725,12 @@
     private void readObject(java.io.ObjectInputStream s)
         throws java.io.IOException, ClassNotFoundException {
         java.io.ObjectInputStream.GetField fields = s.readFields();
-        value = (char[])fields.get("value", null);
+        char[] val = (char[])fields.get("value", null);
+        initBytes(val, 0, val.length);
         count = fields.get("count", 0);
     }
+
+    protected synchronized void getBytes(byte dst[], int dstBegin, byte coder) {
+        super.getBytes(dst, dstBegin, coder);
+    }
 }
--- a/jdk/src/java.base/share/classes/java/lang/StringBuilder.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/StringBuilder.java	Tue Nov 17 10:29:28 2015 -0800
@@ -412,7 +412,8 @@
     @HotSpotIntrinsicCandidate
     public String toString() {
         // Create a copy, don't share the array
-        return new String(value, 0, count);
+        return isLatin1() ? StringLatin1.newString(value, 0, count)
+                          : StringUTF16.newStringSB(value, 0, count);
     }
 
     /**
@@ -430,7 +431,13 @@
         throws java.io.IOException {
         s.defaultWriteObject();
         s.writeInt(count);
-        s.writeObject(value);
+        char[] val = new char[capacity()];
+        if (isLatin1()) {
+            StringLatin1.getChars(value, 0, count, val, 0);
+        } else {
+            StringUTF16.getChars(value, 0, count, val, 0);
+        }
+        s.writeObject(val);
     }
 
     /**
@@ -441,7 +448,8 @@
         throws java.io.IOException, ClassNotFoundException {
         s.defaultReadObject();
         count = s.readInt();
-        value = (char[]) s.readObject();
+        char[] val = (char[]) s.readObject();
+        initBytes(val, 0, val.length);
     }
 
 }
--- a/jdk/src/java.base/share/classes/java/lang/StringCoding.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/StringCoding.java	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, 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
@@ -38,11 +38,19 @@
 import java.nio.charset.IllegalCharsetNameException;
 import java.nio.charset.UnsupportedCharsetException;
 import java.util.Arrays;
+import jdk.internal.HotSpotIntrinsicCandidate;
 import sun.misc.MessageUtils;
 import sun.nio.cs.HistoricallyNamedCharset;
 import sun.nio.cs.ArrayDecoder;
 import sun.nio.cs.ArrayEncoder;
 
+import static java.lang.String.LATIN1;
+import static java.lang.String.UTF16;
+import static java.lang.String.COMPACT_STRINGS;
+import static java.nio.charset.StandardCharsets.ISO_8859_1;
+import static java.nio.charset.StandardCharsets.US_ASCII;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
 /**
  * Utility class for string encoding and decoding.
  */
@@ -72,23 +80,13 @@
 
     // Trim the given byte array to the given length
     //
-    private static byte[] safeTrim(byte[] ba, int len, Charset cs, boolean isTrusted) {
+    private static byte[] safeTrim(byte[] ba, int len, boolean isTrusted) {
         if (len == ba.length && (isTrusted || System.getSecurityManager() == null))
             return ba;
         else
             return Arrays.copyOf(ba, len);
     }
 
-    // Trim the given char array to the given length
-    //
-    private static char[] safeTrim(char[] ca, int len,
-                                   Charset cs, boolean isTrusted) {
-        if (len == ca.length && (isTrusted || System.getSecurityManager() == null))
-            return ca;
-        else
-            return Arrays.copyOf(ca, len);
-    }
-
     private static int scale(int len, float expansionFactor) {
         // We need to perform double, not float, arithmetic; otherwise
         // we lose low order bits when len is larger than 2**24.
@@ -117,21 +115,64 @@
         }
     }
 
+    static class Result {
+        byte[] value;
+        byte coder;
+
+        Result with() {
+            coder = COMPACT_STRINGS ? LATIN1 : UTF16;
+            value = new byte[0];
+            return this;
+        }
+
+        Result with(char[] val, int off, int len) {
+            if (String.COMPACT_STRINGS) {
+                byte[] bs = StringUTF16.compress(val, off, len);
+                if (bs != null) {
+                    value = bs;
+                    coder = LATIN1;
+                    return this;
+                }
+            }
+            coder = UTF16;
+            value = StringUTF16.toBytes(val, off, len);
+            return this;
+        }
+
+        Result with(byte[] val, byte coder) {
+            this.coder = coder;
+            value = val;
+            return this;
+        }
+    }
+
+    @HotSpotIntrinsicCandidate
+    private static boolean hasNegatives(byte[] ba, int off, int len) {
+        for (int i = off; i < off + len; i++) {
+            if (ba[i] < 0) {
+                return true;
+            }
+        }
+        return false;
+    }
 
     // -- Decoding --
-    private static class StringDecoder {
+    static class StringDecoder {
         private final String requestedCharsetName;
         private final Charset cs;
+        private final boolean isASCIICompatible;
         private final CharsetDecoder cd;
-        private final boolean isTrusted;
+        protected final Result result;
 
-        private StringDecoder(Charset cs, String rcn) {
+        StringDecoder(Charset cs, String rcn) {
             this.requestedCharsetName = rcn;
             this.cs = cs;
             this.cd = cs.newDecoder()
                 .onMalformedInput(CodingErrorAction.REPLACE)
                 .onUnmappableCharacter(CodingErrorAction.REPLACE);
-            this.isTrusted = (cs.getClass().getClassLoader0() == null);
+            this.result = new Result();
+            this.isASCIICompatible = (cd instanceof ArrayDecoder) &&
+                    ((ArrayDecoder)cd).isASCIICompatible();
         }
 
         String charsetName() {
@@ -144,36 +185,58 @@
             return requestedCharsetName;
         }
 
-        char[] decode(byte[] ba, int off, int len) {
+        Result decode(byte[] ba, int off, int len) {
+            if (len == 0) {
+                return result.with();
+            }
+            // fastpath for ascii compatible
+            if (isASCIICompatible && !hasNegatives(ba, off, len)) {
+                if (COMPACT_STRINGS) {
+                    return result.with(Arrays.copyOfRange(ba, off, off + len),
+                                      LATIN1);
+                } else {
+                    return result.with(StringLatin1.inflate(ba, off, len), UTF16);
+                }
+            }
             int en = scale(len, cd.maxCharsPerByte());
             char[] ca = new char[en];
-            if (len == 0)
-                return ca;
             if (cd instanceof ArrayDecoder) {
                 int clen = ((ArrayDecoder)cd).decode(ba, off, len, ca);
-                return safeTrim(ca, clen, cs, isTrusted);
+                return result.with(ca, 0, clen);
+            }
+            cd.reset();
+            ByteBuffer bb = ByteBuffer.wrap(ba, off, len);
+            CharBuffer cb = CharBuffer.wrap(ca);
+            try {
+                CoderResult cr = cd.decode(bb, cb, true);
+                if (!cr.isUnderflow())
+                    cr.throwException();
+                cr = cd.flush(cb);
+                if (!cr.isUnderflow())
+                    cr.throwException();
+            } catch (CharacterCodingException x) {
+                // Substitution is always enabled,
+                // so this shouldn't happen
+                throw new Error(x);
+            }
+            return result.with(ca, 0, cb.position());
+        }
+    }
+
+    private static class StringDecoder8859_1 extends StringDecoder {
+        StringDecoder8859_1(Charset cs, String rcn) {
+            super(cs, rcn);
+        }
+        Result decode(byte[] ba, int off, int len) {
+            if (COMPACT_STRINGS) {
+                return result.with(Arrays.copyOfRange(ba, off, off + len), LATIN1);
             } else {
-                cd.reset();
-                ByteBuffer bb = ByteBuffer.wrap(ba, off, len);
-                CharBuffer cb = CharBuffer.wrap(ca);
-                try {
-                    CoderResult cr = cd.decode(bb, cb, true);
-                    if (!cr.isUnderflow())
-                        cr.throwException();
-                    cr = cd.flush(cb);
-                    if (!cr.isUnderflow())
-                        cr.throwException();
-                } catch (CharacterCodingException x) {
-                    // Substitution is always enabled,
-                    // so this shouldn't happen
-                    throw new Error(x);
-                }
-                return safeTrim(ca, cb.position(), cs, isTrusted);
+                return result.with(StringLatin1.inflate(ba, off, len), UTF16);
             }
         }
     }
 
-    static char[] decode(String charsetName, byte[] ba, int off, int len)
+    static Result decode(String charsetName, byte[] ba, int off, int len)
         throws UnsupportedEncodingException
     {
         StringDecoder sd = deref(decoder);
@@ -183,8 +246,15 @@
             sd = null;
             try {
                 Charset cs = lookupCharset(csn);
-                if (cs != null)
-                    sd = new StringDecoder(cs, csn);
+                if (cs != null) {
+                    if (cs == UTF_8) {
+                        sd = new StringDecoderUTF8(cs, csn);
+                    } else if (cs == ISO_8859_1) {
+                        sd = new StringDecoder8859_1(cs, csn);
+                    } else {
+                        sd = new StringDecoder(cs, csn);
+                    }
+                }
             } catch (IllegalCharsetNameException x) {}
             if (sd == null)
                 throw new UnsupportedEncodingException(csn);
@@ -193,7 +263,7 @@
         return sd.decode(ba, off, len);
     }
 
-    static char[] decode(Charset cs, byte[] ba, int off, int len) {
+    static Result decode(Charset cs, byte[] ba, int off, int len) {
         // (1)We never cache the "external" cs, the only benefit of creating
         // an additional StringDe/Encoder object to wrap it is to share the
         // de/encode() method. These SD/E objects are short-lived, the young-gen
@@ -210,44 +280,57 @@
         // check (... && (isTrusted || SM == null || getClassLoader0())) in trim
         // but it then can be argued that the SM is null when the operation
         // is started...
+        if (cs == UTF_8) {
+            return StringDecoderUTF8.decode(ba, off, len, new Result());
+        }
         CharsetDecoder cd = cs.newDecoder();
+        // ascii fastpath
+        if (cs == ISO_8859_1 || ((cd instanceof ArrayDecoder) &&
+                                 ((ArrayDecoder)cd).isASCIICompatible() &&
+                                 !hasNegatives(ba, off, len))) {
+             if (COMPACT_STRINGS) {
+                 return new Result().with(Arrays.copyOfRange(ba, off, off + len),
+                                          LATIN1);
+             } else {
+                 return new Result().with(StringLatin1.inflate(ba, off, len), UTF16);
+             }
+        }
         int en = scale(len, cd.maxCharsPerByte());
-        char[] ca = new char[en];
-        if (len == 0)
-            return ca;
-        boolean isTrusted = false;
-        if (System.getSecurityManager() != null) {
-            if (!(isTrusted = (cs.getClass().getClassLoader0() == null))) {
-                ba =  Arrays.copyOfRange(ba, off, off + len);
-                off = 0;
-            }
+        if (len == 0) {
+            return new Result().with();
+        }
+        if (System.getSecurityManager() != null &&
+            cs.getClass().getClassLoader0() != null) {
+            ba =  Arrays.copyOfRange(ba, off, off + len);
+            off = 0;
         }
         cd.onMalformedInput(CodingErrorAction.REPLACE)
           .onUnmappableCharacter(CodingErrorAction.REPLACE)
           .reset();
+
+        char[] ca = new char[en];
         if (cd instanceof ArrayDecoder) {
             int clen = ((ArrayDecoder)cd).decode(ba, off, len, ca);
-            return safeTrim(ca, clen, cs, isTrusted);
-        } else {
-            ByteBuffer bb = ByteBuffer.wrap(ba, off, len);
-            CharBuffer cb = CharBuffer.wrap(ca);
-            try {
-                CoderResult cr = cd.decode(bb, cb, true);
-                if (!cr.isUnderflow())
-                    cr.throwException();
-                cr = cd.flush(cb);
-                if (!cr.isUnderflow())
-                    cr.throwException();
-            } catch (CharacterCodingException x) {
-                // Substitution is always enabled,
-                // so this shouldn't happen
-                throw new Error(x);
-            }
-            return safeTrim(ca, cb.position(), cs, isTrusted);
+            return new Result().with(ca, 0, clen);
         }
+        ByteBuffer bb = ByteBuffer.wrap(ba, off, len);
+        CharBuffer cb = CharBuffer.wrap(ca);
+        try {
+            CoderResult cr = cd.decode(bb, cb, true);
+            if (!cr.isUnderflow())
+                cr.throwException();
+            cr = cd.flush(cb);
+            if (!cr.isUnderflow())
+                cr.throwException();
+        } catch (CharacterCodingException x) {
+            // Substitution is always enabled,
+            // so this shouldn't happen
+            throw new Error(x);
+        }
+        return new Result().with(ca, 0, cb.position());
     }
 
-    static char[] decode(byte[] ba, int off, int len) {
+    static Result decode(byte[] ba, int off, int len) {
         String csn = Charset.defaultCharset().name();
         try {
             // use charset name decode() variant which provides caching.
@@ -273,6 +356,7 @@
     private static class StringEncoder {
         private Charset cs;
         private CharsetEncoder ce;
+        private final boolean isASCIICompatible;
         private final String requestedCharsetName;
         private final boolean isTrusted;
 
@@ -283,6 +367,8 @@
                 .onMalformedInput(CodingErrorAction.REPLACE)
                 .onUnmappableCharacter(CodingErrorAction.REPLACE);
             this.isTrusted = (cs.getClass().getClassLoader0() == null);
+            this.isASCIICompatible = (ce instanceof ArrayEncoder) &&
+                    ((ArrayEncoder)ce).isASCIICompatible();
         }
 
         String charsetName() {
@@ -295,36 +381,186 @@
             return requestedCharsetName;
         }
 
-        byte[] encode(char[] ca, int off, int len) {
+        byte[] encode(byte coder, byte[] val) {
+            // fastpath for ascii compatible
+            if (coder == LATIN1 && isASCIICompatible &&
+                !hasNegatives(val, 0, val.length)) {
+                return Arrays.copyOf(val, val.length);
+            }
+            int len = val.length >> coder;  // assume LATIN1=0/UTF16=1;
             int en = scale(len, ce.maxBytesPerChar());
             byte[] ba = new byte[en];
-            if (len == 0)
+            if (len == 0) {
                 return ba;
+            }
             if (ce instanceof ArrayEncoder) {
-                int blen = ((ArrayEncoder)ce).encode(ca, off, len, ba);
-                return safeTrim(ba, blen, cs, isTrusted);
-            } else {
-                ce.reset();
-                ByteBuffer bb = ByteBuffer.wrap(ba);
-                CharBuffer cb = CharBuffer.wrap(ca, off, len);
-                try {
-                    CoderResult cr = ce.encode(cb, bb, true);
-                    if (!cr.isUnderflow())
-                        cr.throwException();
-                    cr = ce.flush(bb);
-                    if (!cr.isUnderflow())
-                        cr.throwException();
-                } catch (CharacterCodingException x) {
-                    // Substitution is always enabled,
-                    // so this shouldn't happen
-                    throw new Error(x);
+                if (!isTrusted) {
+                    val = Arrays.copyOf(val, val.length);
+                }
+                int blen = (coder == LATIN1 ) ? ((ArrayEncoder)ce).encodeFromLatin1(val, 0, len, ba)
+                                              : ((ArrayEncoder)ce).encodeFromUTF16(val, 0, len, ba);
+                if (blen != -1) {
+                    return safeTrim(ba, blen, isTrusted);
                 }
-                return safeTrim(ba, bb.position(), cs, isTrusted);
             }
+            char[] ca = (coder == LATIN1 ) ? StringLatin1.toChars(val)
+                                           : StringUTF16.toChars(val);
+            ce.reset();
+            ByteBuffer bb = ByteBuffer.wrap(ba);
+            CharBuffer cb = CharBuffer.wrap(ca, 0, len);
+            try {
+                CoderResult cr = ce.encode(cb, bb, true);
+                if (!cr.isUnderflow())
+                    cr.throwException();
+                cr = ce.flush(bb);
+                if (!cr.isUnderflow())
+                    cr.throwException();
+            } catch (CharacterCodingException x) {
+                // Substitution is always enabled,
+                // so this shouldn't happen
+                throw new Error(x);
+            }
+            return safeTrim(ba, bb.position(), isTrusted);
         }
     }
 
-    static byte[] encode(String charsetName, char[] ca, int off, int len)
+    @HotSpotIntrinsicCandidate
+    private static int implEncodeISOArray(byte[] sa, int sp,
+                                          byte[] da, int dp, int len) {
+        int i = 0;
+        for (; i < len; i++) {
+            char c = StringUTF16.getChar(sa, sp++);
+            if (c > '\u00FF')
+                break;
+            da[dp++] = (byte)c;
+        }
+        return i;
+    }
+
+    static byte[] encode8859_1(byte coder, byte[] val) {
+        if (coder == LATIN1) {
+            return Arrays.copyOf(val, val.length);
+        }
+        int len = val.length >> 1;
+        byte[] dst = new byte[len];
+        int dp = 0;
+        int sp = 0;
+        int sl = len;
+        while (sp < sl) {
+            int ret = implEncodeISOArray(val, sp, dst, dp, len);
+            sp = sp + ret;
+            dp = dp + ret;
+            if (ret != len) {
+                char c = StringUTF16.getChar(val, sp++);
+                if (Character.isHighSurrogate(c) && sp < sl &&
+                    Character.isLowSurrogate(StringUTF16.getChar(val, sp))) {
+                    sp++;
+                }
+                dst[dp++] = '?';
+                len = sl - sp;
+            }
+        }
+        if (dp == dst.length) {
+            return dst;
+        }
+        return Arrays.copyOf(dst, dp);
+    }
+
+    static byte[] encodeASCII(byte coder, byte[] val) {
+        if (coder == LATIN1) {
+            byte[] dst = new byte[val.length];
+            for (int i = 0; i < val.length; i++) {
+                if (val[i] < 0) {
+                    dst[i] = '?';
+                } else {
+                    dst[i] = val[i];
+                }
+            }
+            return dst;
+        }
+        int len = val.length >> 1;
+        byte[] dst = new byte[len];
+        int dp = 0;
+        for (int i = 0; i < len; i++) {
+            char c = StringUTF16.getChar(val, i);
+            if (c < 0x80) {
+                dst[dp++] = (byte)c;
+                continue;
+            }
+            if (Character.isHighSurrogate(c) && i + 1 < len &&
+                Character.isLowSurrogate(StringUTF16.getChar(val, i + 1))) {
+                i++;
+            }
+            dst[dp++] = '?';
+        }
+        if (len == dp) {
+            return dst;
+        }
+        return Arrays.copyOf(dst, dp);
+    }
+
+   static byte[] encodeUTF8(byte coder, byte[] val) {
+        int dp = 0;
+        byte[] dst;
+        if (coder == LATIN1) {
+            dst = new byte[val.length << 1];
+            for (int sp = 0; sp < val.length; sp++) {
+                byte c = val[sp];
+                if (c < 0) {
+                    dst[dp++] = (byte)(0xc0 | ((c & 0xff) >> 6));
+                    dst[dp++] = (byte)(0x80 | (c & 0x3f));
+                } else {
+                    dst[dp++] = c;
+                }
+            }
+        } else {
+            int sp = 0;
+            int sl = val.length >> 1;
+            dst = new byte[sl * 3];
+            char c;
+            while (sp < sl && (c = StringUTF16.getChar(val, sp)) < '\u0080') {
+                // ascii fast loop;
+                dst[dp++] = (byte)c;
+                sp++;
+            }
+            while (sp < sl) {
+                c = StringUTF16.getChar(val, sp++);
+                if (c < 0x80) {
+                    dst[dp++] = (byte)c;
+                } else if (c < 0x800) {
+                    dst[dp++] = (byte)(0xc0 | (c >> 6));
+                    dst[dp++] = (byte)(0x80 | (c & 0x3f));
+                } else if (Character.isSurrogate(c)) {
+                    int uc = -1;
+                    char c2;
+                    if (Character.isHighSurrogate(c) && sp < sl &&
+                        Character.isLowSurrogate(c2 = StringUTF16.getChar(val, sp))) {
+                        uc = Character.toCodePoint(c, c2);
+                    }
+                    if (uc < 0) {
+                        dst[dp++] = '?';
+                    } else {
+                        dst[dp++] = (byte)(0xf0 | ((uc >> 18)));
+                        dst[dp++] = (byte)(0x80 | ((uc >> 12) & 0x3f));
+                        dst[dp++] = (byte)(0x80 | ((uc >>  6) & 0x3f));
+                        dst[dp++] = (byte)(0x80 | (uc & 0x3f));
+                        sp++;  // 2 chars
+                    }
+                } else {
+                    // 3 bytes, 16 bits
+                    dst[dp++] = (byte)(0xe0 | ((c >> 12)));
+                    dst[dp++] = (byte)(0x80 | ((c >>  6) & 0x3f));
+                    dst[dp++] = (byte)(0x80 | (c & 0x3f));
+                }
+            }
+        }
+        if (dp == dst.length) {
+            return dst;
+        }
+        return Arrays.copyOf(dst, dp);
+    }
+
+    static byte[] encode(String charsetName, byte coder, byte[] val)
         throws UnsupportedEncodingException
     {
         StringEncoder se = deref(encoder);
@@ -334,62 +570,88 @@
             se = null;
             try {
                 Charset cs = lookupCharset(csn);
-                if (cs != null)
+                if (cs != null) {
+                    if (cs == UTF_8) {
+                        return encodeUTF8(coder, val);
+                    } else if (cs == ISO_8859_1) {
+                        return encode8859_1(coder, val);
+                    } else if (cs == US_ASCII) {
+                        return encodeASCII(coder, val);
+                    }
                     se = new StringEncoder(cs, csn);
+                }
             } catch (IllegalCharsetNameException x) {}
-            if (se == null)
+            if (se == null) {
                 throw new UnsupportedEncodingException (csn);
+            }
             set(encoder, se);
         }
-        return se.encode(ca, off, len);
+        return se.encode(coder, val);
     }
 
-    static byte[] encode(Charset cs, char[] ca, int off, int len) {
+    static byte[] encode(Charset cs, byte coder, byte[] val) {
+        if (cs == UTF_8) {
+            return encodeUTF8(coder, val);
+        } else if (cs == ISO_8859_1) {
+            return encode8859_1(coder, val);
+        } else if (cs == US_ASCII) {
+            return encodeASCII(coder, val);
+        }
         CharsetEncoder ce = cs.newEncoder();
+        // fastpath for ascii compatible
+        if (coder == LATIN1 && (((ce instanceof ArrayEncoder) &&
+                                 ((ArrayEncoder)ce).isASCIICompatible() &&
+                                 !hasNegatives(val, 0, val.length)))) {
+            return Arrays.copyOf(val, val.length);
+        }
+        int len = val.length >> coder;  // assume LATIN1=0/UTF16=1;
         int en = scale(len, ce.maxBytesPerChar());
         byte[] ba = new byte[en];
-        if (len == 0)
+        if (len == 0) {
             return ba;
-        boolean isTrusted = false;
-        if (System.getSecurityManager() != null) {
-            if (!(isTrusted = (cs.getClass().getClassLoader0() == null))) {
-                ca =  Arrays.copyOfRange(ca, off, off + len);
-                off = 0;
-            }
         }
+        boolean isTrusted = System.getSecurityManager() == null ||
+                            cs.getClass().getClassLoader0() == null;
         ce.onMalformedInput(CodingErrorAction.REPLACE)
           .onUnmappableCharacter(CodingErrorAction.REPLACE)
           .reset();
         if (ce instanceof ArrayEncoder) {
-            int blen = ((ArrayEncoder)ce).encode(ca, off, len, ba);
-            return safeTrim(ba, blen, cs, isTrusted);
-        } else {
-            ByteBuffer bb = ByteBuffer.wrap(ba);
-            CharBuffer cb = CharBuffer.wrap(ca, off, len);
-            try {
-                CoderResult cr = ce.encode(cb, bb, true);
-                if (!cr.isUnderflow())
-                    cr.throwException();
-                cr = ce.flush(bb);
-                if (!cr.isUnderflow())
-                    cr.throwException();
-            } catch (CharacterCodingException x) {
-                throw new Error(x);
+            if (!isTrusted) {
+                val = Arrays.copyOf(val, val.length);
+            }
+            int blen = (coder == LATIN1 ) ? ((ArrayEncoder)ce).encodeFromLatin1(val, 0, len, ba)
+                                          : ((ArrayEncoder)ce).encodeFromUTF16(val, 0, len, ba);
+            if (blen != -1) {
+                return safeTrim(ba, blen, isTrusted);
             }
-            return safeTrim(ba, bb.position(), cs, isTrusted);
         }
+        char[] ca = (coder == LATIN1 ) ? StringLatin1.toChars(val)
+                                       : StringUTF16.toChars(val);
+        ByteBuffer bb = ByteBuffer.wrap(ba);
+        CharBuffer cb = CharBuffer.wrap(ca, 0, len);
+        try {
+            CoderResult cr = ce.encode(cb, bb, true);
+            if (!cr.isUnderflow())
+                cr.throwException();
+            cr = ce.flush(bb);
+            if (!cr.isUnderflow())
+                cr.throwException();
+        } catch (CharacterCodingException x) {
+            throw new Error(x);
+        }
+        return safeTrim(ba, bb.position(), isTrusted);
     }
 
-    static byte[] encode(char[] ca, int off, int len) {
+    static byte[] encode(byte coder, byte[] val) {
         String csn = Charset.defaultCharset().name();
         try {
             // use charset name encode() variant which provides caching.
-            return encode(csn, ca, off, len);
+            return encode(csn, coder, val);
         } catch (UnsupportedEncodingException x) {
             warnUnsupportedCharset(csn);
         }
         try {
-            return encode("ISO-8859-1", ca, off, len);
+            return encode("ISO-8859-1", coder, val);
         } catch (UnsupportedEncodingException x) {
             // If this code is hit during VM initialization, MessageUtils is
             // the only way we will be able to get any kind of error message.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/StringDecoderUTF8.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,235 @@
+/*
+ * 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.
+ */
+
+package java.lang;
+
+import java.nio.charset.Charset;
+import java.util.Arrays;
+
+import static java.lang.String.LATIN1;
+import static java.lang.String.UTF16;
+import static java.lang.String.COMPACT_STRINGS;
+import static java.lang.Character.isSurrogate;
+import static java.lang.Character.highSurrogate;
+import static java.lang.Character.lowSurrogate;
+import static java.lang.Character.isSupplementaryCodePoint;
+import static java.lang.StringUTF16.putChar;
+
+class StringDecoderUTF8 extends StringCoding.StringDecoder {
+
+    StringDecoderUTF8(Charset cs, String rcn) {
+        super(cs, rcn);
+    }
+
+    private static boolean isNotContinuation(int b) {
+        return (b & 0xc0) != 0x80;
+    }
+
+    private static boolean isMalformed3(int b1, int b2, int b3) {
+        return (b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) ||
+               (b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80;
+    }
+
+    private static boolean isMalformed3_2(int b1, int b2) {
+        return (b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) ||
+               (b2 & 0xc0) != 0x80;
+    }
+
+    private static boolean isMalformed4(int b2, int b3, int b4) {
+        return (b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80 ||
+               (b4 & 0xc0) != 0x80;
+    }
+
+    private static boolean isMalformed4_2(int b1, int b2) {
+        return (b1 == 0xf0 && (b2  < 0x90 || b2 > 0xbf)) ||
+               (b1 == 0xf4 && (b2 & 0xf0) != 0x80) ||
+               (b2 & 0xc0) != 0x80;
+    }
+
+    private static boolean isMalformed4_3(int b3) {
+        return (b3 & 0xc0) != 0x80;
+    }
+
+    // for nb == 3/4
+    private static int malformedN(byte[] src, int sp, int nb) {
+        if (nb == 3) {
+            int b1 = src[sp++];
+            int b2 = src[sp++];    // no need to lookup b3
+            return ((b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) ||
+                    isNotContinuation(b2)) ? 1 : 2;
+        } else if (nb == 4) { // we don't care the speed here
+            int b1 = src[sp++] & 0xff;
+            int b2 = src[sp++] & 0xff;
+            if (b1 > 0xf4 ||
+                (b1 == 0xf0 && (b2 < 0x90 || b2 > 0xbf)) ||
+                (b1 == 0xf4 && (b2 & 0xf0) != 0x80) ||
+                isNotContinuation(b2))
+                return 1;
+            if (isNotContinuation(src[sp++]))
+                return 2;
+            return 3;
+        }
+        assert false;
+        return -1;
+    }
+
+    private static char repl = '\ufffd';
+
+    StringCoding.Result decode(byte[] src, int sp, int len) {
+        return decode(src, sp, len, result);
+    }
+
+    static StringCoding.Result decode(byte[] src, int sp, int len,
+                                      StringCoding.Result ret) {
+        int sl = sp + len;
+        byte[] dst = new byte[len];
+        int dp = 0;
+        if (COMPACT_STRINGS) {   // Latin1 only loop
+            while (sp < sl) {
+                int b1 = src[sp];
+                if (b1 >= 0) {
+                    dst[dp++] = (byte)b1;
+                    sp++;
+                    continue;
+                }
+                if ((b1 == (byte)0xc2 || b1 == (byte)0xc3) &&
+                    sp + 1 < sl) {
+                    int b2 = src[sp + 1];
+                    if (!isNotContinuation(b2)) {
+                        dst[dp++] = (byte)(((b1 << 6) ^ b2)^
+                                           (((byte) 0xC0 << 6) ^
+                                           ((byte) 0x80 << 0)));
+                        sp += 2;
+                        continue;
+                    }
+                }
+                // anything not a latin1, including the repl
+                // we have to go with the utf16
+                break;
+            }
+            if (sp == sl) {
+                if (dp != dst.length) {
+                    dst = Arrays.copyOf(dst, dp);
+                }
+                return ret.with(dst, LATIN1);
+            }
+        }
+        if (dp == 0) {
+            dst = new byte[len << 1];
+        } else {
+            byte[] buf = new byte[len << 1];
+            StringLatin1.inflate(dst, 0, buf, 0, dp);
+            dst = buf;
+        }
+        while (sp < sl) {
+            int b1 = src[sp++];
+            if (b1 >= 0) {
+                putChar(dst, dp++, (char) b1);
+            } else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) {
+                if (sp < sl) {
+                    int b2 = src[sp++];
+                    if (isNotContinuation(b2)) {
+                        putChar(dst, dp++, repl);
+                        sp--;
+                    } else {
+                        putChar(dst, dp++, (char)(((b1 << 6) ^ b2)^
+                                                  (((byte) 0xC0 << 6) ^
+                                                  ((byte) 0x80 << 0))));
+                    }
+                    continue;
+                }
+                putChar(dst, dp++, repl);
+                break;
+            } else if ((b1 >> 4) == -2) {
+                if (sp + 1 < sl) {
+                    int b2 = src[sp++];
+                    int b3 = src[sp++];
+                    if (isMalformed3(b1, b2, b3)) {
+                        putChar(dst, dp++, repl);
+                        sp -= 3;
+                        sp += malformedN(src, sp, 3);
+                    } else {
+                        char c = (char)((b1 << 12) ^
+                                        (b2 <<  6) ^
+                                        (b3 ^
+                                         (((byte) 0xE0 << 12) ^
+                                         ((byte) 0x80 <<  6) ^
+                                         ((byte) 0x80 <<  0))));
+                        putChar(dst, dp++, isSurrogate(c) ?  repl : c);
+                    }
+                    continue;
+                }
+                if (sp  < sl && isMalformed3_2(b1, src[sp])) {
+                    putChar(dst, dp++, repl);
+                    continue;
+                }
+                putChar(dst, dp++, repl);
+                break;
+            } else if ((b1 >> 3) == -2) {
+                if (sp + 2 < sl) {
+                    int b2 = src[sp++];
+                    int b3 = src[sp++];
+                    int b4 = src[sp++];
+                    int uc = ((b1 << 18) ^
+                              (b2 << 12) ^
+                              (b3 <<  6) ^
+                              (b4 ^
+                               (((byte) 0xF0 << 18) ^
+                               ((byte) 0x80 << 12) ^
+                               ((byte) 0x80 <<  6) ^
+                               ((byte) 0x80 <<  0))));
+                    if (isMalformed4(b2, b3, b4) ||
+                        !isSupplementaryCodePoint(uc)) { // shortest form check
+                        putChar(dst, dp++, repl);
+                        sp -= 4;
+                        sp += malformedN(src, sp, 4);
+                    } else {
+                        putChar(dst, dp++, highSurrogate(uc));
+                        putChar(dst, dp++, lowSurrogate(uc));
+                    }
+                    continue;
+                }
+                b1 &= 0xff;
+                if (b1 > 0xf4 ||
+                    sp  < sl && isMalformed4_2(b1, src[sp] & 0xff)) {
+                    putChar(dst, dp++, repl);
+                    continue;
+                }
+                sp++;
+                putChar(dst, dp++, repl);
+                if (sp  < sl && isMalformed4_3(src[sp])) {
+                    continue;
+                }
+                break;
+            } else {
+                putChar(dst, dp++, repl);
+            }
+        }
+        if (dp != len) {
+            dst = Arrays.copyOf(dst, dp << 1);
+        }
+        return ret.with(dst, UTF16);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/StringLatin1.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,600 @@
+/*
+ * 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.
+ */
+
+package java.lang;
+
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.Spliterator;
+import java.util.function.IntConsumer;
+import java.util.stream.IntStream;
+import jdk.internal.HotSpotIntrinsicCandidate;
+
+import static java.lang.String.LATIN1;
+import static java.lang.String.UTF16;
+import static java.lang.String.checkOffset;
+
+final class StringLatin1 {
+
+    public static char charAt(byte[] value, int index) {
+        if (index < 0 || index >= value.length) {
+            throw new StringIndexOutOfBoundsException(index);
+        }
+        return (char)(value[index] & 0xff);
+    }
+
+    public static boolean canEncode(int cp) {
+        return cp >>> 8 == 0;
+    }
+
+    public static int length(byte[] value) {
+        return value.length;
+    }
+
+    public static int codePointAt(byte[] value, int index, int end) {
+        return value[index] & 0xff;
+    }
+
+    public static int codePointBefore(byte[] value, int index) {
+        return value[index - 1] & 0xff;
+    }
+
+    public static int codePointCount(byte[] value, int beginIndex, int endIndex) {
+        return endIndex - beginIndex;
+    }
+
+    public static char[] toChars(byte[] value) {
+        char[] dst = new char[value.length];
+        inflate(value, 0, dst, 0, value.length);
+        return dst;
+    }
+
+    public static byte[] inflate(byte[] value, int off, int len) {
+        byte[] ret = StringUTF16.newBytesFor(len);
+        inflate(value, off, ret, 0, len);
+        return ret;
+    }
+
+    public static void getChars(byte[] value, int srcBegin, int srcEnd, char dst[], int dstBegin) {
+        inflate(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
+    }
+
+    public static void getBytes(byte[] value, int srcBegin, int srcEnd, byte dst[], int dstBegin) {
+        System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
+    }
+
+    @HotSpotIntrinsicCandidate
+    public static boolean equals(byte[] value, byte[] other) {
+        if (value.length == other.length) {
+            for (int i = 0; i < value.length; i++) {
+                if (value[i] != other[i]) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @HotSpotIntrinsicCandidate
+    public static int compareTo(byte[] value, byte[] other) {
+        int len1 = value.length;
+        int len2 = other.length;
+        int lim = Math.min(len1, len2);
+        for (int k = 0; k < lim; k++) {
+            if (value[k] != other[k]) {
+                return getChar(value, k) - getChar(other, k);
+            }
+        }
+        return len1 - len2;
+    }
+
+    @HotSpotIntrinsicCandidate
+    public static int compareToUTF16(byte[] value, byte[] other) {
+        int len1 = length(value);
+        int len2 = StringUTF16.length(other);
+        int lim = Math.min(len1, len2);
+        for (int k = 0; k < lim; k++) {
+            char c1 = getChar(value, k);
+            char c2 = StringUTF16.getChar(other, k);
+            if (c1 != c2) {
+                return c1 - c2;
+            }
+        }
+        return len1 - len2;
+    }
+
+    public static int hashCode(byte[] value) {
+        int h = 0;
+        for (byte v : value) {
+            h = 31 * h + (v & 0xff);
+        }
+        return h;
+    }
+
+    public static int indexOf(byte[] value, int ch, int fromIndex) {
+        if (!canEncode(ch)) {
+            return -1;
+        }
+        int max = value.length;
+        if (fromIndex < 0) {
+            fromIndex = 0;
+        } else if (fromIndex >= max) {
+            // Note: fromIndex might be near -1>>>1.
+            return -1;
+        }
+        byte c = (byte)ch;
+        for (int i = fromIndex; i < max; i++) {
+            if (value[i] == c) {
+               return i;
+            }
+        }
+        return -1;
+    }
+
+    @HotSpotIntrinsicCandidate
+    public static int indexOf(byte[] value, byte[] str) {
+        if (str.length == 0) {
+            return 0;
+        }
+        if (value.length == 0) {
+            return -1;
+        }
+        return indexOf(value, value.length, str, str.length, 0);
+    }
+
+    @HotSpotIntrinsicCandidate
+    public static int indexOf(byte[] value, int valueCount, byte[] str, int strCount, int fromIndex) {
+        byte first = str[0];
+        int max = (valueCount - strCount);
+        for (int i = fromIndex; i <= max; i++) {
+            // Look for first character.
+            if (value[i] != first) {
+                while (++i <= max && value[i] != first);
+            }
+            // Found first character, now look at the rest of value
+            if (i <= max) {
+                int j = i + 1;
+                int end = j + strCount - 1;
+                for (int k = 1; j < end && value[j] == str[k]; j++, k++);
+                if (j == end) {
+                    // Found whole string.
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+
+    public static int lastIndexOf(byte[] src, int srcCount,
+                                  byte[] tgt, int tgtCount, int fromIndex) {
+        int min = tgtCount - 1;
+        int i = min + fromIndex;
+        int strLastIndex = tgtCount - 1;
+        char strLastChar = (char)(tgt[strLastIndex] & 0xff);
+
+  startSearchForLastChar:
+        while (true) {
+            while (i >= min && (src[i] & 0xff) != strLastChar) {
+                i--;
+            }
+            if (i < min) {
+                return -1;
+            }
+            int j = i - 1;
+            int start = j - strLastIndex;
+            int k = strLastIndex - 1;
+            while (j > start) {
+                if ((src[j--] & 0xff) != (tgt[k--] & 0xff)) {
+                    i--;
+                    continue startSearchForLastChar;
+                }
+            }
+            return start + 1;
+        }
+    }
+
+    public static int lastIndexOf(final byte[] value, int ch, int fromIndex) {
+        if (!canEncode(ch)) {
+            return -1;
+        }
+        int off  = Math.min(fromIndex, value.length - 1);
+        for (; off >= 0; off--) {
+            if (value[off] == (byte)ch) {
+                return off;
+            }
+        }
+        return -1;
+    }
+
+    public static String replace(byte[] value, char oldChar, char newChar) {
+        if (canEncode(oldChar)) {
+            int len = value.length;
+            int i = -1;
+            while (++i < len) {
+                if (value[i] == (byte)oldChar) {
+                    break;
+                }
+            }
+            if (i < len) {
+                if (canEncode(newChar)) {
+                    byte buf[] = new byte[len];
+                    for (int j = 0; j < i; j++) {    // TBD arraycopy?
+                        buf[j] = value[j];
+                    }
+                    while (i < len) {
+                        byte c = value[i];
+                        buf[i] = (c == (byte)oldChar) ? (byte)newChar : c;
+                        i++;
+                    }
+                    return new String(buf, LATIN1);
+                } else {
+                    byte[] buf = StringUTF16.newBytesFor(len);
+                    // inflate from latin1 to UTF16
+                    inflate(value, 0, buf, 0, i);
+                    while (i < len) {
+                        char c = (char)(value[i] & 0xff);
+                        StringUTF16.putChar(buf, i, (c == oldChar) ? newChar : c);
+                        i++;
+                    }
+                    return new String(buf, UTF16);
+                }
+            }
+        }
+        return null; // for string to return this;
+    }
+
+    // case insensitive
+    public static boolean regionMatchesCI(byte[] value, int toffset,
+                                          byte[] other, int ooffset, int len) {
+        int last = toffset + len;
+        while (toffset < last) {
+            char c1 = (char)(value[toffset++] & 0xff);
+            char c2 = (char)(other[ooffset++] & 0xff);
+            if (c1 == c2) {
+                continue;
+            }
+            char u1 = Character.toUpperCase(c1);
+            char u2 = Character.toUpperCase(c2);
+            if (u1 == u2) {
+                continue;
+            }
+            if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
+                continue;
+            }
+            return false;
+        }
+        return true;
+    }
+
+    public static boolean regionMatchesCI_UTF16(byte[] value, int toffset,
+                                                byte[] other, int ooffset, int len) {
+        int last = toffset + len;
+        while (toffset < last) {
+            char c1 = (char)(value[toffset++] & 0xff);
+            char c2 = StringUTF16.getChar(other, ooffset++);
+            if (c1 == c2) {
+                continue;
+            }
+            char u1 = Character.toUpperCase(c1);
+            char u2 = Character.toUpperCase(c2);
+            if (u1 == u2) {
+                continue;
+            }
+            if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
+                continue;
+            }
+            return false;
+        }
+        return true;
+    }
+
+    public static String toLowerCase(String str, byte[] value, Locale locale) {
+        if (locale == null) {
+            throw new NullPointerException();
+        }
+        int first;
+        final int len = value.length;
+        // Now check if there are any characters that need to be changed, or are surrogate
+        for (first = 0 ; first < len; first++) {
+            int cp = value[first] & 0xff;
+            if (cp != Character.toLowerCase(cp)) {  // no need to check Character.ERROR
+                break;
+            }
+        }
+        if (first == len)
+            return str;
+        String lang = locale.getLanguage();
+        if (lang == "tr" || lang == "az" || lang == "lt") {
+            return toLowerCaseEx(str, value, first, locale, true);
+        }
+        byte[] result = new byte[len];
+        System.arraycopy(value, 0, result, 0, first);  // Just copy the first few
+                                                       // lowerCase characters.
+        for (int i = first; i < len; i++) {
+            int cp = value[i] & 0xff;
+            cp = Character.toLowerCase(cp);
+            if (!canEncode(cp)) {                      // not a latin1 character
+                return toLowerCaseEx(str, value, first, locale, false);
+            }
+            result[i] = (byte)cp;
+        }
+        return new String(result, LATIN1);
+    }
+
+    private static String toLowerCaseEx(String str, byte[] value,
+                                        int first, Locale locale, boolean localeDependent)
+    {
+        byte[] result = StringUTF16.newBytesFor(value.length);
+        int resultOffset = 0;
+        for (int i = 0; i < first; i++) {
+            StringUTF16.putChar(result, resultOffset++, value[i] & 0xff);
+        }
+        for (int i = first; i < value.length; i++) {
+            int srcChar = value[i] & 0xff;
+            int lowerChar;
+            char[] lowerCharArray;
+            if (localeDependent) {
+                lowerChar = ConditionalSpecialCasing.toLowerCaseEx(str, i, locale);
+            } else {
+                lowerChar = Character.toLowerCase(srcChar);
+            }
+            if (Character.isBmpCodePoint(lowerChar)) {    // Character.ERROR is not a bmp
+                StringUTF16.putChar(result, resultOffset++, lowerChar);
+            } else {
+                if (lowerChar == Character.ERROR) {
+                    lowerCharArray = ConditionalSpecialCasing.toLowerCaseCharArray(str, i, locale);
+                } else {
+                    lowerCharArray = Character.toChars(lowerChar);
+                }
+                /* Grow result if needed */
+                int mapLen = lowerCharArray.length;
+                if (mapLen > 1) {
+                    byte[] result2 = StringUTF16.newBytesFor((result.length >> 1) + mapLen - 1);
+                    System.arraycopy(result, 0, result2, 0, resultOffset << 1);
+                    result = result2;
+                }
+                for (int x = 0; x < mapLen; ++x) {
+                    StringUTF16.putChar(result, resultOffset++, lowerCharArray[x]);
+                }
+            }
+        }
+        return StringUTF16.newString(result, 0, resultOffset);
+    }
+
+    public static String toUpperCase(String str, byte[] value, Locale locale) {
+        if (locale == null) {
+            throw new NullPointerException();
+        }
+        int first;
+        final int len = value.length;
+
+        // Now check if there are any characters that need to be changed, or are surrogate
+        for (first = 0 ; first < len; first++ ) {
+            int cp = value[first] & 0xff;
+            if (cp != Character.toUpperCaseEx(cp)) {   // no need to check Character.ERROR
+                break;
+            }
+        }
+        if (first == len) {
+            return str;
+        }
+        String lang = locale.getLanguage();
+        if (lang == "tr" || lang == "az" || lang == "lt") {
+            return toUpperCaseEx(str, value, first, locale, true);
+        }
+        byte[] result = new byte[len];
+        System.arraycopy(value, 0, result, 0, first);  // Just copy the first few
+                                                       // upperCase characters.
+        for (int i = first; i < len; i++) {
+            int cp = value[i] & 0xff;
+            cp = Character.toUpperCaseEx(cp);
+            if (!canEncode(cp)) {                      // not a latin1 character
+                return toUpperCaseEx(str, value, first, locale, false);
+            }
+            result[i] = (byte)cp;
+        }
+        return new String(result, LATIN1);
+    }
+
+    private static String toUpperCaseEx(String str, byte[] value,
+                                        int first, Locale locale, boolean localeDependent)
+    {
+        byte[] result = StringUTF16.newBytesFor(value.length);
+        int resultOffset = 0;
+        for (int i = 0; i < first; i++) {
+            StringUTF16.putChar(result, resultOffset++, value[i] & 0xff);
+        }
+        for (int i = first; i < value.length; i++) {
+            int srcChar = value[i] & 0xff;
+            int upperChar;
+            char[] upperCharArray;
+            if (localeDependent) {
+                upperChar = ConditionalSpecialCasing.toUpperCaseEx(str, i, locale);
+            } else {
+                upperChar = Character.toUpperCaseEx(srcChar);
+            }
+            if (Character.isBmpCodePoint(upperChar)) {
+                StringUTF16.putChar(result, resultOffset++, upperChar);
+            } else {
+                if (upperChar == Character.ERROR) {
+                    if (localeDependent) {
+                        upperCharArray =
+                            ConditionalSpecialCasing.toUpperCaseCharArray(str, i, locale);
+                    } else {
+                        upperCharArray = Character.toUpperCaseCharArray(srcChar);
+                    }
+                } else {
+                    upperCharArray = Character.toChars(upperChar);
+                }
+                /* Grow result if needed */
+                int mapLen = upperCharArray.length;
+                if (mapLen > 1) {
+                    byte[] result2 = StringUTF16.newBytesFor((result.length >> 1) + mapLen - 1);
+                    System.arraycopy(result, 0, result2, 0, resultOffset << 1);
+                    result = result2;
+                }
+                for (int x = 0; x < mapLen; ++x) {
+                    StringUTF16.putChar(result, resultOffset++, upperCharArray[x]);
+                }
+            }
+        }
+        return StringUTF16.newString(result, 0, resultOffset);
+    }
+
+    public static String trim(byte[] value) {
+        int len = value.length;
+        int st = 0;
+        while ((st < len) && ((value[st] & 0xff) <= ' ')) {
+            st++;
+        }
+        while ((st < len) && ((value[len - 1] & 0xff) <= ' ')) {
+            len--;
+        }
+        return ((st > 0) || (len < value.length)) ?
+            newString(value, st, len - st) : null;
+    }
+
+    public static void putChar(byte[] val, int index, int c) {
+        //assert (canEncode(c));
+        val[index] = (byte)(c);
+    }
+
+    public static char getChar(byte[] val, int index) {
+        return (char)(val[index] & 0xff);
+    }
+
+    public static byte[] toBytes(int[] val, int off, int len) {
+        byte[] ret = new byte[len];
+        for (int i = 0; i < len; i++) {
+            int cp = val[off++];
+            if (!canEncode(cp)) {
+                return null;
+            }
+            ret[i] = (byte)cp;
+        }
+        return ret;
+    }
+
+    public static byte[] toBytes(char c) {
+        return new byte[] { (byte)c };
+    }
+
+    public static String newString(byte[] val, int index, int len) {
+        return new String(Arrays.copyOfRange(val, index, index + len),
+                          LATIN1);
+    }
+
+    public static void fillNull(byte[] val, int index, int end) {
+        Arrays.fill(val, index, end, (byte)0);
+    }
+
+    // inflatedCopy byte[] -> char[]
+    @HotSpotIntrinsicCandidate
+    private static void inflate(byte[] src, int srcOff, char[] dst, int dstOff, int len) {
+        for (int i = 0; i < len; i++) {
+            dst[dstOff++] = (char)(src[srcOff++] & 0xff);
+        }
+    }
+
+    // inflatedCopy byte[] -> byte[]
+    @HotSpotIntrinsicCandidate
+    public static void inflate(byte[] src, int srcOff, byte[] dst, int dstOff, int len) {
+        for (int i = 0; i < len; i++) {
+            StringUTF16.putChar(dst, dstOff++, src[srcOff++] & 0xff);
+        }
+    }
+
+    static class CharsSpliterator implements Spliterator.OfInt {
+        private final byte[] array;
+        private int index;        // current index, modified on advance/split
+        private final int fence;  // one past last index
+        private final int cs;
+
+        CharsSpliterator(byte[] array, int acs) {
+            this(array, 0, array.length, acs);
+        }
+
+        CharsSpliterator(byte[] array, int origin, int fence, int acs) {
+            this.array = array;
+            this.index = origin;
+            this.fence = fence;
+            this.cs = acs | Spliterator.ORDERED | Spliterator.SIZED
+                      | Spliterator.SUBSIZED;
+        }
+
+        @Override
+        public OfInt trySplit() {
+            int lo = index, mid = (lo + fence) >>> 1;
+            return (lo >= mid)
+                   ? null
+                   : new CharsSpliterator(array, lo, index = mid, cs);
+        }
+
+        @Override
+        public void forEachRemaining(IntConsumer action) {
+            byte[] a; int i, hi; // hoist accesses and checks from loop
+            if (action == null)
+                throw new NullPointerException();
+            if ((a = array).length >= (hi = fence) &&
+                (i = index) >= 0 && i < (index = hi)) {
+                do { action.accept(a[i] & 0xff); } while (++i < hi);
+            }
+        }
+
+        @Override
+        public boolean tryAdvance(IntConsumer action) {
+            if (action == null)
+                throw new NullPointerException();
+            if (index >= 0 && index < fence) {
+                action.accept(array[index++] & 0xff);
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        public long estimateSize() { return (long)(fence - index); }
+
+        @Override
+        public int characteristics() {
+            return cs;
+        }
+    }
+
+    ////////////////////////////////////////////////////////////////
+
+    public static void getCharsSB(byte[] val, int srcBegin, int srcEnd, char dst[], int dstBegin) {
+        checkOffset(srcEnd, val.length);
+        getChars(val, srcBegin, srcEnd, dst, dstBegin);
+    }
+
+    public static void inflateSB(byte[] val, byte[] dst, int dstOff, int count) {
+        checkOffset(count, val.length);
+        checkOffset(dstOff + count, dst.length >> 1);  // dst is utf16
+        inflate(val, 0, dst, dstOff, count);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/StringUTF16.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,971 @@
+/*
+ * 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.
+ */
+
+package java.lang;
+
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.Spliterator;
+import java.util.function.IntConsumer;
+import jdk.internal.HotSpotIntrinsicCandidate;
+
+import static java.lang.String.UTF16;
+import static java.lang.String.LATIN1;
+import static java.lang.String.checkIndex;
+import static java.lang.String.checkOffset;
+
+final class StringUTF16 {
+
+    public static byte[] newBytesFor(int len) {
+        if (len < 0) {
+            throw new NegativeArraySizeException();
+        }
+        if (len > MAX_LENGTH) {
+            throw new OutOfMemoryError("UTF16 String size is " + len +
+                                       ", should be less than " + MAX_LENGTH);
+        }
+        return new byte[len << 1];
+    }
+
+    @HotSpotIntrinsicCandidate
+    public static void putChar(byte[] val, int index, int c) {
+        index <<= 1;
+        val[index++] = (byte)(c >> HI_BYTE_SHIFT);
+        val[index]   = (byte)(c >> LO_BYTE_SHIFT);
+    }
+
+    @HotSpotIntrinsicCandidate
+    public static char getChar(byte[] val, int index) {
+        index <<= 1;
+        return (char)(((val[index++] & 0xff) << HI_BYTE_SHIFT) |
+                      ((val[index]   & 0xff) << LO_BYTE_SHIFT));
+    }
+
+    public static char charAt(byte[] value, int index) {
+        if (index < 0 || index >= value.length >> 1) {
+            throw new StringIndexOutOfBoundsException(index);
+        }
+        return getChar(value, index);
+    }
+
+    public static int length(byte[] value) {
+        return value.length >> 1;
+    }
+
+    public static int codePointAt(byte[] value, int index, int end) {
+        char c1 = getChar(value, index);
+        if (Character.isHighSurrogate(c1) && ++index < end) {
+            char c2 = getChar(value, index);
+            if (Character.isLowSurrogate(c2)) {
+               return Character.toCodePoint(c1, c2);
+            }
+        }
+        return c1;
+    }
+
+    public static int codePointBefore(byte[] value, int index) {
+        char c2 = getChar(value, --index);
+        if (Character.isLowSurrogate(c2) && index > 0) {
+            char c1 = getChar(value, --index);
+            if (Character.isHighSurrogate(c1)) {
+               return Character.toCodePoint(c1, c2);
+            }
+        }
+        return c2;
+    }
+
+    public static int codePointCount(byte[] value, int beginIndex, int endIndex) {
+        int count = endIndex - beginIndex;
+        for (int i = beginIndex; i < endIndex; ) {
+            if (Character.isHighSurrogate(getChar(value, i++)) &&
+                i < endIndex &&
+                Character.isLowSurrogate(getChar(value, i))) {
+                count--;
+                i++;
+            }
+        }
+        return count;
+    }
+
+    public static char[] toChars(byte[] value) {
+        char[] dst = new char[value.length >> 1];
+        getChars(value, 0, dst.length, dst, 0);
+        return dst;
+    }
+
+    @HotSpotIntrinsicCandidate
+    public static byte[] toBytes(char[] value, int off, int len) {
+        byte[] val = newBytesFor(len);
+        for (int i = 0; i < len; i++) {
+            putChar(val, i, value[off++]);
+        }
+        return val;
+    }
+
+    public static byte[] compress(char[] val, int off, int len) {
+        byte[] ret = new byte[len];
+        if (compress(val, off, ret, 0, len) == len) {
+            return ret;
+        }
+        return null;
+    }
+
+    public static byte[] compress(byte[] val, int off, int len) {
+        byte[] ret = new byte[len];
+        if (compress(val, off, ret, 0, len) == len) {
+            return ret;
+        }
+        return null;
+    }
+
+    // compressedCopy char[] -> byte[]
+    @HotSpotIntrinsicCandidate
+    private static int compress(char[] src, int srcOff, byte[] dst, int dstOff, int len) {
+        for (int i = 0; i < len; i++) {
+            int c = src[srcOff++];
+            if (c >>> 8 != 0) {
+                return 0;
+            }
+            dst[dstOff++] = (byte)c;
+        }
+        return len;
+    }
+
+    // compressedCopy byte[] -> byte[]
+    @HotSpotIntrinsicCandidate
+    public static int compress(byte[] src, int srcOff, byte[] dst, int dstOff, int len) {
+        for (int i = 0; i < len; i++) {
+            int c = getChar(src, srcOff++);
+            if (c >>> 8 != 0) {
+                return 0;
+            }
+            dst[dstOff++] = (byte)c;
+        }
+        return len;
+    }
+
+    public static byte[] toBytes(int[] val, int index, int len) {
+        final int end = index + len;
+        // Pass 1: Compute precise size of char[]
+        int n = len;
+        for (int i = index; i < end; i++) {
+            int cp = val[i];
+            if (Character.isBmpCodePoint(cp))
+                continue;
+            else if (Character.isValidCodePoint(cp))
+                n++;
+            else throw new IllegalArgumentException(Integer.toString(cp));
+        }
+        // Pass 2: Allocate and fill in <high, low> pair
+        byte[] buf = newBytesFor(n);
+        for (int i = index, j = 0; i < end; i++, j++) {
+            int cp = val[i];
+            if (Character.isBmpCodePoint(cp)) {
+                putChar(buf, j, cp);
+            } else {
+                putChar(buf, j++, Character.highSurrogate(cp));
+                putChar(buf, j, Character.lowSurrogate(cp));
+            }
+        }
+        return buf;
+    }
+
+    public static byte[] toBytes(char c) {
+        byte[] result = new byte[2];
+        putChar(result, 0, c);
+        return result;
+    }
+
+    @HotSpotIntrinsicCandidate
+    public static void getChars(byte[] value, int srcBegin, int srcEnd, char dst[], int dstBegin) {
+        for (int i = srcBegin; i < srcEnd; i++) {
+            dst[dstBegin++] = getChar(value, i);
+        }
+    }
+
+    /* @see java.lang.String.getBytes(int, int, byte[], int) */
+    public static void getBytes(byte[] value, int srcBegin, int srcEnd, byte dst[], int dstBegin) {
+        srcBegin <<= 1;
+        srcEnd <<= 1;
+        for (int i = srcBegin + (1 >> LO_BYTE_SHIFT); i < srcEnd; i += 2) {
+            dst[dstBegin++] = value[i];
+        }
+    }
+
+    @HotSpotIntrinsicCandidate
+    public static boolean equals(byte[] value, byte[] other) {
+        if (value.length == other.length) {
+            int len = value.length >> 1;
+            for (int i = 0; i < len; i++) {
+                if (getChar(value, i) != getChar(other, i)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @HotSpotIntrinsicCandidate
+    public static int compareTo(byte[] value, byte[] other) {
+        int len1 = length(value);
+        int len2 = length(other);
+        int lim = Math.min(len1, len2);
+        for (int k = 0; k < lim; k++) {
+            char c1 = getChar(value, k);
+            char c2 = getChar(other, k);
+            if (c1 != c2) {
+                return c1 - c2;
+            }
+        }
+        return len1 - len2;
+    }
+
+    @HotSpotIntrinsicCandidate
+    public static int compareToLatin1(byte[] value, byte[] other) {
+        int len1 = length(value);
+        int len2 = StringLatin1.length(other);
+        int lim = Math.min(len1, len2);
+        for (int k = 0; k < lim; k++) {
+            char c1 = getChar(value, k);
+            char c2 = StringLatin1.getChar(other, k);
+            if (c1 != c2) {
+                return c1 - c2;
+            }
+        }
+        return len1 - len2;
+    }
+
+    public static int hashCode(byte[] value) {
+        int h = 0;
+        int length = value.length >> 1;
+        for (int i = 0; i < length; i++) {
+            h = 31 * h + getChar(value, i);
+        }
+        return h;
+    }
+
+    public static int indexOf(byte[] value, int ch, int fromIndex) {
+        int max = value.length >> 1;
+        if (fromIndex < 0) {
+            fromIndex = 0;
+        } else if (fromIndex >= max) {
+            // Note: fromIndex might be near -1>>>1.
+            return -1;
+        }
+        if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
+            // handle most cases here (ch is a BMP code point or a
+            // negative value (invalid code point))
+            return indexOfChar(value, ch, fromIndex, max);
+        } else {
+            return indexOfSupplementary(value, ch, fromIndex, max);
+        }
+    }
+
+    @HotSpotIntrinsicCandidate
+    public static int indexOf(byte[] value, byte[] str) {
+        if (str.length == 0) {
+            return 0;
+        }
+        if (value.length == 0) {
+            return -1;
+        }
+        return indexOf(value, length(value), str, length(str), 0);
+    }
+
+    @HotSpotIntrinsicCandidate
+    public static int indexOf(byte[] value, int valueCount, byte[] str, int strCount, int fromIndex) {
+        char first = getChar(str, 0);
+        int max = (valueCount - strCount);
+        for (int i = fromIndex; i <= max; i++) {
+            // Look for first character.
+            if (getChar(value, i) != first) {
+                while (++i <= max && getChar(value, i) != first);
+            }
+            // Found first character, now look at the rest of value
+            if (i <= max) {
+                int j = i + 1;
+                int end = j + strCount - 1;
+                for (int k = 1; j < end && getChar(value, j) == getChar(str, k); j++, k++);
+                if (j == end) {
+                    // Found whole string.
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Handles indexOf Latin1 substring in UTF16 string.
+     */
+    @HotSpotIntrinsicCandidate
+    public static int indexOfLatin1(byte[] value, byte[] str) {
+        if (str.length == 0) {
+            return 0;
+        }
+        if (value.length == 0) {
+            return -1;
+        }
+        return indexOfLatin1(value, length(value), str, str.length, 0);
+    }
+
+    @HotSpotIntrinsicCandidate
+    public static int indexOfLatin1(byte[] src, int srcCount, byte[] tgt, int tgtCount, int fromIndex) {
+        char first = (char)(tgt[0] & 0xff);
+        int max = (srcCount - tgtCount);
+        for (int i = fromIndex; i <= max; i++) {
+            // Look for first character.
+            if (getChar(src, i) != first) {
+                while (++i <= max && getChar(src, i) != first);
+            }
+            // Found first character, now look at the rest of v2
+            if (i <= max) {
+                int j = i + 1;
+                int end = j + tgtCount - 1;
+                for (int k = 1;
+                     j < end && getChar(src, j) == (tgt[k] & 0xff);
+                     j++, k++);
+                if (j == end) {
+                    // Found whole string.
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+
+    @HotSpotIntrinsicCandidate
+    private static int indexOfChar(byte[] value, int ch, int fromIndex, int max) {
+        for (int i = fromIndex; i < max; i++) {
+            if (getChar(value, i) == ch) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Handles (rare) calls of indexOf with a supplementary character.
+     */
+    private static int indexOfSupplementary(byte[] value, int ch, int fromIndex, int max) {
+        if (Character.isValidCodePoint(ch)) {
+            final char hi = Character.highSurrogate(ch);
+            final char lo = Character.lowSurrogate(ch);
+            for (int i = fromIndex; i < max - 1; i++) {
+                if (getChar(value, i) == hi && getChar(value, i + 1 ) == lo) {
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+
+    public static int lastIndexOf(byte[] src, int srcCount,
+                                  byte[] tgt, int tgtCount, int fromIndex) {
+        int min = tgtCount - 1;
+        int i = min + fromIndex;
+        int strLastIndex = tgtCount - 1;
+        char strLastChar = getChar(tgt, strLastIndex);
+
+    startSearchForLastChar:
+        while (true) {
+            while (i >= min && getChar(src, i) != strLastChar) {
+                i--;
+            }
+            if (i < min) {
+                return -1;
+            }
+            int j = i - 1;
+            int start = j - strLastIndex;
+            int k = strLastIndex - 1;
+            while (j > start) {
+                if (getChar(src, j--) != getChar(tgt, k--)) {
+                    i--;
+                    continue startSearchForLastChar;
+                }
+            }
+            return start + 1;
+        }
+    }
+
+    public static int lastIndexOf(byte[] value, int ch, int fromIndex) {
+        if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
+            // handle most cases here (ch is a BMP code point or a
+            // negative value (invalid code point))
+            int i = Math.min(fromIndex, (value.length >> 1) - 1);
+            for (; i >= 0; i--) {
+                if (getChar(value, i) == ch) {
+                    return i;
+                }
+            }
+            return -1;
+        } else {
+            return lastIndexOfSupplementary(value, ch, fromIndex);
+        }
+    }
+
+    /**
+     * Handles (rare) calls of lastIndexOf with a supplementary character.
+     */
+    private static int lastIndexOfSupplementary(final byte[] value, int ch, int fromIndex) {
+        if (Character.isValidCodePoint(ch)) {
+            char hi = Character.highSurrogate(ch);
+            char lo = Character.lowSurrogate(ch);
+            int i = Math.min(fromIndex, (value.length >> 1) - 2);
+            for (; i >= 0; i--) {
+                if (getChar(value, i) == hi && getChar(value, i + 1) == lo) {
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+
+    public static String replace(byte[] value, char oldChar, char newChar) {
+        int len = value.length >> 1;
+        int i = -1;
+        while (++i < len) {
+            if (getChar(value, i) == oldChar) {
+                break;
+            }
+        }
+        if (i < len) {
+            byte buf[] = new byte[value.length];
+            for (int j = 0; j < i; j++) {
+                putChar(buf, j, getChar(value, j)); // TBD:arraycopy?
+            }
+            while (i < len) {
+                char c = getChar(value, i);
+                putChar(buf, i, c == oldChar ? newChar : c);
+                i++;
+           }
+           // Check if we should try to compress to latin1
+           if (String.COMPACT_STRINGS &&
+               !StringLatin1.canEncode(oldChar) &&
+               StringLatin1.canEncode(newChar)) {
+               byte[] val = compress(buf, 0, len);
+               if (val != null) {
+                   return new String(val, LATIN1);
+               }
+           }
+           return new String(buf, UTF16);
+        }
+        return null;
+    }
+
+    public static boolean regionMatchesCI(byte[] value, int toffset,
+                                          byte[] other, int ooffset, int len) {
+        int last = toffset + len;
+        while (toffset < last) {
+            char c1 = getChar(value, toffset++);
+            char c2 = getChar(other, ooffset++);
+            if (c1 == c2) {
+                continue;
+            }
+            // try converting both characters to uppercase.
+            // If the results match, then the comparison scan should
+            // continue.
+            char u1 = Character.toUpperCase(c1);
+            char u2 = Character.toUpperCase(c2);
+            if (u1 == u2) {
+                continue;
+            }
+            // Unfortunately, conversion to uppercase does not work properly
+            // for the Georgian alphabet, which has strange rules about case
+            // conversion.  So we need to make one last check before
+            // exiting.
+            if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
+                continue;
+            }
+            return false;
+        }
+        return true;
+    }
+
+    public static boolean regionMatchesCI_Latin1(byte[] value, int toffset,
+                                                 byte[] other, int ooffset,
+                                                 int len) {
+        int last = toffset + len;
+        while (toffset < last) {
+            char c1 = getChar(value, toffset++);
+            char c2 = (char)(other[ooffset++] & 0xff);
+            if (c1 == c2) {
+                continue;
+            }
+            char u1 = Character.toUpperCase(c1);
+            char u2 = Character.toUpperCase(c2);
+            if (u1 == u2) {
+                continue;
+            }
+            if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
+                continue;
+            }
+            return false;
+        }
+        return true;
+    }
+
+    public static String toLowerCase(String str, byte[] value, Locale locale) {
+        if (locale == null) {
+            throw new NullPointerException();
+        }
+        int first;
+        boolean hasSurr = false;
+        final int len = value.length >> 1;
+
+        // Now check if there are any characters that need to be changed, or are surrogate
+        for (first = 0 ; first < len; first++) {
+            int cp = (int)getChar(value, first);
+            if (Character.isSurrogate((char)cp)) {
+                hasSurr = true;
+                break;
+            }
+            if (cp != Character.toLowerCase(cp)) {  // no need to check Character.ERROR
+                break;
+            }
+        }
+        if (first == len)
+            return str;
+        byte[] result = new byte[value.length];
+        System.arraycopy(value, 0, result, 0, first << 1);  // Just copy the first few
+                                                            // lowerCase characters.
+        String lang = locale.getLanguage();
+        if (lang == "tr" || lang == "az" || lang == "lt") {
+            return toLowerCaseEx(str, value, result, first, locale, true);
+        }
+        if (hasSurr) {
+            return toLowerCaseEx(str, value, result, first, locale, false);
+        }
+        int bits = 0;
+        for (int i = first; i < len; i++) {
+            int cp = (int)getChar(value, i);
+            if (cp == '\u03A3' ||                       // GREEK CAPITAL LETTER SIGMA
+                Character.isSurrogate((char)cp)) {
+                return toLowerCaseEx(str, value, result, i, locale, false);
+            }
+            if (cp == '\u0130') {                       // LATIN CAPITAL LETTER I WITH DOT ABOVE
+                return toLowerCaseEx(str, value, result, i, locale, true);
+            }
+            cp = Character.toLowerCase(cp);
+            if (!Character.isBmpCodePoint(cp)) {
+                return toLowerCaseEx(str, value, result, i, locale, false);
+            }
+            bits |= cp;
+            putChar(result, i, cp);
+        }
+        if (bits >>> 8 != 0) {
+            return new String(result, UTF16);
+        } else {
+            return newString(result, 0, len);
+        }
+    }
+
+    private static String toLowerCaseEx(String str, byte[] value,
+                                        byte[] result, int first, Locale locale,
+                                        boolean localeDependent) {
+        int resultOffset = first;
+        int length = value.length >> 1;
+        int srcCount;
+        for (int i = first; i < length; i += srcCount) {
+            int srcChar = getChar(value, i);
+            int lowerChar;
+            char[] lowerCharArray;
+            srcCount = 1;
+            if (Character.isSurrogate((char)srcChar)) {
+                srcChar = codePointAt(value, i, length);
+                srcCount = Character.charCount(srcChar);
+            }
+            if (localeDependent ||
+                srcChar == '\u03A3' ||  // GREEK CAPITAL LETTER SIGMA
+                srcChar == '\u0130') {  // LATIN CAPITAL LETTER I WITH DOT ABOVE
+                lowerChar = ConditionalSpecialCasing.toLowerCaseEx(str, i, locale);
+            } else {
+                lowerChar = Character.toLowerCase(srcChar);
+            }
+            if (Character.isBmpCodePoint(lowerChar)) {    // Character.ERROR is not a bmp
+                putChar(result, resultOffset++, lowerChar);
+            } else {
+                if (lowerChar == Character.ERROR) {
+                    lowerCharArray = ConditionalSpecialCasing.toLowerCaseCharArray(str, i, locale);
+                } else {
+                    lowerCharArray = Character.toChars(lowerChar);
+                }
+                /* Grow result if needed */
+                int mapLen = lowerCharArray.length;
+                if (mapLen > srcCount) {
+                    byte[] result2 = newBytesFor((result.length >> 1) + mapLen - srcCount);
+                    System.arraycopy(result, 0, result2, 0, resultOffset << 1);
+                    result = result2;
+                }
+                for (int x = 0; x < mapLen; ++x) {
+                    putChar(result, resultOffset++, lowerCharArray[x]);
+                }
+            }
+        }
+        return newString(result, 0, resultOffset);
+    }
+
+    public static String toUpperCase(String str, byte[] value, Locale locale) {
+        if (locale == null) {
+            throw new NullPointerException();
+        }
+        int first;
+        boolean hasSurr = false;
+        final int len = value.length >> 1;
+
+        // Now check if there are any characters that need to be changed, or are surrogate
+        for (first = 0 ; first < len; first++) {
+            int cp = (int)getChar(value, first);
+            if (Character.isSurrogate((char)cp)) {
+                hasSurr = true;
+                break;
+            }
+            if (cp != Character.toUpperCaseEx(cp)) {   // no need to check Character.ERROR
+                break;
+            }
+        }
+        if (first == len) {
+            return str;
+        }
+        byte[] result = new byte[value.length];
+        System.arraycopy(value, 0, result, 0, first << 1); // Just copy the first few
+                                                           // upperCase characters.
+        String lang = locale.getLanguage();
+        if (lang == "tr" || lang == "az" || lang == "lt") {
+            return toUpperCaseEx(str, value, result, first, locale, true);
+        }
+        if (hasSurr) {
+            return toUpperCaseEx(str, value, result, first, locale, false);
+        }
+        int bits = 0;
+        for (int i = first; i < len; i++) {
+            int cp = (int)getChar(value, i);
+            if (Character.isSurrogate((char)cp)) {
+                return toUpperCaseEx(str, value, result, i, locale, false);
+            }
+            cp = Character.toUpperCaseEx(cp);
+            if (!Character.isBmpCodePoint(cp)) {    // Character.ERROR is not bmp
+                return toUpperCaseEx(str, value, result, i, locale, false);
+            }
+            bits |= cp;
+            putChar(result, i, cp);
+        }
+        if (bits >>> 8 != 0) {
+            return new String(result, UTF16);
+        } else {
+            return newString(result, 0, len);
+        }
+    }
+
+    private static String toUpperCaseEx(String str, byte[] value,
+                                        byte[] result, int first,
+                                        Locale locale, boolean localeDependent)
+    {
+        int resultOffset = first;
+        int length = value.length >> 1;
+        int srcCount;
+        for (int i = first; i < length; i += srcCount) {
+            int srcChar = getChar(value, i);
+            int upperChar;
+            char[] upperCharArray;
+            srcCount = 1;
+            if (Character.isSurrogate((char)srcChar)) {
+                srcChar = codePointAt(value, i, length);
+                srcCount = Character.charCount(srcChar);
+            }
+            if (localeDependent) {
+                upperChar = ConditionalSpecialCasing.toUpperCaseEx(str, i, locale);
+            } else {
+                upperChar = Character.toUpperCaseEx(srcChar);
+            }
+            if (Character.isBmpCodePoint(upperChar)) {
+                putChar(result, resultOffset++, upperChar);
+            } else {
+                if (upperChar == Character.ERROR) {
+                    if (localeDependent) {
+                        upperCharArray =
+                            ConditionalSpecialCasing.toUpperCaseCharArray(str, i, locale);
+                    } else {
+                        upperCharArray = Character.toUpperCaseCharArray(srcChar);
+                    }
+                } else {
+                    upperCharArray = Character.toChars(upperChar);
+                }
+                /* Grow result if needed */
+                int mapLen = upperCharArray.length;
+                if (mapLen > srcCount) {
+                    byte[] result2 = newBytesFor((result.length >> 1) + mapLen - srcCount);
+                    System.arraycopy(result, 0, result2, 0, resultOffset << 1);
+                    result = result2;
+                 }
+                 for (int x = 0; x < mapLen; ++x) {
+                    putChar(result, resultOffset++, upperCharArray[x]);
+                 }
+            }
+        }
+        return newString(result, 0, resultOffset);
+    }
+
+    public static String trim(byte[] value) {
+        int length = value.length >> 1;
+        int len = length;
+        int st = 0;
+        while (st < len && getChar(value, st) <= ' ') {
+            st++;
+        }
+        while (st < len && getChar(value, len - 1) <= ' ') {
+            len--;
+        }
+        return ((st > 0) || (len < length )) ?
+            new String(Arrays.copyOfRange(value, st << 1, len << 1), UTF16) :
+            null;
+    }
+
+    public static void putChars(byte[] val, int index, char[] str, int off, int end) {
+        while (off < end) {
+            putChar(val, index++, str[off++]);
+        }
+    }
+
+    public static String newString(byte[] val, int index, int len) {
+        if (String.COMPACT_STRINGS) {
+            byte[] buf = compress(val, index, len);
+            if (buf != null) {
+                return new String(buf, LATIN1);
+            }
+        }
+        int last = index + len;
+        return new String(Arrays.copyOfRange(val, index << 1, last << 1), UTF16);
+    }
+
+    public static void fillNull(byte[] val, int index, int end) {
+        Arrays.fill(val, index << 1, end << 1, (byte)0);
+    }
+
+    static class CharsSpliterator implements Spliterator.OfInt {
+        private final byte[] array;
+        private int index;        // current index, modified on advance/split
+        private final int fence;  // one past last index
+        private final int cs;
+
+        CharsSpliterator(byte[] array, int acs) {
+            this(array, 0, array.length >> 1, acs);
+        }
+
+        CharsSpliterator(byte[] array, int origin, int fence, int acs) {
+            this.array = array;
+            this.index = origin;
+            this.fence = fence;
+            this.cs = acs | Spliterator.ORDERED | Spliterator.SIZED
+                      | Spliterator.SUBSIZED;
+        }
+
+        @Override
+        public OfInt trySplit() {
+            int lo = index, mid = (lo + fence) >>> 1;
+            return (lo >= mid)
+                   ? null
+                   : new CharsSpliterator(array, lo, index = mid, cs);
+        }
+
+        @Override
+        public void forEachRemaining(IntConsumer action) {
+            byte[] a; int i, hi; // hoist accesses and checks from loop
+            if (action == null)
+                throw new NullPointerException();
+            if (((a = array).length >> 1) >= (hi = fence) &&
+                (i = index) >= 0 && i < (index = hi)) {
+                do { action.accept(getChar(a, i)); } while (++i < hi);
+            }
+        }
+
+        @Override
+        public boolean tryAdvance(IntConsumer action) {
+            if (action == null)
+                throw new NullPointerException();
+            if (index >= 0 && index < fence) {
+                action.accept(getChar(array, index++));
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        public long estimateSize() { return (long)(fence - index); }
+
+        @Override
+        public int characteristics() {
+            return cs;
+        }
+    }
+
+    static class CodePointsSpliterator implements Spliterator.OfInt {
+        private final byte[] array;
+        private int index;        // current index, modified on advance/split
+        private final int fence;  // one past last index
+        private final int cs;
+
+        CodePointsSpliterator(byte[] array, int acs) {
+            this(array, 0, array.length >> 1, acs);
+        }
+
+        CodePointsSpliterator(byte[] array, int origin, int fence, int acs) {
+            this.array = array;
+            this.index = origin;
+            this.fence = fence;
+            this.cs = acs | Spliterator.ORDERED;
+        }
+
+        @Override
+        public OfInt trySplit() {
+            int lo = index, mid = (lo + fence) >>> 1;
+            if (lo >= mid)
+                return null;
+
+            int midOneLess;
+            // If the mid-point intersects a surrogate pair
+            if (Character.isLowSurrogate(getChar(array, mid)) &&
+                Character.isHighSurrogate(getChar(array, midOneLess = (mid -1)))) {
+                // If there is only one pair it cannot be split
+                if (lo >= midOneLess)
+                    return null;
+                // Shift the mid-point to align with the surrogate pair
+                return new CodePointsSpliterator(array, lo, index = midOneLess, cs);
+            }
+            return new CodePointsSpliterator(array, lo, index = mid, cs);
+        }
+
+        @Override
+        public void forEachRemaining(IntConsumer action) {
+            byte[] a; int i, hi; // hoist accesses and checks from loop
+            if (action == null)
+                throw new NullPointerException();
+            if (((a = array).length >> 1) >= (hi = fence) &&
+                (i = index) >= 0 && i < (index = hi)) {
+                do {
+                    i = advance(a, i, hi, action);
+                } while (i < hi);
+            }
+        }
+
+        @Override
+        public boolean tryAdvance(IntConsumer action) {
+            if (action == null)
+                throw new NullPointerException();
+            if (index >= 0 && index < fence) {
+                index = advance(array, index, fence, action);
+                return true;
+            }
+            return false;
+        }
+
+        // Advance one code point from the index, i, and return the next
+        // index to advance from
+        private static int advance(byte[] a, int i, int hi, IntConsumer action) {
+            char c1 = getChar(a, i++);
+            int cp = c1;
+            if (Character.isHighSurrogate(c1) && i < hi) {
+                char c2 = getChar(a, i);
+                if (Character.isLowSurrogate(c2)) {
+                    i++;
+                    cp = Character.toCodePoint(c1, c2);
+                }
+            }
+            action.accept(cp);
+            return i;
+        }
+
+        @Override
+        public long estimateSize() { return (long)(fence - index); }
+
+        @Override
+        public int characteristics() {
+            return cs;
+        }
+    }
+
+    ////////////////////////////////////////////////////////////////
+
+    public static void getCharsSB(byte[] val, int srcBegin, int srcEnd, char dst[], int dstBegin) {
+        checkOffset(srcEnd, val.length >> 1);
+        getChars(val, srcBegin, srcEnd, dst, dstBegin);
+    }
+
+    public static void putCharSB(byte[] val, int index, int c) {
+        checkIndex(index, val.length >> 1);
+        putChar(val, index, c);
+    }
+
+    public static void putCharsSB(byte[] val, int index, char[] ca, int off, int end) {
+        checkOffset(index + end - off, val.length >> 1);
+        putChars(val, index, ca, off, end);
+    }
+
+    public static void putCharsSB(byte[] val, int index, CharSequence s, int off, int end) {
+        checkOffset(index + end - off, val.length >> 1);
+        for (int i = off; i < end; i++) {
+            putChar(val, index++, s.charAt(i));
+        }
+    }
+
+    public static int codePointAtSB(byte[] val, int index, int end) {
+        checkOffset(end, val.length >> 1);
+        return codePointAt(val, index, end);
+    }
+
+    public static int codePointBeforeSB(byte[] val, int index) {
+        checkOffset(index, val.length >> 1);
+        return codePointBefore(val, index);
+    }
+
+    public static int codePointCountSB(byte[] val, int beginIndex, int endIndex) {
+        checkOffset(endIndex, val.length >> 1);
+        return codePointCount(val, beginIndex, endIndex);
+    }
+
+    public static String newStringSB(byte[] val, int index, int len) {
+        checkOffset(index + len, val.length >> 1);
+        return newString(val, index, len);
+    }
+
+    ////////////////////////////////////////////////////////////////
+
+    private static native boolean isBigEndian();
+
+    static final int HI_BYTE_SHIFT;
+    static final int LO_BYTE_SHIFT;
+    static {
+        if (isBigEndian()) {
+            HI_BYTE_SHIFT = 8;
+            LO_BYTE_SHIFT = 0;
+        } else {
+            HI_BYTE_SHIFT = 0;
+            LO_BYTE_SHIFT = 8;
+        }
+    }
+
+    static final int MAX_LENGTH = Integer.MAX_VALUE >> 1;
+}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java	Tue Nov 17 10:29:28 2015 -0800
@@ -25,7 +25,7 @@
 
 package java.lang.invoke;
 
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 import java.lang.reflect.Method;
 import java.util.Arrays;
 import sun.invoke.util.VerifyAccess;
@@ -224,12 +224,12 @@
         assert(names.length == nameCursor);
         if (doesAlloc) {
             // names = { argx,y,z,... new C, init method }
-            names[NEW_OBJ] = new Name(Lazy.NF_allocateInstance, names[DMH_THIS]);
-            names[GET_MEMBER] = new Name(Lazy.NF_constructorMethod, names[DMH_THIS]);
+            names[NEW_OBJ] = new Name(NF_allocateInstance, names[DMH_THIS]);
+            names[GET_MEMBER] = new Name(NF_constructorMethod, names[DMH_THIS]);
         } else if (needsInit) {
-            names[GET_MEMBER] = new Name(Lazy.NF_internalMemberNameEnsureInit, names[DMH_THIS]);
+            names[GET_MEMBER] = new Name(NF_internalMemberNameEnsureInit, names[DMH_THIS]);
         } else {
-            names[GET_MEMBER] = new Name(Lazy.NF_internalMemberName, names[DMH_THIS]);
+            names[GET_MEMBER] = new Name(NF_internalMemberName, names[DMH_THIS]);
         }
         assert(findDirectMethodHandle(names[GET_MEMBER]) == names[DMH_THIS]);
         Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER+1, Object[].class);
@@ -250,9 +250,9 @@
     }
 
     static Object findDirectMethodHandle(Name name) {
-        if (name.function == Lazy.NF_internalMemberName ||
-            name.function == Lazy.NF_internalMemberNameEnsureInit ||
-            name.function == Lazy.NF_constructorMethod) {
+        if (name.function == NF_internalMemberName ||
+            name.function == NF_internalMemberNameEnsureInit ||
+            name.function == NF_constructorMethod) {
             assert(name.arguments.length == 1);
             return name.arguments[0];
         }
@@ -613,18 +613,18 @@
         final int RESULT    = nameCursor-1;  // either the call or the cast
         Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
         if (needsInit)
-            names[INIT_BAR] = new Name(Lazy.NF_ensureInitialized, names[DMH_THIS]);
+            names[INIT_BAR] = new Name(NF_ensureInitialized, names[DMH_THIS]);
         if (needsCast && !isGetter)
-            names[PRE_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[SET_VALUE]);
+            names[PRE_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[SET_VALUE]);
         Object[] outArgs = new Object[1 + linkerType.parameterCount()];
         assert(outArgs.length == (isGetter ? 3 : 4));
         outArgs[0] = UNSAFE;
         if (isStatic) {
-            outArgs[1] = names[F_HOLDER]  = new Name(Lazy.NF_staticBase, names[DMH_THIS]);
-            outArgs[2] = names[F_OFFSET]  = new Name(Lazy.NF_staticOffset, names[DMH_THIS]);
+            outArgs[1] = names[F_HOLDER]  = new Name(NF_staticBase, names[DMH_THIS]);
+            outArgs[2] = names[F_OFFSET]  = new Name(NF_staticOffset, names[DMH_THIS]);
         } else {
-            outArgs[1] = names[OBJ_CHECK] = new Name(Lazy.NF_checkBase, names[OBJ_BASE]);
-            outArgs[2] = names[F_OFFSET]  = new Name(Lazy.NF_fieldOffset, names[DMH_THIS]);
+            outArgs[1] = names[OBJ_CHECK] = new Name(NF_checkBase, names[OBJ_BASE]);
+            outArgs[2] = names[F_OFFSET]  = new Name(NF_fieldOffset, names[DMH_THIS]);
         }
         if (!isGetter) {
             outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
@@ -632,7 +632,7 @@
         for (Object a : outArgs)  assert(a != null);
         names[LINKER_CALL] = new Name(linker, outArgs);
         if (needsCast && isGetter)
-            names[POST_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[LINKER_CALL]);
+            names[POST_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[LINKER_CALL]);
         for (Name n : names)  assert(n != null);
         String fieldOrStatic = (isStatic ? "Static" : "Field");
         String lambdaName = (linkerName + fieldOrStatic);  // significant only for debugging
@@ -645,50 +645,45 @@
      * Pre-initialized NamedFunctions for bootstrapping purposes.
      * Factored in an inner class to delay initialization until first usage.
      */
-    private static class Lazy {
-        static final NamedFunction
-                NF_internalMemberName,
-                NF_internalMemberNameEnsureInit,
-                NF_ensureInitialized,
-                NF_fieldOffset,
-                NF_checkBase,
-                NF_staticBase,
-                NF_staticOffset,
-                NF_checkCast,
-                NF_allocateInstance,
-                NF_constructorMethod;
-        static {
-            try {
-                NamedFunction nfs[] = {
-                        NF_internalMemberName = new NamedFunction(DirectMethodHandle.class
-                                .getDeclaredMethod("internalMemberName", Object.class)),
-                        NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class
-                                .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)),
-                        NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class
-                                .getDeclaredMethod("ensureInitialized", Object.class)),
-                        NF_fieldOffset = new NamedFunction(DirectMethodHandle.class
-                                .getDeclaredMethod("fieldOffset", Object.class)),
-                        NF_checkBase = new NamedFunction(DirectMethodHandle.class
-                                .getDeclaredMethod("checkBase", Object.class)),
-                        NF_staticBase = new NamedFunction(DirectMethodHandle.class
-                                .getDeclaredMethod("staticBase", Object.class)),
-                        NF_staticOffset = new NamedFunction(DirectMethodHandle.class
-                                .getDeclaredMethod("staticOffset", Object.class)),
-                        NF_checkCast = new NamedFunction(DirectMethodHandle.class
-                                .getDeclaredMethod("checkCast", Object.class, Object.class)),
-                        NF_allocateInstance = new NamedFunction(DirectMethodHandle.class
-                                .getDeclaredMethod("allocateInstance", Object.class)),
-                        NF_constructorMethod = new NamedFunction(DirectMethodHandle.class
-                                .getDeclaredMethod("constructorMethod", Object.class))
-                };
-                for (NamedFunction nf : nfs) {
-                    // Each nf must be statically invocable or we get tied up in our bootstraps.
-                    assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf;
-                    nf.resolve();
-                }
-            } catch (ReflectiveOperationException ex) {
-                throw newInternalError(ex);
-            }
+    static final NamedFunction
+            NF_internalMemberName,
+            NF_internalMemberNameEnsureInit,
+            NF_ensureInitialized,
+            NF_fieldOffset,
+            NF_checkBase,
+            NF_staticBase,
+            NF_staticOffset,
+            NF_checkCast,
+            NF_allocateInstance,
+            NF_constructorMethod;
+    static {
+        try {
+            NamedFunction nfs[] = {
+                    NF_internalMemberName = new NamedFunction(DirectMethodHandle.class
+                            .getDeclaredMethod("internalMemberName", Object.class)),
+                    NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class
+                            .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)),
+                    NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class
+                            .getDeclaredMethod("ensureInitialized", Object.class)),
+                    NF_fieldOffset = new NamedFunction(DirectMethodHandle.class
+                            .getDeclaredMethod("fieldOffset", Object.class)),
+                    NF_checkBase = new NamedFunction(DirectMethodHandle.class
+                            .getDeclaredMethod("checkBase", Object.class)),
+                    NF_staticBase = new NamedFunction(DirectMethodHandle.class
+                            .getDeclaredMethod("staticBase", Object.class)),
+                    NF_staticOffset = new NamedFunction(DirectMethodHandle.class
+                            .getDeclaredMethod("staticOffset", Object.class)),
+                    NF_checkCast = new NamedFunction(DirectMethodHandle.class
+                            .getDeclaredMethod("checkCast", Object.class, Object.class)),
+                    NF_allocateInstance = new NamedFunction(DirectMethodHandle.class
+                            .getDeclaredMethod("allocateInstance", Object.class)),
+                    NF_constructorMethod = new NamedFunction(DirectMethodHandle.class
+                            .getDeclaredMethod("constructorMethod", Object.class))
+            };
+            // Each nf must be statically invocable or we get tied up in our bootstraps.
+            assert(InvokerBytecodeGenerator.isStaticallyInvocable(nfs));
+        } catch (ReflectiveOperationException ex) {
+            throw newInternalError(ex);
         }
     }
 }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java	Tue Nov 17 10:29:28 2015 -0800
@@ -27,7 +27,7 @@
 
 import jdk.internal.org.objectweb.asm.*;
 import sun.invoke.util.BytecodeDescriptor;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 import sun.security.action.GetPropertyAction;
 
 import java.io.FilePermission;
--- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Tue Nov 17 10:29:28 2015 -0800
@@ -750,7 +750,7 @@
         assert(!isLinkerMethodInvoke(name));  // should use the static path for these
         if (true) {
             // push receiver
-            MethodHandle target = name.function.resolvedHandle;
+            MethodHandle target = name.function.resolvedHandle();
             assert(target != null) : name.exprString();
             mv.visitLdcInsn(constantPlaceholder(target));
             emitReferenceCast(MethodHandle.class, target);
@@ -775,10 +775,19 @@
         // Sample classes from each package we are willing to bind to statically:
         java.lang.Object.class,
         java.util.Arrays.class,
-        sun.misc.Unsafe.class
+        jdk.internal.misc.Unsafe.class
         //MethodHandle.class already covered
     };
 
+    static boolean isStaticallyInvocable(NamedFunction[] functions) {
+        for (NamedFunction nf : functions) {
+            if (!isStaticallyInvocable(nf.member())) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     static boolean isStaticallyInvocable(Name name) {
         return isStaticallyInvocable(name.function.member());
     }
@@ -881,7 +890,7 @@
             // The array will be a constant.
             Object emptyArray;
             try {
-                emptyArray = name.function.resolvedHandle.invoke();
+                emptyArray = name.function.resolvedHandle().invoke();
             } catch (Throwable ex) {
                 throw newInternalError(ex);
             }
@@ -1085,8 +1094,8 @@
         Label L_handler = new Label();
         Label L_done = new Label();
 
-        Class<?> returnType = result.function.resolvedHandle.type().returnType();
-        MethodType type = args.function.resolvedHandle.type()
+        Class<?> returnType = result.function.resolvedHandle().type().returnType();
+        MethodType type = args.function.resolvedHandle().type()
                               .dropParameterTypes(0,1)
                               .changeReturnType(returnType);
 
--- a/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java	Tue Nov 17 10:29:28 2015 -0800
@@ -429,11 +429,8 @@
                 NF_checkCustomized = new NamedFunction(Invokers.class
                         .getDeclaredMethod("checkCustomized", Object.class))
             };
-            for (NamedFunction nf : nfs) {
-                // Each nf must be statically invocable or we get tied up in our bootstraps.
-                assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf;
-                nf.resolve();
-            }
+            // Each nf must be statically invocable or we get tied up in our bootstraps.
+            assert(InvokerBytecodeGenerator.isStaticallyInvocable(nfs));
         } catch (ReflectiveOperationException ex) {
             throw newInternalError(ex);
         }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java	Tue Nov 17 10:29:28 2015 -0800
@@ -1024,7 +1024,7 @@
 
     static class NamedFunction {
         final MemberName member;
-        @Stable MethodHandle resolvedHandle;
+        private @Stable MethodHandle resolvedHandle;
         @Stable MethodHandle invoker;
 
         NamedFunction(MethodHandle resolvedHandle) {
@@ -1074,8 +1074,10 @@
             return resolvedHandle;
         }
 
-        void resolve() {
-            resolvedHandle = DirectMethodHandle.make(member);
+        synchronized void resolve() {
+            if (resolvedHandle == null) {
+                resolvedHandle = DirectMethodHandle.make(member);
+            }
         }
 
         @Override
@@ -1235,6 +1237,7 @@
                     traceInterpreter("| getInvoker", this);
                     invoker();
                 }
+                // resolvedHandle might be uninitialized, ok for tracing
                 if (resolvedHandle == null) {
                     traceInterpreter("| resolve", this);
                     resolvedHandle();
@@ -1704,88 +1707,108 @@
     private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
 
     static LambdaForm identityForm(BasicType type) {
-        return LF_identityForm[type.ordinal()];
-    }
-    static LambdaForm zeroForm(BasicType type) {
-        return LF_zeroForm[type.ordinal()];
+        int ord = type.ordinal();
+        LambdaForm form = LF_identity[ord];
+        if (form != null) {
+            return form;
+        }
+        createFormsFor(type);
+        return LF_identity[ord];
     }
-    static NamedFunction identity(BasicType type) {
-        return NF_identity[type.ordinal()];
+
+    static LambdaForm zeroForm(BasicType type) {
+        int ord = type.ordinal();
+        LambdaForm form = LF_zero[ord];
+        if (form != null) {
+            return form;
+        }
+        createFormsFor(type);
+        return LF_zero[ord];
     }
-    static NamedFunction constantZero(BasicType type) {
-        return NF_zero[type.ordinal()];
+
+    static NamedFunction identity(BasicType type) {
+        int ord = type.ordinal();
+        NamedFunction function = NF_identity[ord];
+        if (function != null) {
+            return function;
+        }
+        createFormsFor(type);
+        return NF_identity[ord];
     }
-    private static final LambdaForm[] LF_identityForm = new LambdaForm[TYPE_LIMIT];
-    private static final LambdaForm[] LF_zeroForm = new LambdaForm[TYPE_LIMIT];
-    private static final NamedFunction[] NF_identity = new NamedFunction[TYPE_LIMIT];
-    private static final NamedFunction[] NF_zero = new NamedFunction[TYPE_LIMIT];
-    private static void createIdentityForms() {
-        for (BasicType type : BasicType.ALL_TYPES) {
-            int ord = type.ordinal();
-            char btChar = type.basicTypeChar();
-            boolean isVoid = (type == V_TYPE);
-            Class<?> btClass = type.btClass;
-            MethodType zeType = MethodType.methodType(btClass);
-            MethodType idType = isVoid ? zeType : zeType.appendParameterTypes(btClass);
+
+    static NamedFunction constantZero(BasicType type) {
+        int ord = type.ordinal();
+        NamedFunction function = NF_zero[ord];
+        if (function != null) {
+            return function;
+        }
+        createFormsFor(type);
+        return NF_zero[ord];
+    }
+
+    private static final @Stable LambdaForm[] LF_identity = new LambdaForm[TYPE_LIMIT];
+    private static final @Stable LambdaForm[] LF_zero = new LambdaForm[TYPE_LIMIT];
+    private static final @Stable NamedFunction[] NF_identity = new NamedFunction[TYPE_LIMIT];
+    private static final @Stable NamedFunction[] NF_zero = new NamedFunction[TYPE_LIMIT];
 
-            // Look up some symbolic names.  It might not be necessary to have these,
-            // but if we need to emit direct references to bytecodes, it helps.
-            // Zero is built from a call to an identity function with a constant zero input.
-            MemberName idMem = new MemberName(LambdaForm.class, "identity_"+btChar, idType, REF_invokeStatic);
-            MemberName zeMem = new MemberName(LambdaForm.class, "zero_"+btChar, zeType, REF_invokeStatic);
-            try {
+    private static synchronized void createFormsFor(BasicType type) {
+        final int ord = type.ordinal();
+        LambdaForm idForm = LF_identity[ord];
+        if (idForm != null) {
+            return;
+        }
+        char btChar = type.basicTypeChar();
+        boolean isVoid = (type == V_TYPE);
+        Class<?> btClass = type.btClass;
+        MethodType zeType = MethodType.methodType(btClass);
+        MethodType idType = (isVoid) ? zeType : zeType.appendParameterTypes(btClass);
+
+        // Look up symbolic names.  It might not be necessary to have these,
+        // but if we need to emit direct references to bytecodes, it helps.
+        // Zero is built from a call to an identity function with a constant zero input.
+        MemberName idMem = new MemberName(LambdaForm.class, "identity_"+btChar, idType, REF_invokeStatic);
+        MemberName zeMem = null;
+        try {
+            idMem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, idMem, null, NoSuchMethodException.class);
+            if (!isVoid) {
+                zeMem = new MemberName(LambdaForm.class, "zero_"+btChar, zeType, REF_invokeStatic);
                 zeMem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, zeMem, null, NoSuchMethodException.class);
-                idMem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, idMem, null, NoSuchMethodException.class);
-            } catch (IllegalAccessException|NoSuchMethodException ex) {
-                throw newInternalError(ex);
             }
-
-            NamedFunction idFun = new NamedFunction(idMem);
-            LambdaForm idForm;
-            if (isVoid) {
-                Name[] idNames = new Name[] { argument(0, L_TYPE) };
-                idForm = new LambdaForm(idMem.getName(), 1, idNames, VOID_RESULT);
-            } else {
-                Name[] idNames = new Name[] { argument(0, L_TYPE), argument(1, type) };
-                idForm = new LambdaForm(idMem.getName(), 2, idNames, 1);
-            }
-            LF_identityForm[ord] = idForm;
-            NF_identity[ord] = idFun;
-
-            NamedFunction zeFun = new NamedFunction(zeMem);
-            LambdaForm zeForm;
-            if (isVoid) {
-                zeForm = idForm;
-            } else {
-                Object zeValue = Wrapper.forBasicType(btChar).zero();
-                Name[] zeNames = new Name[] { argument(0, L_TYPE), new Name(idFun, zeValue) };
-                zeForm = new LambdaForm(zeMem.getName(), 1, zeNames, 1);
-            }
-            LF_zeroForm[ord] = zeForm;
-            NF_zero[ord] = zeFun;
-
-            assert(idFun.isIdentity());
-            assert(zeFun.isConstantZero());
-            assert(new Name(zeFun).isConstantZero());
+        } catch (IllegalAccessException|NoSuchMethodException ex) {
+            throw newInternalError(ex);
         }
 
-        // Do this in a separate pass, so that SimpleMethodHandle.make can see the tables.
-        for (BasicType type : BasicType.ALL_TYPES) {
-            int ord = type.ordinal();
-            NamedFunction idFun = NF_identity[ord];
-            LambdaForm idForm = LF_identityForm[ord];
-            MemberName idMem = idFun.member;
-            idFun.resolvedHandle = SimpleMethodHandle.make(idMem.getInvocationType(), idForm);
+        NamedFunction idFun;
+        LambdaForm zeForm;
+        NamedFunction zeFun;
+        if (isVoid) {
+            Name[] idNames = new Name[] { argument(0, L_TYPE) };
+            idForm = new LambdaForm(idMem.getName(), 1, idNames, VOID_RESULT);
+            idFun = new NamedFunction(idMem, SimpleMethodHandle.make(idMem.getInvocationType(), idForm));
+
+            assert(zeMem == null);
+            zeForm = idForm;
+            zeFun = idFun;
+        } else {
+            Name[] idNames = new Name[] { argument(0, L_TYPE), argument(1, type) };
+            idForm = new LambdaForm(idMem.getName(), 2, idNames, 1);
+            idFun = new NamedFunction(idMem, SimpleMethodHandle.make(idMem.getInvocationType(), idForm));
 
-            NamedFunction zeFun = NF_zero[ord];
-            LambdaForm zeForm = LF_zeroForm[ord];
-            MemberName zeMem = zeFun.member;
-            zeFun.resolvedHandle = SimpleMethodHandle.make(zeMem.getInvocationType(), zeForm);
+            assert(zeMem != null);
+            Object zeValue = Wrapper.forBasicType(btChar).zero();
+            Name[] zeNames = new Name[] { argument(0, L_TYPE), new Name(idFun, zeValue) };
+            zeForm = new LambdaForm(zeMem.getName(), 1, zeNames, 1);
+            zeFun = new NamedFunction(zeMem, SimpleMethodHandle.make(zeMem.getInvocationType(), zeForm));
+        }
 
-            assert(idFun.isIdentity());
-            assert(zeFun.isConstantZero());
-            assert(new Name(zeFun).isConstantZero());
-        }
+        LF_zero[ord] = zeForm;
+        NF_zero[ord] = zeFun;
+        LF_identity[ord] = idForm;
+        NF_identity[ord] = idFun;
+
+        assert(idFun.isIdentity());
+        assert(zeFun.isConstantZero());
+        assert(new Name(zeFun).isConstantZero());
     }
 
     // Avoid appealing to ValueConversions at bootstrap time:
@@ -1794,13 +1817,12 @@
     private static float identity_F(float x) { return x; }
     private static double identity_D(double x) { return x; }
     private static Object identity_L(Object x) { return x; }
-    private static void identity_V() { return; }  // same as zeroV, but that's OK
+    private static void identity_V() { return; }
     private static int zero_I() { return 0; }
     private static long zero_J() { return 0; }
     private static float zero_F() { return 0; }
     private static double zero_D() { return 0; }
     private static Object zero_L() { return null; }
-    private static void zero_V() { return; }
 
     /**
      * Internal marker for byte-compiled LambdaForms.
@@ -1830,7 +1852,6 @@
 
     // Put this last, so that previous static inits can run before.
     static {
-        createIdentityForms();
         if (USE_PREDEFINED_INTERPRET_METHODS)
             computeInitialPreparedForms();
         NamedFunction.initializeInvokers();
--- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java	Tue Nov 17 10:29:28 2015 -0800
@@ -541,7 +541,7 @@
         assert(pos > 0);  // cannot spread the MH arg itself
 
         Name spreadParam = new Name(L_TYPE);
-        Name checkSpread = new Name(MethodHandleImpl.Lazy.NF_checkSpreadArgument, spreadParam, arrayLength);
+        Name checkSpread = new Name(MethodHandleImpl.NF_checkSpreadArgument, spreadParam, arrayLength);
 
         // insert the new expressions
         int exprPos = lambdaForm.arity();
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Tue Nov 17 10:29:28 2015 -0800
@@ -219,7 +219,7 @@
             if (convSpec == null)  continue;
             MethodHandle fn;
             if (convSpec instanceof Class) {
-                fn = Lazy.MH_cast.bindTo(convSpec);
+                fn = getConstantHandle(MH_cast).bindTo(convSpec);
             } else {
                 fn = (MethodHandle) convSpec;
             }
@@ -239,7 +239,7 @@
                 if (convSpec == void.class)
                     fn = null;
                 else
-                    fn = Lazy.MH_cast.bindTo(convSpec);
+                    fn = getConstantHandle(MH_cast).bindTo(convSpec);
             } else {
                 fn = (MethodHandle) convSpec;
             }
@@ -302,7 +302,7 @@
             Name conv;
             if (convSpec instanceof Class) {
                 Class<?> convClass = (Class<?>) convSpec;
-                conv = new Name(Lazy.MH_cast, convClass, names[INARG_BASE + i]);
+                conv = new Name(getConstantHandle(MH_cast), convClass, names[INARG_BASE + i]);
             } else {
                 MethodHandle fn = (MethodHandle) convSpec;
                 conv = new Name(fn, names[INARG_BASE + i]);
@@ -326,7 +326,7 @@
                 conv = new Name(LambdaForm.constantZero(BasicType.basicType(srcType.returnType())));
             } else if (convSpec instanceof Class) {
                 Class<?> convClass = (Class<?>) convSpec;
-                conv = new Name(Lazy.MH_cast, convClass, names[OUT_CALL]);
+                conv = new Name(getConstantHandle(MH_cast), convClass, names[OUT_CALL]);
             } else {
                 MethodHandle fn = (MethodHandle) convSpec;
                 if (fn.type().parameterCount() == 0)
@@ -529,7 +529,7 @@
                 // Spread the array.
                 MethodHandle aload = MethodHandles.arrayElementGetter(spreadArgType);
                 Name array = names[argIndex];
-                names[nameCursor++] = new Name(Lazy.NF_checkSpreadArgument, array, spreadArgCount);
+                names[nameCursor++] = new Name(NF_checkSpreadArgument, array, spreadArgCount);
                 for (int j = 0; j < spreadArgCount; i++, j++) {
                     indexes[i] = nameCursor;
                     names[nameCursor++] = new Name(aload, array, j);
@@ -566,66 +566,6 @@
         throw newIllegalArgumentException("array is not of length "+n);
     }
 
-    /**
-     * Pre-initialized NamedFunctions for bootstrapping purposes.
-     * Factored in an inner class to delay initialization until first usage.
-     */
-    static class Lazy {
-        private static final Class<?> MHI = MethodHandleImpl.class;
-        private static final Class<?> CLS = Class.class;
-
-        private static final MethodHandle[] ARRAYS;
-        private static final MethodHandle[] FILL_ARRAYS;
-
-        static final NamedFunction NF_checkSpreadArgument;
-        static final NamedFunction NF_guardWithCatch;
-        static final NamedFunction NF_throwException;
-        static final NamedFunction NF_profileBoolean;
-
-        static final MethodHandle MH_cast;
-        static final MethodHandle MH_selectAlternative;
-        static final MethodHandle MH_copyAsPrimitiveArray;
-        static final MethodHandle MH_fillNewTypedArray;
-        static final MethodHandle MH_fillNewArray;
-        static final MethodHandle MH_arrayIdentity;
-
-        static {
-            ARRAYS      = makeArrays();
-            FILL_ARRAYS = makeFillArrays();
-
-            try {
-                NF_checkSpreadArgument = new NamedFunction(MHI.getDeclaredMethod("checkSpreadArgument", Object.class, int.class));
-                NF_guardWithCatch      = new NamedFunction(MHI.getDeclaredMethod("guardWithCatch", MethodHandle.class, Class.class,
-                                                                                 MethodHandle.class, Object[].class));
-                NF_throwException      = new NamedFunction(MHI.getDeclaredMethod("throwException", Throwable.class));
-                NF_profileBoolean      = new NamedFunction(MHI.getDeclaredMethod("profileBoolean", boolean.class, int[].class));
-
-                NF_checkSpreadArgument.resolve();
-                NF_guardWithCatch.resolve();
-                NF_throwException.resolve();
-                NF_profileBoolean.resolve();
-
-                MH_cast                 = IMPL_LOOKUP.findVirtual(CLS, "cast",
-                                            MethodType.methodType(Object.class, Object.class));
-                MH_copyAsPrimitiveArray = IMPL_LOOKUP.findStatic(MHI, "copyAsPrimitiveArray",
-                                            MethodType.methodType(Object.class, Wrapper.class, Object[].class));
-                MH_arrayIdentity        = IMPL_LOOKUP.findStatic(MHI, "identity",
-                                            MethodType.methodType(Object[].class, Object[].class));
-                MH_fillNewArray         = IMPL_LOOKUP.findStatic(MHI, "fillNewArray",
-                                            MethodType.methodType(Object[].class, Integer.class, Object[].class));
-                MH_fillNewTypedArray    = IMPL_LOOKUP.findStatic(MHI, "fillNewTypedArray",
-                                            MethodType.methodType(Object[].class, Object[].class, Integer.class, Object[].class));
-
-                MH_selectAlternative    = makeIntrinsic(
-                        IMPL_LOOKUP.findStatic(MHI, "selectAlternative",
-                                MethodType.methodType(MethodHandle.class, boolean.class, MethodHandle.class, MethodHandle.class)),
-                        Intrinsic.SELECT_ALTERNATIVE);
-            } catch (ReflectiveOperationException ex) {
-                throw newInternalError(ex);
-            }
-        }
-    }
-
     /** Factory method:  Collect or filter selected argument(s). */
     static MethodHandle makeCollectArguments(MethodHandle target,
                 MethodHandle collector, int collectArgPos, boolean retainOriginalArgs) {
@@ -911,10 +851,10 @@
 
         // profile branch
         if (PROFILE != -1) {
-            names[PROFILE] = new Name(Lazy.NF_profileBoolean, names[CALL_TEST], names[GET_COUNTERS]);
+            names[PROFILE] = new Name(NF_profileBoolean, names[CALL_TEST], names[GET_COUNTERS]);
         }
         // call selectAlternative
-        names[SELECT_ALT] = new Name(Lazy.MH_selectAlternative, names[TEST], names[GET_TARGET], names[GET_FALLBACK]);
+        names[SELECT_ALT] = new Name(getConstantHandle(MH_selectAlternative), names[TEST], names[GET_TARGET], names[GET_FALLBACK]);
 
         // call target or fallback
         invokeArgs[0] = names[SELECT_ALT];
@@ -989,7 +929,7 @@
 
         // t_{i+1}:L=MethodHandleImpl.guardWithCatch(target:L,exType:L,catcher:L,t_{i}:L);
         Object[] gwcArgs = new Object[] {names[GET_TARGET], names[GET_CLASS], names[GET_CATCHER], names[BOXED_ARGS]};
-        names[TRY_CATCH] = new Name(Lazy.NF_guardWithCatch, gwcArgs);
+        names[TRY_CATCH] = new Name(NF_guardWithCatch, gwcArgs);
 
         // t_{i+2}:I=MethodHandle.invokeBasic(unbox:L,t_{i+1}:L);
         MethodHandle invokeBasicUnbox = MethodHandles.basicInvoker(MethodType.methodType(basicType.rtype(), Object.class));
@@ -1073,7 +1013,7 @@
             mh = MethodHandles.dropArguments(mh, 1, type.parameterList().subList(1, arity));
             return mh;
         }
-        return makePairwiseConvert(Lazy.NF_throwException.resolvedHandle(), type, false, true);
+        return makePairwiseConvert(NF_throwException.resolvedHandle(), type, false, true);
     }
 
     static <T extends Throwable> Empty throwException(T t) throws T { throw t; }
@@ -1421,25 +1361,7 @@
                 { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
 
     private static final int ARRAYS_COUNT = 11;
-
-    private static MethodHandle[] makeArrays() {
-        MethodHandle[] mhs = new MethodHandle[MAX_ARITY + 1];
-        for (int i = 0; i < ARRAYS_COUNT; i++) {
-            MethodHandle mh = findCollector("array", i, Object[].class);
-            mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY);
-            mhs[i] = mh;
-        }
-        assert(assertArrayMethodCount(mhs));
-        return mhs;
-    }
-
-    private static boolean assertArrayMethodCount(MethodHandle[] mhs) {
-        assert(findCollector("array", ARRAYS_COUNT, Object[].class) == null);
-        for (int i = 0; i < ARRAYS_COUNT; i++) {
-            assert(mhs[i] != null);
-        }
-        return true;
-    }
+    private static final @Stable MethodHandle[] ARRAYS = new MethodHandle[MAX_ARITY + 1];
 
     // filling versions of the above:
     // using Integer len instead of int len and no varargs to avoid bootstrapping problems
@@ -1488,24 +1410,17 @@
                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); return a; }
 
     private static final int FILL_ARRAYS_COUNT = 11; // current number of fillArray methods
+    private static final @Stable MethodHandle[] FILL_ARRAYS = new MethodHandle[FILL_ARRAYS_COUNT];
 
-    private static MethodHandle[] makeFillArrays() {
-        MethodHandle[] mhs = new MethodHandle[FILL_ARRAYS_COUNT];
-        mhs[0] = null;  // there is no empty fill; at least a0 is required
-        for (int i = 1; i < FILL_ARRAYS_COUNT; i++) {
-            MethodHandle mh = findCollector("fillArray", i, Object[].class, Integer.class, Object[].class);
-            mhs[i] = mh;
+    private static MethodHandle getFillArray(int count) {
+        assert (count > 0 && count < FILL_ARRAYS_COUNT);
+        MethodHandle mh = FILL_ARRAYS[count];
+        if (mh != null) {
+            return mh;
         }
-        assert(assertFillArrayMethodCount(mhs));
-        return mhs;
-    }
-
-    private static boolean assertFillArrayMethodCount(MethodHandle[] mhs) {
-        assert(findCollector("fillArray", FILL_ARRAYS_COUNT, Object[].class, Integer.class, Object[].class) == null);
-        for (int i = 1; i < FILL_ARRAYS_COUNT; i++) {
-            assert(mhs[i] != null);
-        }
-        return true;
+        mh = findCollector("fillArray", count, Object[].class, Integer.class, Object[].class);
+        FILL_ARRAYS[count] = mh;
+        return mh;
     }
 
     private static Object copyAsPrimitiveArray(Wrapper w, Object... boxes) {
@@ -1518,12 +1433,19 @@
      *  arguments and returns an Object array of them, as if for varargs.
      */
     static MethodHandle varargsArray(int nargs) {
-        MethodHandle mh = Lazy.ARRAYS[nargs];
-        if (mh != null)  return mh;
-        mh = buildVarargsArray(Lazy.MH_fillNewArray, Lazy.MH_arrayIdentity, nargs);
+        MethodHandle mh = ARRAYS[nargs];
+        if (mh != null) {
+            return mh;
+        }
+        if (nargs < ARRAYS_COUNT) {
+            mh = findCollector("array", nargs, Object[].class);
+        } else {
+            mh = buildVarargsArray(getConstantHandle(MH_fillNewArray),
+                    getConstantHandle(MH_arrayIdentity), nargs);
+        }
         assert(assertCorrectArity(mh, nargs));
         mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY);
-        return Lazy.ARRAYS[nargs] = mh;
+        return ARRAYS[nargs] = mh;
     }
 
     private static boolean assertCorrectArity(MethodHandle mh, int arity) {
@@ -1531,7 +1453,7 @@
         return true;
     }
 
-    // Array identity function (used as Lazy.MH_arrayIdentity).
+    // Array identity function (used as getConstantHandle(MH_arrayIdentity)).
     static <T> T[] identity(T[] x) {
         return x;
     }
@@ -1547,12 +1469,12 @@
         MethodHandle mh = finisher;
         if (rightLen > 0) {
             MethodHandle rightFiller = fillToRight(LEFT_ARGS + rightLen);
-            if (mh == Lazy.MH_arrayIdentity)
+            if (mh.equals(getConstantHandle(MH_arrayIdentity)))
                 mh = rightFiller;
             else
                 mh = MethodHandles.collectArguments(mh, 0, rightFiller);
         }
-        if (mh == Lazy.MH_arrayIdentity)
+        if (mh.equals(getConstantHandle(MH_arrayIdentity)))
             mh = leftCollector;
         else
             mh = MethodHandles.collectArguments(mh, 0, leftCollector);
@@ -1560,7 +1482,7 @@
     }
 
     private static final int LEFT_ARGS = FILL_ARRAYS_COUNT - 1;
-    private static final MethodHandle[] FILL_ARRAY_TO_RIGHT = new MethodHandle[MAX_ARITY+1];
+    private static final @Stable MethodHandle[] FILL_ARRAY_TO_RIGHT = new MethodHandle[MAX_ARITY+1];
     /** fill_array_to_right(N).invoke(a, argL..arg[N-1])
      *  fills a[L]..a[N-1] with corresponding arguments,
      *  and then returns a.  The value L is a global constant (LEFT_ARGS).
@@ -1574,7 +1496,7 @@
     }
     private static MethodHandle buildFiller(int nargs) {
         if (nargs <= LEFT_ARGS)
-            return Lazy.MH_arrayIdentity;  // no args to fill; return the array unchanged
+            return getConstantHandle(MH_arrayIdentity);  // no args to fill; return the array unchanged
         // we need room for both mh and a in mh.invoke(a, arg*[nargs])
         final int CHUNK = LEFT_ARGS;
         int rightLen = nargs % CHUNK;
@@ -1590,7 +1512,7 @@
         if (midLen < LEFT_ARGS) rightLen = nargs - (midLen = LEFT_ARGS);
         assert(rightLen > 0);
         MethodHandle midFill = fillToRight(midLen);  // recursive fill
-        MethodHandle rightFill = Lazy.FILL_ARRAYS[rightLen].bindTo(midLen);  // [midLen..nargs-1]
+        MethodHandle rightFill = getFillArray(rightLen).bindTo(midLen);  // [midLen..nargs-1]
         assert(midFill.type().parameterCount()   == 1 + midLen - LEFT_ARGS);
         assert(rightFill.type().parameterCount() == 1 + rightLen);
 
@@ -1641,14 +1563,14 @@
             Object example = java.lang.reflect.Array.newInstance(arrayType.getComponentType(), 0);
             mh = MethodHandles.constant(arrayType, example);
         } else if (elemType.isPrimitive()) {
-            MethodHandle builder = Lazy.MH_fillNewArray;
+            MethodHandle builder = getConstantHandle(MH_fillNewArray);
             MethodHandle producer = buildArrayProducer(arrayType);
             mh = buildVarargsArray(builder, producer, nargs);
         } else {
             Class<? extends Object[]> objArrayType = arrayType.asSubclass(Object[].class);
             Object[] example = Arrays.copyOf(NO_ARGS_ARRAY, 0, objArrayType);
-            MethodHandle builder = Lazy.MH_fillNewTypedArray.bindTo(example);
-            MethodHandle producer = Lazy.MH_arrayIdentity; // must be weakly typed
+            MethodHandle builder = getConstantHandle(MH_fillNewTypedArray).bindTo(example);
+            MethodHandle producer = getConstantHandle(MH_arrayIdentity); // must be weakly typed
             mh = buildVarargsArray(builder, producer, nargs);
         }
         mh = mh.asType(MethodType.methodType(arrayType, Collections.<Class<?>>nCopies(nargs, elemType)));
@@ -1662,7 +1584,7 @@
     private static MethodHandle buildArrayProducer(Class<?> arrayType) {
         Class<?> elemType = arrayType.getComponentType();
         assert(elemType.isPrimitive());
-        return Lazy.MH_copyAsPrimitiveArray.bindTo(Wrapper.forPrimitiveType(elemType));
+        return getConstantHandle(MH_copyAsPrimitiveArray).bindTo(Wrapper.forPrimitiveType(elemType));
     }
 
     /*non-public*/ static void assertSame(Object mh1, Object mh2) {
@@ -1673,4 +1595,87 @@
             throw newInternalError(msg);
         }
     }
+
+    // Local constant functions:
+    /*non-public*/ static final NamedFunction
+        NF_checkSpreadArgument,
+        NF_guardWithCatch,
+        NF_throwException,
+        NF_profileBoolean;
+
+    static {
+        try {
+            NF_checkSpreadArgument = new NamedFunction(MethodHandleImpl.class
+                    .getDeclaredMethod("checkSpreadArgument", Object.class, int.class));
+            NF_guardWithCatch = new NamedFunction(MethodHandleImpl.class
+                    .getDeclaredMethod("guardWithCatch", MethodHandle.class, Class.class,
+                            MethodHandle.class, Object[].class));
+            NF_throwException = new NamedFunction(MethodHandleImpl.class
+                    .getDeclaredMethod("throwException", Throwable.class));
+            NF_profileBoolean = new NamedFunction(MethodHandleImpl.class
+                    .getDeclaredMethod("profileBoolean", boolean.class, int[].class));
+        } catch (ReflectiveOperationException ex) {
+            throw newInternalError(ex);
+        }
+    }
+
+    // Indexes into constant method handles:
+    private static final int
+            MH_cast                  =  0,
+            MH_selectAlternative     =  1,
+            MH_copyAsPrimitiveArray  =  2,
+            MH_fillNewTypedArray     =  3,
+            MH_fillNewArray          =  4,
+            MH_arrayIdentity         =  5,
+            MH_LIMIT                 =  6;
+
+    private static MethodHandle getConstantHandle(int idx) {
+        MethodHandle handle = HANDLES[idx];
+        if (handle != null) {
+            return handle;
+        }
+        return setCachedHandle(idx, makeConstantHandle(idx));
+    }
+
+    private static synchronized MethodHandle setCachedHandle(int idx, final MethodHandle method) {
+        // Simulate a CAS, to avoid racy duplication of results.
+        MethodHandle prev = HANDLES[idx];
+        if (prev != null) {
+            return prev;
+        }
+        HANDLES[idx] = method;
+        return method;
+    }
+
+    // Local constant method handles:
+    private static final @Stable MethodHandle[] HANDLES = new MethodHandle[MH_LIMIT];
+
+    private static MethodHandle makeConstantHandle(int idx) {
+        try {
+            switch (idx) {
+                case MH_cast:
+                    return IMPL_LOOKUP.findVirtual(Class.class, "cast",
+                            MethodType.methodType(Object.class, Object.class));
+                case MH_copyAsPrimitiveArray:
+                    return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "copyAsPrimitiveArray",
+                            MethodType.methodType(Object.class, Wrapper.class, Object[].class));
+                case MH_arrayIdentity:
+                    return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "identity",
+                            MethodType.methodType(Object[].class, Object[].class));
+                case MH_fillNewArray:
+                    return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "fillNewArray",
+                            MethodType.methodType(Object[].class, Integer.class, Object[].class));
+                case MH_fillNewTypedArray:
+                    return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "fillNewTypedArray",
+                            MethodType.methodType(Object[].class, Object[].class, Integer.class, Object[].class));
+                case MH_selectAlternative:
+                    return makeIntrinsic(IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "selectAlternative",
+                            MethodType.methodType(MethodHandle.class, boolean.class, MethodHandle.class, MethodHandle.class)),
+                        Intrinsic.SELECT_ALTERNATIVE);
+            }
+        } catch (ReflectiveOperationException ex) {
+            throw newInternalError(ex);
+        }
+        throw newInternalError("Unknown function index: " + idx);
+    }
 }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java	Tue Nov 17 10:29:28 2015 -0800
@@ -50,7 +50,7 @@
     static native int getMembers(Class<?> defc, String matchName, String matchSig,
             int matchFlags, Class<?> caller, int skip, MemberName[] results);
 
-    /// Field layout queries parallel to sun.misc.Unsafe:
+    /// Field layout queries parallel to jdk.internal.misc.Unsafe:
     static native long objectFieldOffset(MemberName self);  // e.g., returns vmindex
     static native long staticFieldOffset(MemberName self);  // e.g., returns vmindex
     static native Object staticFieldBase(MemberName self);  // e.g., returns clazz
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java	Tue Nov 17 10:29:28 2015 -0800
@@ -27,7 +27,7 @@
 
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 /**
  * This class consists exclusively of static names internal to the
--- a/jdk/src/java.base/share/classes/java/math/BigDecimal.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/math/BigDecimal.java	Tue Nov 17 10:29:28 2015 -0800
@@ -3726,12 +3726,12 @@
     }
 
     private static class UnsafeHolder {
-        private static final sun.misc.Unsafe unsafe;
+        private static final jdk.internal.misc.Unsafe unsafe;
         private static final long intCompactOffset;
         private static final long intValOffset;
         static {
             try {
-                unsafe = sun.misc.Unsafe.getUnsafe();
+                unsafe = jdk.internal.misc.Unsafe.getUnsafe();
                 intCompactOffset = unsafe.objectFieldOffset
                     (BigDecimal.class.getDeclaredField("intCompact"));
                 intValOffset = unsafe.objectFieldOffset
--- a/jdk/src/java.base/share/classes/java/math/BigInteger.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/math/BigInteger.java	Tue Nov 17 10:29:28 2015 -0800
@@ -4526,12 +4526,12 @@
 
     // Support for resetting final fields while deserializing
     private static class UnsafeHolder {
-        private static final sun.misc.Unsafe unsafe;
+        private static final jdk.internal.misc.Unsafe unsafe;
         private static final long signumOffset;
         private static final long magOffset;
         static {
             try {
-                unsafe = sun.misc.Unsafe.getUnsafe();
+                unsafe = jdk.internal.misc.Unsafe.getUnsafe();
                 signumOffset = unsafe.objectFieldOffset
                     (BigInteger.class.getDeclaredField("signum"));
                 magOffset = unsafe.objectFieldOffset
--- a/jdk/src/java.base/share/classes/java/net/Inet6Address.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/net/Inet6Address.java	Tue Nov 17 10:29:28 2015 -0800
@@ -576,11 +576,11 @@
     };
 
     private static final long FIELDS_OFFSET;
-    private static final sun.misc.Unsafe UNSAFE;
+    private static final jdk.internal.misc.Unsafe UNSAFE;
 
     static {
         try {
-            sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
+            jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe();
             FIELDS_OFFSET = unsafe.objectFieldOffset(
                     Inet6Address.class.getDeclaredField("holder6"));
             UNSAFE = unsafe;
--- a/jdk/src/java.base/share/classes/java/net/InetAddress.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/net/InetAddress.java	Tue Nov 17 10:29:28 2015 -0800
@@ -29,6 +29,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.ArrayList;
+import java.util.Objects;
 import java.util.ServiceLoader;
 import java.security.AccessController;
 import java.io.ObjectStreamException;
@@ -733,7 +734,7 @@
      */
     public String toString() {
         String hostName = holder().getHostName();
-        return ((hostName != null) ? hostName : "")
+        return Objects.toString(hostName, "")
             + "/" + getHostAddress();
     }
 
@@ -1493,11 +1494,11 @@
     }
 
     private static final long FIELDS_OFFSET;
-    private static final sun.misc.Unsafe UNSAFE;
+    private static final jdk.internal.misc.Unsafe UNSAFE;
 
     static {
         try {
-            sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
+            jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe();
             FIELDS_OFFSET = unsafe.objectFieldOffset(
                 InetAddress.class.getDeclaredField("holder")
             );
--- a/jdk/src/java.base/share/classes/java/net/InetSocketAddress.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/net/InetSocketAddress.java	Tue Nov 17 10:29:28 2015 -0800
@@ -303,10 +303,10 @@
     }
 
     private static final long FIELDS_OFFSET;
-    private static final sun.misc.Unsafe UNSAFE;
+    private static final jdk.internal.misc.Unsafe UNSAFE;
     static {
         try {
-            sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
+            jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe();
             FIELDS_OFFSET = unsafe.objectFieldOffset(
                     InetSocketAddress.class.getDeclaredField("holder"));
             UNSAFE = unsafe;
--- a/jdk/src/java.base/share/classes/java/net/SocketOptions.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/net/SocketOptions.java	Tue Nov 17 10:29:28 2015 -0800
@@ -61,21 +61,21 @@
      * If the requested option is binary, it can be set using this method by
      * a java.lang.Boolean:
      * <BR><PRE>
-     * s.setOption(TCP_NODELAY, new Boolean(true));
+     * s.setOption(TCP_NODELAY, Boolean.TRUE);
      *    // OK - enables TCP_NODELAY, a binary option
      * </PRE>
      * <BR>
-     * Any option can be disabled using this method with a Boolean(false):
+     * Any option can be disabled using this method with a Boolean.FALSE:
      * <BR><PRE>
-     * s.setOption(TCP_NODELAY, new Boolean(false));
+     * s.setOption(TCP_NODELAY, Boolean.FALSE);
      *    // OK - disables TCP_NODELAY
-     * s.setOption(SO_LINGER, new Boolean(false));
+     * s.setOption(SO_LINGER, Boolean.FALSE);
      *    // OK - disables SO_LINGER
      * </PRE>
      * <BR>
      * For an option that has a notion of on and off, and requires
      * a non-boolean parameter, setting its value to anything other than
-     * <I>Boolean(false)</I> implicitly enables it.
+     * <I>Boolean.FALSE</I> implicitly enables it.
      * <BR>
      * Throws SocketException if the option is unrecognized,
      * the socket is closed, or some low-level error occurred
@@ -91,8 +91,8 @@
 
     /**
      * Fetch the value of an option.
-     * Binary options will return java.lang.Boolean(true)
-     * if enabled, java.lang.Boolean(false) if disabled, e.g.:
+     * Binary options will return java.lang.Boolean.TRUE
+     * if enabled, java.lang.Boolean.FALSE if disabled, e.g.:
      * <BR><PRE>
      * SocketImpl s;
      * ...
@@ -105,13 +105,13 @@
      * <P>
      * For options that take a particular type as a parameter,
      * getOption(int) will return the parameter's value, else
-     * it will return java.lang.Boolean(false):
+     * it will return java.lang.Boolean.FALSE:
      * <PRE>
      * Object o = s.getOption(SO_LINGER);
      * if (o instanceof Integer) {
      *     System.out.print("Linger time is " + ((Integer)o).intValue());
      * } else {
-     *   // the true type of o is java.lang.Boolean(false);
+     *   // the true type of o is java.lang.Boolean.FALSE;
      * }
      * </PRE>
      *
--- a/jdk/src/java.base/share/classes/java/net/URLConnection.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/net/URLConnection.java	Tue Nov 17 10:29:28 2015 -0800
@@ -32,6 +32,7 @@
 import java.util.Hashtable;
 import java.util.Date;
 import java.util.Iterator;
+import java.util.Objects;
 import java.util.ServiceConfigurationError;
 import java.util.ServiceLoader;
 import java.util.StringTokenizer;
@@ -1250,7 +1251,7 @@
 
         if (handler != null) {
             ContentHandler h = handlers.putIfAbsent(contentType, handler);
-            return h != null ? h : handler;
+            return Objects.requireNonNullElse(h, handler);
         }
 
         try {
@@ -1263,7 +1264,7 @@
         assert handler != null;
 
         ContentHandler h = handlers.putIfAbsent(contentType, handler);
-        return h != null ? h : handler;
+        return Objects.requireNonNullElse(h, handler);
     }
 
     /*
--- a/jdk/src/java.base/share/classes/java/nio/Bits.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/nio/Bits.java	Tue Nov 17 10:29:28 2015 -0800
@@ -32,7 +32,7 @@
 import jdk.internal.misc.JavaNioAccess;
 import jdk.internal.misc.JavaLangRefAccess;
 import jdk.internal.misc.SharedSecrets;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 import sun.misc.VM;
 
 /**
--- a/jdk/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template	Tue Nov 17 10:29:28 2015 -0800
@@ -29,7 +29,7 @@
 
 import java.io.FileDescriptor;
 import sun.misc.Cleaner;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 import sun.misc.VM;
 import sun.nio.ch.DirectBuffer;
 
--- a/jdk/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template	Tue Nov 17 10:29:28 2015 -0800
@@ -27,7 +27,7 @@
 
 package java.nio;
 
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 /**
 #if[rw]
@@ -477,7 +477,7 @@
 #if[rw]
 
     public float getFloat() {
-        int x = unsafe.getIntUnaligned(hb, byteOffset(nextPutIndex(4)), bigEndian);
+        int x = unsafe.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian);
         return Float.intBitsToFloat(x);
     }
 
--- a/jdk/src/java.base/share/classes/java/nio/MappedByteBuffer.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/nio/MappedByteBuffer.java	Tue Nov 17 10:29:28 2015 -0800
@@ -26,7 +26,7 @@
 package java.nio;
 
 import java.io.FileDescriptor;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 
 /**
--- a/jdk/src/java.base/share/classes/java/nio/charset/Charset.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/nio/charset/Charset.java	Tue Nov 17 10:29:28 2015 -0800
@@ -37,6 +37,7 @@
 import java.util.Locale;
 import java.util.Map;
 import java.util.NoSuchElementException;
+import java.util.Objects;
 import java.util.Set;
 import java.util.ServiceLoader;
 import java.util.ServiceConfigurationError;
@@ -625,6 +626,7 @@
 
     private final String name;          // tickles a bug in oldjavac
     private final String[] aliases;     // tickles a bug in oldjavac
+    private final String[] zeroAliases = new String[0];
     private Set<String> aliasSet = null;
 
     /**
@@ -642,7 +644,7 @@
      */
     protected Charset(String canonicalName, String[] aliases) {
         checkName(canonicalName);
-        String[] as = (aliases == null) ? new String[0] : aliases;
+        String[] as = Objects.requireNonNullElse(aliases, zeroAliases);
         for (int i = 0; i < as.length; i++)
             checkName(as[i]);
         this.name = canonicalName;
--- a/jdk/src/java.base/share/classes/java/security/SecureRandom.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/security/SecureRandom.java	Tue Nov 17 10:29:28 2015 -0800
@@ -419,7 +419,7 @@
      * @since 1.5
      */
     public String getAlgorithm() {
-        return (algorithm != null) ? algorithm : "unknown";
+        return Objects.toString(algorithm, "unknown");
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/time/Clock.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/time/Clock.java	Tue Nov 17 10:29:28 2015 -0800
@@ -65,7 +65,7 @@
 import java.io.ObjectInputStream;
 import static java.time.LocalTime.NANOS_PER_MINUTE;
 import static java.time.LocalTime.NANOS_PER_SECOND;
-
+import static java.time.LocalTime.NANOS_PER_MILLI;
 import java.io.Serializable;
 import java.util.Objects;
 import java.util.TimeZone;
@@ -182,7 +182,7 @@
     }
 
     /**
-     * Obtains a clock that returns the current instant using best available
+     * Obtains a clock that returns the current instant using the best available
      * system clock.
      * <p>
      * This clock is based on the best available system clock.
@@ -206,8 +206,32 @@
 
     //-------------------------------------------------------------------------
     /**
+     * Obtains a clock that returns the current instant ticking in whole milliseconds
+     * using the best available system clock.
+     * <p>
+     * This clock will always have the nano-of-second field truncated to milliseconds.
+     * This ensures that the visible time ticks in whole milliseconds.
+     * The underlying clock is the best available system clock, equivalent to
+     * using {@link #system(ZoneId)}.
+     * <p>
+     * Implementations may use a caching strategy for performance reasons.
+     * As such, it is possible that the start of the millisecond observed via this
+     * clock will be later than that observed directly via the underlying clock.
+     * <p>
+     * The returned implementation is immutable, thread-safe and {@code Serializable}.
+     * It is equivalent to {@code tick(system(zone), Duration.ofMillis(1))}.
+     *
+     * @param zone  the time-zone to use to convert the instant to date-time, not null
+     * @return a clock that ticks in whole milliseconds using the specified zone, not null
+     */
+    public static Clock tickMillis(ZoneId zone) {
+        return new TickClock(system(zone), NANOS_PER_MILLI);
+    }
+
+    //-------------------------------------------------------------------------
+    /**
      * Obtains a clock that returns the current instant ticking in whole seconds
-     * using best available system clock.
+     * using the best available system clock.
      * <p>
      * This clock will always have the nano-of-second field set to zero.
      * This ensures that the visible time ticks in whole seconds.
@@ -230,7 +254,7 @@
 
     /**
      * Obtains a clock that returns the current instant ticking in whole minutes
-     * using best available system clock.
+     * using the best available system clock.
      * <p>
      * This clock will always have the nano-of-second and second-of-minute fields set to zero.
      * This ensures that the visible time ticks in whole minutes.
--- a/jdk/src/java.base/share/classes/java/time/Duration.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/time/Duration.java	Tue Nov 17 10:29:28 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
@@ -359,8 +359,8 @@
      * there must be at least one section after the "T".
      * The number part of each section must consist of one or more ASCII digits.
      * The number may be prefixed by the ASCII negative or positive symbol.
-     * The number of days, hours and minutes must parse to an {@code long}.
-     * The number of seconds must parse to an {@code long} with optional fraction.
+     * The number of days, hours and minutes must parse to a {@code long}.
+     * The number of seconds must parse to a {@code long} with optional fraction.
      * The decimal point may be either a dot or a comma.
      * The fractional part may have from zero to 9 digits.
      * <p>
@@ -374,9 +374,9 @@
      *    "PT10H"     -- parses as "10 hours" (where an hour is 3600 seconds)
      *    "P2D"       -- parses as "2 days" (where a day is 24 hours or 86400 seconds)
      *    "P2DT3H4M"  -- parses as "2 days, 3 hours and 4 minutes"
-     *    "P-6H3M"    -- parses as "-6 hours and +3 minutes"
-     *    "-P6H3M"    -- parses as "-6 hours and -3 minutes"
-     *    "-P-6H+3M"  -- parses as "+6 hours and -3 minutes"
+     *    "PT-6H3M"    -- parses as "-6 hours and +3 minutes"
+     *    "-PT6H3M"    -- parses as "-6 hours and -3 minutes"
+     *    "-PT-6H+3M"  -- parses as "+6 hours and -3 minutes"
      * </pre>
      *
      * @param text  the text to parse, not null
@@ -402,7 +402,8 @@
                     long hoursAsSecs = parseNumber(text, hourStart, hourEnd, SECONDS_PER_HOUR, "hours");
                     long minsAsSecs = parseNumber(text, minuteStart, minuteEnd, SECONDS_PER_MINUTE, "minutes");
                     long seconds = parseNumber(text, secondStart, secondEnd, 1, "seconds");
-                    int nanos = parseFraction(text, fractionStart, fractionEnd, seconds < 0 ? -1 : 1);
+                    boolean negativeSecs = secondStart >= 0 && text.charAt(secondStart) == '-';
+                    int nanos = parseFraction(text, fractionStart, fractionEnd, negativeSecs ? -1 : 1);
                     try {
                         return create(negate, daysAsSecs, hoursAsSecs, minsAsSecs, seconds, nanos);
                     } catch (ArithmeticException ex) {
--- a/jdk/src/java.base/share/classes/java/time/LocalDate.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/time/LocalDate.java	Tue Nov 17 10:29:28 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
@@ -81,7 +81,7 @@
 import java.io.ObjectInputStream;
 import java.io.Serializable;
 import java.time.chrono.ChronoLocalDate;
-import java.time.chrono.Era;
+import java.time.chrono.IsoEra;
 import java.time.chrono.IsoChronology;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeParseException;
@@ -220,12 +220,8 @@
      */
     public static LocalDate now(Clock clock) {
         Objects.requireNonNull(clock, "clock");
-        // inline to avoid creating object and Instant checks
         final Instant now = clock.instant();  // called once
-        ZoneOffset offset = clock.getZone().getRules().getOffset(now);
-        long epochSec = now.getEpochSecond() + offset.getTotalSeconds();  // overflow caught later
-        long epochDay = Math.floorDiv(epochSec, SECONDS_PER_DAY);
-        return LocalDate.ofEpochDay(epochDay);
+        return ofInstant(now, clock.getZone());
     }
 
     //-----------------------------------------------------------------------
@@ -300,6 +296,30 @@
 
     //-----------------------------------------------------------------------
     /**
+     * Obtains an instance of {@code LocalDate} from an {@code Instant} and zone ID.
+     * <p>
+     * This creates a local date based on the specified instant.
+     * First, the offset from UTC/Greenwich is obtained using the zone ID and instant,
+     * which is simple as there is only one valid offset for each instant.
+     * Then, the instant and offset are used to calculate the local date.
+     *
+     * @param instant  the instant to create the date from, not null
+     * @param zone  the time-zone, which may be an offset, not null
+     * @return the local date, not null
+     * @throws DateTimeException if the result exceeds the supported range
+     */
+    public static LocalDate ofInstant(Instant instant, ZoneId zone) {
+        Objects.requireNonNull(instant, "instant");
+        Objects.requireNonNull(zone, "zone");
+        ZoneRules rules = zone.getRules();
+        ZoneOffset offset = rules.getOffset(instant);
+        long localSecond = instant.getEpochSecond() + offset.getTotalSeconds();
+        long localEpochDay = Math.floorDiv(localSecond, SECONDS_PER_DAY);
+        return ofEpochDay(localEpochDay);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
      * Obtains an instance of {@code LocalDate} from the epoch day count.
      * <p>
      * This returns a {@code LocalDate} with the specified epoch-day.
@@ -712,15 +732,12 @@
      * Users of this class should typically ignore this method as it exists primarily
      * to fulfill the {@link ChronoLocalDate} contract where it is necessary to support
      * the Japanese calendar system.
-     * <p>
-     * The returned era will be a singleton capable of being compared with the constants
-     * in {@link IsoChronology} using the {@code ==} operator.
      *
-     * @return the {@code IsoChronology} era constant applicable at this date, not null
+     * @return the IsoEra applicable at this date, not null
      */
     @Override // override for Javadoc
-    public Era getEra() {
-        return ChronoLocalDate.super.getEra();
+    public IsoEra getEra() {
+        return (getYear() >= 1 ? IsoEra.CE : IsoEra.BCE);
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/time/LocalTime.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/time/LocalTime.java	Tue Nov 17 10:29:28 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
@@ -190,9 +190,13 @@
      */
     static final long MICROS_PER_DAY = SECONDS_PER_DAY * 1000_000L;
     /**
+     * Nanos per millisecond.
+     */
+    static final long NANOS_PER_MILLI = 1000_000L;
+    /**
      * Nanos per second.
      */
-    static final long NANOS_PER_SECOND = 1000_000_000L;
+    static final long NANOS_PER_SECOND =  1000_000_000L;
     /**
      * Nanos per minute.
      */
@@ -272,12 +276,8 @@
      */
     public static LocalTime now(Clock clock) {
         Objects.requireNonNull(clock, "clock");
-        // inline OffsetTime factory to avoid creating object and InstantProvider checks
         final Instant now = clock.instant();  // called once
-        ZoneOffset offset = clock.getZone().getRules().getOffset(now);
-        long localSecond = now.getEpochSecond() + offset.getTotalSeconds();  // overflow caught later
-        int secsOfDay = (int) Math.floorMod(localSecond, SECONDS_PER_DAY);
-        return ofNanoOfDay(secsOfDay * NANOS_PER_SECOND + now.getNano());
+        return ofInstant(now, clock.getZone());
     }
 
     //-----------------------------------------------------------------------
@@ -343,6 +343,27 @@
         return create(hour, minute, second, nanoOfSecond);
     }
 
+    /**
+     * Obtains an instance of {@code LocalTime} from an {@code Instant} and zone ID.
+     * <p>
+     * This creates a local time based on the specified instant.
+     * First, the offset from UTC/Greenwich is obtained using the zone ID and instant,
+     * which is simple as there is only one valid offset for each instant.
+     * Then, the instant and offset are used to calculate the local time.
+     *
+     * @param instant  the instant to create the time from, not null
+     * @param zone  the time-zone, which may be an offset, not null
+     * @return the local time, not null
+     */
+     public static LocalTime ofInstant(Instant instant, ZoneId zone) {
+         Objects.requireNonNull(instant, "instant");
+         Objects.requireNonNull(zone, "zone");
+         ZoneOffset offset = zone.getRules().getOffset(instant);
+         long localSecond = instant.getEpochSecond() + offset.getTotalSeconds();
+         int secsOfDay = (int) Math.floorMod(localSecond, SECONDS_PER_DAY);
+         return ofNanoOfDay(secsOfDay * NANOS_PER_SECOND + instant.getNano());
+     }
+
     //-----------------------------------------------------------------------
     /**
      * Obtains an instance of {@code LocalTime} from a second-of-day value.
--- a/jdk/src/java.base/share/classes/java/time/ZoneId.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/time/ZoneId.java	Tue Nov 17 10:29:28 2015 -0800
@@ -310,8 +310,7 @@
     public static ZoneId of(String zoneId, Map<String, String> aliasMap) {
         Objects.requireNonNull(zoneId, "zoneId");
         Objects.requireNonNull(aliasMap, "aliasMap");
-        String id = aliasMap.get(zoneId);
-        id = (id != null ? id : zoneId);
+        String id = Objects.requireNonNullElse(aliasMap.get(zoneId), zoneId);
         return of(id);
     }
 
--- a/jdk/src/java.base/share/classes/java/time/chrono/Chronology.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/time/chrono/Chronology.java	Tue Nov 17 10:29:28 2015 -0800
@@ -177,7 +177,7 @@
     static Chronology from(TemporalAccessor temporal) {
         Objects.requireNonNull(temporal, "temporal");
         Chronology obj = temporal.query(TemporalQueries.chronology());
-        return (obj != null ? obj : IsoChronology.INSTANCE);
+        return Objects.requireNonNullElse(obj, IsoChronology.INSTANCE);
     }
 
     //-----------------------------------------------------------------------
--- a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java	Tue Nov 17 10:29:28 2015 -0800
@@ -2892,7 +2892,8 @@
 
         @Override
         public String toString() {
-            return "ReducedValue(" + field + "," + minWidth + "," + maxWidth + "," + (baseDate != null ? baseDate : baseValue) + ")";
+            return "ReducedValue(" + field + "," + minWidth + "," + maxWidth +
+                    "," + Objects.requireNonNullElse(baseDate, baseValue) + ")";
         }
     }
 
@@ -3851,6 +3852,10 @@
                     return parseOffsetBased(context, text, position, position + 2, OffsetIdPrinterParser.INSTANCE_ID_ZERO);
                 } else if (context.charEquals(nextChar, 'G') && length >= position + 3 &&
                         context.charEquals(nextNextChar, 'M') && context.charEquals(text.charAt(position + 2), 'T')) {
+                    if (length >= position + 4 && context.charEquals(text.charAt(position + 3), '0')) {
+                        context.setParsed(ZoneId.of("GMT0"));
+                        return position + 4;
+                    }
                     return parseOffsetBased(context, text, position, position + 3, OffsetIdPrinterParser.INSTANCE_ID_ZERO);
                 }
             }
@@ -4328,7 +4333,7 @@
         private String getChronologyName(Chronology chrono, Locale locale) {
             String key = "calendarname." + chrono.getCalendarType();
             String name = DateTimeTextProvider.getLocalizedResource(key, locale);
-            return name != null ? name : chrono.getId();
+            return Objects.requireNonNullElseGet(name, () -> chrono.getId());
         }
     }
 
--- a/jdk/src/java.base/share/classes/java/time/format/DateTimePrintContext.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/time/format/DateTimePrintContext.java	Tue Nov 17 10:29:28 2015 -0800
@@ -146,7 +146,7 @@
         if (overrideZone != null) {
             // if have zone and instant, calculation is simple, defaulting chrono if necessary
             if (temporal.isSupported(INSTANT_SECONDS)) {
-                Chronology chrono = (effectiveChrono != null ? effectiveChrono : IsoChronology.INSTANCE);
+                Chronology chrono = Objects.requireNonNullElse(effectiveChrono, IsoChronology.INSTANCE);
                 return chrono.zonedDateTime(Instant.from(temporal), overrideZone);
             }
             // block changing zone on OffsetTime, and similar problem cases
--- a/jdk/src/java.base/share/classes/java/time/temporal/IsoFields.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/time/temporal/IsoFields.java	Tue Nov 17 10:29:28 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
@@ -102,7 +102,7 @@
  * The complete date is expressed using three fields:
  * <ul>
  * <li>{@link #DAY_OF_QUARTER DAY_OF_QUARTER} - the day within the quarter, from 1 to 90, 91 or 92
- * <li>{@link #QUARTER_OF_YEAR QUARTER_OF_YEAR} - the week within the week-based-year
+ * <li>{@link #QUARTER_OF_YEAR QUARTER_OF_YEAR} - the quarter within the year, from 1 to 4
  * <li>{@link ChronoField#YEAR YEAR} - the standard ISO year
  * </ul>
  *
@@ -571,9 +571,6 @@
         //-------------------------------------------------------------------------
         private static final int[] QUARTER_DAYS = {0, 90, 181, 273, 0, 91, 182, 274};
 
-        private static boolean isIso(TemporalAccessor temporal) {
-            return Chronology.from(temporal).equals(IsoChronology.INSTANCE);
-        }
 
         private static void ensureIso(TemporalAccessor temporal) {
             if (isIso(temporal) == false) {
@@ -681,7 +678,7 @@
 
         @Override
         public boolean isSupportedBy(Temporal temporal) {
-            return temporal.isSupported(EPOCH_DAY);
+            return temporal.isSupported(EPOCH_DAY) && isIso(temporal);
         }
 
         @SuppressWarnings("unchecked")
@@ -721,4 +718,8 @@
             return name;
         }
     }
+
+    static boolean isIso(TemporalAccessor temporal) {
+        return Chronology.from(temporal).equals(IsoChronology.INSTANCE);
+    }
 }
--- a/jdk/src/java.base/share/classes/java/util/Arrays.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/Arrays.java	Tue Nov 17 10:29:28 2015 -0800
@@ -2882,6 +2882,7 @@
      * @param a2 the other array to be tested for equality
      * @return {@code true} if the two arrays are equal
      */
+    @HotSpotIntrinsicCandidate
     public static boolean equals(byte[] a, byte[] a2) {
         if (a==a2)
             return true;
@@ -3304,6 +3305,103 @@
         return true;
     }
 
+    /**
+     * Returns {@code true} if the two specified arrays of Objects are
+     * <i>equal</i> to one another.
+     *
+     * <p>Two arrays are considered equal if both arrays contain the same number
+     * of elements, and all corresponding pairs of elements in the two arrays
+     * are equal.  In other words, the two arrays are equal if they contain the
+     * same elements in the same order.  Also, two array references are
+     * considered equal if both are {@code null}.
+     *
+     * <p>Two objects {@code e1} and {@code e2} are considered <i>equal</i> if,
+     * given the specified comparator, {@code cmp.compare(e1, e2) == 0}.
+     *
+     * @param a one array to be tested for equality
+     * @param a2 the other array to be tested for equality
+     * @param cmp the comparator to compare array elements
+     * @param <T> the type of array elements
+     * @return {@code true} if the two arrays are equal
+     * @throws NullPointerException if the comparator is {@code null}
+     * @since 9
+     */
+    public static <T> boolean equals(T[] a, T[] a2, Comparator<? super T> cmp) {
+        Objects.requireNonNull(cmp);
+        if (a==a2)
+            return true;
+        if (a==null || a2==null)
+            return false;
+
+        int length = a.length;
+        if (a2.length != length)
+            return false;
+
+        for (int i=0; i<length; i++) {
+            if (cmp.compare(a[i], a2[i]) != 0)
+                return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns true if the two specified arrays of Objects, over the specified
+     * ranges, are <i>equal</i> to one another.
+     *
+     * <p>Two arrays are considered equal if the number of elements covered by
+     * each range is the same, and all corresponding pairs of elements over the
+     * specified ranges in the two arrays are equal.  In other words, two arrays
+     * are equal if they contain, over the specified ranges, the same elements
+     * in the same order.
+     *
+     * <p>Two objects {@code e1} and {@code e2} are considered <i>equal</i> if,
+     * given the specified comparator, {@code cmp.compare(e1, e2) == 0}.
+     *
+     * @param a the first array to be tested for equality
+     * @param aFromIndex the index (inclusive) of the first element in the
+     *                   first array to be tested
+     * @param aToIndex the index (exclusive) of the last element in the
+     *                 first array to be tested
+     * @param b the second array to be tested fro equality
+     * @param bFromIndex the index (inclusive) of the first element in the
+     *                   second array to be tested
+     * @param bToIndex the index (exclusive) of the last element in the
+     *                 second array to be tested
+     * @param cmp the comparator to compare array elements
+     * @param <T> the type of array elements
+     * @return {@code true} if the two arrays, over the specified ranges, are
+     *         equal
+     * @throws IllegalArgumentException
+     *         if {@code aFromIndex > aToIndex} or
+     *         if {@code bFromIndex > bToIndex}
+     * @throws ArrayIndexOutOfBoundsException
+     *         if {@code aFromIndex < 0 or aToIndex > a.length} or
+     *         if {@code bFromIndex < 0 or bToIndex > b.length}
+     * @throws NullPointerException
+     *         if either array or the comparator is {@code null}
+     * @since 9
+     */
+    public static <T> boolean equals(T[] a, int aFromIndex, int aToIndex,
+                                     T[] b, int bFromIndex, int bToIndex,
+                                     Comparator<? super T> cmp) {
+        Objects.requireNonNull(cmp);
+        rangeCheck(a.length, aFromIndex, aToIndex);
+        rangeCheck(b.length, bFromIndex, bToIndex);
+
+        int aLength = aToIndex - aFromIndex;
+        int bLength = bToIndex - bFromIndex;
+        if (aLength != bLength)
+            return false;
+
+        for (int i = 0; i < aLength; i++) {
+            if (cmp.compare(a[aFromIndex++], b[bFromIndex++]) != 0)
+                return false;
+        }
+
+        return true;
+    }
+
     // Filling
 
     /**
@@ -8743,9 +8841,7 @@
      * <pre>{@code
      *     pl >= 0 &&
      *     pl < Math.min(a.length, b.length) &&
-     *     IntStream.range(0, pl).
-     *         map(i -> cmp.compare(a[i], b[i])).
-     *         allMatch(c -> c == 0) &&
+     *     Arrays.equals(a, 0, pl, b, 0, pl, cmp)
      *     cmp.compare(a[pl], b[pl]) != 0
      * }</pre>
      * Note that a common prefix length of {@code 0} indicates that the first
@@ -8755,9 +8851,9 @@
      * prefix if the following expression is true:
      * <pre>{@code
      *     a.length != b.length &&
-     *     IntStream.range(0, Math.min(a.length, b.length)).
-     *         map(i -> cmp.compare(a[i], b[i])).
-     *         allMatch(c -> c == 0) &&
+     *     Arrays.equals(a, 0, Math.min(a.length, b.length),
+     *                   b, 0, Math.min(a.length, b.length),
+     *                   cmp)
      * }</pre>
      *
      * @param a the first array to be tested for a mismatch
@@ -8814,9 +8910,7 @@
      * <pre>{@code
      *     pl >= 0 &&
      *     pl < Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex) &&
-     *     IntStream.range(0, pl).
-     *         map(i -> cmp.compare(a[aFromIndex + i], b[bFromIndex + i])).
-     *         allMatch(c -> c == 0) &&
+     *     Arrays.equals(a, aFromIndex, aFromIndex + pl, b, bFromIndex, bFromIndex + pl, cmp) &&
      *     cmp.compare(a[aFromIndex + pl], b[bFromIndex + pl]) != 0
      * }</pre>
      * Note that a common prefix length of {@code 0} indicates that the first
@@ -8828,9 +8922,9 @@
      * if the following expression is true:
      * <pre>{@code
      *     (aToIndex - aFromIndex) != (bToIndex - bFromIndex) &&
-     *     IntStream.range(0, Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex)).
-     *         map(i -> cmp.compare(a[aFromIndex + i], b[bFromIndex + i])).
-     *         allMatch(c -> c == 0)
+     *     Arrays.equals(a, 0, Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex),
+     *                   b, 0, Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex),
+     *                   cmp)
      * }</pre>
      *
      * @param a the first array to be tested for a mismatch
--- a/jdk/src/java.base/share/classes/java/util/Formatter.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/Formatter.java	Tue Nov 17 10:29:28 2015 -0800
@@ -49,6 +49,7 @@
 import java.text.NumberFormat;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.Objects;
 
 import java.time.DateTimeException;
 import java.time.Instant;
@@ -3860,7 +3861,7 @@
                     ampm = dfs.getAmPmStrings();
                 }
                 String s = ampm[t.get(Calendar.AM_PM)];
-                sb.append(s.toLowerCase(l != null ? l : Locale.US));
+                sb.append(s.toLowerCase(Objects.requireNonNullElse(l, Locale.US)));
                 break;
             }
             case DateTime.SECONDS_SINCE_EPOCH: { // 's' (0 - 99...?)
@@ -3893,7 +3894,7 @@
                 TimeZone tz = t.getTimeZone();
                 sb.append(tz.getDisplayName((t.get(Calendar.DST_OFFSET) != 0),
                                            TimeZone.SHORT,
-                                            (l == null) ? Locale.US : l));
+                                           Objects.requireNonNullElse(l, Locale.US)));
                 break;
             }
 
@@ -3901,7 +3902,7 @@
             case DateTime.NAME_OF_DAY_ABBREV:     // 'a'
             case DateTime.NAME_OF_DAY:          { // 'A'
                 int i = t.get(Calendar.DAY_OF_WEEK);
-                Locale lt = ((l == null) ? Locale.US : l);
+                Locale lt = Objects.requireNonNullElse(l, Locale.US);
                 DateFormatSymbols dfs = DateFormatSymbols.getInstance(lt);
                 if (c == DateTime.NAME_OF_DAY)
                     sb.append(dfs.getWeekdays()[i]);
@@ -3913,7 +3914,7 @@
             case DateTime.NAME_OF_MONTH_ABBREV_X: // 'h' -- same b
             case DateTime.NAME_OF_MONTH:        { // 'B'
                 int i = t.get(Calendar.MONTH);
-                Locale lt = ((l == null) ? Locale.US : l);
+                Locale lt = Objects.requireNonNullElse(l, Locale.US);
                 DateFormatSymbols dfs = DateFormatSymbols.getInstance(lt);
                 if (c == DateTime.NAME_OF_MONTH)
                     sb.append(dfs.getMonths()[i]);
@@ -3984,7 +3985,7 @@
                 StringBuilder tsb = new StringBuilder();
                 print(tsb, t, DateTime.AM_PM, l);
 
-                sb.append(tsb.toString().toUpperCase(l != null ? l : Locale.US));
+                sb.append(tsb.toString().toUpperCase(Objects.requireNonNullElse(l, Locale.US)));
                 break;
             }
             case DateTime.DATE_TIME:    { // 'c' (Sat Nov 04 12:02:33 EST 1999)
@@ -4092,7 +4093,7 @@
                         ampm = dfs.getAmPmStrings();
                     }
                     String s = ampm[t.get(ChronoField.AMPM_OF_DAY)];
-                    sb.append(s.toLowerCase(l != null ? l : Locale.US));
+                    sb.append(s.toLowerCase(Objects.requireNonNullElse(l, Locale.US)));
                     break;
                 }
                 case DateTime.SECONDS_SINCE_EPOCH: { // 's' (0 - 99...?)
@@ -4131,7 +4132,7 @@
                         sb.append(TimeZone.getTimeZone(zid.getId())
                                           .getDisplayName(zid.getRules().isDaylightSavings(instant),
                                                           TimeZone.SHORT,
-                                                          (l == null) ? Locale.US : l));
+                                                          Objects.requireNonNullElse(l, Locale.US)));
                         break;
                     }
                     sb.append(zid.getId());
@@ -4141,7 +4142,7 @@
                 case DateTime.NAME_OF_DAY_ABBREV:     // 'a'
                 case DateTime.NAME_OF_DAY:          { // 'A'
                     int i = t.get(ChronoField.DAY_OF_WEEK) % 7 + 1;
-                    Locale lt = ((l == null) ? Locale.US : l);
+                    Locale lt = Objects.requireNonNullElse(l, Locale.US);
                     DateFormatSymbols dfs = DateFormatSymbols.getInstance(lt);
                     if (c == DateTime.NAME_OF_DAY)
                         sb.append(dfs.getWeekdays()[i]);
@@ -4153,7 +4154,7 @@
                 case DateTime.NAME_OF_MONTH_ABBREV_X: // 'h' -- same b
                 case DateTime.NAME_OF_MONTH:        { // 'B'
                     int i = t.get(ChronoField.MONTH_OF_YEAR) - 1;
-                    Locale lt = ((l == null) ? Locale.US : l);
+                    Locale lt = Objects.requireNonNullElse(l, Locale.US);
                     DateFormatSymbols dfs = DateFormatSymbols.getInstance(lt);
                     if (c == DateTime.NAME_OF_MONTH)
                         sb.append(dfs.getMonths()[i]);
@@ -4223,7 +4224,7 @@
                     // this may be in wrong place for some locales
                     StringBuilder tsb = new StringBuilder();
                     print(tsb, t, DateTime.AM_PM, l);
-                    sb.append(tsb.toString().toUpperCase(l != null ? l : Locale.US));
+                    sb.append(tsb.toString().toUpperCase(Objects.requireNonNullElse(l, Locale.US)));
                     break;
                 }
                 case DateTime.DATE_TIME:    { // 'c' (Sat Nov 04 12:02:33 EST 1999)
--- a/jdk/src/java.base/share/classes/java/util/Objects.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/Objects.java	Tue Nov 17 10:29:28 2015 -0800
@@ -295,7 +295,7 @@
      *        {@code defaultObj} is {@code null}
      * @since 9
      */
-    public static <T> T nonNullElse(T obj, T defaultObj) {
+    public static <T> T requireNonNullElse(T obj, T defaultObj) {
         return (obj != null) ? obj : requireNonNull(defaultObj, "defaultObj");
     }
 
@@ -314,8 +314,9 @@
      *        the {@code supplier.get()} value is {@code null}
      * @since 9
      */
-    public static <T> T nonNullElseGet(T obj, Supplier<? extends T> supplier) {
-        return (obj != null) ? obj : requireNonNull(requireNonNull(supplier, "supplier").get(), "supplier.get()");
+    public static <T> T requireNonNullElseGet(T obj, Supplier<? extends T> supplier) {
+        return (obj != null) ? obj
+                : requireNonNull(requireNonNull(supplier, "supplier").get(), "supplier.get()");
     }
 
     /**
@@ -351,15 +352,16 @@
      * @param b the second out of bound value
      * @param oobe the exception mapping function that when applied with out of
      *        bounds arguments returns a runtime exception.  If {@code null}
-     *        then, it's as if an exception mapping function was supplied that
+     *        then, it is as if an exception mapping function was supplied that
      *        returns {@link IndexOutOfBoundsException} for any given arguments.
      * @return the runtime exception
      */
     private static RuntimeException outOfBounds(
             int a, int b, BiFunction<Integer, Integer, ? extends RuntimeException> oobe) {
-        return oobe == null
-               ? new IndexOutOfBoundsException(a, b)
-               : oobe.apply(a, b);
+        RuntimeException e = oobe == null
+                             ? null : oobe.apply(a, b);
+        return e == null
+               ? new IndexOutOfBoundsException(a, b) : e;
     }
 
     /**
@@ -407,8 +409,10 @@
      * @param length the upper-bound (exclusive) of the range
      * @param oobe the exception mapping function that when applied with out
      *        of bounds arguments returns a runtime exception.  If {@code null}
-     *        then, it's as if an exception mapping function was supplied that
-     *        returns {@link IndexOutOfBoundsException} for any given arguments.
+     *        or returns {@code null} then, it is as if an exception mapping
+     *        function was supplied that returns
+     *        {@link IndexOutOfBoundsException} for any given arguments.
+     *        Exceptions thrown by the function are relayed to the caller.
      * @return {@code index} if it is within bounds of the range
      * @throws T if the {@code index} is out of bounds, then a runtime exception
      *         is thrown that is the result of applying the out of bounds
@@ -483,8 +487,10 @@
      * @param length the upper-bound (exclusive) the range
      * @param oobe the exception mapping function that when applied with out
      *        of bounds arguments returns a runtime exception.  If {@code null}
-     *        then, it's as if an exception mapping function was supplied that
-     *        returns {@link IndexOutOfBoundsException} for any given arguments.
+     *        or returns {@code null} then, it is as if an exception mapping
+     *        function was supplied that returns
+     *        {@link IndexOutOfBoundsException} for any given arguments.
+     *        Exceptions thrown by the function are relayed to the caller.
      * @return {@code fromIndex} if the sub-range within bounds of the range
      * @throws T if the sub-range is out of bounds, then a runtime exception is
      *         thrown that is the result of applying the out of bounds arguments
@@ -552,8 +558,10 @@
      * @param length the upper-bound (exclusive) of the range
      * @param oobe the exception mapping function that when applied with out
      *        of bounds arguments returns a runtime exception.  If {@code null}
-     *        then, it's as if an exception mapping function was supplied that
-     *        returns {@link IndexOutOfBoundsException} for any given arguments.
+     *        or returns {@code null} then, it is as if an exception mapping
+     *        function was supplied that returns
+     *        {@link IndexOutOfBoundsException} for any given arguments.
+     *        Exceptions thrown by the function are relayed to the caller.
      * @return {@code fromIndex} if the sub-range within bounds of the range
      * @throws T if the sub-range is out of bounds, then a runtime exception is
      *         thrown that is the result of applying the out of bounds arguments
--- a/jdk/src/java.base/share/classes/java/util/Random.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/Random.java	Tue Nov 17 10:29:28 2015 -0800
@@ -34,7 +34,7 @@
 import java.util.stream.LongStream;
 import java.util.stream.StreamSupport;
 
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 /**
  * An instance of this class is used to generate a stream of
--- a/jdk/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java	Tue Nov 17 10:29:28 2015 -0800
@@ -2775,7 +2775,7 @@
     }
 
     // Unsafe mechanics
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long RESULT;
     private static final long STACK;
     private static final long NEXT;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java	Tue Nov 17 10:29:28 2015 -0800
@@ -297,7 +297,7 @@
      * Table accesses require volatile/atomic reads, writes, and
      * CASes.  Because there is no other way to arrange this without
      * adding further indirections, we use intrinsics
-     * (sun.misc.Unsafe) operations.
+     * (jdk.internal.misc.Unsafe) operations.
      *
      * We use the top (sign) bit of Node hash fields for control
      * purposes -- it is available anyway because of addressing
@@ -3287,7 +3287,7 @@
             return true;
         }
 
-        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
         private static final long LOCKSTATE;
         static {
             try {
@@ -6330,7 +6330,7 @@
     }
 
     // Unsafe mechanics
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long SIZECTL;
     private static final long TRANSFERINDEX;
     private static final long BASECOUNT;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java	Tue Nov 17 10:29:28 2015 -0800
@@ -326,7 +326,7 @@
 
         // Unsafe mechanics
 
-        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
         private static final long PREV;
         private static final long ITEM;
         private static final long NEXT;
@@ -1608,7 +1608,7 @@
 
     // Unsafe mechanics
 
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long HEAD;
     private static final long TAIL;
     static {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java	Tue Nov 17 10:29:28 2015 -0800
@@ -929,7 +929,7 @@
 
     // Unsafe mechanics
 
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long HEAD;
     private static final long TAIL;
     private static final long ITEM;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java	Tue Nov 17 10:29:28 2015 -0800
@@ -534,7 +534,7 @@
 
         // Unsafe mechanics
 
-        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
         private static final long VALUE;
         private static final long NEXT;
 
@@ -614,7 +614,7 @@
         }
 
         // Unsafe mechanics
-        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
         private static final long RIGHT;
         static {
             try {
@@ -3596,7 +3596,7 @@
     }
 
     // Unsafe mechanics
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long HEAD;
     static {
         try {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java	Tue Nov 17 10:29:28 2015 -0800
@@ -510,7 +510,7 @@
         U.putObjectVolatile(this, MAP, map);
     }
 
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long MAP;
     static {
         try {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java	Tue Nov 17 10:29:28 2015 -0800
@@ -1545,7 +1545,7 @@
     private void resetLock() {
         U.putObjectVolatile(this, LOCK, new Object());
     }
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long LOCK;
     static {
         try {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java	Tue Nov 17 10:29:28 2015 -0800
@@ -754,7 +754,7 @@
     protected void setRawResult(T t) { }
 
     // Unsafe mechanics
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long PENDING;
     static {
         try {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/Exchanger.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/Exchanger.java	Tue Nov 17 10:29:28 2015 -0800
@@ -625,7 +625,7 @@
     }
 
     // Unsafe mechanics
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long BOUND;
     private static final long SLOT;
     private static final long MATCH;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java	Tue Nov 17 10:29:28 2015 -0800
@@ -1337,7 +1337,7 @@
         }
 
         // Unsafe mechanics. Note that some are (and must be) the same as in FJP
-        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
         private static final long QLOCK;
         private static final int ABASE;
         private static final int ASHIFT;
@@ -3452,7 +3452,7 @@
     }
 
     // Unsafe mechanics
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long CTL;
     private static final long RUNSTATE;
     private static final int ABASE;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java	Tue Nov 17 10:29:28 2015 -0800
@@ -1517,7 +1517,7 @@
     }
 
     // Unsafe mechanics
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long STATUS;
 
     static {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinWorkerThread.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinWorkerThread.java	Tue Nov 17 10:29:28 2015 -0800
@@ -185,7 +185,7 @@
     }
 
     // Set up to allow setting thread fields in constructor
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long THREADLOCALS;
     private static final long INHERITABLETHREADLOCALS;
     private static final long INHERITEDACCESSCONTROLCONTEXT;
@@ -248,7 +248,7 @@
          */
         private static ThreadGroup createThreadGroup() {
             try {
-                sun.misc.Unsafe u = sun.misc.Unsafe.getUnsafe();
+                jdk.internal.misc.Unsafe u = jdk.internal.misc.Unsafe.getUnsafe();
                 long tg = u.objectFieldOffset
                     (Thread.class.getDeclaredField("group"));
                 long gp = u.objectFieldOffset
--- a/jdk/src/java.base/share/classes/java/util/concurrent/FutureTask.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/FutureTask.java	Tue Nov 17 10:29:28 2015 -0800
@@ -484,7 +484,7 @@
     }
 
     // Unsafe mechanics
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long STATE;
     private static final long RUNNER;
     private static final long WAITERS;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java	Tue Nov 17 10:29:28 2015 -0800
@@ -538,7 +538,7 @@
         private static final long serialVersionUID = -3375979862319811754L;
 
         // Unsafe mechanics
-        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
         private static final long ITEM;
         private static final long NEXT;
         private static final long WAITER;
@@ -1564,7 +1564,7 @@
 
     // Unsafe mechanics
 
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long HEAD;
     private static final long TAIL;
     private static final long SWEEPVOTES;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/Phaser.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/Phaser.java	Tue Nov 17 10:29:28 2015 -0800
@@ -1137,7 +1137,7 @@
 
     // Unsafe mechanics
 
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long STATE;
     static {
         try {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java	Tue Nov 17 10:29:28 2015 -0800
@@ -1010,7 +1010,7 @@
     }
 
     // Unsafe mechanics
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long ALLOCATIONSPINLOCK;
     static {
         try {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java	Tue Nov 17 10:29:28 2015 -0800
@@ -1596,7 +1596,7 @@
         }
 
         // Unsafe mechanics
-        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
         private static final long CTL;
         private static final long TAIL;
         private static final long HEAD;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java	Tue Nov 17 10:29:28 2015 -0800
@@ -283,7 +283,7 @@
             }
 
             // Unsafe mechanics
-            private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+            private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
             private static final long MATCH;
             private static final long NEXT;
 
@@ -509,7 +509,7 @@
         }
 
         // Unsafe mechanics
-        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
         private static final long HEAD;
         static {
             try {
@@ -575,7 +575,7 @@
             }
 
             // Unsafe mechanics
-            private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+            private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
             private static final long ITEM;
             private static final long NEXT;
 
@@ -817,7 +817,7 @@
             }
         }
 
-        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
         private static final long HEAD;
         private static final long TAIL;
         private static final long CLEANME;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java	Tue Nov 17 10:29:28 2015 -0800
@@ -1050,7 +1050,7 @@
     }
 
     // Unsafe mechanics
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long SEED;
     private static final long PROBE;
     private static final long SECONDARY;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java	Tue Nov 17 10:29:28 2015 -0800
@@ -49,7 +49,7 @@
 public class AtomicBoolean implements java.io.Serializable {
     private static final long serialVersionUID = 4654671469794556979L;
 
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long VALUE;
 
     static {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java	Tue Nov 17 10:29:28 2015 -0800
@@ -54,7 +54,7 @@
 public class AtomicInteger extends Number implements java.io.Serializable {
     private static final long serialVersionUID = 6214790243416807050L;
 
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long VALUE;
 
     static {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java	Tue Nov 17 10:29:28 2015 -0800
@@ -49,7 +49,7 @@
 public class AtomicIntegerArray implements java.io.Serializable {
     private static final long serialVersionUID = 2862133569453604235L;
 
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final int ABASE;
     private static final int ASHIFT;
     private final int[] array;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java	Tue Nov 17 10:29:28 2015 -0800
@@ -367,7 +367,7 @@
      */
     private static class AtomicIntegerFieldUpdaterImpl<T>
             extends AtomicIntegerFieldUpdater<T> {
-        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
         private final long offset;
         private final Class<T> tclass;
         private final Class<?> cclass;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java	Tue Nov 17 10:29:28 2015 -0800
@@ -54,7 +54,7 @@
 public class AtomicLong extends Number implements java.io.Serializable {
     private static final long serialVersionUID = 1927816293512124184L;
 
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long VALUE;
 
     /**
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java	Tue Nov 17 10:29:28 2015 -0800
@@ -48,7 +48,7 @@
 public class AtomicLongArray implements java.io.Serializable {
     private static final long serialVersionUID = -2308431214976778248L;
 
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final int ABASE;
     private static final int ASHIFT;
     private final long[] array;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java	Tue Nov 17 10:29:28 2015 -0800
@@ -366,7 +366,7 @@
     }
 
     private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
-        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
         private final long offset;
         private final Class<T> tclass;
         private final Class<?> cclass;
@@ -490,7 +490,7 @@
 
 
     private static class LockedUpdater<T> extends AtomicLongFieldUpdater<T> {
-        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
         private final long offset;
         private final Class<T> tclass;
         private final Class<?> cclass;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicMarkableReference.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicMarkableReference.java	Tue Nov 17 10:29:28 2015 -0800
@@ -190,7 +190,7 @@
 
     // Unsafe mechanics
 
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long PAIR;
     static {
         try {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java	Tue Nov 17 10:29:28 2015 -0800
@@ -49,7 +49,7 @@
 public class AtomicReference<V> implements java.io.Serializable {
     private static final long serialVersionUID = -1848883965231344442L;
 
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long VALUE;
 
     static {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java	Tue Nov 17 10:29:28 2015 -0800
@@ -52,7 +52,7 @@
 public class AtomicReferenceArray<E> implements java.io.Serializable {
     private static final long serialVersionUID = -6209656149925076980L;
 
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long ARRAY;
     private static final int ABASE;
     private static final int ASHIFT;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java	Tue Nov 17 10:29:28 2015 -0800
@@ -284,7 +284,7 @@
 
     private static final class AtomicReferenceFieldUpdaterImpl<T,V>
         extends AtomicReferenceFieldUpdater<T,V> {
-        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
         private final long offset;
         private final Class<T> tclass;
         private final Class<V> vclass;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicStampedReference.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicStampedReference.java	Tue Nov 17 10:29:28 2015 -0800
@@ -190,7 +190,7 @@
 
     // Unsafe mechanics
 
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long PAIR;
     static {
         try {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java	Tue Nov 17 10:29:28 2015 -0800
@@ -133,7 +133,7 @@
         }
 
         // Unsafe mechanics
-        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
         private static final long VALUE;
         static {
             try {
@@ -372,7 +372,7 @@
     }
 
     // Unsafe mechanics
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long BASE;
     private static final long CELLSBUSY;
     private static final long PROBE;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java	Tue Nov 17 10:29:28 2015 -0800
@@ -1821,7 +1821,7 @@
      * are at it, we do the same for other CASable fields (which could
      * otherwise be done with atomic field updaters).
      */
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long STATE;
     private static final long HEAD;
     private static final long TAIL;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java	Tue Nov 17 10:29:28 2015 -0800
@@ -524,7 +524,7 @@
             return U.compareAndSwapObject(this, NEXT, expect, update);
         }
 
-        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
         private static final long NEXT;
         static final long PREV;
         private static final long THREAD;
@@ -2285,7 +2285,7 @@
      * are at it, we do the same for other CASable fields (which could
      * otherwise be done with atomic field updaters).
      */
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long STATE;
     private static final long HEAD;
     private static final long TAIL;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/LockSupport.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/LockSupport.java	Tue Nov 17 10:29:28 2015 -0800
@@ -394,7 +394,7 @@
     }
 
     // Hotspot implementation via intrinsics API
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long PARKBLOCKER;
     private static final long SECONDARY;
     static {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java	Tue Nov 17 10:29:28 2015 -0800
@@ -1501,7 +1501,7 @@
     }
 
     // Unsafe mechanics
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long TID;
     static {
         try {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/StampedLock.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/StampedLock.java	Tue Nov 17 10:29:28 2015 -0800
@@ -1398,7 +1398,7 @@
     }
 
     // Unsafe mechanics
-    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
     private static final long STATE;
     private static final long WHEAD;
     private static final long WTAIL;
--- a/jdk/src/java.base/share/classes/java/util/zip/CRC32C.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/zip/CRC32C.java	Tue Nov 17 10:29:28 2015 -0800
@@ -28,7 +28,7 @@
 import java.nio.ByteOrder;
 
 import jdk.internal.HotSpotIntrinsicCandidate;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 import sun.nio.ch.DirectBuffer;
 
 /**
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java	Tue Nov 17 10:29:28 2015 -0800
@@ -30,7 +30,7 @@
 import java.io.FileDescriptor;
 import java.security.ProtectionDomain;
 import java.security.AccessController;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 /** A repository of "shared secrets", which are a mechanism for
     calling implementation-private methods in another package without
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,1391 @@
+/*
+ * 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
+ * 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.
+ */
+
+package jdk.internal.misc;
+
+import java.lang.reflect.Field;
+import java.security.ProtectionDomain;
+
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
+import sun.misc.VM;
+
+import jdk.internal.HotSpotIntrinsicCandidate;
+
+
+/**
+ * A collection of methods for performing low-level, unsafe operations.
+ * Although the class and all methods are public, use of this class is
+ * limited because only trusted code can obtain instances of it.
+ *
+ * @author John R. Rose
+ * @see #getUnsafe
+ */
+
+public final class Unsafe {
+
+    private static native void registerNatives();
+    static {
+        registerNatives();
+        sun.reflect.Reflection.registerMethodsToFilter(Unsafe.class, "getUnsafe");
+    }
+
+    private Unsafe() {}
+
+    private static final Unsafe theUnsafe = new Unsafe();
+
+    /**
+     * Provides the caller with the capability of performing unsafe
+     * operations.
+     *
+     * <p>The returned {@code Unsafe} object should be carefully guarded
+     * by the caller, since it can be used to read and write data at arbitrary
+     * memory addresses.  It must never be passed to untrusted code.
+     *
+     * <p>Most methods in this class are very low-level, and correspond to a
+     * small number of hardware instructions (on typical machines).  Compilers
+     * are encouraged to optimize these methods accordingly.
+     *
+     * <p>Here is a suggested idiom for using unsafe operations:
+     *
+     * <pre> {@code
+     * class MyTrustedClass {
+     *   private static final Unsafe unsafe = Unsafe.getUnsafe();
+     *   ...
+     *   private long myCountAddress = ...;
+     *   public int getCount() { return unsafe.getByte(myCountAddress); }
+     * }}</pre>
+     *
+     * (It may assist compilers to make the local variable {@code final}.)
+     *
+     * @throws  SecurityException  if a security manager exists and its
+     *          {@code checkPropertiesAccess} method doesn't allow
+     *          access to the system properties.
+     */
+    @CallerSensitive
+    public static Unsafe getUnsafe() {
+        Class<?> caller = Reflection.getCallerClass();
+        if (!VM.isSystemDomainLoader(caller.getClassLoader()))
+            throw new SecurityException("Unsafe");
+        return theUnsafe;
+    }
+
+    /// peek and poke operations
+    /// (compilers should optimize these to memory ops)
+
+    // These work on object fields in the Java heap.
+    // They will not work on elements of packed arrays.
+
+    /**
+     * Fetches a value from a given Java variable.
+     * More specifically, fetches a field or array element within the given
+     * object {@code o} at the given offset, or (if {@code o} is null)
+     * from the memory address whose numerical value is the given offset.
+     * <p>
+     * The results are undefined unless one of the following cases is true:
+     * <ul>
+     * <li>The offset was obtained from {@link #objectFieldOffset} on
+     * the {@link java.lang.reflect.Field} of some Java field and the object
+     * referred to by {@code o} is of a class compatible with that
+     * field's class.
+     *
+     * <li>The offset and object reference {@code o} (either null or
+     * non-null) were both obtained via {@link #staticFieldOffset}
+     * and {@link #staticFieldBase} (respectively) from the
+     * reflective {@link Field} representation of some Java field.
+     *
+     * <li>The object referred to by {@code o} is an array, and the offset
+     * is an integer of the form {@code B+N*S}, where {@code N} is
+     * a valid index into the array, and {@code B} and {@code S} are
+     * the values obtained by {@link #arrayBaseOffset} and {@link
+     * #arrayIndexScale} (respectively) from the array's class.  The value
+     * referred to is the {@code N}<em>th</em> element of the array.
+     *
+     * </ul>
+     * <p>
+     * If one of the above cases is true, the call references a specific Java
+     * variable (field or array element).  However, the results are undefined
+     * if that variable is not in fact of the type returned by this method.
+     * <p>
+     * This method refers to a variable by means of two parameters, and so
+     * it provides (in effect) a <em>double-register</em> addressing mode
+     * for Java variables.  When the object reference is null, this method
+     * uses its offset as an absolute address.  This is similar in operation
+     * to methods such as {@link #getInt(long)}, which provide (in effect) a
+     * <em>single-register</em> addressing mode for non-Java variables.
+     * However, because Java variables may have a different layout in memory
+     * from non-Java variables, programmers should not assume that these
+     * two addressing modes are ever equivalent.  Also, programmers should
+     * remember that offsets from the double-register addressing mode cannot
+     * be portably confused with longs used in the single-register addressing
+     * mode.
+     *
+     * @param o Java heap object in which the variable resides, if any, else
+     *        null
+     * @param offset indication of where the variable resides in a Java heap
+     *        object, if any, else a memory address locating the variable
+     *        statically
+     * @return the value fetched from the indicated Java variable
+     * @throws RuntimeException No defined exceptions are thrown, not even
+     *         {@link NullPointerException}
+     */
+    @HotSpotIntrinsicCandidate
+    public native int getInt(Object o, long offset);
+
+    /**
+     * Stores a value into a given Java variable.
+     * <p>
+     * The first two parameters are interpreted exactly as with
+     * {@link #getInt(Object, long)} to refer to a specific
+     * Java variable (field or array element).  The given value
+     * is stored into that variable.
+     * <p>
+     * The variable must be of the same type as the method
+     * parameter {@code x}.
+     *
+     * @param o Java heap object in which the variable resides, if any, else
+     *        null
+     * @param offset indication of where the variable resides in a Java heap
+     *        object, if any, else a memory address locating the variable
+     *        statically
+     * @param x the value to store into the indicated Java variable
+     * @throws RuntimeException No defined exceptions are thrown, not even
+     *         {@link NullPointerException}
+     */
+    @HotSpotIntrinsicCandidate
+    public native void putInt(Object o, long offset, int x);
+
+    /**
+     * Fetches a reference value from a given Java variable.
+     * @see #getInt(Object, long)
+     */
+    @HotSpotIntrinsicCandidate
+    public native Object getObject(Object o, long offset);
+
+    /**
+     * Stores a reference value into a given Java variable.
+     * <p>
+     * Unless the reference {@code x} being stored is either null
+     * or matches the field type, the results are undefined.
+     * If the reference {@code o} is non-null, card marks or
+     * other store barriers for that object (if the VM requires them)
+     * are updated.
+     * @see #putInt(Object, long, int)
+     */
+    @HotSpotIntrinsicCandidate
+    public native void putObject(Object o, long offset, Object x);
+
+    /** @see #getInt(Object, long) */
+    @HotSpotIntrinsicCandidate
+    public native boolean getBoolean(Object o, long offset);
+    /** @see #putInt(Object, long, int) */
+    @HotSpotIntrinsicCandidate
+    public native void    putBoolean(Object o, long offset, boolean x);
+    /** @see #getInt(Object, long) */
+    @HotSpotIntrinsicCandidate
+    public native byte    getByte(Object o, long offset);
+    /** @see #putInt(Object, long, int) */
+    @HotSpotIntrinsicCandidate
+    public native void    putByte(Object o, long offset, byte x);
+    /** @see #getInt(Object, long) */
+    @HotSpotIntrinsicCandidate
+    public native short   getShort(Object o, long offset);
+    /** @see #putInt(Object, long, int) */
+    @HotSpotIntrinsicCandidate
+    public native void    putShort(Object o, long offset, short x);
+    /** @see #getInt(Object, long) */
+    @HotSpotIntrinsicCandidate
+    public native char    getChar(Object o, long offset);
+    /** @see #putInt(Object, long, int) */
+    @HotSpotIntrinsicCandidate
+    public native void    putChar(Object o, long offset, char x);
+    /** @see #getInt(Object, long) */
+    @HotSpotIntrinsicCandidate
+    public native long    getLong(Object o, long offset);
+    /** @see #putInt(Object, long, int) */
+    @HotSpotIntrinsicCandidate
+    public native void    putLong(Object o, long offset, long x);
+    /** @see #getInt(Object, long) */
+    @HotSpotIntrinsicCandidate
+    public native float   getFloat(Object o, long offset);
+    /** @see #putInt(Object, long, int) */
+    @HotSpotIntrinsicCandidate
+    public native void    putFloat(Object o, long offset, float x);
+    /** @see #getInt(Object, long) */
+    @HotSpotIntrinsicCandidate
+    public native double  getDouble(Object o, long offset);
+    /** @see #putInt(Object, long, int) */
+    @HotSpotIntrinsicCandidate
+    public native void    putDouble(Object o, long offset, double x);
+
+    // These read VM internal data.
+
+    /**
+     * Fetches an uncompressed reference value from a given native variable
+     * ignoring the VM's compressed references mode.
+     *
+     * @param address a memory address locating the variable
+     * @return the value fetched from the indicated native variable
+     */
+    public native Object getUncompressedObject(long address);
+
+    /**
+     * Fetches the {@link java.lang.Class} Java mirror for the given native
+     * metaspace {@code Klass} pointer.
+     *
+     * @param metaspaceKlass a native metaspace {@code Klass} pointer
+     * @return the {@link java.lang.Class} Java mirror
+     */
+    public native Class<?> getJavaMirror(long metaspaceKlass);
+
+    /**
+     * Fetches a native metaspace {@code Klass} pointer for the given Java
+     * object.
+     *
+     * @param o Java heap object for which to fetch the class pointer
+     * @return a native metaspace {@code Klass} pointer
+     */
+    public native long getKlassPointer(Object o);
+
+    // These work on values in the C heap.
+
+    /**
+     * Fetches a value from a given memory address.  If the address is zero, or
+     * does not point into a block obtained from {@link #allocateMemory}, the
+     * results are undefined.
+     *
+     * @see #allocateMemory
+     */
+    @HotSpotIntrinsicCandidate
+    public native byte    getByte(long address);
+
+    /**
+     * Stores a value into a given memory address.  If the address is zero, or
+     * does not point into a block obtained from {@link #allocateMemory}, the
+     * results are undefined.
+     *
+     * @see #getByte(long)
+     */
+    @HotSpotIntrinsicCandidate
+    public native void    putByte(long address, byte x);
+
+    /** @see #getByte(long) */
+    @HotSpotIntrinsicCandidate
+    public native short   getShort(long address);
+    /** @see #putByte(long, byte) */
+    @HotSpotIntrinsicCandidate
+    public native void    putShort(long address, short x);
+    /** @see #getByte(long) */
+    @HotSpotIntrinsicCandidate
+    public native char    getChar(long address);
+    /** @see #putByte(long, byte) */
+    @HotSpotIntrinsicCandidate
+    public native void    putChar(long address, char x);
+    /** @see #getByte(long) */
+    @HotSpotIntrinsicCandidate
+    public native int     getInt(long address);
+    /** @see #putByte(long, byte) */
+    @HotSpotIntrinsicCandidate
+    public native void    putInt(long address, int x);
+    /** @see #getByte(long) */
+    @HotSpotIntrinsicCandidate
+    public native long    getLong(long address);
+    /** @see #putByte(long, byte) */
+    @HotSpotIntrinsicCandidate
+    public native void    putLong(long address, long x);
+    /** @see #getByte(long) */
+    @HotSpotIntrinsicCandidate
+    public native float   getFloat(long address);
+    /** @see #putByte(long, byte) */
+    @HotSpotIntrinsicCandidate
+    public native void    putFloat(long address, float x);
+    /** @see #getByte(long) */
+    @HotSpotIntrinsicCandidate
+    public native double  getDouble(long address);
+    /** @see #putByte(long, byte) */
+    @HotSpotIntrinsicCandidate
+    public native void    putDouble(long address, double x);
+
+    /**
+     * Fetches a native pointer from a given memory address.  If the address is
+     * zero, or does not point into a block obtained from {@link
+     * #allocateMemory}, the results are undefined.
+     *
+     * <p>If the native pointer is less than 64 bits wide, it is extended as
+     * an unsigned number to a Java long.  The pointer may be indexed by any
+     * given byte offset, simply by adding that offset (as a simple integer) to
+     * the long representing the pointer.  The number of bytes actually read
+     * from the target address may be determined by consulting {@link
+     * #addressSize}.
+     *
+     * @see #allocateMemory
+     */
+    @HotSpotIntrinsicCandidate
+    public native long getAddress(long address);
+
+    /**
+     * Stores a native pointer into a given memory address.  If the address is
+     * zero, or does not point into a block obtained from {@link
+     * #allocateMemory}, the results are undefined.
+     *
+     * <p>The number of bytes actually written at the target address may be
+     * determined by consulting {@link #addressSize}.
+     *
+     * @see #getAddress(long)
+     */
+    @HotSpotIntrinsicCandidate
+    public native void putAddress(long address, long x);
+
+    /// wrappers for malloc, realloc, free:
+
+    /**
+     * Allocates a new block of native memory, of the given size in bytes.  The
+     * contents of the memory are uninitialized; they will generally be
+     * garbage.  The resulting native pointer will never be zero, and will be
+     * aligned for all value types.  Dispose of this memory by calling {@link
+     * #freeMemory}, or resize it with {@link #reallocateMemory}.
+     *
+     * @throws IllegalArgumentException if the size is negative or too large
+     *         for the native size_t type
+     *
+     * @throws OutOfMemoryError if the allocation is refused by the system
+     *
+     * @see #getByte(long)
+     * @see #putByte(long, byte)
+     */
+    public native long allocateMemory(long bytes);
+
+    /**
+     * Resizes a new block of native memory, to the given size in bytes.  The
+     * contents of the new block past the size of the old block are
+     * uninitialized; they will generally be garbage.  The resulting native
+     * pointer will be zero if and only if the requested size is zero.  The
+     * resulting native pointer will be aligned for all value types.  Dispose
+     * of this memory by calling {@link #freeMemory}, or resize it with {@link
+     * #reallocateMemory}.  The address passed to this method may be null, in
+     * which case an allocation will be performed.
+     *
+     * @throws IllegalArgumentException if the size is negative or too large
+     *         for the native size_t type
+     *
+     * @throws OutOfMemoryError if the allocation is refused by the system
+     *
+     * @see #allocateMemory
+     */
+    public native long reallocateMemory(long address, long bytes);
+
+    /**
+     * Sets all bytes in a given block of memory to a fixed value
+     * (usually zero).
+     *
+     * <p>This method determines a block's base address by means of two parameters,
+     * and so it provides (in effect) a <em>double-register</em> addressing mode,
+     * as discussed in {@link #getInt(Object,long)}.  When the object reference is null,
+     * the offset supplies an absolute base address.
+     *
+     * <p>The stores are in coherent (atomic) units of a size determined
+     * by the address and length parameters.  If the effective address and
+     * length are all even modulo 8, the stores take place in 'long' units.
+     * If the effective address and length are (resp.) even modulo 4 or 2,
+     * the stores take place in units of 'int' or 'short'.
+     *
+     * @since 1.7
+     */
+    public native void setMemory(Object o, long offset, long bytes, byte value);
+
+    /**
+     * Sets all bytes in a given block of memory to a fixed value
+     * (usually zero).  This provides a <em>single-register</em> addressing mode,
+     * as discussed in {@link #getInt(Object,long)}.
+     *
+     * <p>Equivalent to {@code setMemory(null, address, bytes, value)}.
+     */
+    public void setMemory(long address, long bytes, byte value) {
+        setMemory(null, address, bytes, value);
+    }
+
+    /**
+     * Sets all bytes in a given block of memory to a copy of another
+     * block.
+     *
+     * <p>This method determines each block's base address by means of two parameters,
+     * and so it provides (in effect) a <em>double-register</em> addressing mode,
+     * as discussed in {@link #getInt(Object,long)}.  When the object reference is null,
+     * the offset supplies an absolute base address.
+     *
+     * <p>The transfers are in coherent (atomic) units of a size determined
+     * by the address and length parameters.  If the effective addresses and
+     * length are all even modulo 8, the transfer takes place in 'long' units.
+     * If the effective addresses and length are (resp.) even modulo 4 or 2,
+     * the transfer takes place in units of 'int' or 'short'.
+     *
+     * @since 1.7
+     */
+    @HotSpotIntrinsicCandidate
+    public native void copyMemory(Object srcBase, long srcOffset,
+                                  Object destBase, long destOffset,
+                                  long bytes);
+    /**
+     * Sets all bytes in a given block of memory to a copy of another
+     * block.  This provides a <em>single-register</em> addressing mode,
+     * as discussed in {@link #getInt(Object,long)}.
+     *
+     * Equivalent to {@code copyMemory(null, srcAddress, null, destAddress, bytes)}.
+     */
+    public void copyMemory(long srcAddress, long destAddress, long bytes) {
+        copyMemory(null, srcAddress, null, destAddress, bytes);
+    }
+
+    /**
+     * Disposes of a block of native memory, as obtained from {@link
+     * #allocateMemory} or {@link #reallocateMemory}.  The address passed to
+     * this method may be null, in which case no action is taken.
+     *
+     * @see #allocateMemory
+     */
+    public native void freeMemory(long address);
+
+    /// random queries
+
+    /**
+     * This constant differs from all results that will ever be returned from
+     * {@link #staticFieldOffset}, {@link #objectFieldOffset},
+     * or {@link #arrayBaseOffset}.
+     */
+    public static final int INVALID_FIELD_OFFSET   = -1;
+
+    /**
+     * Reports the location of a given field in the storage allocation of its
+     * class.  Do not expect to perform any sort of arithmetic on this offset;
+     * it is just a cookie which is passed to the unsafe heap memory accessors.
+     *
+     * <p>Any given field will always have the same offset and base, and no
+     * two distinct fields of the same class will ever have the same offset
+     * and base.
+     *
+     * <p>As of 1.4.1, offsets for fields are represented as long values,
+     * although the Sun JVM does not use the most significant 32 bits.
+     * However, JVM implementations which store static fields at absolute
+     * addresses can use long offsets and null base pointers to express
+     * the field locations in a form usable by {@link #getInt(Object,long)}.
+     * Therefore, code which will be ported to such JVMs on 64-bit platforms
+     * must preserve all bits of static field offsets.
+     * @see #getInt(Object, long)
+     */
+    public native long objectFieldOffset(Field f);
+
+    /**
+     * Reports the location of a given static field, in conjunction with {@link
+     * #staticFieldBase}.
+     * <p>Do not expect to perform any sort of arithmetic on this offset;
+     * it is just a cookie which is passed to the unsafe heap memory accessors.
+     *
+     * <p>Any given field will always have the same offset, and no two distinct
+     * fields of the same class will ever have the same offset.
+     *
+     * <p>As of 1.4.1, offsets for fields are represented as long values,
+     * although the Sun JVM does not use the most significant 32 bits.
+     * It is hard to imagine a JVM technology which needs more than
+     * a few bits to encode an offset within a non-array object,
+     * However, for consistency with other methods in this class,
+     * this method reports its result as a long value.
+     * @see #getInt(Object, long)
+     */
+    public native long staticFieldOffset(Field f);
+
+    /**
+     * Reports the location of a given static field, in conjunction with {@link
+     * #staticFieldOffset}.
+     * <p>Fetch the base "Object", if any, with which static fields of the
+     * given class can be accessed via methods like {@link #getInt(Object,
+     * long)}.  This value may be null.  This value may refer to an object
+     * which is a "cookie", not guaranteed to be a real Object, and it should
+     * not be used in any way except as argument to the get and put routines in
+     * this class.
+     */
+    public native Object staticFieldBase(Field f);
+
+    /**
+     * Detects if the given class may need to be initialized. This is often
+     * needed in conjunction with obtaining the static field base of a
+     * class.
+     * @return false only if a call to {@code ensureClassInitialized} would have no effect
+     */
+    public native boolean shouldBeInitialized(Class<?> c);
+
+    /**
+     * Ensures the given class has been initialized. This is often
+     * needed in conjunction with obtaining the static field base of a
+     * class.
+     */
+    public native void ensureClassInitialized(Class<?> c);
+
+    /**
+     * Reports the offset of the first element in the storage allocation of a
+     * given array class.  If {@link #arrayIndexScale} returns a non-zero value
+     * for the same class, you may use that scale factor, together with this
+     * base offset, to form new offsets to access elements of arrays of the
+     * given class.
+     *
+     * @see #getInt(Object, long)
+     * @see #putInt(Object, long, int)
+     */
+    public native int arrayBaseOffset(Class<?> arrayClass);
+
+    /** The value of {@code arrayBaseOffset(boolean[].class)} */
+    public static final int ARRAY_BOOLEAN_BASE_OFFSET
+            = theUnsafe.arrayBaseOffset(boolean[].class);
+
+    /** The value of {@code arrayBaseOffset(byte[].class)} */
+    public static final int ARRAY_BYTE_BASE_OFFSET
+            = theUnsafe.arrayBaseOffset(byte[].class);
+
+    /** The value of {@code arrayBaseOffset(short[].class)} */
+    public static final int ARRAY_SHORT_BASE_OFFSET
+            = theUnsafe.arrayBaseOffset(short[].class);
+
+    /** The value of {@code arrayBaseOffset(char[].class)} */
+    public static final int ARRAY_CHAR_BASE_OFFSET
+            = theUnsafe.arrayBaseOffset(char[].class);
+
+    /** The value of {@code arrayBaseOffset(int[].class)} */
+    public static final int ARRAY_INT_BASE_OFFSET
+            = theUnsafe.arrayBaseOffset(int[].class);
+
+    /** The value of {@code arrayBaseOffset(long[].class)} */
+    public static final int ARRAY_LONG_BASE_OFFSET
+            = theUnsafe.arrayBaseOffset(long[].class);
+
+    /** The value of {@code arrayBaseOffset(float[].class)} */
+    public static final int ARRAY_FLOAT_BASE_OFFSET
+            = theUnsafe.arrayBaseOffset(float[].class);
+
+    /** The value of {@code arrayBaseOffset(double[].class)} */
+    public static final int ARRAY_DOUBLE_BASE_OFFSET
+            = theUnsafe.arrayBaseOffset(double[].class);
+
+    /** The value of {@code arrayBaseOffset(Object[].class)} */
+    public static final int ARRAY_OBJECT_BASE_OFFSET
+            = theUnsafe.arrayBaseOffset(Object[].class);
+
+    /**
+     * Reports the scale factor for addressing elements in the storage
+     * allocation of a given array class.  However, arrays of "narrow" types
+     * will generally not work properly with accessors like {@link
+     * #getByte(Object, long)}, so the scale factor for such classes is reported
+     * as zero.
+     *
+     * @see #arrayBaseOffset
+     * @see #getInt(Object, long)
+     * @see #putInt(Object, long, int)
+     */
+    public native int arrayIndexScale(Class<?> arrayClass);
+
+    /** The value of {@code arrayIndexScale(boolean[].class)} */
+    public static final int ARRAY_BOOLEAN_INDEX_SCALE
+            = theUnsafe.arrayIndexScale(boolean[].class);
+
+    /** The value of {@code arrayIndexScale(byte[].class)} */
+    public static final int ARRAY_BYTE_INDEX_SCALE
+            = theUnsafe.arrayIndexScale(byte[].class);
+
+    /** The value of {@code arrayIndexScale(short[].class)} */
+    public static final int ARRAY_SHORT_INDEX_SCALE
+            = theUnsafe.arrayIndexScale(short[].class);
+
+    /** The value of {@code arrayIndexScale(char[].class)} */
+    public static final int ARRAY_CHAR_INDEX_SCALE
+            = theUnsafe.arrayIndexScale(char[].class);
+
+    /** The value of {@code arrayIndexScale(int[].class)} */
+    public static final int ARRAY_INT_INDEX_SCALE
+            = theUnsafe.arrayIndexScale(int[].class);
+
+    /** The value of {@code arrayIndexScale(long[].class)} */
+    public static final int ARRAY_LONG_INDEX_SCALE
+            = theUnsafe.arrayIndexScale(long[].class);
+
+    /** The value of {@code arrayIndexScale(float[].class)} */
+    public static final int ARRAY_FLOAT_INDEX_SCALE
+            = theUnsafe.arrayIndexScale(float[].class);
+
+    /** The value of {@code arrayIndexScale(double[].class)} */
+    public static final int ARRAY_DOUBLE_INDEX_SCALE
+            = theUnsafe.arrayIndexScale(double[].class);
+
+    /** The value of {@code arrayIndexScale(Object[].class)} */
+    public static final int ARRAY_OBJECT_INDEX_SCALE
+            = theUnsafe.arrayIndexScale(Object[].class);
+
+    /**
+     * Reports the size in bytes of a native pointer, as stored via {@link
+     * #putAddress}.  This value will be either 4 or 8.  Note that the sizes of
+     * other primitive types (as stored in native memory blocks) is determined
+     * fully by their information content.
+     */
+    public native int addressSize();
+
+    /** The value of {@code addressSize()} */
+    public static final int ADDRESS_SIZE = theUnsafe.addressSize();
+
+    /**
+     * Reports the size in bytes of a native memory page (whatever that is).
+     * This value will always be a power of two.
+     */
+    public native int pageSize();
+
+
+    /// random trusted operations from JNI:
+
+    /**
+     * Tells the VM to define a class, without security checks.  By default, the
+     * class loader and protection domain come from the caller's class.
+     */
+    public native Class<?> defineClass(String name, byte[] b, int off, int len,
+                                       ClassLoader loader,
+                                       ProtectionDomain protectionDomain);
+
+    /**
+     * Defines a class but does not make it known to the class loader or system dictionary.
+     * <p>
+     * For each CP entry, the corresponding CP patch must either be null or have
+     * the a format that matches its tag:
+     * <ul>
+     * <li>Integer, Long, Float, Double: the corresponding wrapper object type from java.lang
+     * <li>Utf8: a string (must have suitable syntax if used as signature or name)
+     * <li>Class: any java.lang.Class object
+     * <li>String: any object (not just a java.lang.String)
+     * <li>InterfaceMethodRef: (NYI) a method handle to invoke on that call site's arguments
+     * </ul>
+     * @param hostClass context for linkage, access control, protection domain, and class loader
+     * @param data      bytes of a class file
+     * @param cpPatches where non-null entries exist, they replace corresponding CP entries in data
+     */
+    public native Class<?> defineAnonymousClass(Class<?> hostClass, byte[] data, Object[] cpPatches);
+
+    /**
+     * Allocates an instance but does not run any constructor.
+     * Initializes the class if it has not yet been.
+     */
+    @HotSpotIntrinsicCandidate
+    public native Object allocateInstance(Class<?> cls)
+        throws InstantiationException;
+
+    /** Throws the exception without telling the verifier. */
+    public native void throwException(Throwable ee);
+
+    /**
+     * Atomically updates Java variable to {@code x} if it is currently
+     * holding {@code expected}.
+     *
+     * <p>This operation has memory semantics of a {@code volatile} read
+     * and write.  Corresponds to C11 atomic_compare_exchange_strong.
+     *
+     * @return {@code true} if successful
+     */
+    @HotSpotIntrinsicCandidate
+    public final native boolean compareAndSwapObject(Object o, long offset,
+                                                     Object expected,
+                                                     Object x);
+
+    /**
+     * Atomically updates Java variable to {@code x} if it is currently
+     * holding {@code expected}.
+     *
+     * <p>This operation has memory semantics of a {@code volatile} read
+     * and write.  Corresponds to C11 atomic_compare_exchange_strong.
+     *
+     * @return {@code true} if successful
+     */
+    @HotSpotIntrinsicCandidate
+    public final native boolean compareAndSwapInt(Object o, long offset,
+                                                  int expected,
+                                                  int x);
+
+    /**
+     * Atomically updates Java variable to {@code x} if it is currently
+     * holding {@code expected}.
+     *
+     * <p>This operation has memory semantics of a {@code volatile} read
+     * and write.  Corresponds to C11 atomic_compare_exchange_strong.
+     *
+     * @return {@code true} if successful
+     */
+    @HotSpotIntrinsicCandidate
+    public final native boolean compareAndSwapLong(Object o, long offset,
+                                                   long expected,
+                                                   long x);
+
+    /**
+     * Fetches a reference value from a given Java variable, with volatile
+     * load semantics. Otherwise identical to {@link #getObject(Object, long)}
+     */
+    @HotSpotIntrinsicCandidate
+    public native Object getObjectVolatile(Object o, long offset);
+
+    /**
+     * Stores a reference value into a given Java variable, with
+     * volatile store semantics. Otherwise identical to {@link #putObject(Object, long, Object)}
+     */
+    @HotSpotIntrinsicCandidate
+    public native void    putObjectVolatile(Object o, long offset, Object x);
+
+    /** Volatile version of {@link #getInt(Object, long)}  */
+    @HotSpotIntrinsicCandidate
+    public native int     getIntVolatile(Object o, long offset);
+
+    /** Volatile version of {@link #putInt(Object, long, int)}  */
+    @HotSpotIntrinsicCandidate
+    public native void    putIntVolatile(Object o, long offset, int x);
+
+    /** Volatile version of {@link #getBoolean(Object, long)}  */
+    @HotSpotIntrinsicCandidate
+    public native boolean getBooleanVolatile(Object o, long offset);
+
+    /** Volatile version of {@link #putBoolean(Object, long, boolean)}  */
+    @HotSpotIntrinsicCandidate
+    public native void    putBooleanVolatile(Object o, long offset, boolean x);
+
+    /** Volatile version of {@link #getByte(Object, long)}  */
+    @HotSpotIntrinsicCandidate
+    public native byte    getByteVolatile(Object o, long offset);
+
+    /** Volatile version of {@link #putByte(Object, long, byte)}  */
+    @HotSpotIntrinsicCandidate
+    public native void    putByteVolatile(Object o, long offset, byte x);
+
+    /** Volatile version of {@link #getShort(Object, long)}  */
+    @HotSpotIntrinsicCandidate
+    public native short   getShortVolatile(Object o, long offset);
+
+    /** Volatile version of {@link #putShort(Object, long, short)}  */
+    @HotSpotIntrinsicCandidate
+    public native void    putShortVolatile(Object o, long offset, short x);
+
+    /** Volatile version of {@link #getChar(Object, long)}  */
+    @HotSpotIntrinsicCandidate
+    public native char    getCharVolatile(Object o, long offset);
+
+    /** Volatile version of {@link #putChar(Object, long, char)}  */
+    @HotSpotIntrinsicCandidate
+    public native void    putCharVolatile(Object o, long offset, char x);
+
+    /** Volatile version of {@link #getLong(Object, long)}  */
+    @HotSpotIntrinsicCandidate
+    public native long    getLongVolatile(Object o, long offset);
+
+    /** Volatile version of {@link #putLong(Object, long, long)}  */
+    @HotSpotIntrinsicCandidate
+    public native void    putLongVolatile(Object o, long offset, long x);
+
+    /** Volatile version of {@link #getFloat(Object, long)}  */
+    @HotSpotIntrinsicCandidate
+    public native float   getFloatVolatile(Object o, long offset);
+
+    /** Volatile version of {@link #putFloat(Object, long, float)}  */
+    @HotSpotIntrinsicCandidate
+    public native void    putFloatVolatile(Object o, long offset, float x);
+
+    /** Volatile version of {@link #getDouble(Object, long)}  */
+    @HotSpotIntrinsicCandidate
+    public native double  getDoubleVolatile(Object o, long offset);
+
+    /** Volatile version of {@link #putDouble(Object, long, double)}  */
+    @HotSpotIntrinsicCandidate
+    public native void    putDoubleVolatile(Object o, long offset, double x);
+
+    /**
+     * Version of {@link #putObjectVolatile(Object, long, Object)}
+     * that does not guarantee immediate visibility of the store to
+     * other threads. This method is generally only useful if the
+     * underlying field is a Java volatile (or if an array cell, one
+     * that is otherwise only accessed using volatile accesses).
+     *
+     * Corresponds to C11 atomic_store_explicit(..., memory_order_release).
+     */
+    @HotSpotIntrinsicCandidate
+    public native void    putOrderedObject(Object o, long offset, Object x);
+
+    /** Ordered/Lazy version of {@link #putIntVolatile(Object, long, int)}  */
+    @HotSpotIntrinsicCandidate
+    public native void    putOrderedInt(Object o, long offset, int x);
+
+    /** Ordered/Lazy version of {@link #putLongVolatile(Object, long, long)} */
+    @HotSpotIntrinsicCandidate
+    public native void    putOrderedLong(Object o, long offset, long x);
+
+    /**
+     * Unblocks the given thread blocked on {@code park}, or, if it is
+     * not blocked, causes the subsequent call to {@code park} not to
+     * block.  Note: this operation is "unsafe" solely because the
+     * caller must somehow ensure that the thread has not been
+     * destroyed. Nothing special is usually required to ensure this
+     * when called from Java (in which there will ordinarily be a live
+     * reference to the thread) but this is not nearly-automatically
+     * so when calling from native code.
+     *
+     * @param thread the thread to unpark.
+     */
+    @HotSpotIntrinsicCandidate
+    public native void unpark(Object thread);
+
+    /**
+     * Blocks current thread, returning when a balancing
+     * {@code unpark} occurs, or a balancing {@code unpark} has
+     * already occurred, or the thread is interrupted, or, if not
+     * absolute and time is not zero, the given time nanoseconds have
+     * elapsed, or if absolute, the given deadline in milliseconds
+     * since Epoch has passed, or spuriously (i.e., returning for no
+     * "reason"). Note: This operation is in the Unsafe class only
+     * because {@code unpark} is, so it would be strange to place it
+     * elsewhere.
+     */
+    @HotSpotIntrinsicCandidate
+    public native void park(boolean isAbsolute, long time);
+
+    /**
+     * Gets the load average in the system run queue assigned
+     * to the available processors averaged over various periods of time.
+     * This method retrieves the given {@code nelem} samples and
+     * assigns to the elements of the given {@code loadavg} array.
+     * The system imposes a maximum of 3 samples, representing
+     * averages over the last 1,  5,  and  15 minutes, respectively.
+     *
+     * @param loadavg an array of double of size nelems
+     * @param nelems the number of samples to be retrieved and
+     *        must be 1 to 3.
+     *
+     * @return the number of samples actually retrieved; or -1
+     *         if the load average is unobtainable.
+     */
+    public native int getLoadAverage(double[] loadavg, int nelems);
+
+    // The following contain CAS-based Java implementations used on
+    // platforms not supporting native instructions
+
+    /**
+     * Atomically adds the given value to the current value of a field
+     * or array element within the given object {@code o}
+     * at the given {@code offset}.
+     *
+     * @param o object/array to update the field/element in
+     * @param offset field/element offset
+     * @param delta the value to add
+     * @return the previous value
+     * @since 1.8
+     */
+    @HotSpotIntrinsicCandidate
+    public final int getAndAddInt(Object o, long offset, int delta) {
+        int v;
+        do {
+            v = getIntVolatile(o, offset);
+        } while (!compareAndSwapInt(o, offset, v, v + delta));
+        return v;
+    }
+
+    /**
+     * Atomically adds the given value to the current value of a field
+     * or array element within the given object {@code o}
+     * at the given {@code offset}.
+     *
+     * @param o object/array to update the field/element in
+     * @param offset field/element offset
+     * @param delta the value to add
+     * @return the previous value
+     * @since 1.8
+     */
+    @HotSpotIntrinsicCandidate
+    public final long getAndAddLong(Object o, long offset, long delta) {
+        long v;
+        do {
+            v = getLongVolatile(o, offset);
+        } while (!compareAndSwapLong(o, offset, v, v + delta));
+        return v;
+    }
+
+    /**
+     * Atomically exchanges the given value with the current value of
+     * a field or array element within the given object {@code o}
+     * at the given {@code offset}.
+     *
+     * @param o object/array to update the field/element in
+     * @param offset field/element offset
+     * @param newValue new value
+     * @return the previous value
+     * @since 1.8
+     */
+    @HotSpotIntrinsicCandidate
+    public final int getAndSetInt(Object o, long offset, int newValue) {
+        int v;
+        do {
+            v = getIntVolatile(o, offset);
+        } while (!compareAndSwapInt(o, offset, v, newValue));
+        return v;
+    }
+
+    /**
+     * Atomically exchanges the given value with the current value of
+     * a field or array element within the given object {@code o}
+     * at the given {@code offset}.
+     *
+     * @param o object/array to update the field/element in
+     * @param offset field/element offset
+     * @param newValue new value
+     * @return the previous value
+     * @since 1.8
+     */
+    @HotSpotIntrinsicCandidate
+    public final long getAndSetLong(Object o, long offset, long newValue) {
+        long v;
+        do {
+            v = getLongVolatile(o, offset);
+        } while (!compareAndSwapLong(o, offset, v, newValue));
+        return v;
+    }
+
+    /**
+     * Atomically exchanges the given reference value with the current
+     * reference value of a field or array element within the given
+     * object {@code o} at the given {@code offset}.
+     *
+     * @param o object/array to update the field/element in
+     * @param offset field/element offset
+     * @param newValue new value
+     * @return the previous value
+     * @since 1.8
+     */
+    @HotSpotIntrinsicCandidate
+    public final Object getAndSetObject(Object o, long offset, Object newValue) {
+        Object v;
+        do {
+            v = getObjectVolatile(o, offset);
+        } while (!compareAndSwapObject(o, offset, v, newValue));
+        return v;
+    }
+
+
+    /**
+     * Ensures that loads before the fence will not be reordered with loads and
+     * stores after the fence; a "LoadLoad plus LoadStore barrier".
+     *
+     * Corresponds to C11 atomic_thread_fence(memory_order_acquire)
+     * (an "acquire fence").
+     *
+     * A pure LoadLoad fence is not provided, since the addition of LoadStore
+     * is almost always desired, and most current hardware instructions that
+     * provide a LoadLoad barrier also provide a LoadStore barrier for free.
+     * @since 1.8
+     */
+    @HotSpotIntrinsicCandidate
+    public native void loadFence();
+
+    /**
+     * Ensures that loads and stores before the fence will not be reordered with
+     * stores after the fence; a "StoreStore plus LoadStore barrier".
+     *
+     * Corresponds to C11 atomic_thread_fence(memory_order_release)
+     * (a "release fence").
+     *
+     * A pure StoreStore fence is not provided, since the addition of LoadStore
+     * is almost always desired, and most current hardware instructions that
+     * provide a StoreStore barrier also provide a LoadStore barrier for free.
+     * @since 1.8
+     */
+    @HotSpotIntrinsicCandidate
+    public native void storeFence();
+
+    /**
+     * Ensures that loads and stores before the fence will not be reordered
+     * with loads and stores after the fence.  Implies the effects of both
+     * loadFence() and storeFence(), and in addition, the effect of a StoreLoad
+     * barrier.
+     *
+     * Corresponds to C11 atomic_thread_fence(memory_order_seq_cst).
+     * @since 1.8
+     */
+    @HotSpotIntrinsicCandidate
+    public native void fullFence();
+
+    /**
+     * Throws IllegalAccessError; for use by the VM for access control
+     * error support.
+     * @since 1.8
+     */
+    private static void throwIllegalAccessError() {
+        throw new IllegalAccessError();
+    }
+
+    /**
+     * @return Returns true if the native byte ordering of this
+     * platform is big-endian, false if it is little-endian.
+     */
+    public final boolean isBigEndian() { return BE; }
+
+    /**
+     * @return Returns true if this platform is capable of performing
+     * accesses at addresses which are not aligned for the type of the
+     * primitive type being accessed, false otherwise.
+     */
+    public final boolean unalignedAccess() { return unalignedAccess; }
+
+    /**
+     * Fetches a value at some byte offset into a given Java object.
+     * More specifically, fetches a value within the given object
+     * <code>o</code> at the given offset, or (if <code>o</code> is
+     * null) from the memory address whose numerical value is the
+     * given offset.  <p>
+     *
+     * The specification of this method is the same as {@link
+     * #getLong(Object, long)} except that the offset does not need to
+     * have been obtained from {@link #objectFieldOffset} on the
+     * {@link java.lang.reflect.Field} of some Java field.  The value
+     * in memory is raw data, and need not correspond to any Java
+     * variable.  Unless <code>o</code> is null, the value accessed
+     * must be entirely within the allocated object.  The endianness
+     * of the value in memory is the endianness of the native platform.
+     *
+     * <p> The read will be atomic with respect to the largest power
+     * of two that divides the GCD of the offset and the storage size.
+     * For example, getLongUnaligned will make atomic reads of 2-, 4-,
+     * or 8-byte storage units if the offset is zero mod 2, 4, or 8,
+     * respectively.  There are no other guarantees of atomicity.
+     * <p>
+     * 8-byte atomicity is only guaranteed on platforms on which
+     * support atomic accesses to longs.
+     *
+     * @param o Java heap object in which the value resides, if any, else
+     *        null
+     * @param offset The offset in bytes from the start of the object
+     * @return the value fetched from the indicated object
+     * @throws RuntimeException No defined exceptions are thrown, not even
+     *         {@link NullPointerException}
+     * @since 1.9
+     */
+    @HotSpotIntrinsicCandidate
+    public final long getLongUnaligned(Object o, long offset) {
+        if ((offset & 7) == 0) {
+            return getLong(o, offset);
+        } else if ((offset & 3) == 0) {
+            return makeLong(getInt(o, offset),
+                            getInt(o, offset + 4));
+        } else if ((offset & 1) == 0) {
+            return makeLong(getShort(o, offset),
+                            getShort(o, offset + 2),
+                            getShort(o, offset + 4),
+                            getShort(o, offset + 6));
+        } else {
+            return makeLong(getByte(o, offset),
+                            getByte(o, offset + 1),
+                            getByte(o, offset + 2),
+                            getByte(o, offset + 3),
+                            getByte(o, offset + 4),
+                            getByte(o, offset + 5),
+                            getByte(o, offset + 6),
+                            getByte(o, offset + 7));
+        }
+    }
+    /**
+     * As {@link #getLongUnaligned(Object, long)} but with an
+     * additional argument which specifies the endianness of the value
+     * as stored in memory.
+     *
+     * @param o Java heap object in which the variable resides
+     * @param offset The offset in bytes from the start of the object
+     * @param bigEndian The endianness of the value
+     * @return the value fetched from the indicated object
+     * @since 1.9
+     */
+    public final long getLongUnaligned(Object o, long offset, boolean bigEndian) {
+        return convEndian(bigEndian, getLongUnaligned(o, offset));
+    }
+
+    /** @see #getLongUnaligned(Object, long) */
+    @HotSpotIntrinsicCandidate
+    public final int getIntUnaligned(Object o, long offset) {
+        if ((offset & 3) == 0) {
+            return getInt(o, offset);
+        } else if ((offset & 1) == 0) {
+            return makeInt(getShort(o, offset),
+                           getShort(o, offset + 2));
+        } else {
+            return makeInt(getByte(o, offset),
+                           getByte(o, offset + 1),
+                           getByte(o, offset + 2),
+                           getByte(o, offset + 3));
+        }
+    }
+    /** @see #getLongUnaligned(Object, long, boolean) */
+    public final int getIntUnaligned(Object o, long offset, boolean bigEndian) {
+        return convEndian(bigEndian, getIntUnaligned(o, offset));
+    }
+
+    /** @see #getLongUnaligned(Object, long) */
+    @HotSpotIntrinsicCandidate
+    public final short getShortUnaligned(Object o, long offset) {
+        if ((offset & 1) == 0) {
+            return getShort(o, offset);
+        } else {
+            return makeShort(getByte(o, offset),
+                             getByte(o, offset + 1));
+        }
+    }
+    /** @see #getLongUnaligned(Object, long, boolean) */
+    public final short getShortUnaligned(Object o, long offset, boolean bigEndian) {
+        return convEndian(bigEndian, getShortUnaligned(o, offset));
+    }
+
+    /** @see #getLongUnaligned(Object, long) */
+    @HotSpotIntrinsicCandidate
+    public final char getCharUnaligned(Object o, long offset) {
+        return (char)getShortUnaligned(o, offset);
+    }
+
+    /** @see #getLongUnaligned(Object, long, boolean) */
+    public final char getCharUnaligned(Object o, long offset, boolean bigEndian) {
+        return convEndian(bigEndian, getCharUnaligned(o, offset));
+    }
+
+    /**
+     * Stores a value at some byte offset into a given Java object.
+     * <p>
+     * The specification of this method is the same as {@link
+     * #getLong(Object, long)} except that the offset does not need to
+     * have been obtained from {@link #objectFieldOffset} on the
+     * {@link java.lang.reflect.Field} of some Java field.  The value
+     * in memory is raw data, and need not correspond to any Java
+     * variable.  The endianness of the value in memory is the
+     * endianness of the native platform.
+     * <p>
+     * The write will be atomic with respect to the largest power of
+     * two that divides the GCD of the offset and the storage size.
+     * For example, putLongUnaligned will make atomic writes of 2-, 4-,
+     * or 8-byte storage units if the offset is zero mod 2, 4, or 8,
+     * respectively.  There are no other guarantees of atomicity.
+     * <p>
+     * 8-byte atomicity is only guaranteed on platforms on which
+     * support atomic accesses to longs.
+     *
+     * @param o Java heap object in which the value resides, if any, else
+     *        null
+     * @param offset The offset in bytes from the start of the object
+     * @param x the value to store
+     * @throws RuntimeException No defined exceptions are thrown, not even
+     *         {@link NullPointerException}
+     * @since 1.9
+     */
+    @HotSpotIntrinsicCandidate
+    public final void putLongUnaligned(Object o, long offset, long x) {
+        if ((offset & 7) == 0) {
+            putLong(o, offset, x);
+        } else if ((offset & 3) == 0) {
+            putLongParts(o, offset,
+                         (int)(x >> 0),
+                         (int)(x >>> 32));
+        } else if ((offset & 1) == 0) {
+            putLongParts(o, offset,
+                         (short)(x >>> 0),
+                         (short)(x >>> 16),
+                         (short)(x >>> 32),
+                         (short)(x >>> 48));
+        } else {
+            putLongParts(o, offset,
+                         (byte)(x >>> 0),
+                         (byte)(x >>> 8),
+                         (byte)(x >>> 16),
+                         (byte)(x >>> 24),
+                         (byte)(x >>> 32),
+                         (byte)(x >>> 40),
+                         (byte)(x >>> 48),
+                         (byte)(x >>> 56));
+        }
+    }
+
+    /**
+     * As {@link #putLongUnaligned(Object, long, long)} but with an additional
+     * argument which specifies the endianness of the value as stored in memory.
+     * @param o Java heap object in which the value resides
+     * @param offset The offset in bytes from the start of the object
+     * @param x the value to store
+     * @param bigEndian The endianness of the value
+     * @throws RuntimeException No defined exceptions are thrown, not even
+     *         {@link NullPointerException}
+     * @since 1.9
+     */
+    public final void putLongUnaligned(Object o, long offset, long x, boolean bigEndian) {
+        putLongUnaligned(o, offset, convEndian(bigEndian, x));
+    }
+
+    /** @see #putLongUnaligned(Object, long, long) */
+    @HotSpotIntrinsicCandidate
+    public final void putIntUnaligned(Object o, long offset, int x) {
+        if ((offset & 3) == 0) {
+            putInt(o, offset, x);
+        } else if ((offset & 1) == 0) {
+            putIntParts(o, offset,
+                        (short)(x >> 0),
+                        (short)(x >>> 16));
+        } else {
+            putIntParts(o, offset,
+                        (byte)(x >>> 0),
+                        (byte)(x >>> 8),
+                        (byte)(x >>> 16),
+                        (byte)(x >>> 24));
+        }
+    }
+    /** @see #putLongUnaligned(Object, long, long, boolean) */
+    public final void putIntUnaligned(Object o, long offset, int x, boolean bigEndian) {
+        putIntUnaligned(o, offset, convEndian(bigEndian, x));
+    }
+
+    /** @see #putLongUnaligned(Object, long, long) */
+    @HotSpotIntrinsicCandidate
+    public final void putShortUnaligned(Object o, long offset, short x) {
+        if ((offset & 1) == 0) {
+            putShort(o, offset, x);
+        } else {
+            putShortParts(o, offset,
+                          (byte)(x >>> 0),
+                          (byte)(x >>> 8));
+        }
+    }
+    /** @see #putLongUnaligned(Object, long, long, boolean) */
+    public final void putShortUnaligned(Object o, long offset, short x, boolean bigEndian) {
+        putShortUnaligned(o, offset, convEndian(bigEndian, x));
+    }
+
+    /** @see #putLongUnaligned(Object, long, long) */
+    @HotSpotIntrinsicCandidate
+    public final void putCharUnaligned(Object o, long offset, char x) {
+        putShortUnaligned(o, offset, (short)x);
+    }
+    /** @see #putLongUnaligned(Object, long, long, boolean) */
+    public final void putCharUnaligned(Object o, long offset, char x, boolean bigEndian) {
+        putCharUnaligned(o, offset, convEndian(bigEndian, x));
+    }
+
+    // JVM interface methods
+    private native boolean unalignedAccess0();
+    private native boolean isBigEndian0();
+
+    // BE is true iff the native endianness of this platform is big.
+    private static final boolean BE = theUnsafe.isBigEndian0();
+
+    // unalignedAccess is true iff this platform can perform unaligned accesses.
+    private static final boolean unalignedAccess = theUnsafe.unalignedAccess0();
+
+    private static int pickPos(int top, int pos) { return BE ? top - pos : pos; }
+
+    // These methods construct integers from bytes.  The byte ordering
+    // is the native endianness of this platform.
+    private static long makeLong(byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) {
+        return ((toUnsignedLong(i0) << pickPos(56, 0))
+              | (toUnsignedLong(i1) << pickPos(56, 8))
+              | (toUnsignedLong(i2) << pickPos(56, 16))
+              | (toUnsignedLong(i3) << pickPos(56, 24))
+              | (toUnsignedLong(i4) << pickPos(56, 32))
+              | (toUnsignedLong(i5) << pickPos(56, 40))
+              | (toUnsignedLong(i6) << pickPos(56, 48))
+              | (toUnsignedLong(i7) << pickPos(56, 56)));
+    }
+    private static long makeLong(short i0, short i1, short i2, short i3) {
+        return ((toUnsignedLong(i0) << pickPos(48, 0))
+              | (toUnsignedLong(i1) << pickPos(48, 16))
+              | (toUnsignedLong(i2) << pickPos(48, 32))
+              | (toUnsignedLong(i3) << pickPos(48, 48)));
+    }
+    private static long makeLong(int i0, int i1) {
+        return (toUnsignedLong(i0) << pickPos(32, 0))
+             | (toUnsignedLong(i1) << pickPos(32, 32));
+    }
+    private static int makeInt(short i0, short i1) {
+        return (toUnsignedInt(i0) << pickPos(16, 0))
+             | (toUnsignedInt(i1) << pickPos(16, 16));
+    }
+    private static int makeInt(byte i0, byte i1, byte i2, byte i3) {
+        return ((toUnsignedInt(i0) << pickPos(24, 0))
+              | (toUnsignedInt(i1) << pickPos(24, 8))
+              | (toUnsignedInt(i2) << pickPos(24, 16))
+              | (toUnsignedInt(i3) << pickPos(24, 24)));
+    }
+    private static short makeShort(byte i0, byte i1) {
+        return (short)((toUnsignedInt(i0) << pickPos(8, 0))
+                     | (toUnsignedInt(i1) << pickPos(8, 8)));
+    }
+
+    private static byte  pick(byte  le, byte  be) { return BE ? be : le; }
+    private static short pick(short le, short be) { return BE ? be : le; }
+    private static int   pick(int   le, int   be) { return BE ? be : le; }
+
+    // These methods write integers to memory from smaller parts
+    // provided by their caller.  The ordering in which these parts
+    // are written is the native endianness of this platform.
+    private void putLongParts(Object o, long offset, byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) {
+        putByte(o, offset + 0, pick(i0, i7));
+        putByte(o, offset + 1, pick(i1, i6));
+        putByte(o, offset + 2, pick(i2, i5));
+        putByte(o, offset + 3, pick(i3, i4));
+        putByte(o, offset + 4, pick(i4, i3));
+        putByte(o, offset + 5, pick(i5, i2));
+        putByte(o, offset + 6, pick(i6, i1));
+        putByte(o, offset + 7, pick(i7, i0));
+    }
+    private void putLongParts(Object o, long offset, short i0, short i1, short i2, short i3) {
+        putShort(o, offset + 0, pick(i0, i3));
+        putShort(o, offset + 2, pick(i1, i2));
+        putShort(o, offset + 4, pick(i2, i1));
+        putShort(o, offset + 6, pick(i3, i0));
+    }
+    private void putLongParts(Object o, long offset, int i0, int i1) {
+        putInt(o, offset + 0, pick(i0, i1));
+        putInt(o, offset + 4, pick(i1, i0));
+    }
+    private void putIntParts(Object o, long offset, short i0, short i1) {
+        putShort(o, offset + 0, pick(i0, i1));
+        putShort(o, offset + 2, pick(i1, i0));
+    }
+    private void putIntParts(Object o, long offset, byte i0, byte i1, byte i2, byte i3) {
+        putByte(o, offset + 0, pick(i0, i3));
+        putByte(o, offset + 1, pick(i1, i2));
+        putByte(o, offset + 2, pick(i2, i1));
+        putByte(o, offset + 3, pick(i3, i0));
+    }
+    private void putShortParts(Object o, long offset, byte i0, byte i1) {
+        putByte(o, offset + 0, pick(i0, i1));
+        putByte(o, offset + 1, pick(i1, i0));
+    }
+
+    // Zero-extend an integer
+    private static int toUnsignedInt(byte n)    { return n & 0xff; }
+    private static int toUnsignedInt(short n)   { return n & 0xffff; }
+    private static long toUnsignedLong(byte n)  { return n & 0xffl; }
+    private static long toUnsignedLong(short n) { return n & 0xffffl; }
+    private static long toUnsignedLong(int n)   { return n & 0xffffffffl; }
+
+    // Maybe byte-reverse an integer
+    private static char convEndian(boolean big, char n)   { return big == BE ? n : Character.reverseBytes(n); }
+    private static short convEndian(boolean big, short n) { return big == BE ? n : Short.reverseBytes(n)    ; }
+    private static int convEndian(boolean big, int n)     { return big == BE ? n : Integer.reverseBytes(n)  ; }
+    private static long convEndian(boolean big, long n)   { return big == BE ? n : Long.reverseBytes(n)     ; }
+}
--- a/jdk/src/java.base/share/classes/sun/invoke/anon/AnonymousClassLoader.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/invoke/anon/AnonymousClassLoader.java	Tue Nov 17 10:29:28 2015 -0800
@@ -78,7 +78,7 @@
         this.hostClass = hostClass;
     }
 
-    public static AnonymousClassLoader make(sun.misc.Unsafe unsafe, Class<?> hostClass) {
+    public static AnonymousClassLoader make(jdk.internal.misc.Unsafe unsafe, Class<?> hostClass) {
         if (unsafe == null)  throw new NullPointerException();
         return new AnonymousClassLoader(hostClass);
     }
@@ -189,13 +189,13 @@
     private static int fakeNameCounter = 99999;
 
     // ignore two warnings on this line:
-    private static sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
+    private static jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe();
     // preceding line requires that this class be on the boot class path
 
     private static final Method defineAnonymousClass;
     static {
         Method dac = null;
-        Class<? extends sun.misc.Unsafe> unsafeClass = unsafe.getClass();
+        Class<? extends jdk.internal.misc.Unsafe> unsafeClass = unsafe.getClass();
         try {
             dac = unsafeClass.getMethod("defineAnonymousClass",
                                         Class.class,
--- a/jdk/src/java.base/share/classes/sun/invoke/util/Wrapper.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/invoke/util/Wrapper.java	Tue Nov 17 10:29:28 2015 -0800
@@ -26,36 +26,34 @@
 package sun.invoke.util;
 
 public enum Wrapper {
-    //        wrapperType    primitiveType  char            zero         emptyArray          format
-    BOOLEAN(  Boolean.class, boolean.class, 'Z',          Boolean.FALSE, new boolean[0], Format.unsigned( 1)),
+    //        wrapperType    primitiveType  char     emptyArray          format
+    BOOLEAN(  Boolean.class, boolean.class, 'Z', new boolean[0], Format.unsigned( 1)),
     // These must be in the order defined for widening primitive conversions in JLS 5.1.2
     // Avoid boxing integral types here to defer initialization of internal caches
-    BYTE   (     Byte.class,    byte.class, 'B',      new Byte((byte)0), new    byte[0], Format.signed(   8)),
-    SHORT  (    Short.class,   short.class, 'S',    new Short((short)0), new   short[0], Format.signed(  16)),
-    CHAR   (Character.class,    char.class, 'C', new Character((char)0), new    char[0], Format.unsigned(16)),
-    INT    (  Integer.class,     int.class, 'I',         new Integer(0), new     int[0], Format.signed(  32)),
-    LONG   (     Long.class,    long.class, 'J',            new Long(0), new    long[0], Format.signed(  64)),
-    FLOAT  (    Float.class,   float.class, 'F',        (Float)(float)0, new   float[0], Format.floating(32)),
-    DOUBLE (   Double.class,  double.class, 'D',      (Double)(double)0, new  double[0], Format.floating(64)),
-    OBJECT (   Object.class,  Object.class, 'L',                   null, new  Object[0], Format.other(    1)),
+    BYTE   (     Byte.class,    byte.class, 'B', new    byte[0], Format.signed(   8)),
+    SHORT  (    Short.class,   short.class, 'S', new   short[0], Format.signed(  16)),
+    CHAR   (Character.class,    char.class, 'C', new    char[0], Format.unsigned(16)),
+    INT    (  Integer.class,     int.class, 'I', new     int[0], Format.signed(  32)),
+    LONG   (     Long.class,    long.class, 'J', new    long[0], Format.signed(  64)),
+    FLOAT  (    Float.class,   float.class, 'F', new   float[0], Format.floating(32)),
+    DOUBLE (   Double.class,  double.class, 'D', new  double[0], Format.floating(64)),
+    OBJECT (   Object.class,  Object.class, 'L', new  Object[0], Format.other(    1)),
     // VOID must be the last type, since it is "assignable" from any other type:
-    VOID   (     Void.class,    void.class, 'V',                   null,           null, Format.other(    0)),
+    VOID   (     Void.class,    void.class, 'V',           null, Format.other(    0)),
     ;
 
     private final Class<?> wrapperType;
     private final Class<?> primitiveType;
     private final char     basicTypeChar;
-    private final Object   zero;
     private final Object   emptyArray;
     private final int      format;
     private final String   wrapperSimpleName;
     private final String   primitiveSimpleName;
 
-    private Wrapper(Class<?> wtype, Class<?> ptype, char tchar, Object zero, Object emptyArray, int format) {
+    private Wrapper(Class<?> wtype, Class<?> ptype, char tchar, Object emptyArray, int format) {
         this.wrapperType = wtype;
         this.primitiveType = ptype;
         this.basicTypeChar = tchar;
-        this.zero = zero;
         this.emptyArray = emptyArray;
         this.format = format;
         this.wrapperSimpleName = wtype.getSimpleName();
@@ -66,7 +64,7 @@
     public String detailString() {
         return wrapperSimpleName+
                 java.util.Arrays.asList(wrapperType, primitiveType,
-                basicTypeChar, zero,
+                basicTypeChar, zero(),
                 "0x"+Integer.toHexString(format));
     }
 
@@ -223,13 +221,39 @@
      *  type.  (For void, it is what a reflective method returns
      *  instead of no value at all.)
      */
-    public Object zero() { return zero; }
+    public Object zero() {
+        switch (this) {
+            case BOOLEAN:
+                return Boolean.FALSE;
+            case INT:
+                return (Integer)0;
+            case BYTE:
+                return (Byte)(byte)0;
+            case CHAR:
+                return (Character)(char)0;
+            case SHORT:
+                return (Short)(short)0;
+            case LONG:
+                return (Long)(long)0;
+            case FLOAT:
+                return FLOAT_ZERO;
+            case DOUBLE:
+                return DOUBLE_ZERO;
+            case VOID:
+            case OBJECT:
+            default:
+                return null;
+        }
+    }
+
+    private static final Object DOUBLE_ZERO = (Double)(double)0;
+    private static final Object FLOAT_ZERO = (Float)(float)0;
 
     /** Produce a zero value for the given wrapper type T.
      *  The optional argument must a type compatible with this wrapper.
      *  Equivalent to {@code this.cast(this.zero(), type)}.
      */
-    public <T> T zero(Class<T> type) { return convert(zero, type); }
+    public <T> T zero(Class<T> type) { return convert(zero(), type); }
 
     /** Return the wrapper that wraps values of the given type.
      *  The type may be {@code Object}, meaning the {@code OBJECT} wrapper.
@@ -474,7 +498,7 @@
             }
         } else if (x == null) {
             @SuppressWarnings("unchecked")
-            T z = (T) zero;
+            T z = (T) zero();
             return z;
         }
         @SuppressWarnings("unchecked")
--- a/jdk/src/java.base/share/classes/sun/misc/InnocuousThread.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/misc/InnocuousThread.java	Tue Nov 17 10:29:28 2015 -0800
@@ -36,7 +36,7 @@
  * ThreadGroup and supports the ability to erase ThreadLocals.
  */
 public final class InnocuousThread extends ManagedLocalsThread {
-    private static final Unsafe UNSAFE;
+    private static final jdk.internal.misc.Unsafe UNSAFE;
     private static final ThreadGroup INNOCUOUSTHREADGROUP;
     private static final AccessControlContext ACC;
     private static final long INHERITEDACCESSCONTROLCONTEXT;
@@ -92,7 +92,7 @@
             });
 
             // Find and use topmost ThreadGroup as parent of new group
-            UNSAFE = Unsafe.getUnsafe();
+            UNSAFE = jdk.internal.misc.Unsafe.getUnsafe();
             Class<?> tk = Thread.class;
             Class<?> gk = ThreadGroup.class;
 
--- a/jdk/src/java.base/share/classes/sun/misc/ManagedLocalsThread.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/misc/ManagedLocalsThread.java	Tue Nov 17 10:29:28 2015 -0800
@@ -30,7 +30,7 @@
  * locals erased on construction.
  */
 public class ManagedLocalsThread extends Thread {
-    private static final Unsafe UNSAFE;
+    private static final jdk.internal.misc.Unsafe UNSAFE;
     private static final long THREAD_LOCALS;
     private static final long INHERITABLE_THREAD_LOCALS;
 
@@ -77,7 +77,7 @@
     }
 
     static {
-        UNSAFE = Unsafe.getUnsafe();
+        UNSAFE = jdk.internal.misc.Unsafe.getUnsafe();
         Class<?> t = Thread.class;
         try {
             THREAD_LOCALS = UNSAFE.objectFieldOffset
--- a/jdk/src/java.base/share/classes/sun/misc/Unsafe.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/misc/Unsafe.java	Tue Nov 17 10:29:28 2015 -0800
@@ -1036,355 +1036,8 @@
         throw new IllegalAccessError();
     }
 
-    /**
-     * @return Returns true if the native byte ordering of this
-     * platform is big-endian, false if it is little-endian.
-     */
-    public final boolean isBigEndian() { return BE; }
-
-    /**
-     * @return Returns true if this platform is capable of performing
-     * accesses at addresses which are not aligned for the type of the
-     * primitive type being accessed, false otherwise.
-     */
-    public final boolean unalignedAccess() { return unalignedAccess; }
-
-    /**
-     * Fetches a value at some byte offset into a given Java object.
-     * More specifically, fetches a value within the given object
-     * <code>o</code> at the given offset, or (if <code>o</code> is
-     * null) from the memory address whose numerical value is the
-     * given offset.  <p>
-     *
-     * The specification of this method is the same as {@link
-     * #getLong(Object, long)} except that the offset does not need to
-     * have been obtained from {@link #objectFieldOffset} on the
-     * {@link java.lang.reflect.Field} of some Java field.  The value
-     * in memory is raw data, and need not correspond to any Java
-     * variable.  Unless <code>o</code> is null, the value accessed
-     * must be entirely within the allocated object.  The endianness
-     * of the value in memory is the endianness of the native platform.
-     *
-     * <p> The read will be atomic with respect to the largest power
-     * of two that divides the GCD of the offset and the storage size.
-     * For example, getLongUnaligned will make atomic reads of 2-, 4-,
-     * or 8-byte storage units if the offset is zero mod 2, 4, or 8,
-     * respectively.  There are no other guarantees of atomicity.
-     * <p>
-     * 8-byte atomicity is only guaranteed on platforms on which
-     * support atomic accesses to longs.
-     *
-     * @param o Java heap object in which the value resides, if any, else
-     *        null
-     * @param offset The offset in bytes from the start of the object
-     * @return the value fetched from the indicated object
-     * @throws RuntimeException No defined exceptions are thrown, not even
-     *         {@link NullPointerException}
-     * @since 1.9
-     */
-    @HotSpotIntrinsicCandidate
-    public final long getLongUnaligned(Object o, long offset) {
-        if ((offset & 7) == 0) {
-            return getLong(o, offset);
-        } else if ((offset & 3) == 0) {
-            return makeLong(getInt(o, offset),
-                            getInt(o, offset + 4));
-        } else if ((offset & 1) == 0) {
-            return makeLong(getShort(o, offset),
-                            getShort(o, offset + 2),
-                            getShort(o, offset + 4),
-                            getShort(o, offset + 6));
-        } else {
-            return makeLong(getByte(o, offset),
-                            getByte(o, offset + 1),
-                            getByte(o, offset + 2),
-                            getByte(o, offset + 3),
-                            getByte(o, offset + 4),
-                            getByte(o, offset + 5),
-                            getByte(o, offset + 6),
-                            getByte(o, offset + 7));
-        }
-    }
-    /**
-     * As {@link #getLongUnaligned(Object, long)} but with an
-     * additional argument which specifies the endianness of the value
-     * as stored in memory.
-     *
-     * @param o Java heap object in which the variable resides
-     * @param offset The offset in bytes from the start of the object
-     * @param bigEndian The endianness of the value
-     * @return the value fetched from the indicated object
-     * @since 1.9
-     */
-    public final long getLongUnaligned(Object o, long offset, boolean bigEndian) {
-        return convEndian(bigEndian, getLongUnaligned(o, offset));
-    }
-
-    /** @see #getLongUnaligned(Object, long) */
-    @HotSpotIntrinsicCandidate
-    public final int getIntUnaligned(Object o, long offset) {
-        if ((offset & 3) == 0) {
-            return getInt(o, offset);
-        } else if ((offset & 1) == 0) {
-            return makeInt(getShort(o, offset),
-                           getShort(o, offset + 2));
-        } else {
-            return makeInt(getByte(o, offset),
-                           getByte(o, offset + 1),
-                           getByte(o, offset + 2),
-                           getByte(o, offset + 3));
-        }
-    }
-    /** @see #getLongUnaligned(Object, long, boolean) */
-    public final int getIntUnaligned(Object o, long offset, boolean bigEndian) {
-        return convEndian(bigEndian, getIntUnaligned(o, offset));
-    }
-
-    /** @see #getLongUnaligned(Object, long) */
-    @HotSpotIntrinsicCandidate
-    public final short getShortUnaligned(Object o, long offset) {
-        if ((offset & 1) == 0) {
-            return getShort(o, offset);
-        } else {
-            return makeShort(getByte(o, offset),
-                             getByte(o, offset + 1));
-        }
-    }
-    /** @see #getLongUnaligned(Object, long, boolean) */
-    public final short getShortUnaligned(Object o, long offset, boolean bigEndian) {
-        return convEndian(bigEndian, getShortUnaligned(o, offset));
-    }
-
-    /** @see #getLongUnaligned(Object, long) */
-    @HotSpotIntrinsicCandidate
-    public final char getCharUnaligned(Object o, long offset) {
-        return (char)getShortUnaligned(o, offset);
-    }
-
-    /** @see #getLongUnaligned(Object, long, boolean) */
-    public final char getCharUnaligned(Object o, long offset, boolean bigEndian) {
-        return convEndian(bigEndian, getCharUnaligned(o, offset));
-    }
-
-    /**
-     * Stores a value at some byte offset into a given Java object.
-     * <p>
-     * The specification of this method is the same as {@link
-     * #getLong(Object, long)} except that the offset does not need to
-     * have been obtained from {@link #objectFieldOffset} on the
-     * {@link java.lang.reflect.Field} of some Java field.  The value
-     * in memory is raw data, and need not correspond to any Java
-     * variable.  The endianness of the value in memory is the
-     * endianness of the native platform.
-     * <p>
-     * The write will be atomic with respect to the largest power of
-     * two that divides the GCD of the offset and the storage size.
-     * For example, putLongUnaligned will make atomic writes of 2-, 4-,
-     * or 8-byte storage units if the offset is zero mod 2, 4, or 8,
-     * respectively.  There are no other guarantees of atomicity.
-     * <p>
-     * 8-byte atomicity is only guaranteed on platforms on which
-     * support atomic accesses to longs.
-     *
-     * @param o Java heap object in which the value resides, if any, else
-     *        null
-     * @param offset The offset in bytes from the start of the object
-     * @param x the value to store
-     * @throws RuntimeException No defined exceptions are thrown, not even
-     *         {@link NullPointerException}
-     * @since 1.9
-     */
-    @HotSpotIntrinsicCandidate
-    public final void putLongUnaligned(Object o, long offset, long x) {
-        if ((offset & 7) == 0) {
-            putLong(o, offset, x);
-        } else if ((offset & 3) == 0) {
-            putLongParts(o, offset,
-                         (int)(x >> 0),
-                         (int)(x >>> 32));
-        } else if ((offset & 1) == 0) {
-            putLongParts(o, offset,
-                         (short)(x >>> 0),
-                         (short)(x >>> 16),
-                         (short)(x >>> 32),
-                         (short)(x >>> 48));
-        } else {
-            putLongParts(o, offset,
-                         (byte)(x >>> 0),
-                         (byte)(x >>> 8),
-                         (byte)(x >>> 16),
-                         (byte)(x >>> 24),
-                         (byte)(x >>> 32),
-                         (byte)(x >>> 40),
-                         (byte)(x >>> 48),
-                         (byte)(x >>> 56));
-        }
-    }
-
-    /**
-     * As {@link #putLongUnaligned(Object, long, long)} but with an additional
-     * argument which specifies the endianness of the value as stored in memory.
-     * @param o Java heap object in which the value resides
-     * @param offset The offset in bytes from the start of the object
-     * @param x the value to store
-     * @param bigEndian The endianness of the value
-     * @throws RuntimeException No defined exceptions are thrown, not even
-     *         {@link NullPointerException}
-     * @since 1.9
-     */
-    public final void putLongUnaligned(Object o, long offset, long x, boolean bigEndian) {
-        putLongUnaligned(o, offset, convEndian(bigEndian, x));
-    }
-
-    /** @see #putLongUnaligned(Object, long, long) */
-    @HotSpotIntrinsicCandidate
-    public final void putIntUnaligned(Object o, long offset, int x) {
-        if ((offset & 3) == 0) {
-            putInt(o, offset, x);
-        } else if ((offset & 1) == 0) {
-            putIntParts(o, offset,
-                        (short)(x >> 0),
-                        (short)(x >>> 16));
-        } else {
-            putIntParts(o, offset,
-                        (byte)(x >>> 0),
-                        (byte)(x >>> 8),
-                        (byte)(x >>> 16),
-                        (byte)(x >>> 24));
-        }
-    }
-    /** @see #putLongUnaligned(Object, long, long, boolean) */
-    public final void putIntUnaligned(Object o, long offset, int x, boolean bigEndian) {
-        putIntUnaligned(o, offset, convEndian(bigEndian, x));
-    }
-
-    /** @see #putLongUnaligned(Object, long, long) */
-    @HotSpotIntrinsicCandidate
-    public final void putShortUnaligned(Object o, long offset, short x) {
-        if ((offset & 1) == 0) {
-            putShort(o, offset, x);
-        } else {
-            putShortParts(o, offset,
-                          (byte)(x >>> 0),
-                          (byte)(x >>> 8));
-        }
-    }
-    /** @see #putLongUnaligned(Object, long, long, boolean) */
-    public final void putShortUnaligned(Object o, long offset, short x, boolean bigEndian) {
-        putShortUnaligned(o, offset, convEndian(bigEndian, x));
-    }
-
-    /** @see #putLongUnaligned(Object, long, long) */
-    @HotSpotIntrinsicCandidate
-    public final void putCharUnaligned(Object o, long offset, char x) {
-        putShortUnaligned(o, offset, (short)x);
-    }
-    /** @see #putLongUnaligned(Object, long, long, boolean) */
-    public final void putCharUnaligned(Object o, long offset, char x, boolean bigEndian) {
-        putCharUnaligned(o, offset, convEndian(bigEndian, x));
-    }
-
     // JVM interface methods
     private native boolean unalignedAccess0();
     private native boolean isBigEndian0();
 
-    // BE is true iff the native endianness of this platform is big.
-    private static final boolean BE = theUnsafe.isBigEndian0();
-
-    // unalignedAccess is true iff this platform can perform unaligned accesses.
-    private static final boolean unalignedAccess = theUnsafe.unalignedAccess0();
-
-    private static int pickPos(int top, int pos) { return BE ? top - pos : pos; }
-
-    // These methods construct integers from bytes.  The byte ordering
-    // is the native endianness of this platform.
-    private static long makeLong(byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) {
-        return ((toUnsignedLong(i0) << pickPos(56, 0))
-              | (toUnsignedLong(i1) << pickPos(56, 8))
-              | (toUnsignedLong(i2) << pickPos(56, 16))
-              | (toUnsignedLong(i3) << pickPos(56, 24))
-              | (toUnsignedLong(i4) << pickPos(56, 32))
-              | (toUnsignedLong(i5) << pickPos(56, 40))
-              | (toUnsignedLong(i6) << pickPos(56, 48))
-              | (toUnsignedLong(i7) << pickPos(56, 56)));
-    }
-    private static long makeLong(short i0, short i1, short i2, short i3) {
-        return ((toUnsignedLong(i0) << pickPos(48, 0))
-              | (toUnsignedLong(i1) << pickPos(48, 16))
-              | (toUnsignedLong(i2) << pickPos(48, 32))
-              | (toUnsignedLong(i3) << pickPos(48, 48)));
-    }
-    private static long makeLong(int i0, int i1) {
-        return (toUnsignedLong(i0) << pickPos(32, 0))
-             | (toUnsignedLong(i1) << pickPos(32, 32));
-    }
-    private static int makeInt(short i0, short i1) {
-        return (toUnsignedInt(i0) << pickPos(16, 0))
-             | (toUnsignedInt(i1) << pickPos(16, 16));
-    }
-    private static int makeInt(byte i0, byte i1, byte i2, byte i3) {
-        return ((toUnsignedInt(i0) << pickPos(24, 0))
-              | (toUnsignedInt(i1) << pickPos(24, 8))
-              | (toUnsignedInt(i2) << pickPos(24, 16))
-              | (toUnsignedInt(i3) << pickPos(24, 24)));
-    }
-    private static short makeShort(byte i0, byte i1) {
-        return (short)((toUnsignedInt(i0) << pickPos(8, 0))
-                     | (toUnsignedInt(i1) << pickPos(8, 8)));
-    }
-
-    private static byte  pick(byte  le, byte  be) { return BE ? be : le; }
-    private static short pick(short le, short be) { return BE ? be : le; }
-    private static int   pick(int   le, int   be) { return BE ? be : le; }
-
-    // These methods write integers to memory from smaller parts
-    // provided by their caller.  The ordering in which these parts
-    // are written is the native endianness of this platform.
-    private void putLongParts(Object o, long offset, byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) {
-        putByte(o, offset + 0, pick(i0, i7));
-        putByte(o, offset + 1, pick(i1, i6));
-        putByte(o, offset + 2, pick(i2, i5));
-        putByte(o, offset + 3, pick(i3, i4));
-        putByte(o, offset + 4, pick(i4, i3));
-        putByte(o, offset + 5, pick(i5, i2));
-        putByte(o, offset + 6, pick(i6, i1));
-        putByte(o, offset + 7, pick(i7, i0));
-    }
-    private void putLongParts(Object o, long offset, short i0, short i1, short i2, short i3) {
-        putShort(o, offset + 0, pick(i0, i3));
-        putShort(o, offset + 2, pick(i1, i2));
-        putShort(o, offset + 4, pick(i2, i1));
-        putShort(o, offset + 6, pick(i3, i0));
-    }
-    private void putLongParts(Object o, long offset, int i0, int i1) {
-        putInt(o, offset + 0, pick(i0, i1));
-        putInt(o, offset + 4, pick(i1, i0));
-    }
-    private void putIntParts(Object o, long offset, short i0, short i1) {
-        putShort(o, offset + 0, pick(i0, i1));
-        putShort(o, offset + 2, pick(i1, i0));
-    }
-    private void putIntParts(Object o, long offset, byte i0, byte i1, byte i2, byte i3) {
-        putByte(o, offset + 0, pick(i0, i3));
-        putByte(o, offset + 1, pick(i1, i2));
-        putByte(o, offset + 2, pick(i2, i1));
-        putByte(o, offset + 3, pick(i3, i0));
-    }
-    private void putShortParts(Object o, long offset, byte i0, byte i1) {
-        putByte(o, offset + 0, pick(i0, i1));
-        putByte(o, offset + 1, pick(i1, i0));
-    }
-
-    // Zero-extend an integer
-    private static int toUnsignedInt(byte n)    { return n & 0xff; }
-    private static int toUnsignedInt(short n)   { return n & 0xffff; }
-    private static long toUnsignedLong(byte n)  { return n & 0xffl; }
-    private static long toUnsignedLong(short n) { return n & 0xffffl; }
-    private static long toUnsignedLong(int n)   { return n & 0xffffffffl; }
-
-    // Maybe byte-reverse an integer
-    private static char convEndian(boolean big, char n)   { return big == BE ? n : Character.reverseBytes(n); }
-    private static short convEndian(boolean big, short n) { return big == BE ? n : Short.reverseBytes(n)    ; }
-    private static int convEndian(boolean big, int n)     { return big == BE ? n : Integer.reverseBytes(n)  ; }
-    private static long convEndian(boolean big, long n)   { return big == BE ? n : Long.reverseBytes(n)     ; }
 }
--- a/jdk/src/java.base/share/classes/sun/nio/ch/NativeObject.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/NativeObject.java	Tue Nov 17 10:29:28 2015 -0800
@@ -29,7 +29,7 @@
 package sun.nio.ch;                                     // Formerly in sun.misc
 
 import java.nio.ByteOrder;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 
 // ## In the fullness of time, this class will be eliminated
--- a/jdk/src/java.base/share/classes/sun/nio/ch/Util.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/Util.java	Tue Nov 17 10:29:28 2015 -0800
@@ -35,7 +35,7 @@
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.*;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 import sun.misc.Cleaner;
 import sun.security.action.GetPropertyAction;
 
--- a/jdk/src/java.base/share/classes/sun/nio/cs/ArrayDecoder.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/ArrayDecoder.java	Tue Nov 17 10:29:28 2015 -0800
@@ -32,4 +32,8 @@
 
 public interface ArrayDecoder {
     int decode(byte[] src, int off, int len, char[] dst);
+
+    default boolean isASCIICompatible() {
+        return false;
+    }
 }
--- a/jdk/src/java.base/share/classes/sun/nio/cs/ArrayEncoder.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/ArrayEncoder.java	Tue Nov 17 10:29:28 2015 -0800
@@ -26,10 +26,24 @@
 package sun.nio.cs;
 
 /*
- * FastPath char[]->byte[] encoder, REPLACE on malformed input or
+ * FastPath char[]/byte[] -> byte[] encoder, REPLACE on malformed input or
  * unmappable input.
  */
 
 public interface ArrayEncoder {
+
+    //  is only used by j.u.zip.ZipCoder for utf8
     int encode(char[] src, int off, int len, byte[] dst);
+
+    default int encodeFromLatin1(byte[] src, int sp, int len, byte[] dst) {
+        return -1;
+    }
+
+    default int encodeFromUTF16(byte[] src, int sp, int len, byte[] dst) {
+        return -1;
+    }
+
+    default boolean isASCIICompatible() {
+        return false;
+    }
 }
--- a/jdk/src/java.base/share/classes/sun/nio/cs/DoubleByte.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/DoubleByte.java	Tue Nov 17 10:29:28 2015 -0800
@@ -115,6 +115,7 @@
         final char[] b2cSB;
         final int b2Min;
         final int b2Max;
+        final boolean isASCIICompatible;
 
         // for SimpleEUC override
         protected CoderResult crMalformedOrUnderFlow(int b) {
@@ -132,16 +133,23 @@
 
         public Decoder(Charset cs, float avgcpb, float maxcpb,
                        char[][] b2c, char[] b2cSB,
-                       int b2Min, int b2Max) {
+                       int b2Min, int b2Max,
+                       boolean isASCIICompatible) {
             super(cs, avgcpb, maxcpb);
             this.b2c = b2c;
             this.b2cSB = b2cSB;
             this.b2Min = b2Min;
             this.b2Max = b2Max;
+            this.isASCIICompatible = isASCIICompatible;
+        }
+
+        public Decoder(Charset cs, char[][] b2c, char[] b2cSB, int b2Min, int b2Max,
+                       boolean isASCIICompatible) {
+            this(cs, 0.5f, 1.0f, b2c, b2cSB, b2Min, b2Max, isASCIICompatible);
         }
 
         public Decoder(Charset cs, char[][] b2c, char[] b2cSB, int b2Min, int b2Max) {
-            this(cs, 0.5f, 1.0f, b2c, b2cSB, b2Min, b2Max);
+            this(cs, 0.5f, 1.0f, b2c, b2cSB, b2Min, b2Max, false);
         }
 
         protected CoderResult decodeArrayLoop(ByteBuffer src, CharBuffer dst) {
@@ -215,6 +223,7 @@
                 return decodeBufferLoop(src, dst);
         }
 
+        @Override
         public int decode(byte[] src, int sp, int len, char[] dst) {
             int dp = 0;
             int sl = sp + len;
@@ -230,12 +239,12 @@
                             if (b2c[b1] == B2C_UNMAPPABLE ||  // isNotLeadingByte
                                 b2c[b2] != B2C_UNMAPPABLE ||  // isLeadingByte
                                 decodeSingle(b2) != UNMAPPABLE_DECODING) {
-                                sp--;
+                               sp--;
                             }
                         }
                     }
                     if (c == UNMAPPABLE_DECODING) {
-                        c = repl;
+                         c = repl;
                     }
                 }
                 dst[dp++] = c;
@@ -243,6 +252,11 @@
             return dp;
         }
 
+        @Override
+        public boolean isASCIICompatible() {
+            return isASCIICompatible;
+        }
+
         public void implReset() {
             super.implReset();
         }
@@ -274,8 +288,14 @@
         private int  currentState;
 
         public Decoder_EBCDIC(Charset cs,
-                       char[][] b2c, char[] b2cSB, int b2Min, int b2Max) {
-            super(cs, b2c, b2cSB, b2Min, b2Max);
+                              char[][] b2c, char[] b2cSB, int b2Min, int b2Max,
+                              boolean isASCIICompatible) {
+            super(cs, b2c, b2cSB, b2Min, b2Max, isASCIICompatible);
+        }
+
+        public Decoder_EBCDIC(Charset cs,
+                              char[][] b2c, char[] b2cSB, int b2Min, int b2Max) {
+            super(cs, b2c, b2cSB, b2Min, b2Max, false);
         }
 
         public void implReset() {
@@ -403,6 +423,7 @@
             }
         }
 
+        @Override
         public int decode(byte[] src, int sp, int len, char[] dst) {
             int dp = 0;
             int sl = sp + len;
@@ -451,8 +472,13 @@
             b2cSB_UNMAPPABLE = new char[0x100];
             Arrays.fill(b2cSB_UNMAPPABLE, UNMAPPABLE_DECODING);
         }
+        public Decoder_DBCSONLY(Charset cs, char[][] b2c, char[] b2cSB, int b2Min, int b2Max,
+                                boolean isASCIICompatible) {
+            super(cs, 0.5f, 1.0f, b2c, b2cSB_UNMAPPABLE, b2Min, b2Max, isASCIICompatible);
+        }
+
         public Decoder_DBCSONLY(Charset cs, char[][] b2c, char[] b2cSB, int b2Min, int b2Max) {
-            super(cs, 0.5f, 1.0f, b2c, b2cSB_UNMAPPABLE, b2Min, b2Max);
+            super(cs, 0.5f, 1.0f, b2c, b2cSB_UNMAPPABLE, b2Min, b2Max, false);
         }
     }
 
@@ -464,8 +490,9 @@
         private final int SS3 =  0x8F;
 
         public Decoder_EUC_SIM(Charset cs,
-                        char[][] b2c, char[] b2cSB, int b2Min, int b2Max) {
-            super(cs, b2c, b2cSB, b2Min, b2Max);
+                               char[][] b2c, char[] b2cSB, int b2Min, int b2Max,
+                               boolean isASCIICompatible) {
+            super(cs, b2c, b2cSB, b2Min, b2Max, isASCIICompatible);
         }
 
         // No support provided for G2/G3 for SimpleEUC
@@ -481,6 +508,7 @@
             return CoderResult.unmappableForLength(2);
         }
 
+        @Override
         public int decode(byte[] src, int sp, int len, char[] dst) {
             int dp = 0;
             int sl = sp + len;
@@ -515,17 +543,25 @@
         private final char[] c2b;
         private final char[] c2bIndex;
         protected Surrogate.Parser sgp;
+        final boolean isASCIICompatible;
 
         public Encoder(Charset cs, char[] c2b, char[] c2bIndex) {
+            this(cs, c2b, c2bIndex, false);
+        }
+
+        public Encoder(Charset cs, char[] c2b, char[] c2bIndex, boolean isASCIICompatible) {
             super(cs, 2.0f, 2.0f);
             this.c2b = c2b;
             this.c2bIndex = c2bIndex;
+            this.isASCIICompatible = isASCIICompatible;
         }
 
-        public Encoder(Charset cs, float avg, float max, byte[] repl, char[] c2b, char[] c2bIndex) {
+        public Encoder(Charset cs, float avg, float max, byte[] repl, char[] c2b, char[] c2bIndex,
+                       boolean isASCIICompatible) {
             super(cs, avg, max, repl);
             this.c2b = c2b;
             this.c2bIndex = c2bIndex;
+            this.isASCIICompatible = isASCIICompatible;
         }
 
         public boolean canEncode(char c) {
@@ -624,6 +660,7 @@
             repl = newReplacement;
         }
 
+        @Override
         public int encode(char[] src, int sp, int len, byte[] dst) {
             int dp = 0;
             int sl = sp + len;
@@ -647,11 +684,69 @@
                 } else {                          // SingleByte
                     dst[dp++] = (byte)bb;
                 }
+            }
+            return dp;
+        }
+
+        @Override
+        public int encodeFromLatin1(byte[] src, int sp, int len, byte[] dst) {
+            int dp = 0;
+            int sl = sp + len;
+            while (sp < sl) {
+                char c = (char)(src[sp++] & 0xff);
+                int bb = encodeChar(c);
+                if (bb == UNMAPPABLE_ENCODING) {
+                    // no surrogate pair in latin1 string
+                    dst[dp++] = repl[0];
+                    if (repl.length > 1) {
+                        dst[dp++] = repl[1];
+                    }
+                    continue;
+                } //else
+                if (bb > MAX_SINGLEBYTE) { // DoubleByte
+                    dst[dp++] = (byte)(bb >> 8);
+                    dst[dp++] = (byte)bb;
+                } else {                   // SingleByte
+                    dst[dp++] = (byte)bb;
+                }
 
             }
             return dp;
         }
 
+        @Override
+        public int encodeFromUTF16(byte[] src, int sp, int len, byte[] dst) {
+            int dp = 0;
+            int sl = sp + len;
+            while (sp < sl) {
+                char c = StringUTF16.getChar(src, sp++);
+                int bb = encodeChar(c);
+                if (bb == UNMAPPABLE_ENCODING) {
+                    if (Character.isHighSurrogate(c) && sp < sl &&
+                        Character.isLowSurrogate(StringUTF16.getChar(src, sp))) {
+                        sp++;
+                    }
+                    dst[dp++] = repl[0];
+                    if (repl.length > 1) {
+                        dst[dp++] = repl[1];
+                    }
+                    continue;
+                } //else
+                if (bb > MAX_SINGLEBYTE) { // DoubleByte
+                    dst[dp++] = (byte)(bb >> 8);
+                    dst[dp++] = (byte)bb;
+                } else {                   // SingleByte
+                    dst[dp++] = (byte)bb;
+                }
+            }
+            return dp;
+        }
+
+        @Override
+        public boolean isASCIICompatible() {
+            return isASCIICompatible;
+        }
+
         public int encodeChar(char ch) {
             return c2b[c2bIndex[ch >> 8] + (ch & 0xff)];
         }
@@ -741,9 +836,11 @@
     }
 
     public static class Encoder_DBCSONLY extends Encoder {
+
         public Encoder_DBCSONLY(Charset cs, byte[] repl,
-                         char[] c2b, char[] c2bIndex) {
-            super(cs, 2.0f, 2.0f, repl, c2b, c2bIndex);
+                                char[] c2b, char[] c2bIndex,
+                                boolean isASCIICompatible) {
+            super(cs, 2.0f, 2.0f, repl, c2b, c2bIndex, isASCIICompatible);
         }
 
         public int encodeChar(char ch) {
@@ -754,8 +851,6 @@
         }
     }
 
-
-
     public static class Encoder_EBCDIC extends Encoder {
         static final int SBCS = 0;
         static final int DBCS = 1;
@@ -764,8 +859,9 @@
 
         protected int  currentState = SBCS;
 
-        public Encoder_EBCDIC(Charset cs, char[] c2b, char[] c2bIndex) {
-            super(cs, 4.0f, 5.0f, new byte[] {(byte)0x6f}, c2b, c2bIndex);
+        public Encoder_EBCDIC(Charset cs, char[] c2b, char[] c2bIndex,
+                              boolean isASCIICompatible) {
+            super(cs, 4.0f, 5.0f, new byte[] {(byte)0x6f}, c2b, c2bIndex, isASCIICompatible);
         }
 
         protected void implReset() {
@@ -878,6 +974,7 @@
             }
         }
 
+        @Override
         public int encode(char[] src, int sp, int len, byte[] dst) {
             int dp = 0;
             int sl = sp + len;
@@ -917,12 +1014,88 @@
             }
             return dp;
         }
+
+        @Override
+        public int encodeFromLatin1(byte[] src, int sp, int len, byte[] dst) {
+            int dp = 0;
+            int sl = sp + len;
+            while (sp < sl) {
+                char c = (char)(src[sp++] & 0xff);
+                int bb = encodeChar(c);
+                if (bb == UNMAPPABLE_ENCODING) {
+                    // no surrogate pair in latin1 string
+                    dst[dp++] = repl[0];
+                    if (repl.length > 1)
+                        dst[dp++] = repl[1];
+                    continue;
+                } //else
+                if (bb > MAX_SINGLEBYTE) {           // DoubleByte
+                    if (currentState == SBCS) {
+                        currentState = DBCS;
+                        dst[dp++] = SO;
+                    }
+                    dst[dp++] = (byte)(bb >> 8);
+                    dst[dp++] = (byte)bb;
+                } else {                             // SingleByte
+                    if (currentState == DBCS) {
+                         currentState = SBCS;
+                         dst[dp++] = SI;
+                    }
+                    dst[dp++] = (byte)bb;
+                }
+            }
+            if (currentState == DBCS) {
+                 currentState = SBCS;
+                 dst[dp++] = SI;
+            }
+            return dp;
+        }
+
+        @Override
+        public int encodeFromUTF16(byte[] src, int sp, int len, byte[] dst) {
+            int dp = 0;
+            int sl = sp + len;
+            while (sp < sl) {
+                char c = StringUTF16.getChar(src, sp++);
+                int bb = encodeChar(c);
+                if (bb == UNMAPPABLE_ENCODING) {
+                    if (Character.isHighSurrogate(c) && sp < sl &&
+                        Character.isLowSurrogate(StringUTF16.getChar(src, sp))) {
+                        sp++;
+                    }
+                    dst[dp++] = repl[0];
+                    if (repl.length > 1)
+                        dst[dp++] = repl[1];
+                    continue;
+                } //else
+                if (bb > MAX_SINGLEBYTE) {           // DoubleByte
+                    if (currentState == SBCS) {
+                        currentState = DBCS;
+                        dst[dp++] = SO;
+                    }
+                    dst[dp++] = (byte)(bb >> 8);
+                    dst[dp++] = (byte)bb;
+                } else {                             // SingleByte
+                    if (currentState == DBCS) {
+                         currentState = SBCS;
+                         dst[dp++] = SI;
+                    }
+                    dst[dp++] = (byte)bb;
+                }
+            }
+            if (currentState == DBCS) {
+                 currentState = SBCS;
+                 dst[dp++] = SI;
+            }
+            return dp;
+        }
     }
 
     // EUC_SIMPLE
     public static class Encoder_EUC_SIM extends Encoder {
-        public Encoder_EUC_SIM(Charset cs, char[] c2b, char[] c2bIndex) {
-            super(cs, c2b, c2bIndex);
+        public Encoder_EUC_SIM(Charset cs, char[] c2b, char[] c2bIndex,
+                               boolean isASCIICompatible) {
+            super(cs, c2b, c2bIndex, isASCIICompatible);
         }
     }
 
--- a/jdk/src/java.base/share/classes/sun/nio/cs/HKSCS.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/HKSCS.java	Tue Nov 17 10:29:28 2015 -0800
@@ -53,7 +53,7 @@
             // super(cs, 0.5f, 1.0f);
             // need to extends DoubleByte.Decoder so the
             // sun.io can use it. this implementation
-            super(cs, 0.5f, 1.0f, null, null, 0, 0);
+            super(cs, 0.5f, 1.0f, null, null, 0, 0, true);
             this.big5Dec = big5Dec;
             this.b2cBmp = b2cBmp;
             this.b2cSupp = b2cSupp;
@@ -239,7 +239,7 @@
                           char[][] c2bBmp,
                           char[][] c2bSupp)
         {
-            super(cs, null, null);
+            super(cs, null, null, true);
             this.big5Enc = big5Enc;
             this.c2bBmp = c2bBmp;
             this.c2bSupp = c2bSupp;
@@ -389,6 +389,33 @@
             return dp;
         }
 
+        public int encodeFromUTF16(byte[] src, int sp, int len, byte[] dst) {
+            int dp = 0;
+            int sl = sp + len;
+            int dl = dst.length;
+            while (sp < sl) {
+                char c = StringUTF16.getChar(src, sp++);
+                int bb = encodeChar(c);
+                if (bb == UNMAPPABLE_ENCODING) {
+                    if (!Character.isHighSurrogate(c) || sp == sl ||
+                        !Character.isLowSurrogate(StringUTF16.getChar(src,sp)) ||
+                        (bb = encodeSupp(Character.toCodePoint(c, StringUTF16.getChar(src, sp++))))
+                        == UNMAPPABLE_ENCODING) {
+                        dst[dp++] = repl[0];
+                        if (repl.length > 1)
+                            dst[dp++] = repl[1];
+                        continue;
+                    }
+                }
+                if (bb > MAX_SINGLEBYTE) { // DoubleByte
+                    dst[dp++] = (byte)(bb >> 8);
+                    dst[dp++] = (byte)bb;
+                } else {                   // SingleByte
+                    dst[dp++] = (byte)bb;
+                }
+            }
+            return dp;
+        }
 
         static char[] C2B_UNMAPPABLE = new char[0x100];
         static {
--- a/jdk/src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java	Tue Nov 17 10:29:28 2015 -0800
@@ -132,6 +132,10 @@
                 dst[dp++] = (char)(src[sp++] & 0xff);
             return dp;
         }
+
+        public boolean isASCIICompatible() {
+            return true;
+        }
     }
 
     private static class Encoder extends CharsetEncoder
@@ -297,5 +301,9 @@
             }
             return dp;
         }
+
+        public boolean isASCIICompatible() {
+            return true;
+        }
     }
 }
--- a/jdk/src/java.base/share/classes/sun/nio/cs/SingleByte.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/SingleByte.java	Tue Nov 17 10:29:28 2015 -0800
@@ -49,10 +49,18 @@
     public static final class Decoder extends CharsetDecoder
                                       implements ArrayDecoder {
         private final char[] b2c;
+        private final boolean isASCIICompatible;
 
         public Decoder(Charset cs, char[] b2c) {
             super(cs, 1.0f, 1.0f);
             this.b2c = b2c;
+            this.isASCIICompatible = false;
+        }
+
+        public Decoder(Charset cs, char[] b2c, boolean isASCIICompatible) {
+            super(cs, 1.0f, 1.0f);
+            this.b2c = b2c;
+            this.isASCIICompatible = isASCIICompatible;
         }
 
         private CoderResult decodeArrayLoop(ByteBuffer src, CharBuffer dst) {
@@ -116,6 +124,7 @@
             repl = newReplacement.charAt(0);
         }
 
+        @Override
         public int decode(byte[] src, int sp, int len, char[] dst) {
             if (len > dst.length)
                 len = dst.length;
@@ -129,6 +138,11 @@
             }
             return dp;
         }
+
+        @Override
+        public boolean isASCIICompatible() {
+            return isASCIICompatible;
+        }
     }
 
     public static final class Encoder extends CharsetEncoder
@@ -136,11 +150,13 @@
         private Surrogate.Parser sgp;
         private final char[] c2b;
         private final char[] c2bIndex;
+        private final boolean isASCIICompatible;
 
-        public Encoder(Charset cs, char[] c2b, char[] c2bIndex) {
+        public Encoder(Charset cs, char[] c2b, char[] c2bIndex, boolean isASCIICompatible) {
             super(cs, 1.0f, 1.0f);
             this.c2b = c2b;
             this.c2bIndex = c2bIndex;
+            this.isASCIICompatible = isASCIICompatible;
         }
 
         public boolean canEncode(char c) {
@@ -252,6 +268,51 @@
             }
             return dp;
         }
+
+        @Override
+        public int encodeFromLatin1(byte[] src, int sp, int len, byte[] dst) {
+            int dp = 0;
+            int sl = sp + Math.min(len, dst.length);
+            while (sp < sl) {
+                char c = (char)(src[sp++] & 0xff);
+                int b = encode(c);
+                if (b == UNMAPPABLE_ENCODING) {
+                    dst[dp++] = repl;
+                } else {
+                    dst[dp++] = (byte)b;
+                }
+            }
+            return dp;
+        }
+
+        @Override
+        public int encodeFromUTF16(byte[] src, int sp, int len, byte[] dst) {
+            int dp = 0;
+            int sl = sp + Math.min(len, dst.length);
+            while (sp < sl) {
+                char c = StringUTF16.getChar(src, sp++);
+                int b = encode(c);
+                if (b != UNMAPPABLE_ENCODING) {
+                    dst[dp++] = (byte)b;
+                    continue;
+                }
+                if (Character.isHighSurrogate(c) && sp < sl &&
+                    Character.isLowSurrogate(StringUTF16.getChar(src, sp))) {
+                    if (len > dst.length) {
+                        sl++;
+                        len--;
+                    }
+                    sp++;
+                }
+                dst[dp++] = repl;
+            }
+            return dp;
+        }
+
+        @Override
+        public boolean isASCIICompatible() {
+            return isASCIICompatible;
+        }
     }
 
     // init the c2b and c2bIndex tables from b2c.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/StringUTF16.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+package sun.nio.cs;
+
+import static sun.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET;
+import static sun.misc.Unsafe.ARRAY_BYTE_INDEX_SCALE;
+
+class StringUTF16 {
+
+    public static char getChar(byte[] val, int index) {
+        return unsafe.getChar(val,
+                              ARRAY_BYTE_BASE_OFFSET + ARRAY_BYTE_INDEX_SCALE * index * 2L);
+    }
+
+    private static final sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
+}
--- a/jdk/src/java.base/share/classes/sun/nio/cs/US_ASCII.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/US_ASCII.java	Tue Nov 17 10:29:28 2015 -0800
@@ -146,6 +146,10 @@
             }
             return dp;
         }
+
+        public boolean isASCIICompatible() {
+            return true;
+        }
     }
 
     private static class Encoder extends CharsetEncoder
@@ -259,6 +263,10 @@
             }
             return dp;
         }
+
+        public boolean isASCIICompatible() {
+            return true;
+        }
     }
 
 }
--- a/jdk/src/java.base/share/classes/sun/nio/cs/UTF_8.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/UTF_8.java	Tue Nov 17 10:29:28 2015 -0800
@@ -549,6 +549,10 @@
             }
             return dp;
         }
+
+        public boolean isASCIICompatible() {
+            return true;
+        }
     }
 
     private static final class Encoder extends CharsetEncoder
@@ -742,5 +746,9 @@
             }
             return dp;
         }
+
+        public boolean isASCIICompatible() {
+            return true;
+        }
     }
 }
--- a/jdk/src/java.base/share/classes/sun/nio/fs/Cancellable.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/nio/fs/Cancellable.java	Tue Nov 17 10:29:28 2015 -0800
@@ -26,7 +26,7 @@
 package sun.nio.fs;
 
 import sun.misc.ManagedLocalsThread;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 import java.util.concurrent.ExecutionException;
 
 /**
--- a/jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffer.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffer.java	Tue Nov 17 10:29:28 2015 -0800
@@ -25,7 +25,7 @@
 
 package sun.nio.fs;
 
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 import sun.misc.Cleaner;
 
 /**
--- a/jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffers.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffers.java	Tue Nov 17 10:29:28 2015 -0800
@@ -25,7 +25,7 @@
 
 package sun.nio.fs;
 
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 /**
  * Factory for native buffers.
--- a/jdk/src/java.base/share/classes/sun/reflect/AccessorGenerator.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/reflect/AccessorGenerator.java	Tue Nov 17 10:29:28 2015 -0800
@@ -26,7 +26,7 @@
 package sun.reflect;
 
 import java.lang.reflect.*;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 /** Shared functionality for all accessor generators */
 
--- a/jdk/src/java.base/share/classes/sun/reflect/ClassDefiner.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/reflect/ClassDefiner.java	Tue Nov 17 10:29:28 2015 -0800
@@ -27,7 +27,7 @@
 
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 /** Utility class which assists in calling Unsafe.defineClass() by
     creating a new class loader which delegates to the one needed in
--- a/jdk/src/java.base/share/classes/sun/reflect/FieldInfo.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/reflect/FieldInfo.java	Tue Nov 17 10:29:28 2015 -0800
@@ -38,7 +38,7 @@
     private String signature;
     private int    modifiers;
     // This is compatible with the old reflection implementation's
-    // "slot" value to allow sun.misc.Unsafe to work
+    // "slot" value to allow jdk.internal.misc.Unsafe to work
     private int    slot;
 
     // Not really necessary to provide a constructor since the VM
--- a/jdk/src/java.base/share/classes/sun/reflect/MagicAccessorImpl.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/reflect/MagicAccessorImpl.java	Tue Nov 17 10:29:28 2015 -0800
@@ -32,7 +32,7 @@
     fields and methods of other classes. It is used to hold the code
     for dynamically-generated FieldAccessorImpl and MethodAccessorImpl
     subclasses. (Use of the word "unsafe" was avoided in this class's
-    name to avoid confusion with {@link sun.misc.Unsafe}.) </P>
+    name to avoid confusion with {@link jdk.internal.misc.Unsafe}.) </P>
 
     <P> The bug fix for 4486457 also necessitated disabling
     verification for this class and all subclasses, as opposed to just
--- a/jdk/src/java.base/share/classes/sun/reflect/ReflectionFactory.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/reflect/ReflectionFactory.java	Tue Nov 17 10:29:28 2015 -0800
@@ -44,7 +44,7 @@
     subversion of both the language and the verifier. For this reason,
     they are all instance methods, and access to the constructor of
     this factory is guarded by a security check, in similar style to
-    {@link sun.misc.Unsafe}. </P>
+    {@link jdk.internal.misc.Unsafe}. </P>
 */
 
 public class ReflectionFactory {
--- a/jdk/src/java.base/share/classes/sun/reflect/UnsafeFieldAccessorImpl.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/reflect/UnsafeFieldAccessorImpl.java	Tue Nov 17 10:29:28 2015 -0800
@@ -27,9 +27,9 @@
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
-/** Base class for sun.misc.Unsafe-based FieldAccessors. The
+/** Base class for jdk.internal.misc.Unsafe-based FieldAccessors. The
     observation is that there are only nine types of fields from the
     standpoint of reflection code: the eight primitive types and
     Object. Using class Unsafe instead of generated bytecodes saves
--- a/jdk/src/java.base/share/classes/sun/reflect/UnsafeQualifiedFieldAccessorImpl.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/reflect/UnsafeQualifiedFieldAccessorImpl.java	Tue Nov 17 10:29:28 2015 -0800
@@ -27,10 +27,10 @@
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 /**
- * Base class for sun.misc.Unsafe-based FieldAccessors for fields with
+ * Base class for jdk.internal.misc.Unsafe-based FieldAccessors for fields with
  * final or volatile qualifiers. These differ from unqualified
  * versions in that (1) they check for read-only status (2) they use
  * the volatile forms of Unsafe get/put methods. (When accessed via
--- a/jdk/src/java.base/share/classes/sun/reflect/UnsafeQualifiedStaticFieldAccessorImpl.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/reflect/UnsafeQualifiedStaticFieldAccessorImpl.java	Tue Nov 17 10:29:28 2015 -0800
@@ -28,9 +28,9 @@
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 import java.security.AccessController;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
-/** Base class for sun.misc.Unsafe-based FieldAccessors for final or
+/** Base class for jdk.internal.misc.Unsafe-based FieldAccessors for final or
     static volatile fields.  */
 
 abstract class UnsafeQualifiedStaticFieldAccessorImpl
--- a/jdk/src/java.base/share/classes/sun/reflect/UnsafeStaticFieldAccessorImpl.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/reflect/UnsafeStaticFieldAccessorImpl.java	Tue Nov 17 10:29:28 2015 -0800
@@ -28,9 +28,9 @@
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 import java.security.AccessController;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
-/** Base class for sun.misc.Unsafe-based FieldAccessors for static
+/** Base class for jdk.internal.misc.Unsafe-based FieldAccessors for static
     fields. The observation is that there are only nine types of
     fields from the standpoint of reflection code: the eight primitive
     types and Object. Using class Unsafe instead of generated
--- a/jdk/src/java.base/share/classes/sun/reflect/misc/ReflectUtil.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/reflect/misc/ReflectUtil.java	Tue Nov 17 10:29:28 2015 -0800
@@ -337,7 +337,7 @@
 
     /**
      * Checks if {@code Class cls} is a VM-anonymous class
-     * as defined by {@link sun.misc.Unsafe#defineAnonymousClass}
+     * as defined by {@link jdk.internal.misc.Unsafe#defineAnonymousClass}
      * (not to be confused with a Java Language anonymous inner class).
      */
     public static boolean isVMAnonymousClass(Class<?> cls) {
--- a/jdk/src/java.base/share/classes/sun/security/provider/ByteArrayAccess.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/security/provider/ByteArrayAccess.java	Tue Nov 17 10:29:28 2015 -0800
@@ -30,7 +30,7 @@
 
 import java.nio.ByteOrder;
 
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 /**
  * Optimized methods for converting between byte[] and int[]/long[], both for
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/AdaptableX509CertSelector.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/AdaptableX509CertSelector.java	Tue Nov 17 10:29:28 2015 -0800
@@ -36,9 +36,7 @@
 
 import sun.security.util.Debug;
 import sun.security.util.DerInputStream;
-import sun.security.util.DerOutputStream;
 import sun.security.x509.SerialNumber;
-import sun.security.x509.KeyIdentifier;
 import sun.security.x509.AuthorityKeyIdentifierExtension;
 
 /**
@@ -131,13 +129,7 @@
         serial = null;
 
         if (ext != null) {
-            KeyIdentifier akid = (KeyIdentifier)ext.get(
-                AuthorityKeyIdentifierExtension.KEY_ID);
-            if (akid != null) {
-                DerOutputStream derout = new DerOutputStream();
-                derout.putOctetString(akid.getIdentifier());
-                ski = derout.toByteArray();
-            }
+            ski = ext.getEncodedKeyIdentifier();
             SerialNumber asn = (SerialNumber)ext.get(
                 AuthorityKeyIdentifierExtension.SERIAL_NUMBER);
             if (asn != null) {
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java	Tue Nov 17 10:29:28 2015 -0800
@@ -33,7 +33,6 @@
 import java.util.*;
 
 import sun.security.util.Debug;
-import sun.security.util.DerOutputStream;
 import static sun.security.x509.PKIXExtensions.*;
 import sun.security.x509.*;
 
@@ -607,12 +606,9 @@
             AuthorityKeyIdentifierExtension akidext =
                                             crlImpl.getAuthKeyIdExtension();
             if (akidext != null) {
-                KeyIdentifier akid = (KeyIdentifier)akidext.get(
-                        AuthorityKeyIdentifierExtension.KEY_ID);
-                if (akid != null) {
-                    DerOutputStream derout = new DerOutputStream();
-                    derout.putOctetString(akid.getIdentifier());
-                    certSel.setSubjectKeyIdentifier(derout.toByteArray());
+                byte[] kid = akidext.getEncodedKeyIdentifier();
+                if (kid != null) {
+                    certSel.setSubjectKeyIdentifier(kid);
                 }
 
                 SerialNumber asn = (SerialNumber)akidext.get(
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java	Tue Nov 17 10:29:28 2015 -0800
@@ -46,9 +46,10 @@
 import sun.security.util.Debug;
 import sun.security.x509.AccessDescription;
 import sun.security.x509.AuthorityInfoAccessExtension;
+import sun.security.x509.AuthorityKeyIdentifierExtension;
 import static sun.security.x509.PKIXExtensions.*;
 import sun.security.x509.X500Name;
-import sun.security.x509.AuthorityKeyIdentifierExtension;
+import sun.security.x509.X509CertImpl;
 
 /**
  * This class represents a forward builder, which is able to retrieve
@@ -69,7 +70,6 @@
     private AdaptableX509CertSelector caSelector;
     private X509CertSelector caTargetSelector;
     TrustAnchor trustAnchor;
-    private Comparator<X509Certificate> comparator;
     private boolean searchAllCertStores = true;
 
     /**
@@ -93,7 +93,6 @@
                 trustedSubjectDNs.add(anchor.getCA());
             }
         }
-        comparator = new PKIXCertComparator(trustedSubjectDNs);
         this.searchAllCertStores = searchAllCertStores;
     }
 
@@ -122,6 +121,8 @@
          * As each cert is added, it is sorted based on the PKIXCertComparator
          * algorithm.
          */
+        Comparator<X509Certificate> comparator =
+            new PKIXCertComparator(trustedSubjectDNs, currState.cert);
         Set<X509Certificate> certs = new TreeSet<>(comparator);
 
         /*
@@ -265,14 +266,6 @@
                 (caSelector, currentState.subjectNamesTraversed);
 
             /*
-             * Facilitate certification path construction with authority
-             * key identifier and subject key identifier.
-             */
-            AuthorityKeyIdentifierExtension akidext =
-                    currentState.cert.getAuthorityKeyIdentifierExtension();
-            caSelector.setSkiAndSerialNumber(akidext);
-
-            /*
              * check the validity period
              */
             caSelector.setValidityPeriod(currentState.cert.getNotBefore(),
@@ -404,41 +397,68 @@
      *
      * Preference order for current cert:
      *
-     * 1) Issuer matches a trusted subject
+     * 1) The key identifier of an AKID extension (if present) in the
+     *    previous certificate matches the key identifier in the SKID extension
+     *
+     * 2) Issuer matches a trusted subject
      *    Issuer: ou=D,ou=C,o=B,c=A
      *
-     * 2) Issuer is a descendant of a trusted subject (in order of
+     * 3) Issuer is a descendant of a trusted subject (in order of
      *    number of links to the trusted subject)
      *    a) Issuer: ou=E,ou=D,ou=C,o=B,c=A        [links=1]
      *    b) Issuer: ou=F,ou=E,ou=D,ou=C,ou=B,c=A  [links=2]
      *
-     * 3) Issuer is an ancestor of a trusted subject (in order of number of
+     * 4) Issuer is an ancestor of a trusted subject (in order of number of
      *    links to the trusted subject)
      *    a) Issuer: ou=C,o=B,c=A [links=1]
      *    b) Issuer: o=B,c=A      [links=2]
      *
-     * 4) Issuer is in the same namespace as a trusted subject (in order of
+     * 5) Issuer is in the same namespace as a trusted subject (in order of
      *    number of links to the trusted subject)
      *    a) Issuer: ou=G,ou=C,o=B,c=A  [links=2]
      *    b) Issuer: ou=H,o=B,c=A       [links=3]
      *
-     * 5) Issuer is an ancestor of certificate subject (in order of number
+     * 6) Issuer is an ancestor of certificate subject (in order of number
      *    of links to the certificate subject)
      *    a) Issuer:  ou=K,o=J,c=A
      *       Subject: ou=L,ou=K,o=J,c=A
      *    b) Issuer:  o=J,c=A
      *       Subject: ou=L,ou=K,0=J,c=A
      *
-     * 6) Any other certificates
+     * 7) Any other certificates
      */
     static class PKIXCertComparator implements Comparator<X509Certificate> {
 
         static final String METHOD_NME = "PKIXCertComparator.compare()";
 
         private final Set<X500Principal> trustedSubjectDNs;
+        private final X509CertSelector certSkidSelector;
 
-        PKIXCertComparator(Set<X500Principal> trustedSubjectDNs) {
+        PKIXCertComparator(Set<X500Principal> trustedSubjectDNs,
+                           X509CertImpl previousCert) throws IOException {
             this.trustedSubjectDNs = trustedSubjectDNs;
+            this.certSkidSelector = getSelector(previousCert);
+        }
+
+        /**
+         * Returns an X509CertSelector for matching on the authority key
+         * identifier, or null if not applicable.
+         */
+        private X509CertSelector getSelector(X509CertImpl previousCert)
+            throws IOException {
+            if (previousCert != null) {
+                AuthorityKeyIdentifierExtension akidExt =
+                    previousCert.getAuthorityKeyIdentifierExtension();
+                if (akidExt != null) {
+                    byte[] skid = akidExt.getEncodedKeyIdentifier();
+                    if (skid != null) {
+                        X509CertSelector selector = new X509CertSelector();
+                        selector.setSubjectKeyIdentifier(skid);
+                        return selector;
+                    }
+                }
+            }
+            return null;
         }
 
         /**
@@ -462,6 +482,16 @@
             // if certs are the same, return 0
             if (oCert1.equals(oCert2)) return 0;
 
+            // If akid/skid match then it is preferable
+            if (certSkidSelector != null) {
+                if (certSkidSelector.match(oCert1)) {
+                    return -1;
+                }
+                if (certSkidSelector.match(oCert2)) {
+                    return 1;
+                }
+            }
+
             X500Principal cIssuer1 = oCert1.getIssuerX500Principal();
             X500Principal cIssuer2 = oCert2.getIssuerX500Principal();
             X500Name cIssuer1Name = X500Name.asX500Name(cIssuer1);
--- a/jdk/src/java.base/share/classes/sun/security/x509/AuthorityKeyIdentifierExtension.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/classes/sun/security/x509/AuthorityKeyIdentifierExtension.java	Tue Nov 17 10:29:28 2015 -0800
@@ -310,4 +310,16 @@
     public String getName() {
         return (NAME);
     }
+
+    /**
+     * Return the encoded key identifier, or null if not specified.
+     */
+    public byte[] getEncodedKeyIdentifier() throws IOException {
+        if (id != null) {
+            DerOutputStream derOut = new DerOutputStream();
+            id.encode(derOut);
+            return derOut.toByteArray();
+        }
+        return null;
+    }
 }
--- a/jdk/src/java.base/share/native/libjava/String.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/native/libjava/String.c	Tue Nov 17 10:29:28 2015 -0800
@@ -31,3 +31,14 @@
 {
     return JVM_InternString(env, this);
 }
+
+JNIEXPORT jboolean JNICALL
+Java_java_lang_StringUTF16_isBigEndian(JNIEnv *env, jclass cls)
+{
+  unsigned int endianTest = 0xff000000;
+  if (((char*)(&endianTest))[0] != 0) {
+    return JNI_TRUE;
+  } else {
+    return JNI_FALSE;
+  }
+}
--- a/jdk/src/java.base/share/native/libjava/check_version.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/native/libjava/check_version.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -24,10 +24,11 @@
  */
 
 #include "jni.h"
+#include "jni_util.h"
 #include "jvm.h"
 
 JNIEXPORT jint JNICALL
-JNI_OnLoad(JavaVM *vm, void *reserved)
+DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
 {
     jint vm_version = JVM_GetInterfaceVersion();
     if (vm_version != JVM_INTERFACE_VERSION) {
--- a/jdk/src/java.base/share/native/libjava/jio.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/native/libjava/jio.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -27,6 +27,7 @@
 
 #include "jni.h"
 
+#ifndef STATIC_BUILD
 
 /* This is a temporary solution until we figure out how to let native
  * libraries use jio_* without linking with the VM.
@@ -63,3 +64,6 @@
 
     return len;
 }
+
+#endif
+
--- a/jdk/src/java.base/share/native/libjava/jni_util.h	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/native/libjava/jni_util.h	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -389,6 +389,117 @@
 
 extern size_t getLastErrorString(char *buf, size_t len);
 extern int getErrorString(int err, char *buf, size_t len);
+
+#ifdef STATIC_BUILD
+/* Macros for handling declaration of static/dynamic
+ * JNI library Load/Unload functions
+ *
+ * Use DEF_JNI_On{Un}Load when you want a static and non-static entry points.
+ * Use DEF_STATIC_JNI_On{Un}Load when you only want a static one.
+ *
+ * LIBRARY_NAME must be set to the name of the library
+ */
+
+/* These three macros are needed to get proper concatenation of
+ * the LIBRARY_NAME
+ *
+ * NOTE: LIBRARY_NAME must be set for static builds.
+ */
+#define ADD_LIB_NAME3(name, lib) name ## lib
+#define ADD_LIB_NAME2(name, lib) ADD_LIB_NAME3(name, lib)
+#define ADD_LIB_NAME(entry) ADD_LIB_NAME2(entry, LIBRARY_NAME)
+
+#define DEF_JNI_OnLoad \
+ADD_LIB_NAME(JNI_OnLoad_)(JavaVM *vm, void *reserved) \
+{ \
+  jint JNICALL ADD_LIB_NAME(JNI_OnLoad_dynamic_)(JavaVM *vm, void *reserved); \
+  ADD_LIB_NAME(JNI_OnLoad_dynamic_)(vm, reserved); \
+  return JNI_VERSION_1_8; \
+} \
+jint JNICALL ADD_LIB_NAME(JNI_OnLoad_dynamic_)
+
+#define DEF_STATIC_JNI_OnLoad \
+JNIEXPORT jint JNICALL ADD_LIB_NAME(JNI_OnLoad_)(JavaVM *vm, void *reserved) { \
+    return JNI_VERSION_1_8; \
+}
+
+#define DEF_JNI_OnUnload \
+ADD_LIB_NAME(JNI_OnUnload_)(JavaVM *vm, void *reserved) \
+{ \
+  void JNICALL ADD_LIB_NAME(JNI_OnUnload_dynamic_)(JavaVM *vm, void *reserved); \
+  ADD_LIB_NAME(JNI_OnUnload_dynamic_)(vm, reserved); \
+} \
+void JNICALL ADD_LIB_NAME(JNI_OnUnload_dynamic_)
+
+#define DEF_STATIC_JNI_OnUnload \
+ADD_LIB_NAME(JNI_OnUnload_)
+
+#else
+
+#define DEF_JNI_OnLoad JNI_OnLoad
+#define DEF_STATIC_JNI_OnLoad
+#define DEF_JNI_OnUnload JNI_OnUnload
+#define DEF_STATIC_JNI_OnUnload
+#endif
+
+#ifdef STATIC_BUILD
+/* Macros for handling declaration of static/dynamic
+ * Agent library Load/Attach/Unload functions
+ *
+ * Use DEF_Agent_OnLoad, DEF_Agent_OnAttach or DEF_Agent_OnUnload
+ *     when you want both static and non-static entry points.
+ * Use DEF_STATIC_Agent_OnLoad, DEF_STATIC_Agent_OnAttach or
+ *     DEF_STATIC_Agent_OnUnload when you only want a static one.
+ *
+ * LIBRARY_NAME must be set to the name of the library for static builds.
+ */
+
+#define DEF_Agent_OnLoad \
+ADD_LIB_NAME(Agent_OnLoad_)(JavaVM *vm, char *options, void *reserved) \
+{ \
+  jint JNICALL ADD_LIB_NAME(Agent_OnLoad_dynamic_)(JavaVM *vm, char *options, void *reserved); \
+  return ADD_LIB_NAME(Agent_OnLoad_dynamic_)(vm, options, reserved); \
+} \
+jint JNICALL ADD_LIB_NAME(Agent_OnLoad_dynamic_)
+
+#define DEF_STATIC_Agent_OnLoad \
+JNIEXPORT jint JNICALL ADD_LIB_NAME(Agent_OnLoad_)(JavaVM *vm, char *options, void *reserved) { \
+    return JNI_FALSE; \
+}
+
+#define DEF_Agent_OnAttach \
+ADD_LIB_NAME(Agent_OnAttach_)(JavaVM *vm, char *options, void *reserved) \
+{ \
+  jint JNICALL ADD_LIB_NAME(Agent_OnAttach_dynamic_)(JavaVM *vm, char *options, void *reserved); \
+  return ADD_LIB_NAME(Agent_OnAttach_dynamic_)(vm, options, reserved); \
+} \
+jint JNICALL ADD_LIB_NAME(Agent_OnAttach_dynamic_)
+
+#define DEF_STATIC_Agent_OnAttach \
+JNIEXPORT jint JNICALL ADD_LIB_NAME(Agent_OnLoad_)(JavaVM *vm, char *options, void *reserved) { \
+    return JNI_FALSE; \
+}
+
+#define DEF_Agent_OnUnload \
+ADD_LIB_NAME(Agent_OnUnload_)(JavaVM *vm) \
+{ \
+  void JNICALL ADD_LIB_NAME(Agent_OnUnload_dynamic_)(JavaVM *vm); \
+  ADD_LIB_NAME(Agent_OnUnload_dynamic_)(vm); \
+} \
+void JNICALL ADD_LIB_NAME(Agent_OnUnload_dynamic_)
+
+#define DEF_STATIC_Agent_OnUnload \
+ADD_LIB_NAME(Agent_OnUnload_)
+
+#else
+#define DEF_Agent_OnLoad Agent_OnLoad
+#define DEF_Agent_OnAttach Agent_OnAttach
+#define DEF_Agent_OnUnload Agent_OnUnload
+#define DEF_STATIC_Agent_OnLoad
+#define DEF_STATIC_Agent_OnAttach
+#define DEF_STATIC_Agent_OnUnload
+#endif
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif /* __cplusplus */
--- a/jdk/src/java.base/share/native/libjimage/ImageNativeSubstrate.cpp	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/native/libjimage/ImageNativeSubstrate.cpp	Tue Nov 17 10:29:28 2015 -0800
@@ -26,6 +26,7 @@
 #include <string.h>
 
 #include "jni.h"
+#include "jni_util.h"
 
 #include "endian.hpp"
 #include "imageDecompressor.hpp"
@@ -201,6 +202,9 @@
     if (reader == NULL) return NULL;
     // Convert byte array to a cstring.
     char* path = new char[size + 1];
+    if (path == NULL) {
+        return NULL;
+    }
     memcpy(path, rawBytes, size);
     path[size] = '\0';
     // Locate resource location data.
@@ -246,7 +250,7 @@
 }
 
 JNIEXPORT jint JNICALL
-JNI_OnLoad(JavaVM *vm, void *reserved) {
+DEF_JNI_OnLoad(JavaVM *vm, void *reserved) {
     JNIEnv *env;
 
     if (vm->GetEnv((void**) &env, JNI_VERSION_1_2) != JNI_OK) {
@@ -646,6 +650,6 @@
     return module;
 }
 
-JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) {
+JNIEXPORT void JNICALL DEF_JNI_OnUnload(JavaVM *vm, void *reserved) {
     ImageDecompressor::image_decompressor_close();
 }
--- a/jdk/src/java.base/share/native/libjimage/imageFile.cpp	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/native/libjimage/imageFile.cpp	Tue Nov 17 10:29:28 2015 -0800
@@ -149,6 +149,7 @@
     if (found) {
         u8 data_size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
         _data = new u1[(size_t)data_size];
+        assert(_data != NULL && "allocation failed");
         _image_file->get_resource(location, _data);
         // Map out the header.
         _header = (Header*)_data;
@@ -254,6 +255,7 @@
             // Construct an array of all the package entries.
             u4 count = data->package_count(_endian);
             const char** packages = new const char*[count + 1];
+            assert(packages != NULL && "allocation failed");
             s4 package_offset = data->package_offset(_endian);
             for (u4 i = 0; i < count; i++) {
                 u4 package_name_offset = mtp_package(package_offset + i);
@@ -271,6 +273,7 @@
 // to share an open image.
 ImageFileReaderTable::ImageFileReaderTable() : _count(0), _max(_growth) {
     _table = new ImageFileReader*[_max];
+    assert( _table != NULL && "allocation failed");
 }
 
 ImageFileReaderTable::~ImageFileReaderTable() {
@@ -330,6 +333,7 @@
             // Retrieve table entry.
             ImageFileReader* reader = _reader_table.get(i);
             // If name matches, then reuse (bump up use count.)
+            assert(reader->name() != NULL && "reader->name must not be null");
             if (strcmp(reader->name(), name) == 0) {
                 reader->inc_use();
                 return reader;
@@ -339,20 +343,20 @@
 
     // Need a new image reader.
     ImageFileReader* reader = new ImageFileReader(name, big_endian);
-    bool opened = reader->open();
-    // If failed to open.
-    if (!opened) {
+    if (reader == NULL || !reader->open()) {
+        // Failed to open.
         delete reader;
         return NULL;
     }
 
     // Lock to update
     SimpleCriticalSectionLock cs(&_reader_table_lock);
-    // Search for an exist image file.
+    // Search for an existing image file.
     for (u4 i = 0; i < _reader_table.count(); i++) {
         // Retrieve table entry.
         ImageFileReader* existing_reader = _reader_table.get(i);
         // If name matches, then reuse (bump up use count.)
+        assert(reader->name() != NULL && "reader->name still must not be null");
         if (strcmp(existing_reader->name(), name) == 0) {
             existing_reader->inc_use();
             reader->close();
@@ -401,6 +405,7 @@
     // Copy the image file name.
      int len = (int) strlen(name) + 1;
     _name = new char[len];
+    assert(_name != NULL  && "allocation failed");
     strncpy(_name, name, len);
     // Initialize for a closed file.
     _fd = -1;
@@ -473,8 +478,8 @@
     // Initialize the module data
     ImageModuleData::module_data_name(buffer, _name);
     module_data = new ImageModuleData(this, buffer);
-    // Successful open.
-    return true;
+    // Successful open (if memory allocation succeeded).
+    return module_data != NULL;
 }
 
 // Close image file.
@@ -655,6 +660,7 @@
         if (!MemoryMapImage) {
             // Allocate buffer for compression.
             compressed_data = new u1[(u4)compressed_size];
+            assert (compressed_data != NULL && "allocation failed");
             // Read bytes from offset beyond the image index.
             bool is_read = read_at(compressed_data, compressed_size, _index_size + offset);
             assert(is_read && "error reading from image or short read");
--- a/jdk/src/java.base/share/native/libnet/net_util.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/native/libnet/net_util.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -38,7 +38,7 @@
 }
 
 JNIEXPORT jint JNICALL
-JNI_OnLoad(JavaVM *vm, void *reserved)
+DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
 {
     JNIEnv *env;
     jclass iCls;
--- a/jdk/src/java.base/share/native/libnio/nio_util.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/native/libnio/nio_util.c	Tue Nov 17 10:29:28 2015 -0800
@@ -28,7 +28,7 @@
 #include "jni_util.h"
 
 JNIEXPORT jint JNICALL
-JNI_OnLoad(JavaVM *vm, void *reserved)
+DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
 {
     JNIEnv *env;
 
--- a/jdk/src/java.base/share/native/libverify/check_code.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/native/libverify/check_code.c	Tue Nov 17 10:29:28 2015 -0800
@@ -86,6 +86,7 @@
 #include <stdlib.h>
 
 #include "jni.h"
+#include "jni_util.h"
 #include "jvm.h"
 #include "classfile_constants.h"
 #include "opcodes.in_out"
@@ -481,6 +482,11 @@
 static void print_formatted_methodname(context_type *context, int index);
 #endif
 
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
 void initialize_class_hash(context_type *context)
 {
     hash_table_type *class_hash = &(context->class_hash);
--- a/jdk/src/java.base/share/native/libzip/ZipFile.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/share/native/libzip/ZipFile.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -55,6 +55,12 @@
 static int OPEN_READ = java_util_zip_ZipFile_OPEN_READ;
 static int OPEN_DELETE = java_util_zip_ZipFile_OPEN_DELETE;
 
+
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
 JNIEXPORT void JNICALL
 Java_java_util_zip_ZipFile_initIDs(JNIEnv *env, jclass cls)
 {
--- a/jdk/src/java.base/solaris/classes/sun/nio/ch/EventPortWrapper.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/solaris/classes/sun/nio/ch/EventPortWrapper.java	Tue Nov 17 10:29:28 2015 -0800
@@ -31,7 +31,7 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 import sun.security.action.GetIntegerAction;
 import static sun.nio.ch.SolarisEventPort.*;
 
--- a/jdk/src/java.base/solaris/classes/sun/nio/ch/SolarisEventPort.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/solaris/classes/sun/nio/ch/SolarisEventPort.java	Tue Nov 17 10:29:28 2015 -0800
@@ -28,7 +28,7 @@
 import java.nio.channels.spi.AsynchronousChannelProvider;
 import java.util.concurrent.RejectedExecutionException;
 import java.io.IOException;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 /**
  * Provides an AsynchronousChannelGroup implementation based on the Solaris 10
--- a/jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java	Tue Nov 17 10:29:28 2015 -0800
@@ -29,7 +29,7 @@
 import java.nio.file.attribute.*;
 import java.util.*;
 import java.io.IOException;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 import static sun.nio.fs.UnixConstants.*;
 import static sun.nio.fs.SolarisConstants.*;
--- a/jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisWatchService.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisWatchService.java	Tue Nov 17 10:29:28 2015 -0800
@@ -30,7 +30,7 @@
 import java.security.PrivilegedAction;
 import java.util.*;
 import java.io.IOException;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 import static sun.nio.fs.UnixConstants.*;
 
--- a/jdk/src/java.base/unix/classes/java/lang/ProcessImpl.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/unix/classes/java/lang/ProcessImpl.java	Tue Nov 17 10:29:28 2015 -0800
@@ -224,48 +224,75 @@
         FileOutputStream f2 = null;
 
         try {
+            boolean forceNullOutputStream = false;
             if (redirects == null) {
                 std_fds = new int[] { -1, -1, -1 };
             } else {
                 std_fds = new int[3];
 
-                if (redirects[0] == Redirect.PIPE)
+                if (redirects[0] == Redirect.PIPE) {
                     std_fds[0] = -1;
-                else if (redirects[0] == Redirect.INHERIT)
+                } else if (redirects[0] == Redirect.INHERIT) {
                     std_fds[0] = 0;
-                else {
+                } else if (redirects[0] instanceof ProcessBuilder.RedirectPipeImpl) {
+                    std_fds[0] = fdAccess.get(((ProcessBuilder.RedirectPipeImpl) redirects[0]).getFd());
+                } else {
                     f0 = new FileInputStream(redirects[0].file());
                     std_fds[0] = fdAccess.get(f0.getFD());
                 }
 
-                if (redirects[1] == Redirect.PIPE)
+                if (redirects[1] == Redirect.PIPE) {
                     std_fds[1] = -1;
-                else if (redirects[1] == Redirect.INHERIT)
+                } else if (redirects[1] == Redirect.INHERIT) {
                     std_fds[1] = 1;
-                else {
+                } else if (redirects[1] instanceof ProcessBuilder.RedirectPipeImpl) {
+                    std_fds[1] = fdAccess.get(((ProcessBuilder.RedirectPipeImpl) redirects[1]).getFd());
+                    // Force getInputStream to return a null stream,
+                    // the fd is directly assigned to the next process.
+                    forceNullOutputStream = true;
+                } else {
                     f1 = new FileOutputStream(redirects[1].file(),
                             redirects[1].append());
                     std_fds[1] = fdAccess.get(f1.getFD());
                 }
 
-                if (redirects[2] == Redirect.PIPE)
+                if (redirects[2] == Redirect.PIPE) {
                     std_fds[2] = -1;
-                else if (redirects[2] == Redirect.INHERIT)
+                } else if (redirects[2] == Redirect.INHERIT) {
                     std_fds[2] = 2;
-                else {
+                } else if (redirects[2] instanceof ProcessBuilder.RedirectPipeImpl) {
+                    std_fds[2] = fdAccess.get(((ProcessBuilder.RedirectPipeImpl) redirects[2]).getFd());
+                } else {
                     f2 = new FileOutputStream(redirects[2].file(),
                             redirects[2].append());
                     std_fds[2] = fdAccess.get(f2.getFD());
                 }
             }
 
-            return new ProcessImpl
+            Process p = new ProcessImpl
                     (toCString(cmdarray[0]),
                             argBlock, args.length,
                             envBlock, envc[0],
                             toCString(dir),
                             std_fds,
+                            forceNullOutputStream,
                             redirectErrorStream);
+            if (redirects != null) {
+                // Copy the fd's if they are to be redirected to another process
+                if (std_fds[0] >= 0 &&
+                        redirects[0] instanceof ProcessBuilder.RedirectPipeImpl) {
+                    fdAccess.set(((ProcessBuilder.RedirectPipeImpl) redirects[0]).getFd(), std_fds[0]);
+                }
+                if (std_fds[1] >= 0 &&
+                        redirects[1] instanceof ProcessBuilder.RedirectPipeImpl) {
+                    fdAccess.set(((ProcessBuilder.RedirectPipeImpl) redirects[1]).getFd(), std_fds[1]);
+                }
+                if (std_fds[2] >= 0 &&
+                        redirects[2] instanceof ProcessBuilder.RedirectPipeImpl) {
+                    fdAccess.set(((ProcessBuilder.RedirectPipeImpl) redirects[2]).getFd(), std_fds[2]);
+                }
+            }
+            return p;
         } finally {
             // In theory, close() can throw IOException
             // (although it is rather unlikely to happen here)
@@ -311,6 +338,7 @@
                 final byte[] envBlock, final int envc,
                 final byte[] dir,
                 final int[] fds,
+                final boolean forceNullOutputStream,
                 final boolean redirectErrorStream)
             throws IOException {
 
@@ -326,7 +354,7 @@
 
         try {
             doPrivileged((PrivilegedExceptionAction<Void>) () -> {
-                initStreams(fds);
+                initStreams(fds, forceNullOutputStream);
                 return null;
             });
         } catch (PrivilegedActionException ex) {
@@ -340,7 +368,14 @@
         return fileDescriptor;
     }
 
-    void initStreams(int[] fds) throws IOException {
+    /**
+     * Initialize the streams from the file descriptors.
+     * @param fds array of stdin, stdout, stderr fds
+     * @param forceNullOutputStream true if the stdout is being directed to
+     *        a subsequent process. The stdout stream should be a null output stream .
+     * @throws IOException
+     */
+    void initStreams(int[] fds, boolean forceNullOutputStream) throws IOException {
         switch (platform) {
             case LINUX:
             case BSD:
@@ -348,7 +383,7 @@
                         ProcessBuilder.NullOutputStream.INSTANCE :
                         new ProcessPipeOutputStream(fds[0]);
 
-                stdout = (fds[1] == -1) ?
+                stdout = (fds[1] == -1 || forceNullOutputStream) ?
                          ProcessBuilder.NullInputStream.INSTANCE :
                          new ProcessPipeInputStream(fds[1]);
 
--- a/jdk/src/java.base/unix/native/libjava/jlong_md.h	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/unix/native/libjava/jlong_md.h	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -65,11 +65,19 @@
 #define jlong_zero_init  ((jlong) 0L)
 
 #ifdef _LP64
-#define jlong_to_ptr(a) ((void*)(a))
-#define ptr_to_jlong(a) ((jlong)(a))
+  #ifndef jlong_to_ptr
+    #define jlong_to_ptr(a) ((void*)(a))
+  #endif
+  #ifndef ptr_to_jlong
+    #define ptr_to_jlong(a) ((jlong)(a))
+  #endif
 #else
-#define jlong_to_ptr(a) ((void*)(int)(a))
-#define ptr_to_jlong(a) ((jlong)(int)(a))
+  #ifndef jlong_to_ptr
+    #define jlong_to_ptr(a) ((void*)(int)(a))
+  #endif
+  #ifndef ptr_to_jlong
+    #define ptr_to_jlong(a) ((jlong)(int)(a))
+  #endif
 #endif
 
 #define jint_to_jlong(a)        ((jlong)(a))
--- a/jdk/src/java.base/windows/classes/java/lang/ProcessImpl.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/windows/classes/java/lang/ProcessImpl.java	Tue Nov 17 10:29:28 2015 -0800
@@ -110,38 +110,63 @@
             } else {
                 stdHandles = new long[3];
 
-                if (redirects[0] == Redirect.PIPE)
+                if (redirects[0] == Redirect.PIPE) {
                     stdHandles[0] = -1L;
-                else if (redirects[0] == Redirect.INHERIT)
+                } else if (redirects[0] == Redirect.INHERIT) {
                     stdHandles[0] = fdAccess.getHandle(FileDescriptor.in);
-                else {
+                } else if (redirects[0] instanceof ProcessBuilder.RedirectPipeImpl) {
+                    stdHandles[0] = fdAccess.getHandle(((ProcessBuilder.RedirectPipeImpl) redirects[0]).getFd());
+                } else {
                     f0 = new FileInputStream(redirects[0].file());
                     stdHandles[0] = fdAccess.getHandle(f0.getFD());
                 }
 
-                if (redirects[1] == Redirect.PIPE)
+                if (redirects[1] == Redirect.PIPE) {
                     stdHandles[1] = -1L;
-                else if (redirects[1] == Redirect.INHERIT)
+                } else if (redirects[1] == Redirect.INHERIT) {
                     stdHandles[1] = fdAccess.getHandle(FileDescriptor.out);
-                else {
+                } else if (redirects[1] instanceof ProcessBuilder.RedirectPipeImpl) {
+                    stdHandles[1] = fdAccess.getHandle(((ProcessBuilder.RedirectPipeImpl) redirects[1]).getFd());
+                } else {
                     f1 = newFileOutputStream(redirects[1].file(),
                                              redirects[1].append());
                     stdHandles[1] = fdAccess.getHandle(f1.getFD());
                 }
 
-                if (redirects[2] == Redirect.PIPE)
+                if (redirects[2] == Redirect.PIPE) {
                     stdHandles[2] = -1L;
-                else if (redirects[2] == Redirect.INHERIT)
+                } else if (redirects[2] == Redirect.INHERIT) {
                     stdHandles[2] = fdAccess.getHandle(FileDescriptor.err);
-                else {
+                } else if (redirects[2] instanceof ProcessBuilder.RedirectPipeImpl) {
+                    stdHandles[2] = fdAccess.getHandle(((ProcessBuilder.RedirectPipeImpl) redirects[2]).getFd());
+                } else {
                     f2 = newFileOutputStream(redirects[2].file(),
                                              redirects[2].append());
                     stdHandles[2] = fdAccess.getHandle(f2.getFD());
                 }
             }
 
-            return new ProcessImpl(cmdarray, envblock, dir,
+            Process p = new ProcessImpl(cmdarray, envblock, dir,
                                    stdHandles, redirectErrorStream);
+            if (redirects != null) {
+                // Copy the handles's if they are to be redirected to another process
+                if (stdHandles[0] >= 0
+                        && redirects[0] instanceof ProcessBuilder.RedirectPipeImpl) {
+                    fdAccess.setHandle(((ProcessBuilder.RedirectPipeImpl) redirects[0]).getFd(),
+                            stdHandles[0]);
+                }
+                if (stdHandles[1] >= 0
+                        && redirects[1] instanceof ProcessBuilder.RedirectPipeImpl) {
+                    fdAccess.setHandle(((ProcessBuilder.RedirectPipeImpl) redirects[1]).getFd(),
+                            stdHandles[1]);
+                }
+                if (stdHandles[2] >= 0
+                        && redirects[2] instanceof ProcessBuilder.RedirectPipeImpl) {
+                    fdAccess.setHandle(((ProcessBuilder.RedirectPipeImpl) redirects[2]).getFd(),
+                            stdHandles[2]);
+                }
+            }
+            return p;
         } finally {
             // In theory, close() can throw IOException
             // (although it is rather unlikely to happen here)
--- a/jdk/src/java.base/windows/classes/sun/nio/ch/Iocp.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/windows/classes/sun/nio/ch/Iocp.java	Tue Nov 17 10:29:28 2015 -0800
@@ -36,7 +36,7 @@
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 import java.security.AccessController;
 import sun.security.action.GetPropertyAction;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 /**
  * Windows implementation of AsynchronousChannelGroup encapsulating an I/O
--- a/jdk/src/java.base/windows/classes/sun/nio/ch/PendingIoCache.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/windows/classes/sun/nio/ch/PendingIoCache.java	Tue Nov 17 10:29:28 2015 -0800
@@ -27,7 +27,7 @@
 
 import java.nio.channels.*;
 import java.util.*;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 /**
  * Maintains a mapping of pending I/O requests (identified by the address of
--- a/jdk/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java	Tue Nov 17 10:29:28 2015 -0800
@@ -33,7 +33,7 @@
 import java.security.AccessControlContext;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 /**
  * Windows implementation of AsynchronousServerSocketChannel using overlapped I/O.
--- a/jdk/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java	Tue Nov 17 10:29:28 2015 -0800
@@ -34,7 +34,7 @@
 import java.security.AccessController;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 /**
  * Windows implementation of AsynchronousSocketChannel using overlapped I/O.
--- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java	Tue Nov 17 10:29:28 2015 -0800
@@ -28,7 +28,7 @@
 import java.nio.file.attribute.*;
 import java.util.concurrent.TimeUnit;
 import java.security.AccessController;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 import sun.security.action.GetPropertyAction;
 
 import static sun.nio.fs.WindowsNativeDispatcher.*;
--- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java	Tue Nov 17 10:29:28 2015 -0800
@@ -33,7 +33,7 @@
 import java.io.*;
 import java.util.*;
 import java.security.AccessController;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 import sun.nio.ch.ThreadPool;
 import sun.security.util.SecurityConstants;
 
--- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsLinkSupport.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsLinkSupport.java	Tue Nov 17 10:29:28 2015 -0800
@@ -30,7 +30,7 @@
 import java.io.IOError;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 import static sun.nio.fs.WindowsNativeDispatcher.*;
 import static sun.nio.fs.WindowsConstants.*;
--- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java	Tue Nov 17 10:29:28 2015 -0800
@@ -27,7 +27,7 @@
 
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 /**
  * Win32 and library calls.
--- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsSecurityDescriptor.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsSecurityDescriptor.java	Tue Nov 17 10:29:28 2015 -0800
@@ -29,7 +29,7 @@
 import java.nio.file.attribute.*;
 import java.util.*;
 import java.io.IOException;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 import static sun.nio.fs.WindowsNativeDispatcher.*;
 import static sun.nio.fs.WindowsConstants.*;
--- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsUserDefinedFileAttributeView.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsUserDefinedFileAttributeView.java	Tue Nov 17 10:29:28 2015 -0800
@@ -31,7 +31,7 @@
 import java.nio.channels.FileChannel;
 import java.io.IOException;
 import java.util.*;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 import static sun.nio.fs.WindowsNativeDispatcher.*;
 import static sun.nio.fs.WindowsConstants.*;
--- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsWatchService.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsWatchService.java	Tue Nov 17 10:29:28 2015 -0800
@@ -36,7 +36,7 @@
 import java.util.Set;
 
 import com.sun.nio.file.ExtendedWatchEventModifier;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 import static sun.nio.fs.WindowsNativeDispatcher.*;
 import static sun.nio.fs.WindowsConstants.*;
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m	Tue Nov 17 10:29:28 2015 -0800
@@ -740,7 +740,7 @@
     JNF_COCOA_EXIT(env)
 }
 
-JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
+JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved) {
     OSXAPP_SetJavaVM(vm);
 
     // We need to let Foundation know that this is a multithreaded application, if it isn't already.
--- a/jdk/src/java.desktop/macosx/native/libjawt/jawt.m	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/macosx/native/libjawt/jawt.m	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -24,12 +24,18 @@
  */
 
 #import <jawt.h>
+#import "jni_util.h"
 
 #import <jawt_md.h>
 
 #import "awt_DrawingSurface.h"
 
 /*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
+/*
  * Get the AWT native structure.
  * This function returns JNI_FALSE if an error occurs.
  */
--- a/jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.h	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.h	Tue Nov 17 10:29:28 2015 -0800
@@ -23,6 +23,12 @@
  * questions.
  */
 
+/*
+ * Must include this before JavaNativeFoundation.h to get jni.h from build
+ */
+#include "jni.h"
+#include "jni_util.h"
+
 #import <Cocoa/Cocoa.h>
 #import <JavaNativeFoundation/JavaNativeFoundation.h>
 
--- a/jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.m	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.m	Tue Nov 17 10:29:28 2015 -0800
@@ -33,6 +33,10 @@
 #import "QueuingApplicationDelegate.h"
 #import "AWTIconData.h"
 
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
 
 static BOOL sUsingDefaultNIB = YES;
 static NSString *SHARED_FRAMEWORK_BUNDLE = @"/System/Library/Frameworks/JavaVM.framework";
@@ -432,10 +436,10 @@
 @end
 
 
-void OSXAPP_SetApplicationDelegate(id <NSApplicationDelegate> delegate)
+void OSXAPP_SetApplicationDelegate(id <NSApplicationDelegate> newdelegate)
 {
 AWT_ASSERT_APPKIT_THREAD;
-    applicationDelegate = delegate;
+    applicationDelegate = newdelegate;
 
     if (NSApp != nil) {
         [NSApp setDelegate: applicationDelegate];
--- a/jdk/src/java.desktop/macosx/native/libosxui/AquaLookAndFeel.m	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/macosx/native/libosxui/AquaLookAndFeel.m	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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,6 +23,10 @@
  * questions.
  */
 
+// Must include this before JavaNativeFoundation.h to get jni.h from build
+#include "jni.h"
+#include "jni_util.h"
+
 #import <JavaNativeFoundation/JavaNativeFoundation.h>
 
 /*
@@ -30,6 +34,7 @@
  *    <rdar://4984599> AWT's JNI_OnLoad called multiple times
  *    Please remove when <rdar://5121166> has been resolved.
  */
-JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
+JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
+{
     return JNI_VERSION_1_4;
 }
--- a/jdk/src/java.desktop/share/classes/sun/awt/AWTAccessor.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/share/classes/sun/awt/AWTAccessor.java	Tue Nov 17 10:29:28 2015 -0800
@@ -25,7 +25,7 @@
 
 package sun.awt;
 
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 import javax.accessibility.AccessibleContext;
 import java.awt.*;
--- a/jdk/src/java.desktop/share/classes/sun/font/StrikeCache.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/share/classes/sun/font/StrikeCache.java	Tue Nov 17 10:29:28 2015 -0800
@@ -37,7 +37,7 @@
 import sun.java2d.pipe.BufferedContext;
 import sun.java2d.pipe.RenderQueue;
 import sun.java2d.pipe.hw.AccelGraphicsConfig;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 /**
 
--- a/jdk/src/java.desktop/share/classes/sun/java2d/pipe/RenderBuffer.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/pipe/RenderBuffer.java	Tue Nov 17 10:29:28 2015 -0800
@@ -25,7 +25,7 @@
 
 package sun.java2d.pipe;
 
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 
 /**
--- a/jdk/src/java.desktop/share/classes/sun/swing/SwingAccessor.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/share/classes/sun/swing/SwingAccessor.java	Tue Nov 17 10:29:28 2015 -0800
@@ -25,7 +25,7 @@
 
 package sun.swing;
 
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 import java.awt.*;
 import javax.swing.*;
--- a/jdk/src/java.desktop/share/native/libfontmanager/sunFont.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/share/native/libfontmanager/sunFont.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -37,6 +37,10 @@
 static void *theNullScalerContext = NULL;
 extern void AccelGlyphCache_RemoveAllCellInfos(GlyphInfo *glyph);
 
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
 
 JNIEXPORT jlong JNICALL
 Java_sun_font_NullFontScaler_getNullScalerContext
--- a/jdk/src/java.desktop/share/native/libjavajpeg/jpegdecoder.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/share/native/libjavajpeg/jpegdecoder.c	Tue Nov 17 10:29:28 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
@@ -67,7 +67,7 @@
 JavaVM *jvm;
 
 JNIEXPORT jint JNICALL
-JNI_OnLoad(JavaVM *vm, void *reserved)
+DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
 {
     jvm = vm;
     return JNI_VERSION_1_2;
--- a/jdk/src/java.desktop/share/native/libjsound/Platform.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/share/native/libjsound/Platform.c	Tue Nov 17 10:29:28 2015 -0800
@@ -28,6 +28,10 @@
 // Platform.java includes
 #include "com_sun_media_sound_Platform.h"
 
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
 
 /*
  * Class:     com_sun_media_sound_Platform
--- a/jdk/src/java.desktop/share/native/libjsound/Utilities.h	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/share/native/libjsound/Utilities.h	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -24,6 +24,7 @@
  */
 
 #include <jni.h>
+#include "jni_util.h"
 #include "SoundDefs.h"
 #include "Configure.h"          // put flags for debug msgs etc. here
 
--- a/jdk/src/java.desktop/share/native/liblcms/LCMS.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/share/native/liblcms/LCMS.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -134,7 +134,7 @@
     JNU_ThrowByName(env, "java/awt/color/CMMException", errMsg);
 }
 
-JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
+JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *jvm, void *reserved) {
     javaVM = jvm;
 
     cmsSetLogErrorHandler(errorHandler);
--- a/jdk/src/java.desktop/share/native/libmlib_image/mlib_ImageUtils.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/share/native/libmlib_image/mlib_ImageUtils.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2003, 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
@@ -26,6 +26,14 @@
 
 #include "mlib_image.h"
 
+#include <jni.h>
+#include "jni_util.h"
+
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
 /***************************************************************/
 typedef union {
   mlib_d64 db;
--- a/jdk/src/java.desktop/share/native/libsplashscreen/java_awt_SplashScreen.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/share/native/libsplashscreen/java_awt_SplashScreen.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -30,7 +30,7 @@
 #include <sizecalc.h>
 
 JNIEXPORT jint JNICALL
-JNI_OnLoad(JavaVM * vm, void *reserved)
+DEF_JNI_OnLoad(JavaVM * vm, void *reserved)
 {
     return JNI_VERSION_1_2;
 }
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/MotifDnDConstants.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/MotifDnDConstants.java	Tue Nov 17 10:29:28 2015 -0800
@@ -31,7 +31,7 @@
 
 import java.util.Arrays;
 
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 /**
  * Motif DnD protocol global constants and convenience routines.
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/MotifDnDDragSourceProtocol.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/MotifDnDDragSourceProtocol.java	Tue Nov 17 10:29:28 2015 -0800
@@ -33,7 +33,7 @@
 
 import java.util.Map;
 
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 /**
  * XDragSourceProtocol implementation for Motif DnD protocol.
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/MotifDnDDropTargetProtocol.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/MotifDnDDropTargetProtocol.java	Tue Nov 17 10:29:28 2015 -0800
@@ -33,7 +33,7 @@
 
 import java.io.IOException;
 
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 /**
  * XDropTargetProtocol implementation for Motif DnD protocol.
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/Native.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/Native.java	Tue Nov 17 10:29:28 2015 -0800
@@ -25,7 +25,7 @@
 
 package sun.awt.X11;
 
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 import java.util.Vector;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/UnsafeXDisposerRecord.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/UnsafeXDisposerRecord.java	Tue Nov 17 10:29:28 2015 -0800
@@ -24,7 +24,7 @@
  */
 package sun.awt.X11;
 
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 import sun.util.logging.PlatformLogger;
 
 class UnsafeXDisposerRecord implements sun.java2d.DisposerRecord {
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/WindowPropertyGetter.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/WindowPropertyGetter.java	Tue Nov 17 10:29:28 2015 -0800
@@ -26,7 +26,7 @@
 package sun.awt.X11;
 
 import java.util.*;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 public class WindowPropertyGetter {
     private static Unsafe unsafe = XlibWrapper.unsafe;
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XAtom.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XAtom.java	Tue Nov 17 10:29:28 2015 -0800
@@ -55,7 +55,7 @@
  * @since       1.5
  */
 
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 import java.util.HashMap;
 
 public final class XAtom {
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDnDDragSourceProtocol.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDnDDragSourceProtocol.java	Tue Nov 17 10:29:28 2015 -0800
@@ -35,7 +35,7 @@
 
 import sun.util.logging.PlatformLogger;
 
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 /**
  * XDragSourceProtocol implementation for XDnD protocol.
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDnDDropTargetProtocol.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDnDDropTargetProtocol.java	Tue Nov 17 10:29:28 2015 -0800
@@ -35,7 +35,7 @@
 
 import sun.util.logging.PlatformLogger;
 
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 /**
  * XDropTargetProtocol implementation for XDnD protocol.
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDropTargetContextPeer.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDropTargetContextPeer.java	Tue Nov 17 10:29:28 2015 -0800
@@ -41,7 +41,7 @@
 import sun.awt.dnd.SunDropTargetContextPeer;
 import sun.awt.dnd.SunDropTargetEvent;
 
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 /**
  * The XDropTargetContextPeer is the class responsible for handling
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XEmbedHelper.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XEmbedHelper.java	Tue Nov 17 10:29:28 2015 -0800
@@ -25,7 +25,7 @@
 
 package sun.awt.X11;
 
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 import sun.util.logging.PlatformLogger;
 
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XKeysym.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XKeysym.java	Tue Nov 17 10:29:28 2015 -0800
@@ -27,7 +27,7 @@
 
 package sun.awt.X11;
 import java.util.Hashtable;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 import sun.util.logging.PlatformLogger;
 
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XQueryTree.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XQueryTree.java	Tue Nov 17 10:29:28 2015 -0800
@@ -27,7 +27,7 @@
 
 package sun.awt.X11;
 
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 public class XQueryTree {
         private static Unsafe unsafe = XlibWrapper.unsafe;
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTranslateCoordinates.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTranslateCoordinates.java	Tue Nov 17 10:29:28 2015 -0800
@@ -27,7 +27,7 @@
 
 package sun.awt.X11;
 
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 public class XTranslateCoordinates {
         private static Unsafe unsafe = XlibWrapper.unsafe;
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWM.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWM.java	Tue Nov 17 10:29:28 2015 -0800
@@ -31,7 +31,7 @@
 package sun.awt.X11;
 
 import sun.awt.IconInfo;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 import java.awt.Insets;
 import java.awt.Frame;
 import java.awt.Rectangle;
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XlibWrapper.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XlibWrapper.java	Tue Nov 17 10:29:28 2015 -0800
@@ -27,7 +27,7 @@
 
 import java.security.AccessController;
 
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 import sun.security.action.GetPropertyAction;
 
 final class XlibWrapper {
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/keysym2ucs.h	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/keysym2ucs.h	Tue Nov 17 10:29:28 2015 -0800
@@ -65,7 +65,7 @@
 tojava
 tojava package sun.awt.X11;
 tojava import java.util.Hashtable;
-tojava import sun.misc.Unsafe;
+tojava import jdk.internal.misc.Unsafe;
 tojava
 tojava import sun.util.logging.PlatformLogger;
 tojava
--- a/jdk/src/java.desktop/unix/native/libawt/awt/awt_LoadLibrary.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/unix/native/libawt/awt/awt_LoadLibrary.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2014, 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
@@ -178,7 +178,7 @@
 }
 
 JNIEXPORT jint JNICALL
-JNI_OnLoad(JavaVM *vm, void *reserved)
+DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
 {
     return AWT_OnLoad(vm, reserved);
 }
--- a/jdk/src/java.desktop/unix/native/libawt_headless/awt/HeadlessToolkit.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/unix/native/libawt_headless/awt/HeadlessToolkit.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -31,14 +31,17 @@
 extern JavaVM *jvm;
 
 JNIEXPORT jint JNICALL
-JNI_OnLoad(JavaVM *vm, void *reserved)
+DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
 {
     jvm = vm;
     return JNI_VERSION_1_2;
 }
 
+#ifndef STATIC_BUILD
+// The same function exists in libawt.a::awt_LoadLibrary.c
 JNIEXPORT jboolean JNICALL AWTIsHeadless() {
     return JNI_TRUE;
 }
+#endif
 
 #endif
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/XToolkit.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/XToolkit.c	Tue Nov 17 10:29:28 2015 -0800
@@ -151,7 +151,7 @@
 
 
 JNIEXPORT jint JNICALL
-JNI_OnLoad(JavaVM *vm, void *reserved)
+DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
 {
     jvm = vm;
     return JNI_VERSION_1_2;
--- a/jdk/src/java.desktop/unix/native/libjawt/jawt.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/unix/native/libjawt/jawt.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, 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
@@ -24,10 +24,16 @@
  */
 
 #include <jawt.h>
+#include "jni_util.h"
 
 #include "awt_DrawingSurface.h"
 
 /*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
+/*
  * Get the AWT native structure.  This function returns JNI_FALSE if
  * an error occurs.
  */
--- a/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -44,6 +44,11 @@
 static int alsa_enumerate_pcm_subdevices = FALSE; // default: no
 static int alsa_enumerate_midi_subdevices = FALSE; // default: no
 
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
 void initAlsaSupport() {
     char* enumerate;
     if (!alsa_inited) {
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2014, 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
@@ -91,7 +91,7 @@
 JavaVM *jvm = NULL;
 
 JNIEXPORT jint JNICALL
-JNI_OnLoad(JavaVM *vm, void *reserved)
+DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
 {
     TRY;
 
--- a/jdk/src/java.desktop/windows/native/libjawt/jawt.cpp	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.desktop/windows/native/libjawt/jawt.cpp	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2008, 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
@@ -25,11 +25,17 @@
 
 #define _JNI_IMPLEMENTATION_
 #include <jawt.h>
+#include "jni_util.h"
 
 #include "awt.h"
 #include "awt_DrawingSurface.h"
 
 /*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
+/*
  * Get the AWT native structure.  This function returns JNI_FALSE if
  * an error occurs.
  */
--- a/jdk/src/java.instrument/share/native/libinstrument/InstrumentationImplNativeMethods.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.instrument/share/native/libinstrument/InstrumentationImplNativeMethods.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -50,6 +50,11 @@
  */
 
 /*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
+/*
  * Class:     sun_instrument_InstrumentationImpl
  * Method:    isModifiableClass0
  * Signature: (Ljava/lang/Class;)Z
--- a/jdk/src/java.instrument/share/native/libinstrument/InvocationAdapter.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.instrument/share/native/libinstrument/InvocationAdapter.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -141,7 +141,7 @@
  *  to create boot class path segments to append to the boot class path.
  */
 JNIEXPORT jint JNICALL
-Agent_OnLoad(JavaVM *vm, char *tail, void * reserved) {
+DEF_Agent_OnLoad(JavaVM *vm, char *tail, void * reserved) {
     JPLISInitializationError initerror  = JPLIS_INIT_ERROR_NONE;
     jint                     result     = JNI_OK;
     JPLISAgent *             agent      = NULL;
@@ -290,7 +290,7 @@
  *  the JPLIS library.
  */
 JNIEXPORT jint JNICALL
-Agent_OnAttach(JavaVM* vm, char *args, void * reserved) {
+DEF_Agent_OnAttach(JavaVM* vm, char *args, void * reserved) {
     JPLISInitializationError initerror  = JPLIS_INIT_ERROR_NONE;
     jint                     result     = JNI_OK;
     JPLISAgent *             agent      = NULL;
@@ -435,7 +435,7 @@
 
 
 JNIEXPORT void JNICALL
-Agent_OnUnload(JavaVM *vm) {
+DEF_Agent_OnUnload(JavaVM *vm) {
 }
 
 
--- a/jdk/src/java.instrument/share/native/libinstrument/JarFacade.h	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.instrument/share/native/libinstrument/JarFacade.h	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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,6 +23,10 @@
  * questions.
  */
 
+#ifdef STATIC_BUILD
+#define getAttribute JarGetAttribute
+#endif
+
 typedef struct _jarAttribute {
     char* name;
     char* value;
--- a/jdk/src/java.instrument/share/native/libinstrument/Utilities.h	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.instrument/share/native/libinstrument/Utilities.h	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -32,6 +32,13 @@
 
 #include    <jni.h>
 #include    <jvmti.h>
+#include    "jni_util.h"
+
+#ifdef STATIC_BUILD
+#define allocate instAllocate
+#define deallocate instDeallocate
+#endif
+
 
 #ifdef __cplusplus
 extern "C" {
--- a/jdk/src/java.management/share/classes/sun/management/BaseOperatingSystemImpl.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.management/share/classes/sun/management/BaseOperatingSystemImpl.java	Tue Nov 17 10:29:28 2015 -0800
@@ -28,7 +28,7 @@
 import java.lang.management.OperatingSystemMXBean;
 import java.lang.management.ManagementFactory;
 import javax.management.ObjectName;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 /**
  * Implementation class for the operating system.
--- a/jdk/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java	Tue Nov 17 10:29:28 2015 -0800
@@ -51,7 +51,7 @@
     static {
         // make sure that the management lib is loaded within
         // java.lang.management.ManagementFactory
-        sun.misc.Unsafe.getUnsafe().ensureClassInitialized(ManagementFactory.class);
+        jdk.internal.misc.Unsafe.getUnsafe().ensureClassInitialized(ManagementFactory.class);
     }
 
     private static final VMManagement jvm = new VMManagementImpl();
--- a/jdk/src/java.management/share/native/libmanagement/management.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.management/share/native/libmanagement/management.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -25,6 +25,7 @@
 
 #include <stdio.h>
 #include <jni.h>
+#include "jni_util.h"
 #include "jvm.h"
 #include "management.h"
 
@@ -35,7 +36,7 @@
 jint jmm_version = 0;
 
 JNIEXPORT jint JNICALL
-   JNI_OnLoad(JavaVM *vm, void *reserved) {
+   DEF_JNI_OnLoad(JavaVM *vm, void *reserved) {
     JNIEnv* env;
 
     jvm = vm;
--- a/jdk/src/java.prefs/macosx/native/libprefs/MacOSXPreferencesFile.m	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.prefs/macosx/native/libprefs/MacOSXPreferencesFile.m	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -64,6 +64,11 @@
 #include "jlong.h"
 #include "jvm.h"
 
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
 
 // Throw an OutOfMemoryError with the given message.
 static void throwOutOfMemoryError(JNIEnv *env, const char *msg)
--- a/jdk/src/java.prefs/unix/native/libprefs/FileSystemPreferences.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.prefs/unix/native/libprefs/FileSystemPreferences.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -35,6 +35,11 @@
 #include <utime.h>
 #include "jni_util.h"
 
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
 JNIEXPORT jint JNICALL
 Java_java_util_prefs_FileSystemPreferences_chmod(JNIEnv *env,
                        jclass thisclass, jstring java_fname, jint permission) {
--- a/jdk/src/java.prefs/windows/native/libprefs/WindowsPreferences.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.prefs/windows/native/libprefs/WindowsPreferences.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2002, 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
@@ -31,6 +31,12 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
+
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
     JNIEXPORT jintArray JNICALL Java_java_util_prefs_WindowsPreferences_WindowsRegOpenKey
                (JNIEnv* env, jclass this_class, jint hKey, jbyteArray lpSubKey, jint securityMask) {
         HKEY handle;
--- a/jdk/src/java.security.jgss/macosx/native/libosxkrb5/nativeccache.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.security.jgss/macosx/native/libosxkrb5/nativeccache.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -28,6 +28,8 @@
 #import <string.h>
 #import <time.h>
 
+#include "jni_util.h"
+
 /*
  * Based largely on klist.c,
  *
@@ -92,7 +94,7 @@
  * Class:     sun_security_krb5_KrbCreds
  * Method:    JNI_OnLoad
  */
-JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
+JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *jvm, void *reserved)
 {
     JNIEnv *env;
 
@@ -191,7 +193,7 @@
  * Class:     sun_security_jgss_KrbCreds
  * Method:    JNI_OnUnload
  */
-JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *jvm, void *reserved)
+JNIEXPORT void JNICALL DEF_JNI_OnUnload(JavaVM *jvm, void *reserved)
 {
     JNIEnv *env;
 
--- a/jdk/src/java.security.jgss/share/classes/sun/security/krb5/KerberosSecrets.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/krb5/KerberosSecrets.java	Tue Nov 17 10:29:28 2015 -0800
@@ -26,7 +26,7 @@
 package sun.security.krb5;
 
 import javax.security.auth.kerberos.KeyTab;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
 
 public class KerberosSecrets {
     private static final Unsafe unsafe = Unsafe.getUnsafe();
--- a/jdk/src/java.security.jgss/share/classes/sun/security/krb5/PrincipalName.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/krb5/PrincipalName.java	Tue Nov 17 10:29:28 2015 -0800
@@ -187,10 +187,10 @@
     }
 
     private static final long NAME_STRINGS_OFFSET;
-    private static final sun.misc.Unsafe UNSAFE;
+    private static final jdk.internal.misc.Unsafe UNSAFE;
     static {
         try {
-            sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
+            jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe();
             NAME_STRINGS_OFFSET = unsafe.objectFieldOffset(
                     PrincipalName.class.getDeclaredField("nameStrings"));
             UNSAFE = unsafe;
--- a/jdk/src/java.security.jgss/share/native/libj2gss/NativeUtil.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.security.jgss/share/native/libj2gss/NativeUtil.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -27,6 +27,7 @@
 #include "NativeFunc.h"
 #include "jlong.h"
 #include <jni.h>
+#include "jni_util.h"
 
 const int JAVA_DUPLICATE_TOKEN_CODE = 19; /* DUPLICATE_TOKEN */
 const int JAVA_OLD_TOKEN_CODE = 20; /* OLD_TOKEN */
@@ -94,7 +95,7 @@
 int JGSS_DEBUG;
 
 JNIEXPORT jint JNICALL
-JNI_OnLoad(JavaVM *jvm, void *reserved) {
+DEF_JNI_OnLoad(JavaVM *jvm, void *reserved) {
   JNIEnv *env;
   jclass cls;
 
@@ -363,7 +364,7 @@
 }
 
 JNIEXPORT void JNICALL
-JNI_OnUnload(JavaVM *jvm, void *reserved) {
+DEF_JNI_OnUnload(JavaVM *jvm, void *reserved) {
   JNIEnv *env;
 
   if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2)) {
--- a/jdk/src/java.security.jgss/share/native/libj2gss/NativeUtil.h	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.security.jgss/share/native/libj2gss/NativeUtil.h	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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,9 +54,6 @@
   extern jstring getMinorMessage(JNIEnv *, jobject, OM_uint32);
   extern int sameMech(gss_OID, gss_OID);
 
-  JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *, void *);
-  JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *, void *);
-
   extern int JGSS_DEBUG;
 
   extern jclass CLS_Object;
--- a/jdk/src/java.security.jgss/windows/native/libw2k_lsa_auth/NativeCreds.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.security.jgss/windows/native/libw2k_lsa_auth/NativeCreds.c	Tue Nov 17 10:29:28 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
@@ -42,6 +42,7 @@
 #include <lmcons.h>
 #include <lmapibuf.h>
 #include <jni.h>
+#include "jni_util.h"
 #include <winsock.h>
 
 #undef LSA_SUCCESS
@@ -107,7 +108,7 @@
  * Method:    JNI_OnLoad
  */
 
-JNIEXPORT jint JNICALL JNI_OnLoad(
+JNIEXPORT jint JNICALL DEF_JNI_OnLoad(
         JavaVM  *jvm,
         void    *reserved) {
 
@@ -329,7 +330,7 @@
  * Method:    JNI_OnUnload
  */
 
-JNIEXPORT void JNICALL JNI_OnUnload(
+JNIEXPORT void JNICALL DEF_JNI_OnUnload(
         JavaVM  *jvm,
         void    *reserved) {
 
--- a/jdk/src/java.smartcardio/share/native/libj2pcsc/pcsc.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/java.smartcardio/share/native/libj2pcsc/pcsc.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -55,6 +55,8 @@
 
 #include "pcsc_md.h"
 
+#include "jni_util.h"
+
 #define MAX_STACK_BUFFER_SIZE 8192
 
 // make the buffers larger than what should be necessary, just in case
@@ -101,7 +103,7 @@
     }
 }
 
-JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
+JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved) {
     return JNI_VERSION_1_4;
 }
 
--- a/jdk/src/jdk.attach/linux/native/libattach/VirtualMachineImpl.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/jdk.attach/linux/native/libattach/VirtualMachineImpl.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -50,6 +50,11 @@
 } while(0)
 
 /*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
+/*
  * Defines a callback that is invoked for each process
  */
 typedef void (*ProcessCallback)(const pid_t pid, void* user_data);
--- a/jdk/src/jdk.attach/macosx/native/libattach/VirtualMachineImpl.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/jdk.attach/macosx/native/libattach/VirtualMachineImpl.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -51,6 +51,11 @@
 } while(0)
 
 /*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
+/*
  * Class:     sun_tools_attach_VirtualMachineImpl
  * Method:    socket
  * Signature: ()I
--- a/jdk/src/jdk.attach/solaris/native/libattach/VirtualMachineImpl.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/jdk.attach/solaris/native/libattach/VirtualMachineImpl.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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,6 +46,11 @@
 } while(0)
 
 /*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
+/*
  * Class:     sun_tools_attach_VirtualMachineImpl
  * Method:    open
  * Signature: (Ljava/lang/String;)I
--- a/jdk/src/jdk.attach/windows/native/libattach/VirtualMachineImpl.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/jdk.attach/windows/native/libattach/VirtualMachineImpl.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -87,6 +87,10 @@
 #define ERR_OPEN_JVM_FAIL           200
 #define ERR_GET_ENQUEUE_FUNC_FAIL   201
 
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
 
 /*
  * Code copied to target process
--- a/jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/Big5_Solaris.java.template	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/Big5_Solaris.java.template	Tue Nov 17 10:29:28 2015 -0800
@@ -51,12 +51,12 @@
 
     public CharsetDecoder newDecoder() {
         initb2c();
-        return new  DoubleByte.Decoder(this, b2c, b2cSB, 0x40, 0xfe);
+        return new  DoubleByte.Decoder(this, b2c, b2cSB, 0x40, 0xfe, true);
     }
 
     public CharsetEncoder newEncoder() {
         initc2b();
-        return new DoubleByte.Encoder(this, c2b, c2bIndex);
+        return new DoubleByte.Encoder(this, c2b, c2bIndex, true);
     }
 
     static char[][] b2c;
--- a/jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/IBM834.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/IBM834.java	Tue Nov 17 10:29:28 2015 -0800
@@ -62,7 +62,7 @@
     protected static class Encoder extends DoubleByte.Encoder_DBCSONLY {
         public Encoder(Charset cs) {
             super(cs, new byte[] {(byte)0xfe, (byte)0xfe},
-                  IBM933.c2b, IBM933.c2bIndex);
+                  IBM933.c2b, IBM933.c2bIndex, false);
         }
 
         public int encodeChar(char ch) {
--- a/jdk/src/jdk.crypto.ec/share/native/libsunec/ECC_JNI.cpp	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/jdk.crypto.ec/share/native/libsunec/ECC_JNI.cpp	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -24,6 +24,7 @@
  */
 
 #include <jni.h>
+#include "jni_util.h"
 #include "impl/ecc_impl.h"
 
 #define ILLEGAL_STATE_EXCEPTION "java/lang/IllegalStateException"
@@ -36,6 +37,11 @@
 extern "C" {
 
 /*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
+/*
  * Throws an arbitrary Java exception.
  */
 void ThrowException(JNIEnv *env, const char *exceptionName)
--- a/jdk/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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,6 +29,7 @@
 //
 
 #include <jni.h>
+#include "jni_util.h"
 #include <stdlib.h>
 #include <string.h>
 #include <windows.h>
@@ -51,6 +52,11 @@
 extern "C" {
 
 /*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
+/*
  * Throws an arbitrary Java exception.
  * The exception message is a Windows system error message.
  */
--- a/jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_general.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_general.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  */
 
 /* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
@@ -73,7 +73,7 @@
 
 JavaVM* jvm = NULL;
 
-JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
+JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved) {
     jvm = vm;
     return JNI_VERSION_1_4;
 }
--- a/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCrypto.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCrypto.c	Tue Nov 17 10:29:28 2015 -0800
@@ -27,6 +27,7 @@
 #include <string.h>
 #include <strings.h>
 #include <jni.h>
+#include "jni_util.h"
 #include <libsoftcrypto.h>
 #include "nativeCrypto.h"
 #include "nativeFunc.h"
@@ -59,7 +60,7 @@
   (*env)->DeleteLocalRef(env, jExClass);
 }
 
-JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
+JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved) {
     return JNI_VERSION_1_4;
 }
 
--- a/jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/AppleScriptEngine.m	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/AppleScriptEngine.m	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -26,6 +26,10 @@
 #import "apple_applescript_AppleScriptEngine.h"
 #import "apple_applescript_AppleScriptEngineFactory.h"
 
+// Must include this before JavaNativeFoundation.h to get jni.h from build
+#include "jni.h"
+#include "jni_util.h"
+
 #import <JavaNativeFoundation/JavaNativeFoundation.h>
 
 #import "NS_Java_ConversionUtils.h"
@@ -33,6 +37,10 @@
 
 //#define DEBUG 1
 
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
 
 /*
  * Class:     apple_applescript_AppleScriptEngineFactory
--- a/jdk/src/jdk.deploy.osx/macosx/native/libosx/Dispatch.m	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/jdk.deploy.osx/macosx/native/libosx/Dispatch.m	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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,11 +23,21 @@
  * questions.
  */
 
+/*
+ * Must include this before JavaNativeFoundation.h to get jni.h from build
+ */
+#include "jni.h"
+#include "jni_util.h"
+
 #import "com_apple_concurrent_LibDispatchNative.h"
 
 #import <dispatch/dispatch.h>
 #import <JavaNativeFoundation/JavaNativeFoundation.h>
 
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
 
 /*
  * Class:     com_apple_concurrent_LibDispatchNative
--- a/jdk/src/jdk.dev/share/classes/jdk/tools/jimage/ExtractedImage.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/jdk.dev/share/classes/jdk/tools/jimage/ExtractedImage.java	Tue Nov 17 10:29:28 2015 -0800
@@ -102,7 +102,6 @@
             }
             chop = dirPath.toString().length() + 1;
             this.moduleName = dirPath.getFileName().toString();
-            System.out.println("Module name " + this.moduleName);
             this.dirPath = dirPath;
         }
 
--- a/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/InvokableTypeImpl.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/InvokableTypeImpl.java	Tue Nov 17 10:29:28 2015 -0800
@@ -236,6 +236,15 @@
                                            final MethodImpl method,
                                            final ValueImpl[] args,
                                            final int options) {
+        /*
+         * Cache the values of args when TRACE_SENDS is enabled, for later printing.
+         * If not cached, printing causes a remote call while synchronized, and deadlock.
+         */
+        if ((vm.traceFlags & VirtualMachineImpl.TRACE_SENDS) != 0) {
+           for (ValueImpl arg: args) {
+              arg.toString();
+           }
+        }
         CommandSender sender = getInvokeMethodSender(thread, method, args, options);
         PacketStream stream;
         if ((options & ClassType.INVOKE_SINGLE_THREADED) != 0) {
--- a/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -1041,12 +1041,11 @@
     }
 
     Type findBootType(String signature) throws ClassNotLoadedException {
-        List<ReferenceType> types = allClasses();
+        List<ReferenceType> types = retrieveClassesBySignature(signature);
         Iterator<ReferenceType> iter = types.iterator();
         while (iter.hasNext()) {
             ReferenceType type = iter.next();
-            if ((type.classLoader() == null) &&
-                (type.signature().equals(signature))) {
+            if (type.classLoader() == null) {
                 return type;
             }
         }
--- a/jdk/src/jdk.jdwp.agent/share/native/libjdwp/debugInit.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/jdk.jdwp.agent/share/native/libjdwp/debugInit.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -194,7 +194,7 @@
  *   Returning JNI_ERR will cause the java_g VM to core dump, be careful.
  */
 JNIEXPORT jint JNICALL
-Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
+DEF_Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
 {
     jvmtiError error;
     jvmtiCapabilities needed_capabilities;
@@ -380,7 +380,7 @@
 }
 
 JNIEXPORT void JNICALL
-Agent_OnUnload(JavaVM *vm)
+DEF_Agent_OnUnload(JavaVM *vm)
 {
 
     gdata->isLoaded = JNI_FALSE;
--- a/jdk/src/jdk.jdwp.agent/share/native/libjdwp/debugInit.h	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/jdk.jdwp.agent/share/native/libjdwp/debugInit.h	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -39,7 +39,4 @@
 void debugInit_exit(jvmtiError, const char *);
 void forceExit(int);
 
-JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *, char *, void *);
-JNIEXPORT void JNICALL Agent_OnUnload(JavaVM *);
-
 #endif
--- a/jdk/src/jdk.jdwp.agent/share/native/libjdwp/transport.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/jdk.jdwp.agent/share/native/libjdwp/transport.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -101,9 +101,10 @@
 static void *
 loadTransportLibrary(const char *libdir, const char *name)
 {
+    char buf[MAXPATHLEN*2+100];
+#ifndef STATIC_BUILD
     void *handle;
     char libname[MAXPATHLEN+2];
-    char buf[MAXPATHLEN*2+100];
     const char *plibdir;
 
     /* Convert libdir from UTF-8 to platform encoding */
@@ -125,6 +126,9 @@
     /* dlopen (unix) / LoadLibrary (windows) the transport library */
     handle = dbgsysLoadLibrary(libname, buf, sizeof(buf));
     return handle;
+#else
+    return (dbgsysLoadLibrary(NULL, buf, sizeof(buf)));
+#endif
 }
 
 /*
--- a/jdk/src/jdk.jdwp.agent/share/native/libjdwp/util.h	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/jdk.jdwp.agent/share/native/libjdwp/util.h	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -278,18 +278,6 @@
 #define MOD_SYNTHETIC    0xf0000000  /* not in source code */
 
 /*
- * jlong conversion macros
- */
-#define jlong_zero       ((jlong) 0)
-#define jlong_one        ((jlong) 1)
-
-#define jlong_to_ptr(a)  ((void*)(intptr_t)(a))
-#define ptr_to_jlong(a)  ((jlong)(intptr_t)(a))
-#define jint_to_jlong(a) ((jlong)(a))
-#define jlong_to_jint(a) ((jint)(a))
-
-
-/*
  * util funcs
  */
 void util_initialize(JNIEnv *env);
--- a/jdk/src/jdk.jdwp.agent/share/native/libjdwp/vm_interface.h	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/jdk.jdwp.agent/share/native/libjdwp/vm_interface.h	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -33,6 +33,7 @@
 #include <jni.h>
 #include <jvm.h>
 #include <jvmti.h>
+#include "jni_util.h"
 
 #include "log_messages.h"
 
--- a/jdk/src/jdk.management/share/native/libmanagement_ext/management_ext.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/jdk.management/share/native/libmanagement_ext/management_ext.c	Tue Nov 17 10:29:28 2015 -0800
@@ -25,6 +25,7 @@
 
 #include <stdio.h>
 #include <jni.h>
+#include "jni_util.h"
 #include "jvm.h"
 #include "management_ext.h"
 
@@ -35,7 +36,7 @@
 jint jmm_version = 0;
 
 JNIEXPORT jint JNICALL
-   JNI_OnLoad(JavaVM *vm, void *reserved) {
+   DEF_JNI_OnLoad(JavaVM *vm, void *reserved) {
     JNIEnv* env;
 
     jvm = vm;
--- a/jdk/src/jdk.pack200/share/native/common-unpack/utils.cpp	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/jdk.pack200/share/native/common-unpack/utils.cpp	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -77,6 +77,8 @@
 
 
 #ifndef PRODUCT
+#ifndef STATIC_BUILD
+// use the definition in libjvm when building statically
 void breakpoint() { }  // hook for debugger
 int assert_failed(const char* p) {
   char message[1<<12];
@@ -87,6 +89,7 @@
   return 0;
 }
 #endif
+#endif
 
 void unpack_abort(const char* msg, unpacker* u) {
   if (msg == null)  msg = "corrupt pack file or internal error";
--- a/jdk/src/jdk.pack200/share/native/libunpack/jni.cpp	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/jdk.pack200/share/native/libunpack/jni.cpp	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -95,6 +95,11 @@
     } while (JNI_FALSE)
 #endif
 
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
 static jlong read_input_via_jni(unpacker* self,
                                 void* buf, jlong minlen, jlong maxlen);
 
--- a/jdk/src/jdk.sctp/unix/native/libsctp/SctpNet.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/jdk.sctp/unix/native/libsctp/SctpNet.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -43,7 +43,7 @@
 static const char* nativeSctpLib = "libsctp.so.1";
 static jboolean funcsLoaded = JNI_FALSE;
 
-JNIEXPORT jint JNICALL JNI_OnLoad
+JNIEXPORT jint JNICALL DEF_JNI_OnLoad
   (JavaVM *vm, void *reserved) {
     return JNI_VERSION_1_2;
 }
--- a/jdk/src/jdk.security.auth/unix/native/libjaas/Unix.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/jdk.security.auth/unix/native/libjaas/Unix.c	Tue Nov 17 10:29:28 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
@@ -28,6 +28,7 @@
 #endif
 
 #include <jni.h>
+#include "jni_util.h"
 #include "com_sun_security_auth_module_UnixSystem.h"
 #include <stdio.h>
 #include <pwd.h>
@@ -36,6 +37,11 @@
 #include <stdlib.h>
 #include <string.h>
 
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
 JNIEXPORT void JNICALL
 Java_com_sun_security_auth_module_UnixSystem_getUnixInfo
                                                 (JNIEnv *env, jobject obj) {
--- a/jdk/src/jdk.security.auth/windows/native/libjaas/nt.c	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/src/jdk.security.auth/windows/native/libjaas/nt.c	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2014, 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
@@ -24,6 +24,7 @@
  */
 
 #include <jni.h>
+#include "jni_util.h"
 #include "com_sun_security_auth_module_NTSystem.h"
 
 #include <windows.h>
@@ -49,6 +50,11 @@
         (*env)->ThrowNew(env, clazz, msg);
 }
 
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
 JNIEXPORT jlong JNICALL
 Java_com_sun_security_auth_module_NTSystem_getImpersonationToken0
         (JNIEnv *env, jobject obj) {
--- a/jdk/test/ProblemList.txt	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/ProblemList.txt	Tue Nov 17 10:29:28 2015 -0800
@@ -133,9 +133,6 @@
 # 8029891
 java/lang/ClassLoader/deadlock/GetResource.java                 generic-all
 
-# 8131129
-java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java        windows-all
-
 ############################################################################
 
 # jdk_instrument
@@ -237,6 +234,7 @@
 sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java      generic-all
 
 # 8077138: Some PKCS11 tests fail because NSS library is not initialized
+# 8023434: NSS initialization failed
 sun/security/pkcs11/Cipher/ReinitCipher.java                    windows-all
 sun/security/pkcs11/Cipher/TestPKCS5PaddingError.java           windows-all
 sun/security/pkcs11/Cipher/TestRSACipher.java                   windows-all
@@ -266,6 +264,7 @@
 sun/security/pkcs11/Secmod/Crypto.java                          windows-all
 sun/security/pkcs11/Secmod/GetPrivateKey.java                   windows-all
 sun/security/pkcs11/Secmod/JksSetPrivateKey.java                windows-all
+sun/security/pkcs11/Secmod/LoadKeystore.java                    windows-all
 sun/security/pkcs11/SecureRandom/Basic.java                     windows-all
 sun/security/pkcs11/SecureRandom/TestDeserialization.java       windows-all
 sun/security/pkcs11/Serialize/SerializeProvider.java            windows-all
@@ -363,6 +362,18 @@
 # 8062512
 java/util/spi/ResourceBundleControlProvider/UserDefaultControlTest.java generic-all
 
+# 8076458
+java/util/stream/test/org/openjdk/tests/java/util/stream/FlatMapOpTest.java generic-all
+
+# 8130337
+java/util/stream/test/org/openjdk/tests/java/util/stream/IntPrimitiveOpsTests.java generic-all
+
+# 8080165, 8085982
+java/util/Arrays/ParallelPrefix.java generic-all
+
+# 8079538
+java/util/BitSet/BitSetStreamTest.java generic-all
+
 ############################################################################
 
 # jdk_instrument
--- a/jdk/test/TEST.ROOT	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/TEST.ROOT	Tue Nov 17 10:29:28 2015 -0800
@@ -26,5 +26,9 @@
 # Allow querying of sun.arch.data.model in @requires clauses
 requires.properties=sun.arch.data.model 
 
-# Tests using jtreg 4.1 b11 features
-requiredVersion=4.1 b11
+# Tests using jtreg 4.1 b12 features
+requiredVersion=4.1 b12
+
+# Path to libraries in the topmost test directory. This is needed so @library
+# does not need ../../ notation to reach them
+external.lib.roots = ../../
--- a/jdk/test/TEST.groups	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/TEST.groups	Tue Nov 17 10:29:28 2015 -0800
@@ -28,7 +28,9 @@
 tier1 = \
     :jdk_lang \
     -java/lang/ProcessHandle/TreeTest.java \
+    -java/util/zip/TestLocalTime.java \
     :jdk_util \
+    -java/util/concurrent/Phaser/Basic.java \
     sun/nio/cs/ISO8859x.java \
     java/nio/Buffer \
     com/sun/crypto/provider/Cipher \
@@ -36,6 +38,8 @@
 
 tier2 = \
     java/lang/ProcessHandle/TreeTest.java \
+    java/util/zip/TestLocalTime.java \
+    java/util/concurrent/Phaser/Basic.java \
     :jdk_io \
     :jdk_nio \
     -sun/nio/cs/ISO8859x.java \
--- a/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -47,6 +47,7 @@
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.TimeUnit;
+import javax.net.ssl.SSLHandshakeException;
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static java.util.concurrent.TimeUnit.NANOSECONDS;
@@ -234,6 +235,12 @@
         if (e.getCause() instanceof SocketTimeoutException) {
             // SSL connect will timeout via readReply using
             // SocketTimeoutException
+            e.printStackTrace();
+            pass();
+        } else if (e.getCause() instanceof SSLHandshakeException
+                && e.getCause().getCause() instanceof EOFException) {
+            // test seems to be failing intermittently on some
+            // platforms.
             pass();
         } else {
             fail(e);
--- a/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/DumpHeap.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/DumpHeap.java	Tue Nov 17 10:29:28 2015 -0800
@@ -38,7 +38,7 @@
  * @bug 6455258
  * @summary Sanity test for com.sun.management.HotSpotDiagnosticMXBean.dumpHeap method
  * @library /lib/testlibrary
- * @library /../../test/lib/share/classes
+ * @library /test/lib/share/classes
  * @build jdk.testlibrary.*
  * @build jdk.test.lib.hprof.*
  * @build jdk.test.lib.hprof.module.*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/ProcessBuilder/PipelineTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,299 @@
+/*
+ * 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.
+ *
+ */
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.Arrays;
+import java.util.List;
+
+/*
+ * @test PipelineTest
+ */
+
+public class PipelineTest {
+
+    private static void realMain(String[] args) throws Throwable {
+        t1_simplePipeline();
+        t2_translatePipeline();
+        t3_redirectErrorStream();
+        t4_failStartPipeline();
+    }
+
+    /**
+     * Return a list of the varargs arguments.
+     * @param args elements to include in the list
+     * @param <T> the type of the elements
+     * @return a {@code List<T>} of the arguments
+     */
+    @SafeVarargs
+    @SuppressWarnings("varargs")
+    static <T> List<T> asList(T... args) {
+        return Arrays.asList(args);
+    }
+
+    /**
+     * T1 - simple copy between two processes
+     */
+    static void t1_simplePipeline() {
+        try {
+            String s1 = "Now is the time to check!";
+            verify(s1, s1,
+                    asList(new ProcessBuilder("cat")));
+            verify(s1, s1,
+                    asList(new ProcessBuilder("cat"),
+                            new ProcessBuilder("cat")));
+            verify(s1, s1,
+                    asList(new ProcessBuilder("cat"),
+                            new ProcessBuilder("cat"),
+                            new ProcessBuilder("cat")));
+        } catch (Throwable t) {
+            unexpected(t);
+        }
+    }
+
+    /**
+     * Pipeline that modifies the content.
+     */
+    static void t2_translatePipeline() {
+        try {
+            String s2 = "Now is the time to check!";
+            String r2 = s2.replace('e', 'E').replace('o', 'O');
+            verify(s2, r2,
+                    asList(new ProcessBuilder("tr", "e", "E"),
+                            new ProcessBuilder("tr", "o", "O")));
+        } catch (Throwable t) {
+            unexpected(t);
+        }
+    }
+
+    /**
+     * Test that redirectErrorStream sends standard error of the first process
+     * to the standard output. The standard error of the first process should be empty.
+     * The standard output of the 2nd should contain the error message including the bad file name.
+     */
+    static void t3_redirectErrorStream() {
+        try {
+            File p1err = new File("p1-test.err");
+            File p2out = new File("p2-test.out");
+
+            List<Process> processes = ProcessBuilder.startPipeline(
+                    asList(new ProcessBuilder("cat", "NON-EXISTENT-FILE")
+                                    .redirectErrorStream(true)
+                                    .redirectError(p1err),
+                            new ProcessBuilder("cat").redirectOutput(p2out)));
+            waitForAll(processes);
+
+            check("".equals(fileContents(p1err)), "The first process standard error should be empty");
+            String p2contents = fileContents(p2out);
+            check(p2contents.contains("NON-EXISTENT-FILE"),
+                    "The error from the first process should be in the output of the second: " + p2contents);
+        } catch (Throwable t) {
+            unexpected(t);
+        }
+    }
+
+    /**
+     * Test that no processes are left after a failed startPipeline.
+     * Test illegal combinations of redirects.
+     */
+    static void t4_failStartPipeline() {
+        File p1err = new File("p1-test.err");
+        File p2out = new File("p2-test.out");
+
+        THROWS(IllegalArgumentException.class,
+                () -> {
+                    // Test that output redirect != PIPE throws IAE
+                    List<Process> processes = ProcessBuilder.startPipeline(
+                            asList(new ProcessBuilder("cat", "NON-EXISTENT-FILE1")
+                                            .redirectOutput(p1err),
+                                    new ProcessBuilder("cat")));
+                },
+                () -> {
+                    // Test that input redirect != PIPE throws IAE
+                    List<Process> processes = ProcessBuilder.startPipeline(
+                            asList(new ProcessBuilder("cat", "NON-EXISTENT-FILE2"),
+                                    new ProcessBuilder("cat").redirectInput(p2out)));
+                }
+        );
+
+        THROWS(NullPointerException.class,
+                () -> {
+                    List<Process> processes = ProcessBuilder.startPipeline(
+                            asList(new ProcessBuilder("cat", "a"), null));
+                },
+                () -> {
+                    List<Process> processes = ProcessBuilder.startPipeline(
+                            asList(null, new ProcessBuilder("cat", "b")));
+                }
+        );
+
+        THROWS(IOException.class,
+                () -> {
+                    List<Process> processes = ProcessBuilder.startPipeline(
+                            asList(new ProcessBuilder("cat", "c"),
+                                    new ProcessBuilder("NON-EXISTENT-COMMAND")));
+                });
+
+        // Check no subprocess are left behind
+        ProcessHandle.current().children().forEach(PipelineTest::print);
+        ProcessHandle.current().children()
+                .filter(p -> p.info().command().orElse("").contains("cat"))
+                .forEach(p -> fail("process should have been destroyed: " + p));
+    }
+
+    static void verify(String input, String expected, List<ProcessBuilder> builders) throws IOException {
+        File infile = new File("test.in");
+        File outfile = new File("test.out");
+        setFileContents(infile, expected);
+        for (int i = 0; i < builders.size(); i++) {
+            ProcessBuilder b = builders.get(i);
+            if (i == 0) {
+                b.redirectInput(infile);
+            }
+            if (i == builders.size() - 1) {
+                b.redirectOutput(outfile);
+            }
+        }
+        List<Process> processes = ProcessBuilder.startPipeline(builders);
+        verifyProcesses(processes);
+        waitForAll(processes);
+        String result = fileContents(outfile);
+        System.out.printf(" in: %s%nout: %s%n", input, expected);
+        check(result.equals(expected), "result not as expected");
+    }
+
+    /**
+     * Wait for each of the processes to be done.
+     *
+     * @param processes the list  of processes to check
+     */
+    static void waitForAll(List<Process> processes) {
+        processes.forEach(p -> {
+            try {
+                int status = p.waitFor();
+            } catch (InterruptedException ie) {
+                unexpected(ie);
+            }
+        });
+    }
+
+    static void print(ProcessBuilder pb) {
+        if (pb != null) {
+            System.out.printf(" pb: %s%n", pb);
+            System.out.printf("    cmd: %s%n", pb.command());
+        }
+    }
+
+    static void print(ProcessHandle p) {
+        System.out.printf("process: pid: %d, info: %s%n",
+                p.getPid(), p.info());
+    }
+
+    // Check various aspects of the processes
+    static void verifyProcesses(List<Process> processes) {
+        for (int i = 0; i < processes.size(); i++) {
+            Process p = processes.get(i);
+            if (i != 0) {
+                verifyNullStream(p.getOutputStream(), "getOutputStream");
+            }
+            if (i == processes.size() - 1) {
+                verifyNullStream(p.getInputStream(), "getInputStream");
+                verifyNullStream(p.getErrorStream(), "getErrorStream");
+            }
+        }
+    }
+
+    static void verifyNullStream(OutputStream s, String msg) {
+        try {
+            s.write(0xff);
+            fail("Stream should have been a NullStream" + msg);
+        } catch (IOException ie) {
+            // expected
+        }
+    }
+
+    static void verifyNullStream(InputStream s, String msg) {
+        try {
+            int len = s.read();
+            check(len == -1, "Stream should have been a NullStream" + msg);
+        } catch (IOException ie) {
+            // expected
+        }
+    }
+
+    static void setFileContents(File file, String contents) {
+        try {
+            Writer w = new FileWriter(file);
+            w.write(contents);
+            w.close();
+        } catch (Throwable t) { unexpected(t); }
+    }
+
+    static String fileContents(File file) {
+        try {
+            Reader r = new FileReader(file);
+            StringBuilder sb = new StringBuilder();
+            char[] buffer = new char[1024];
+            int n;
+            while ((n = r.read(buffer)) != -1)
+                sb.append(buffer,0,n);
+            r.close();
+            return new String(sb);
+        } catch (Throwable t) { unexpected(t); return ""; }
+    }
+
+    //--------------------- Infrastructure ---------------------------
+    static volatile int passed = 0, failed = 0;
+    static void pass() {passed++;}
+    static void fail() {failed++; Thread.dumpStack();}
+    static void fail(String msg) {System.err.println(msg); fail();}
+    static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+    static void check(boolean cond) {if (cond) pass(); else fail();}
+    static void check(boolean cond, String m) {if (cond) pass(); else fail(m);}
+    static void equal(Object x, Object y) {
+        if (x == null ? y == null : x.equals(y)) pass();
+        else fail(">'" + x + "'<" + " not equal to " + "'" + y + "'");
+    }
+
+    public static void main(String[] args) throws Throwable {
+        try {realMain(args);} catch (Throwable t) {unexpected(t);}
+        System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+        if (failed > 0) throw new AssertionError("Some tests failed");
+    }
+    interface Fun {void f() throws Throwable;}
+    static void THROWS(Class<? extends Throwable> k, Fun... fs) {
+        for (Fun f : fs)
+            try { f.f(); fail("Expected " + k.getName() + " not thrown"); }
+            catch (Throwable t) {
+                if (k.isAssignableFrom(t.getClass())) pass();
+                else unexpected(t);}
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/Chars.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,89 @@
+/*
+ * 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 8054307
+    @summary test chars() and codePoints()
+*/
+
+import java.util.Arrays;
+import java.util.Random;
+
+public class Chars {
+
+    public static void main(String[] args) {
+        Random r = new Random();
+        for (int i = 0; i < 10; i++) {
+            int n = 100 + r.nextInt(100);
+            char[] cc = new char[n];
+            int[]  ccExp = new int[n];
+            int[]  cpExp = new int[n];
+            // latin1
+            for (int j = 0; j < n; j++) {
+                cc[j] = (char)(ccExp[j] = cpExp[j] = r.nextInt(0x80));
+            }
+            testChars(cc, ccExp);
+            testCPs(cc, cpExp);
+
+            // bmp without surrogates
+            for (int j = 0; j < n; j++) {
+                cc[j] = (char)(ccExp[j] = cpExp[j] = r.nextInt(0x8000));
+            }
+            testChars(cc, ccExp);
+            testCPs(cc, cpExp);
+
+            // bmp with surrogates
+            int k = 0;
+            for (int j = 0; j < n; j++) {
+                if (j % 9 ==  5 && j + 1 < n) {
+                    int cp = 0x10000 + r.nextInt(2000);
+                    cpExp[k++] = cp;
+                    Character.toChars(cp, cc, j);
+                    ccExp[j] = cc[j];
+                    ccExp[j + 1] = cc[j + 1];
+                    j++;
+                } else {
+                    cc[j] = (char)(ccExp[j] = cpExp[k++] = r.nextInt(0x8000));
+                }
+            }
+            cpExp = Arrays.copyOf(cpExp, k);
+            testChars(cc, ccExp);
+            testCPs(cc, cpExp);
+        }
+    }
+
+    static void testChars(char[] cc, int[] expected) {
+        String str = new String(cc);
+        if (!Arrays.equals(expected, str.chars().toArray())) {
+            throw new RuntimeException("chars/codePoints() failed!");
+        }
+    }
+
+    static void testCPs(char[] cc, int[] expected) {
+        String str = new String(cc);
+        if (!Arrays.equals(expected, str.codePoints().toArray())) {
+            throw new RuntimeException("chars/codePoints() failed!");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/CharAt.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+import java.util.stream.IntStream;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.charAt.
+ * @run testng/othervm -XX:+CompactStrings CharAt
+ * @run testng/othervm -XX:-CompactStrings CharAt
+ */
+
+public class CharAt extends CompactString {
+
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+                new Object[] { STRING_L1, new char[] { 'A' } },
+                new Object[] { STRING_L2, new char[] { 'A', 'B' } },
+                new Object[] { STRING_L4, new char[] { 'A', 'B', 'C', 'D' } },
+                new Object[] { STRING_LLONG,
+                        new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' } },
+                new Object[] { STRING_U1, new char[] { '\uFF21' } },
+                new Object[] { STRING_U2, new char[] { '\uFF21', '\uFF22' } },
+                new Object[] { STRING_M12, new char[] { '\uFF21', 'A' } },
+                new Object[] { STRING_M11, new char[] { 'A', '\uFF21' } }, };
+    }
+
+    @Test(dataProvider = "provider")
+    public void testCharAt(String str, char[] expected) {
+        map.get(str)
+                .forEach(
+                        (source, data) -> {
+                            IntStream
+                                    .range(0, str.length())
+                                    .forEach(
+                                            i -> assertEquals(
+                                                    str.charAt(i),
+                                                    expected[i],
+                                                    String.format(
+                                                            "testing String(%s).charAt(%d), source : %s, ",
+                                                            escapeNonASCIIs(data),
+                                                            i, source)));
+                        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/CodePointAt.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+import java.util.stream.IntStream;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.codePointAt.
+ * @run testng/othervm -XX:+CompactStrings CodePointAt
+ * @run testng/othervm -XX:-CompactStrings CodePointAt
+ */
+
+public class CodePointAt extends CompactString {
+
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+
+                new Object[] { STRING_L1, new int[] { 'A' } },
+                new Object[] { STRING_L2, new int[] { 'A', 'B' } },
+                new Object[] { STRING_L4, new int[] { 'A', 'B', 'C', 'D' } },
+                new Object[] { STRING_LLONG,
+                        new int[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' } },
+                new Object[] { STRING_U1, new int[] { '\uFF21' } },
+                new Object[] { STRING_U2, new int[] { '\uFF21', '\uFF22' } },
+                new Object[] { STRING_M12, new int[] { '\uFF21', 'A' } },
+                new Object[] { STRING_M11, new int[] { 'A', '\uFF21' } },
+                new Object[] {
+                        STRING_SUPPLEMENTARY,
+                        new int[] { Character.toCodePoint('\uD801', '\uDC00'),
+                                '\uDC00',
+                                Character.toCodePoint('\uD801', '\uDC01'),
+                                '\uDC01', '\uFF21', 'A' }, } };
+    }
+
+    @Test(dataProvider = "provider")
+    public void testCodePointAt(String str, int[] expected) {
+        map.get(str)
+                .forEach(
+                        (source, data) -> {
+                            IntStream
+                                    .range(0, str.length())
+                                    .forEach(
+                                            i -> assertEquals(
+                                                    str.codePointAt(i),
+                                                    expected[i],
+                                                    String.format(
+                                                            "testing String(%s).codePointAt(%d), source : %s, ",
+                                                            escapeNonASCIIs(data),
+                                                            i, source)));
+                        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/CodePointBefore.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+import java.util.stream.IntStream;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.codePointBefore.
+ * @run testng/othervm -XX:+CompactStrings CodePointBefore
+ * @run testng/othervm -XX:-CompactStrings CodePointBefore
+ */
+
+public class CodePointBefore extends CompactString {
+
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+
+                new Object[] { STRING_L1, new int[] { 'A' } },
+                new Object[] { STRING_L2, new int[] { 'A', 'B' } },
+                new Object[] { STRING_L4, new int[] { 'A', 'B', 'C', 'D' } },
+                new Object[] { STRING_LLONG,
+                        new int[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' } },
+                new Object[] { STRING_U1, new int[] { '\uFF21' } },
+                new Object[] { STRING_U2, new int[] { '\uFF21', '\uFF22' } },
+                new Object[] { STRING_M12, new int[] { '\uFF21', 'A' } },
+                new Object[] { STRING_M11, new int[] { 'A', '\uFF21' } },
+                new Object[] {
+                        STRING_SUPPLEMENTARY,
+                        new int[] { '\uD801', Character.toCodePoint('\uD801', '\uDC00'),
+                                '\uD801', Character.toCodePoint('\uD801', '\uDC01'),
+                                '\uFF21', 'A' }, } };
+    }
+
+    @Test(dataProvider = "provider")
+    public void testCodePointBefore(String str, int[] expected) {
+        map.get(str)
+                .forEach(
+                        (source, data) -> {
+                            IntStream
+                                    .range(0, str.length())
+                                    .forEach(
+                                            i -> assertEquals(
+                                                    str.codePointBefore(i + 1),
+                                                    expected[i],
+                                                    String.format(
+                                                            "testing String(%s).codePointBefore(%d), source : %s, ",
+                                                            escapeNonASCIIs(data),
+                                                            i + 1, source)));
+                        });
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/CodePointCount.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.codePointCount.
+ * @run testng/othervm -XX:+CompactStrings CodePointCount
+ * @run testng/othervm -XX:-CompactStrings CodePointCount
+ */
+
+public class CodePointCount extends CompactString {
+
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] { new Object[] { STRING_EMPTY, 0, 0, 0 },
+                new Object[] { STRING_L1, 0, 1, 1 },
+                new Object[] { STRING_L1, 1, 1, 0 },
+                new Object[] { STRING_L2, 0, 2, 2 },
+                new Object[] { STRING_L2, 0, 1, 1 },
+                new Object[] { STRING_L2, 1, 2, 1 },
+                new Object[] { STRING_L4, 0, 4, 4 },
+                new Object[] { STRING_L4, 0, 1, 1 },
+                new Object[] { STRING_L4, 2, 4, 2 },
+                new Object[] { STRING_LLONG, 0, 8, 8 },
+                new Object[] { STRING_LLONG, 0, 5, 5 },
+                new Object[] { STRING_LLONG, 4, 8, 4 },
+                new Object[] { STRING_LLONG, 0, 7, 7 },
+                new Object[] { STRING_U1, 0, 1, 1 },
+                new Object[] { STRING_U2, 0, 2, 2 },
+                new Object[] { STRING_U2, 0, 1, 1 },
+                new Object[] { STRING_U2, 1, 2, 1 },
+                new Object[] { STRING_M12, 0, 2, 2 },
+                new Object[] { STRING_M12, 0, 1, 1 },
+                new Object[] { STRING_M12, 1, 2, 1 },
+                new Object[] { STRING_M11, 0, 2, 2 },
+                new Object[] { STRING_M11, 0, 1, 1 },
+                new Object[] { STRING_M11, 1, 2, 1 },
+                new Object[] { STRING_SUPPLEMENTARY, 0, 1, 1 },
+                new Object[] { STRING_SUPPLEMENTARY, 0, 2, 1 },
+                new Object[] { STRING_SUPPLEMENTARY, 0, 3, 2 },
+                new Object[] { STRING_SUPPLEMENTARY, 0, 5, 3 },
+                new Object[] { STRING_SUPPLEMENTARY, 0, 6, 4 },
+                new Object[] { STRING_SUPPLEMENTARY, 1, 4, 2 },
+                new Object[] { STRING_SUPPLEMENTARY, 1, 6, 4 },
+                new Object[] { STRING_SUPPLEMENTARY, 2, 4, 1 },};
+    }
+
+    @Test(dataProvider = "provider")
+    public void testCodePointCount(String str, int beginIndex, int endIndex,
+            int expected) {
+        map.get(str)
+                .forEach(
+                        (source, data) -> {
+                            assertEquals(
+                                    data.codePointCount(beginIndex, endIndex),
+                                    expected,
+                                    String.format(
+                                            "testing String(%s).codePointCount(%d, %d), source : %s, ",
+                                            escapeNonASCIIs(data), beginIndex,
+                                            endIndex, source));
+                        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/CompactString.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,307 @@
+/*
+ * 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.
+ */
+
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.testng.annotations.BeforeClass;
+
+/*
+ * Base class of tests for Compact String.
+ *
+ */
+public class CompactString {
+
+    final Map<String, Map<String, String>> map = new HashMap<>();
+
+    enum StringSources {
+        EMPTY(STRING_EMPTY, BYTE_ARRAY_EMTPY, CHAR_ARRAY_EMPTY,
+                POINT_ARRAY_EMTPY), LDUPLICATE(STRING_LDUPLICATE,
+                BYTE_ARRAY_LDUPLICATE, CHAR_ARRAY_LDUPLICATE,
+                POINT_ARRAY_LDUPLICATE), LLONG(STRING_LLONG, BYTE_ARRAY_LLONG,
+                CHAR_ARRAY_LLONG, POINT_ARRAY_LLONG), L1(STRING_L1,
+                BYTE_ARRAY_L1, CHAR_ARRAY_L1, POINT_ARRAY_L1), L2(STRING_L2,
+                BYTE_ARRAY_L2, CHAR_ARRAY_L2, POINT_ARRAY_L2), L4(STRING_L4,
+                BYTE_ARRAY_L4, CHAR_ARRAY_L4, POINT_ARRAY_L4), UDUPLICATE(
+                STRING_UDUPLICATE, BYTE_ARRAY_UDUPLICATE,
+                CHAR_ARRAY_UDUPLICATE, POINT_ARRAY_UDUPLICATE), U1(STRING_U1,
+                BYTE_ARRAY_U1, CHAR_ARRAY_U1, POINT_ARRAY_U1), U2(STRING_U2,
+                BYTE_ARRAY_U2, CHAR_ARRAY_U2, POINT_ARRAY_U2), MDUPLICATE1(
+                STRING_MDUPLICATE1, BYTE_ARRAY_MDUPLICATE1,
+                CHAR_ARRAY_MDUPLICATE1, POINT_ARRAY_MDUPLICATE1), MDUPLICATE2(
+                STRING_MDUPLICATE2, BYTE_ARRAY_MDUPLICATE2,
+                CHAR_ARRAY_MDUPLICATE2, POINT_ARRAY_MDUPLICATE2), MLONG1(
+                STRING_MLONG1, BYTE_ARRAY_MLONG1, CHAR_ARRAY_MLONG1,
+                POINT_ARRAY_MLONG1), MLONG2(STRING_MLONG2, BYTE_ARRAY_MLONG2,
+                CHAR_ARRAY_MLONG2, POINT_ARRAY_MLONG2), M11(STRING_M11,
+                BYTE_ARRAY_M11, CHAR_ARRAY_M11, POINT_ARRAY_M11), M12(
+                STRING_M12, BYTE_ARRAY_M12, CHAR_ARRAY_M12, POINT_ARRAY_M12), SUPPLEMENTARY(
+                STRING_SUPPLEMENTARY, BYTE_ARRAY_SUPPLEMENTARY,
+                CHAR_ARRAY_SUPPLEMENTARY, POINT_ARRAY_SUPPLEMENTARY), SUPPLEMENTARY_LOWERCASE(
+                STRING_SUPPLEMENTARY_LOWERCASE,
+                BYTE_ARRAY_SUPPLEMENTARY_LOWERCASE,
+                CHAR_ARRAY_SUPPLEMENTARY_LOWERCASE,
+                POINT_ARRAY_SUPPLEMENTARY_LOWERCASE);
+
+        private StringSources(String s, byte[] b, char[] c, int[] i) {
+            str = s;
+            ba = b;
+            ca = c;
+            ia = i;
+        }
+
+        String getString() {
+            return str;
+        }
+
+        byte[] getByteArray() {
+            return ba;
+        }
+
+        char[] getCharArray() {
+            return ca;
+        }
+
+        int[] getIntArray() {
+            return ia;
+        }
+
+        private final String str;
+        private final byte[] ba;
+        private final char[] ca;
+        private final int[] ia;
+    }
+
+    protected static final String DEFAULT_CHARSET_NAME = "UTF-8";
+    protected static final Charset DEFAULT_CHARSET = Charset
+            .forName(DEFAULT_CHARSET_NAME);
+
+    protected static final String STRING_EMPTY = "";
+    protected static final byte[] BYTE_ARRAY_EMTPY = new byte[0];
+    protected static final char[] CHAR_ARRAY_EMPTY = new char[0];
+    protected static final int[] POINT_ARRAY_EMTPY = new int[0];
+
+    protected static final String STRING_LDUPLICATE = "ABABABABAB";
+    protected static final byte[] BYTE_ARRAY_LDUPLICATE = new byte[] { 'A', 'B',
+            'A', 'B', 'A', 'B', 'A', 'B', 'A', 'B' };
+    protected static final char[] CHAR_ARRAY_LDUPLICATE = new char[] { 'A', 'B',
+            'A', 'B', 'A', 'B', 'A', 'B', 'A', 'B' };
+    protected static final int[] POINT_ARRAY_LDUPLICATE = new int[] { 'A', 'B',
+            'A', 'B', 'A', 'B', 'A', 'B', 'A', 'B' };
+
+    protected static final String STRING_LLONG = "ABCDEFGH";
+    protected static final byte[] BYTE_ARRAY_LLONG = new byte[] { 'A', 'B', 'C',
+            'D', 'E', 'F', 'G', 'H' };
+    protected static final char[] CHAR_ARRAY_LLONG = new char[] { 'A', 'B', 'C',
+            'D', 'E', 'F', 'G', 'H' };
+    protected static final int[] POINT_ARRAY_LLONG = new int[] { 'A', 'B', 'C',
+            'D', 'E', 'F', 'G', 'H' };
+
+    protected static final String STRING_L1 = "A";
+    protected static final byte[] BYTE_ARRAY_L1 = new byte[] { 'A' };
+    protected static final char[] CHAR_ARRAY_L1 = new char[] { 'A' };
+    protected static final int[] POINT_ARRAY_L1 = new int[] { 'A' };
+
+    protected static final String STRING_L2 = "AB";
+    protected static final byte[] BYTE_ARRAY_L2 = new byte[] { 'A', 'B' };
+    protected static final char[] CHAR_ARRAY_L2 = new char[] { 'A', 'B' };
+    protected static final int[] POINT_ARRAY_L2 = new int[] { 'A', 'B' };
+
+    protected static final String STRING_L4 = "ABCD";
+    protected static final byte[] BYTE_ARRAY_L4 = new byte[] { 'A', 'B', 'C', 'D' };
+    protected static final char[] CHAR_ARRAY_L4 = new char[] { 'A', 'B', 'C', 'D' };
+    protected static final int[] POINT_ARRAY_L4 = new int[] { 'A', 'B', 'C', 'D' };
+
+    /*
+     * Because right now ASCII is the default encoding parameter for source code
+     * in JDK build environment, so we escape them. same as below.
+     */
+    protected static final String STRING_UDUPLICATE = "\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22";
+    protected static final byte[] BYTE_ARRAY_UDUPLICATE = getBytes(STRING_UDUPLICATE);
+    protected static final char[] CHAR_ARRAY_UDUPLICATE = new char[] { '\uFF21',
+            '\uFF22', '\uFF21', '\uFF22', '\uFF21', '\uFF22', '\uFF21',
+            '\uFF22', '\uFF21', '\uFF22' };
+    protected static final int[] POINT_ARRAY_UDUPLICATE = new int[] { '\uFF21',
+            '\uFF22', '\uFF21', '\uFF22', '\uFF21', '\uFF22', '\uFF21',
+            '\uFF22', '\uFF21', '\uFF22' };
+
+    protected static final String STRING_U1 = "\uFF21";
+    protected static final byte[] BYTE_ARRAY_U1 = getBytes(STRING_U1);
+    protected static final char[] CHAR_ARRAY_U1 = new char[] { '\uFF21' };
+    protected static final int[] POINT_ARRAY_U1 = new int[] { '\uFF21' };
+
+    protected static final String STRING_U2 = "\uFF21\uFF22";
+    protected static final byte[] BYTE_ARRAY_U2 = getBytes(STRING_U2);
+    protected static final char[] CHAR_ARRAY_U2 = new char[] { '\uFF21', '\uFF22' };
+    protected static final int[] POINT_ARRAY_U2 = new int[] { '\uFF21', '\uFF22' };
+
+    protected static final String STRING_MDUPLICATE1 = "\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A";
+    protected static final byte[] BYTE_ARRAY_MDUPLICATE1 = getBytes(STRING_MDUPLICATE1);
+    protected static final char[] CHAR_ARRAY_MDUPLICATE1 = new char[] { '\uFF21',
+            'A', '\uFF21', 'A', '\uFF21', 'A', '\uFF21', 'A', '\uFF21', 'A' };
+    protected static final int[] POINT_ARRAY_MDUPLICATE1 = new int[] { '\uFF21',
+            'A', '\uFF21', 'A', '\uFF21', 'A', '\uFF21', 'A', '\uFF21', 'A' };
+
+    protected static final String STRING_MDUPLICATE2 = "A\uFF21A\uFF21A\uFF21A\uFF21A\uFF21";
+    protected static final byte[] BYTE_ARRAY_MDUPLICATE2 = getBytes(STRING_MDUPLICATE2);
+    protected static final char[] CHAR_ARRAY_MDUPLICATE2 = new char[] { 'A',
+            '\uFF21', 'A', '\uFF21', 'A', '\uFF21', 'A', '\uFF21', 'A',
+            '\uFF21' };
+    protected static final int[] POINT_ARRAY_MDUPLICATE2 = new int[] { 'A',
+            '\uFF21', 'A', '\uFF21', 'A', '\uFF21', 'A', '\uFF21', 'A',
+            '\uFF21' };
+
+    protected static final String STRING_MLONG1 = "A\uFF21B\uFF22C\uFF23D\uFF24E\uFF25F\uFF26G\uFF27H\uFF28";
+    protected static final byte[] BYTE_ARRAY_MLONG1 = getBytes(STRING_MLONG1);
+    protected static final char[] CHAR_ARRAY_MLONG1 = new char[] { 'A', '\uFF21',
+            'B', '\uFF22', 'C', '\uFF23', 'D', '\uFF24', 'E', '\uFF25', 'F',
+            '\uFF26', 'G', '\uFF27', 'H', '\uFF28' };
+    protected static final int[] POINT_ARRAY_MLONG1 = new int[] { 'A', '\uFF21',
+            'B', '\uFF22', 'C', '\uFF23', 'D', '\uFF24', 'E', '\uFF25', 'F',
+            '\uFF26', 'G', '\uFF27', 'H', '\uFF28' };
+
+    protected static final String STRING_MLONG2 = "\uFF21A\uFF22B\uFF23C\uFF24D\uFF25E\uFF26F\uFF27G\uFF28H";
+    protected static final byte[] BYTE_ARRAY_MLONG2 = getBytes(STRING_MLONG2);
+    protected static final char[] CHAR_ARRAY_MLONG2 = new char[] { '\uFF21', 'A',
+            '\uFF22', 'B', '\uFF23', 'C', '\uFF24', 'D', '\uFF25', 'E',
+            '\uFF26', 'F', '\uFF27', 'G', '\uFF28', 'H' };
+    protected static final int[] POINT_ARRAY_MLONG2 = new int[] { '\uFF21', 'A',
+            '\uFF22', 'B', '\uFF23', 'C', '\uFF24', 'D', '\uFF25', 'E',
+            '\uFF26', 'F', '\uFF27', 'G', '\uFF28', 'H' };
+
+    protected static final String STRING_M11 = "A\uFF21";
+    protected static final byte[] BYTE_ARRAY_M11 = getBytes(STRING_M11);
+    protected static final char[] CHAR_ARRAY_M11 = new char[] { 'A', '\uFF21' };
+    protected static final int[] POINT_ARRAY_M11 = new int[] { 'A', '\uFF21' };
+
+    protected static final String STRING_M12 = "\uFF21A";
+    protected static final byte[] BYTE_ARRAY_M12 = getBytes(STRING_M12);
+    protected static final char[] CHAR_ARRAY_M12 = new char[] { '\uFF21', 'A' };
+    protected static final int[] POINT_ARRAY_M12 = new int[] { '\uFF21', 'A' };
+
+    protected static final String STRING_SUPPLEMENTARY = "\uD801\uDC00\uD801\uDC01\uFF21A";
+    protected static final byte[] BYTE_ARRAY_SUPPLEMENTARY = getBytes(STRING_SUPPLEMENTARY);
+    protected static final char[] CHAR_ARRAY_SUPPLEMENTARY = new char[] {
+            '\uD801', '\uDC00', '\uD801', '\uDC01', '\uFF21', 'A' };
+    protected static final int[] POINT_ARRAY_SUPPLEMENTARY = new int[] {
+            '\uD801', '\uDC00', '\uD801', '\uDC01', '\uFF21', 'A' };
+
+    protected static final String STRING_SUPPLEMENTARY_LOWERCASE = "\uD801\uDC28\uD801\uDC29\uFF41a";
+    protected static final byte[] BYTE_ARRAY_SUPPLEMENTARY_LOWERCASE = getBytes(STRING_SUPPLEMENTARY_LOWERCASE);
+    protected static final char[] CHAR_ARRAY_SUPPLEMENTARY_LOWERCASE = new char[] {
+            '\uD801', '\uDC28', '\uD801', '\uDC29', '\uFF41', 'a' };
+    protected static final int[] POINT_ARRAY_SUPPLEMENTARY_LOWERCASE = new int[] {
+            '\uD801', '\uDC28', '\uD801', '\uDC29', '\uFF41', 'a' };
+
+    protected static final String SRC_BYTE_ARRAY_WITH_CHARSETNAME = "source from byte array with charset name";
+    protected static final String SRC_BYTE_ARRAY_WITH_CHARSET = "source from byte array with charset";
+    protected static final String SRC_CHAR_ARRAY = "source from char array";
+    protected static final String SRC_POINT_ARRAY = "source from code point array";
+    protected static final String SRC_STRING = "source from String";
+    protected static final String SRC_STRINGBUFFER = "source from StringBuffer";
+    protected static final String SRC_STRINGBUILDER = "source from StringBuilder";
+    protected static final String SRC_COPYVALUEOF = "source from copyValueOf from char array";
+    protected static final String SRC_VALUEOF = "source from valueOf from char array";
+
+    static {
+        System.out
+                .println(String
+                        .format("====== The platform's default charset is \"%s\", we're using \"%s\" for testing.",
+                                Charset.defaultCharset().name(),
+                                DEFAULT_CHARSET_NAME));
+    }
+
+    private static byte[] getBytes(String str) {
+        byte[] res = null;
+        try {
+            res = str.getBytes(DEFAULT_CHARSET_NAME);
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+            throw new RuntimeException("caught UnsupportedEncodingException!!!", e);
+        }
+        return res;
+    }
+
+    private void setUpOneString(String content, byte[] ba, char[] ca, int[] cpa)
+            throws UnsupportedEncodingException {
+        final Map<String, String> m = new HashMap<>();
+        m.put(SRC_BYTE_ARRAY_WITH_CHARSETNAME, new String(ba,
+                DEFAULT_CHARSET_NAME));
+        m.put(SRC_BYTE_ARRAY_WITH_CHARSET, new String(ba, DEFAULT_CHARSET));
+        m.put(SRC_CHAR_ARRAY, new String(ca));
+        m.put(SRC_POINT_ARRAY, new String(cpa, 0, cpa.length));
+        m.put(SRC_STRING, new String(content));
+        m.put(SRC_STRINGBUFFER, new String(new StringBuffer(content)));
+        m.put(SRC_STRINGBUILDER, new String(new StringBuilder(content)));
+        m.put(SRC_COPYVALUEOF, String.copyValueOf(ca));
+        m.put(SRC_VALUEOF, String.valueOf(ca));
+        map.put(content, m);
+    }
+
+    /*
+     * Set up the test data, use 9 ways to construct one String.
+     *
+     * @throws UnsupportedEncodingException
+     *         If the named charset is not supported in setUpOneString(xxx).
+     */
+    @BeforeClass
+    public void setUp() throws UnsupportedEncodingException {
+        for (StringSources src : StringSources.values()) {
+            setUpOneString(src.getString(), src.getByteArray(),
+                    src.getCharArray(), src.getIntArray());
+        }
+    }
+
+    /*
+     * Because right now system default charset in JPRT environment is only
+     * guaranteed to support ASCII characters in log, so we escape them.
+     */
+    protected String escapeNonASCIIs(String str) {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < str.length(); i++) {
+            char c = str.charAt(i);
+            if (c > 0x7F) {
+                sb.append("\\u").append(Integer.toHexString((int) c));
+            } else {
+                sb.append(c);
+            }
+        }
+        return sb.toString();
+    }
+
+    /*
+     * Because right now system default charset in JPRT environment is only
+     * guaranteed to support ASCII characters in log, so we escape them.
+     */
+    protected String escapeNonASCII(char c) {
+        StringBuilder sb = new StringBuilder();
+        if (c > 0x7F) {
+            sb.append("\\u").append(Integer.toHexString((int) c));
+        } else {
+            sb.append(c);
+        }
+        return sb.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/CompareTo.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.compareTo.
+ * @run testng/othervm -XX:+CompactStrings CompareTo
+ * @run testng/othervm -XX:-CompactStrings CompareTo
+ */
+
+public class CompareTo extends CompactString {
+
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+
+        new Object[] { STRING_EMPTY, "A", -1 },
+                new Object[] { STRING_EMPTY, "\uFF21", -1 },
+                new Object[] { STRING_L1, "AB", -1 },
+                new Object[] { STRING_L1, "A", 0 },
+                new Object[] { STRING_L1, "a", -32 },
+                new Object[] { STRING_L1, "\uFF21", -65248 },
+                new Object[] { STRING_L2, "AB", 0 },
+                new Object[] { STRING_L2, "Ab", -32 },
+                new Object[] { STRING_L2, "AA", 1 },
+                new Object[] { STRING_L2, "\uFF21", -65248 },
+                new Object[] { STRING_L2, "A\uFF21", -65247 },
+                new Object[] { STRING_L4, "ABC", 1 },
+                new Object[] { STRING_L4, "AB", 2 },
+                new Object[] { STRING_L4, "ABcD", -32 },
+                new Object[] { STRING_L4, "ABCD\uFF21\uFF21", -2 },
+                new Object[] { STRING_L4, "ABCD\uFF21", -1 },
+                new Object[] { STRING_LLONG, "ABCDEFG\uFF21", -65241 },
+                new Object[] { STRING_LLONG, "AB", 6 },
+                new Object[] { STRING_LLONG, "ABCD", 4 },
+                new Object[] { STRING_LLONG, "ABCDEFGH\uFF21\uFF21", -2 },
+                new Object[] { STRING_U1, "\uFF21", 0 },
+                new Object[] { STRING_U1, "\uFF22", -1 },
+                new Object[] { STRING_U1, "\uFF21\uFF22", -1 },
+                new Object[] { STRING_U1, "A", 65248 },
+                new Object[] { STRING_U2, "\uFF21\uFF22", 0 },
+                new Object[] { STRING_U2, "\uFF22", -1 },
+                new Object[] { STRING_U2, "\uFF21\uFF21", 1 },
+                new Object[] { STRING_U2, "A", 65248 },
+                new Object[] { STRING_M12, "\uFF21A", 0 },
+                new Object[] { STRING_M12, "A\uFF21", 65248 },
+                new Object[] { STRING_M12, "\uFF21\uFF21", -65248 },
+                new Object[] { STRING_M11, "A\uFF21", 0 },
+                new Object[] { STRING_M11, "\uFF21A", -65248 },
+                new Object[] { STRING_M11, "AA", 65248 }, };
+    }
+
+    @Test(dataProvider = "provider")
+    public void testCompareTo(String str, String anotherString, int expected) {
+        map.get(str)
+                .forEach(
+                        (source, data) -> {
+                            assertEquals(
+                                    data.compareTo(anotherString),
+                                    expected,
+                                    String.format(
+                                            "testing String(%s).compareTo(%s), source : %s, ",
+                                            escapeNonASCIIs(data),
+                                            escapeNonASCIIs(anotherString),
+                                            source));
+                        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/CompareToIgnoreCase.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.compareToIgnoreCase.
+ * @run testng/othervm -XX:+CompactStrings CompareToIgnoreCase
+ * @run testng/othervm -XX:-CompactStrings CompareToIgnoreCase
+ */
+
+public class CompareToIgnoreCase extends CompactString {
+
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+
+                new Object[] { STRING_EMPTY, "A", -1 },
+                new Object[] { STRING_L1, "a", 0 },
+                new Object[] { STRING_L1, "A", 0 },
+                new Object[] { STRING_L1, "\uFF21", -65248 },
+                new Object[] { STRING_L1, "B", -1 },
+                new Object[] { STRING_L2, "AB", 0 },
+                new Object[] { STRING_L2, "aB", 0 },
+                new Object[] { STRING_L2, "\uFF21", -65248 },
+                new Object[] { STRING_L2, "A\uFF21", -65247 },
+                new Object[] { STRING_L4, "ABCD", 0 },
+                new Object[] { STRING_L4, "abcd", 0 },
+                new Object[] { STRING_L4, "ABc\uFF21", -65245 },
+                new Object[] { STRING_LLONG, "ABCDEFGH", 0 },
+                new Object[] { STRING_LLONG, "abcdefgh", 0 },
+                new Object[] { STRING_LLONG, "ABCDEFG\uFF21", -65241 },
+                new Object[] { STRING_LLONG, "abcdefg\uFF21", -65241 },
+                new Object[] { STRING_U1, "\uFF41", 0 },
+                new Object[] { STRING_U1,
+                        "\uFF41\uFF42\uFF43\uFF44\uFF45\uFF46\uFF47\uFF48", -7 },
+                new Object[] { STRING_U1, "A", 65248 },
+                new Object[] { STRING_U2, "\uFF41", 1 },
+                new Object[] { STRING_U2, "\uFF41\uFF42", 0 },
+                new Object[] { STRING_U2,
+                        "\uFF41\uFF42\uFF43\uFF44\uFF45\uFF46\uFF47\uFF48", -6 },
+                new Object[] { STRING_M12, "\uFF41a", 0 },
+                new Object[] { STRING_M12, "\uFF41\uFF42", -65249 },
+                new Object[] { STRING_M11, "a\uFF41", 0 },
+                new Object[] { STRING_M11, "a\uFF42", -1 }, };
+    }
+
+    @Test(dataProvider = "provider")
+    public void testCompareToIgnoreCase(String str, String anotherString,
+            int expected) {
+        map.get(str)
+                .forEach(
+                        (source, data) -> {
+                            assertEquals(
+                                    data.compareToIgnoreCase(anotherString),
+                                    expected,
+                                    String.format(
+                                            "testing String(%s).compareToIgnoreCase(%s), source : %s, ",
+                                            escapeNonASCIIs(data),
+                                            escapeNonASCIIs(anotherString),
+                                            source));
+                        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/Concat.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,132 @@
+/*
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.concat.
+ * @run testng/othervm -XX:+CompactStrings Concat
+ * @run testng/othervm -XX:-CompactStrings Concat
+ */
+
+public class Concat extends CompactString {
+
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+                new Object[] { STRING_EMPTY, "ABC", "ABC" },
+                new Object[] { STRING_EMPTY,
+                        "ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
+                        "ABC\uFF21\uFF22\uFF23DEF" },
+                new Object[] {
+                        STRING_EMPTY,
+                        "\uFF21\uFF22\uFF23".concat("ABC").concat(
+                                "\uFF24\uFF25\uFF26"),
+                        "\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" },
+                new Object[] { STRING_L1,
+                        "ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
+                        "AABC\uFF21\uFF22\uFF23DEF" },
+                new Object[] {
+                        STRING_L1,
+                        "\uFF21\uFF22\uFF23".concat("ABC").concat(
+                                "\uFF24\uFF25\uFF26"),
+                        "A\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" },
+                new Object[] { STRING_L2,
+                        "ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
+                        "ABABC\uFF21\uFF22\uFF23DEF" },
+                new Object[] {
+                        STRING_L2,
+                        "\uFF21\uFF22\uFF23".concat("ABC").concat(
+                                "\uFF24\uFF25\uFF26"),
+                        "AB\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" },
+                new Object[] { STRING_L4,
+                        "ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
+                        "ABCDABC\uFF21\uFF22\uFF23DEF" },
+                new Object[] {
+                        STRING_L4,
+                        "\uFF21\uFF22\uFF23".concat("ABC").concat(
+                                "\uFF24\uFF25\uFF26"),
+                        "ABCD\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" },
+                new Object[] { STRING_LLONG,
+                        "ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
+                        "ABCDEFGHABC\uFF21\uFF22\uFF23DEF" },
+                new Object[] {
+                        STRING_LLONG,
+                        "\uFF21\uFF22\uFF23".concat("ABC").concat(
+                                "\uFF24\uFF25\uFF26"),
+                        "ABCDEFGH\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" },
+                new Object[] { STRING_U1,
+                        "ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
+                        "\uFF21ABC\uFF21\uFF22\uFF23DEF" },
+                new Object[] {
+                        STRING_U1,
+                        "\uFF21\uFF22\uFF23".concat("ABC").concat(
+                                "\uFF24\uFF25\uFF26"),
+                        "\uFF21\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" },
+                new Object[] { STRING_U2,
+                        "ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
+                        "\uFF21\uFF22ABC\uFF21\uFF22\uFF23DEF" },
+                new Object[] {
+                        STRING_U2,
+                        "\uFF21\uFF22\uFF23".concat("ABC").concat(
+                                "\uFF24\uFF25\uFF26"),
+                        "\uFF21\uFF22\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" },
+                new Object[] { STRING_M12,
+                        "ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
+                        "\uFF21AABC\uFF21\uFF22\uFF23DEF" },
+                new Object[] {
+                        STRING_M12,
+                        "\uFF21\uFF22\uFF23".concat("ABC").concat(
+                                "\uFF24\uFF25\uFF26"),
+                        "\uFF21A\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" },
+                new Object[] { STRING_M11,
+                        "ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
+                        "A\uFF21ABC\uFF21\uFF22\uFF23DEF" },
+                new Object[] {
+                        STRING_M11,
+                        "\uFF21\uFF22\uFF23".concat("ABC").concat(
+                                "\uFF24\uFF25\uFF26"),
+                        "A\uFF21\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" }, };
+    }
+
+    @Test(dataProvider = "provider")
+    public void testConcat(String str, String anotherString, String expected) {
+        map.get(str)
+                .forEach(
+                        (source, data) -> {
+                            assertEquals(
+                                    data.concat(anotherString),
+                                    expected,
+                                    String.format(
+                                            "testing String(%s).concat(%s), source : %s, ",
+                                            escapeNonASCIIs(data),
+                                            escapeNonASCIIs(anotherString),
+                                            source));
+                        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/Contains.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.contains.
+ * @run testng/othervm -XX:+CompactStrings Contains
+ * @run testng/othervm -XX:-CompactStrings Contains
+ */
+
+public class Contains extends CompactString {
+
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+
+        new Object[] { STRING_EMPTY, "", true },
+                new Object[] { STRING_EMPTY, "A", false },
+                new Object[] { STRING_EMPTY, "\uFF21", false },
+                new Object[] { STRING_L1, "", true },
+                new Object[] { STRING_L1, "A", true },
+                new Object[] { STRING_L1, "\uFF21", false },
+                new Object[] { STRING_L2, "", true },
+                new Object[] { STRING_L2, "A", true },
+                new Object[] { STRING_L2, "AB", true },
+                new Object[] { STRING_L2, "B", true },
+                new Object[] { STRING_L2, "ABC", false },
+                new Object[] { STRING_L2, "ab", false },
+                new Object[] { STRING_L4, "ABCD", true },
+                new Object[] { STRING_L4, "BC", true },
+                new Object[] { STRING_LLONG, "ABCDEFGH", true },
+                new Object[] { STRING_LLONG, "BCDEFGH", true },
+                new Object[] { STRING_LLONG, "EF", true },
+                new Object[] { STRING_U1, "", true },
+                new Object[] { STRING_U1, "\uFF21", true },
+                new Object[] { STRING_U1, "a", false },
+                new Object[] { STRING_U1, "\uFF21B", false },
+                new Object[] { STRING_U2, "", true },
+                new Object[] { STRING_U2, "\uFF21\uFF22", true },
+                new Object[] { STRING_U2, "a", false },
+                new Object[] { STRING_U2, "\uFF21B", false },
+                new Object[] { STRING_M12, "\uFF21A", true },
+                new Object[] { STRING_M12, "\uFF21", true },
+                new Object[] { STRING_M12, "A", true },
+                new Object[] { STRING_M12, "A\uFF21", false },
+                new Object[] { STRING_M11, "A\uFF21", true },
+                new Object[] { STRING_M11, "Ab", false }, };
+    }
+
+    @Test(dataProvider = "provider")
+    public void testContains(String str, String anotherString, boolean expected) {
+        map.get(str)
+                .forEach(
+                        (source, data) -> {
+                            assertEquals(
+                                    data.contains(anotherString),
+                                    expected,
+                                    String.format(
+                                            "testing String(%s).contains(%s), source : %s, ",
+                                            escapeNonASCIIs(data),
+                                            escapeNonASCIIs(anotherString),
+                                            source));
+                        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/EndsWith.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.endsWith.
+ * @run testng/othervm -XX:+CompactStrings EndsWith
+ * @run testng/othervm -XX:-CompactStrings EndsWith
+ */
+
+public class EndsWith extends CompactString {
+
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] { new Object[] { STRING_EMPTY, "", true },
+                new Object[] { STRING_EMPTY, "A", false },
+                new Object[] { STRING_L1, "A", true },
+                new Object[] { STRING_L1, "", true },
+                new Object[] { STRING_L1, " ", false },
+                new Object[] { STRING_L2, "AB", true },
+                new Object[] { STRING_L2, "B", true },
+                new Object[] { STRING_L2, "", true },
+                new Object[] { STRING_L2, "A", false },
+                new Object[] { STRING_L4, "ABCD", true },
+                new Object[] { STRING_L4, "CD", true },
+                new Object[] { STRING_L4, "D", true },
+                new Object[] { STRING_L4, "", true },
+                new Object[] { STRING_L4, "BC", false },
+                new Object[] { STRING_LLONG, "ABCDEFGH", true },
+                new Object[] { STRING_LLONG, "EFGH", true },
+                new Object[] { STRING_LLONG, "", true },
+                new Object[] { STRING_LLONG, "CDEF", false },
+                new Object[] { STRING_LLONG, "\uFF28", false },
+                new Object[] { STRING_U1, "\uFF21", true },
+                new Object[] { STRING_U1, "", true },
+                new Object[] { STRING_U1, "\uFF22", false },
+                new Object[] { STRING_U1, "B", false },
+                new Object[] { STRING_U2, "\uFF21\uFF22", true },
+                new Object[] { STRING_U2, "\uFF22", true },
+                new Object[] { STRING_U2, "", true },
+                new Object[] { STRING_U2, "\uFF21", false },
+                new Object[] { STRING_M12, "\uFF21A", true },
+                new Object[] { STRING_M12, "A", true },
+                new Object[] { STRING_M12, "", true },
+                new Object[] { STRING_M12, "AA", false },
+                new Object[] { STRING_M11, "A\uFF21", true },
+                new Object[] { STRING_M11, "\uFF21", true },
+                new Object[] { STRING_M11, "", true },
+                new Object[] { STRING_M11, "\uFF21\uFF21", false }, };
+    }
+
+    @Test(dataProvider = "provider")
+    public void testEndsWith(String str, String suffix, boolean expected) {
+        map.get(str)
+                .forEach(
+                        (source, data) -> {
+                            assertEquals(
+                                    data.endsWith(suffix),
+                                    expected,
+                                    String.format(
+                                            "testing String(%s).endsWith(%s), source : %s, ",
+                                            escapeNonASCIIs(data),
+                                            escapeNonASCIIs(suffix), source));
+                        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/Equals.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.equals.
+ * @run testng/othervm -XX:+CompactStrings Equals
+ * @run testng/othervm -XX:-CompactStrings Equals
+ */
+
+public class Equals extends CompactString {
+
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+                new Object[] { STRING_EMPTY, "", true },
+                new Object[] { STRING_EMPTY, "A", false },
+                new Object[] { STRING_EMPTY, new StringBuffer(""), false },
+                new Object[] { STRING_L1, "A", true },
+                new Object[] { STRING_L1, "", false },
+                new Object[] { STRING_L1, new StringBuffer("A"), false },
+                new Object[] { STRING_L2, "AB", true },
+                new Object[] { STRING_L2, "", false },
+                new Object[] { STRING_L2, new StringBuilder("AB"), false },
+                new Object[] { STRING_L4, "ABCD", true },
+                new Object[] { STRING_L4, "abc", false },
+                new Object[] { STRING_L4, "", false },
+                new Object[] { STRING_LLONG, "ABCDEFGH", true },
+                new Object[] { STRING_LLONG, "ABCDEFG", false },
+                new Object[] { STRING_LLONG, new StringBuilder("ABCDEFGH"),
+                        false },
+                new Object[] { STRING_U1, "\uFF21", true },
+                new Object[] { STRING_U1, "", false },
+                new Object[] { STRING_U2, "\uFF21\uFF22", true },
+                new Object[] { STRING_U2, "\uFF21", false },
+                new Object[] { STRING_U2, "", false },
+                new Object[] { STRING_U2, new StringBuilder("\uFF21\uFF22"),
+                        false },
+                new Object[] { STRING_M12, "\uFF21A", true },
+                new Object[] { STRING_M12, "A\uFF21", false },
+                new Object[] { STRING_M11, "A\uFF21", true },
+                new Object[] { STRING_M11, new StringBuilder("\uFF21A"), false }, };
+    }
+
+    @Test(dataProvider = "provider")
+    public void testEquals(String str, Object obj, boolean expected) {
+        map.get(str).forEach(
+                (source, data) -> {
+                    assertEquals(data.equals(obj), expected, String.format(
+                            "testing String(%s).equals(%s), source : %s, ",
+                            escapeNonASCIIs(data),
+                            escapeNonASCIIs(obj.toString()), source));
+                });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/EqualsIgnoreCase.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.equalsIgnoreCase.
+ * @run testng/othervm -XX:+CompactStrings EqualsIgnoreCase
+ * @run testng/othervm -XX:-CompactStrings EqualsIgnoreCase
+ */
+
+public class EqualsIgnoreCase extends CompactString {
+
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+
+        new Object[] { STRING_EMPTY, "", true },
+                new Object[] { STRING_L1, "a", true },
+                new Object[] { STRING_L2, "aB", true },
+                new Object[] { STRING_L4, "AbCd", true },
+                new Object[] { STRING_LLONG, "aBcDeFgH", true },
+                new Object[] { STRING_U1, "\uFF41", true },
+                new Object[] { STRING_U1, "\uFF21", true },
+                new Object[] { STRING_U2, "\uFF41\uFF42", true },
+                new Object[] { STRING_U2, "\uFF41\uFF22", true },
+                new Object[] { STRING_U2, "\uFF21\uFF42", true },
+                new Object[] { STRING_M12, "\uFF41a", true },
+                new Object[] { STRING_M12, "\uFF21A", true },
+                new Object[] { STRING_M11, "a\uFF41", true },
+                new Object[] { STRING_M11, "A\uFF21", true },
+
+        };
+    }
+
+    @Test(dataProvider = "provider")
+    public void testEqualsIgnoreCase(String str, String anotherString,
+            boolean expected) {
+        map.get(str)
+                .forEach(
+                        (source, data) -> {
+                            assertEquals(
+                                    data.equalsIgnoreCase(anotherString),
+                                    expected,
+                                    String.format(
+                                            "testing String(%s).equalsIgnoreCase(%s), source : %s, ",
+                                            escapeNonASCIIs(data),
+                                            escapeNonASCIIs(anotherString),
+                                            source));
+                        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/GetChars.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+import java.util.Arrays;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertTrue;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.getChars.
+ * @run testng/othervm -XX:+CompactStrings GetChars
+ * @run testng/othervm -XX:-CompactStrings GetChars
+ */
+
+public class GetChars extends CompactString {
+
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+
+                new Object[] { STRING_EMPTY, 0, STRING_EMPTY.length(),
+                        new char[STRING_EMPTY.length()], 0, CHAR_ARRAY_EMPTY },
+                new Object[] { STRING_L1, 0, STRING_L1.length(),
+                        new char[STRING_L1.length()], 0, CHAR_ARRAY_L1 },
+                new Object[] { STRING_L2, 0, STRING_L2.length(),
+                        new char[STRING_L2.length()], 0, CHAR_ARRAY_L2 },
+                new Object[] { STRING_L4, 0, STRING_L4.length(),
+                        new char[STRING_L4.length()], 0, CHAR_ARRAY_L4 },
+                new Object[] { STRING_LLONG, 0, STRING_LLONG.length(),
+                        new char[STRING_LLONG.length()], 0, CHAR_ARRAY_LLONG },
+                new Object[] { STRING_U1, 0, STRING_U1.length(),
+                        new char[STRING_U1.length()], 0, CHAR_ARRAY_U1 },
+                new Object[] { STRING_U2, 0, STRING_U2.length(),
+                        new char[STRING_U2.length()], 0, CHAR_ARRAY_U2 },
+                new Object[] { STRING_M12, 0, STRING_M12.length(),
+                        new char[STRING_M12.length()], 0, CHAR_ARRAY_M12 },
+                new Object[] { STRING_M11, 0, STRING_M11.length(),
+                        new char[STRING_M11.length()], 0, CHAR_ARRAY_M11 },
+                new Object[] { STRING_UDUPLICATE, 0,
+                        STRING_UDUPLICATE.length(),
+                        new char[STRING_UDUPLICATE.length()], 0,
+                        CHAR_ARRAY_UDUPLICATE },
+                new Object[] { STRING_MDUPLICATE1, 0,
+                        STRING_MDUPLICATE1.length(),
+                        new char[STRING_MDUPLICATE1.length()], 0,
+                        CHAR_ARRAY_MDUPLICATE1 }, };
+    }
+
+    @Test(dataProvider = "provider")
+    public void testGetChars(String str, int srcBegin, int srcEnd, char[] dst,
+            int dstBegin, char[] expected) {
+        map.get(str)
+                .forEach(
+                        (source, data) -> {
+                            data.getChars(srcBegin, srcEnd, dst, dstBegin);
+                            assertTrue(
+                                    Arrays.equals(dst, expected),
+                                    String.format(
+                                            "testing String(%s).getChars(%d, %d, %s, %d), source : %s, ",
+                                            escapeNonASCIIs(data), srcBegin,
+                                            srcEnd, escapeNonASCIIs(Arrays
+                                                    .toString(dst)), dstBegin,
+                                            source));
+                        });
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/IndexOf.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,249 @@
+/*
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.indexOf.
+ * @run testng/othervm -XX:+CompactStrings IndexOf
+ * @run testng/othervm -XX:-CompactStrings IndexOf
+ */
+
+public class IndexOf extends CompactString {
+
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+
+                new Object[] { STRING_EMPTY, (int) 'A', -1 },
+                new Object[] { STRING_L1, (int) 'A', 0 },
+                new Object[] { STRING_L2, (int) 'A', 0 },
+                new Object[] { STRING_L2, (int) 'B', 1 },
+                new Object[] { STRING_L4, (int) 'A', 0 },
+                new Object[] { STRING_L4, (int) 'D', 3 },
+                new Object[] { STRING_L4, (int) 'E', -1 },
+                new Object[] { STRING_LLONG, (int) 'A', 0 },
+                new Object[] { STRING_LLONG, (int) 'H', 7 },
+                new Object[] { STRING_U1, (int) '\uFF21', 0 },
+                new Object[] { STRING_U1, (int) 'A', -1 },
+                new Object[] { STRING_U2, (int) '\uFF21', 0 },
+                new Object[] { STRING_U2, (int) '\uFF22', 1 },
+                new Object[] { STRING_M12, (int) '\uFF21', 0 },
+                new Object[] { STRING_M12, (int) 'A', 1 },
+                new Object[] { STRING_M11, (int) 'A', 0 },
+                new Object[] { STRING_M11, (int) '\uFF21', 1 },
+                new Object[] { STRING_UDUPLICATE, (int) '\uFF21', 0 },
+                new Object[] { STRING_UDUPLICATE, (int) '\uFF22', 1 },
+                new Object[] { STRING_SUPPLEMENTARY, 'A', 5 },
+                new Object[] { STRING_SUPPLEMENTARY, '\uFF21', 4 },
+                new Object[] { STRING_SUPPLEMENTARY,
+                        Character.toCodePoint('\uD801', '\uDC00'), 0 },
+                new Object[] { STRING_SUPPLEMENTARY,
+                        Character.toCodePoint('\uD801', '\uDC01'), 2 }, };
+    }
+
+    @Test(dataProvider = "provider")
+    public void testIndexOf(String str, int ch, int expected) {
+        map.get(str).forEach(
+                (source, data) -> {
+                    assertEquals(data.indexOf(ch), expected, String.format(
+                            "testing String(%s).indexOf(%d), source : %s, ",
+                            escapeNonASCIIs(data), ch, source));
+                });
+    }
+
+    @DataProvider
+    public Object[][] provider2() {
+        return new Object[][] {
+
+        new Object[] { STRING_EMPTY, (int) 'A', 0, -1 },
+                new Object[] { STRING_L1, (int) 'A', 0, 0 },
+                new Object[] { STRING_L1, (int) 'A', 1, -1 },
+                new Object[] { STRING_L1, (int) 'B', 0, -1 },
+                new Object[] { STRING_L2, (int) 'A', 0, 0 },
+                new Object[] { STRING_L2, (int) 'A', 1, -1 },
+                new Object[] { STRING_L2, (int) 'B', 0, 1 },
+                new Object[] { STRING_L2, (int) 'B', 1, 1 },
+                new Object[] { STRING_L4, (int) 'A', 0, 0 },
+                new Object[] { STRING_L4, (int) 'D', 2, 3 },
+                new Object[] { STRING_L4, (int) 'B', 2, -1 },
+                new Object[] { STRING_LLONG, (int) 'A', 0, 0 },
+                new Object[] { STRING_LLONG, (int) 'H', 5, 7 },
+                new Object[] { STRING_U1, (int) '\uFF21', 0, 0 },
+                new Object[] { STRING_U1, (int) 'A', 0, -1 },
+                new Object[] { STRING_U2, (int) '\uFF21', 0, 0 },
+                new Object[] { STRING_U2, (int) '\uFF22', 0, 1 },
+                new Object[] { STRING_M12, (int) '\uFF21', 0, 0 },
+                new Object[] { STRING_M12, (int) 'A', 1, 1 },
+                new Object[] { STRING_M11, (int) 'A', 0, 0 },
+                new Object[] { STRING_M11, (int) '\uFF21', 1, 1 },
+                new Object[] { STRING_UDUPLICATE, (int) '\uFF21', 1, 2 },
+                new Object[] { STRING_UDUPLICATE, (int) '\uFF22', 1, 1 }, };
+    }
+
+    @Test(dataProvider = "provider2")
+    public void testIndexOf(String str, int ch, int fromIndex, int expected) {
+        map.get(str)
+                .forEach(
+                        (source, data) -> {
+                            assertEquals(
+                                    data.indexOf(ch, fromIndex),
+                                    expected,
+                                    String.format(
+                                            "testing String(%s).indexOf(%d, %d), source : %s, ",
+                                            escapeNonASCIIs(data), ch,
+                                            fromIndex, source));
+                        });
+    }
+
+    @DataProvider
+    public Object[][] provider3() {
+        return new Object[][] {
+
+                new Object[] { STRING_EMPTY, "A", -1 },
+                new Object[] { STRING_L1, "A", 0 },
+                new Object[] { STRING_L1, "AB", -1 },
+                new Object[] { STRING_L2, "A", 0 },
+                new Object[] { STRING_L2, "B", 1 },
+                new Object[] { STRING_L2, "AB", 0 },
+                new Object[] { STRING_L2, "AC", -1 },
+                new Object[] { STRING_L2, "ABC", -1 },
+                new Object[] { STRING_L4, "ABCD", 0 },
+                new Object[] { STRING_L4, "D", 3 },
+                new Object[] { STRING_LLONG, "ABCDEFGH", 0 },
+                new Object[] { STRING_LLONG, "EFGH", 4 },
+                new Object[] { STRING_LLONG, "EFGHI", -1 },
+                new Object[] { STRING_U1, "\uFF21", 0 },
+                new Object[] { STRING_U1, "\uFF21A", -1 },
+                new Object[] { STRING_U2, "\uFF21\uFF22", 0 },
+                new Object[] { STRING_U2, "\uFF22", 1 },
+                new Object[] { STRING_U2, "A\uFF22", -1 },
+                new Object[] { STRING_M12, "\uFF21A", 0 },
+                new Object[] { STRING_M12, "A", 1 },
+                new Object[] { STRING_M12, "\uFF21\uFF21", -1 },
+                new Object[] { STRING_M11, "A\uFF21", 0 },
+                new Object[] { STRING_M11, "\uFF21", 1 },
+                new Object[] { STRING_M11, "A", 0 },
+                new Object[] {
+                        STRING_UDUPLICATE,
+                        "\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
+                        0 },
+                new Object[] { STRING_UDUPLICATE,
+                        "\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21", 1 },
+                new Object[] {
+                        STRING_UDUPLICATE,
+                        "\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21",
+                        -1 }, };
+    }
+
+    @Test(dataProvider = "provider3")
+    public void testIndexOf(String str, String anotherString, int expected) {
+        map.get(str)
+                .forEach(
+                        (source, data) -> {
+                            assertEquals(
+                                    data.indexOf(anotherString),
+                                    expected,
+                                    String.format(
+                                            "testing String(%s).indexOf(%s), source : %s, ",
+                                            escapeNonASCIIs(data),
+                                            escapeNonASCIIs(anotherString),
+                                            source));
+                        });
+    }
+
+    @DataProvider
+    public Object[][] provider4() {
+        return new Object[][] {
+
+                new Object[] { STRING_EMPTY, "A", 0, -1 },
+                new Object[] { STRING_L1, "A", 0, 0 },
+                new Object[] { STRING_L1, "A", 1, -1 },
+                new Object[] { STRING_L1, "AB", 0, -1 },
+                new Object[] { STRING_L2, "A", 0, 0 },
+                new Object[] { STRING_L2, "B", 0, 1 },
+                new Object[] { STRING_L2, "AB", 0, 0 },
+                new Object[] { STRING_L2, "AB", 1, -1 },
+                new Object[] { STRING_L4, "ABCD", 0, 0 },
+                new Object[] { STRING_L4, "BC", 0, 1 },
+                new Object[] { STRING_L4, "A", 0, 0 },
+                new Object[] { STRING_L4, "CD", 0, 2 },
+                new Object[] { STRING_L4, "A", 2, -1 },
+                new Object[] { STRING_L4, "ABCDE", 0, -1 },
+                new Object[] { STRING_LLONG, "ABCDEFGH", 0, 0 },
+                new Object[] { STRING_LLONG, "DEFGH", 0, 3 },
+                new Object[] { STRING_LLONG, "A", 0, 0 },
+                new Object[] { STRING_LLONG, "GHI", 0, -1 },
+                new Object[] { STRING_U1, "\uFF21", 0, 0 },
+                new Object[] { STRING_U1, "\uFF21A", 0, -1 },
+                new Object[] { STRING_U2, "\uFF21\uFF22", 0, 0 },
+                new Object[] { STRING_U2, "\uFF22", 0, 1 },
+                new Object[] { STRING_U2, "\uFF21", 1, -1 },
+                new Object[] { STRING_M12, "\uFF21A", 0, 0 },
+                new Object[] { STRING_M12, "A", 1, 1 },
+                new Object[] { STRING_M12, "\uFF21A", 1, -1 },
+                new Object[] { STRING_M12, "\uFF21", 0, 0 },
+                new Object[] { STRING_M11, "A\uFF21", 0, 0 },
+                new Object[] { STRING_M11, "\uFF21", 1, 1 },
+                new Object[] { STRING_M11, "A\uFF21", 1, -1 },
+                new Object[] { STRING_M11, "A\uFF21A", 0, -1 },
+                new Object[] {
+                        STRING_UDUPLICATE,
+                        "\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
+                        0, 0 },
+                new Object[] {
+                        STRING_UDUPLICATE,
+                        "\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
+                        1, -1 },
+                new Object[] {
+                        STRING_UDUPLICATE,
+                        "\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
+                        1, 1 },
+                new Object[] { STRING_UDUPLICATE, "\uFF21\uFF22\uFF21\uFF22",
+                        4, 4 },
+                new Object[] { STRING_UDUPLICATE, "\uFF21\uFF22\uFF21\uFF22",
+                        7, -1 }, };
+    }
+
+    @Test(dataProvider = "provider4")
+    public void testIndexOf(String str, String anotherString, int fromIndex,
+            int expected) {
+        map.get(str)
+                .forEach(
+                        (source, data) -> {
+                            assertEquals(
+                                    data.indexOf(anotherString, fromIndex),
+                                    expected,
+                                    String.format(
+                                            "testing String(%s).indexOf(%s), source : %s, ",
+                                            escapeNonASCIIs(data),
+                                            escapeNonASCIIs(anotherString),
+                                            fromIndex, source));
+                        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/Intern.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertTrue;
+
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.intern.
+ * @run testng/othervm -XX:+CompactStrings Intern
+ * @run testng/othervm -XX:-CompactStrings Intern
+ */
+
+public class Intern extends CompactString {
+
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+
+                new Object[] { STRING_EMPTY, "" },
+                new Object[] { STRING_L1, "A" },
+                new Object[] { STRING_LLONG, "ABCDEFGH" },
+                new Object[] { STRING_U1, "\uFF21" },
+                new Object[] { STRING_U2, "\uFF21\uFF22" },
+                new Object[] { STRING_M12, "\uFF21A" },
+                new Object[] { STRING_M11, "A\uFF21" },
+                new Object[] { STRING_MDUPLICATE1,
+                        "\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A" }, };
+    }
+
+    @Test(dataProvider = "provider")
+    public void testIntern(String str, String expected) {
+        map.get(str).forEach(
+                (source, data) -> {
+                    assertTrue(data.intern() == expected, String.format(
+                            "testing String(%s).intern(), source : %s, ",
+                            escapeNonASCIIs(data), source));
+                });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/LastIndexOf.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,225 @@
+/*
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.lastIndexOf.
+ * @run testng/othervm -XX:+CompactStrings LastIndexOf
+ * @run testng/othervm -XX:-CompactStrings LastIndexOf
+ */
+
+public class LastIndexOf extends CompactString {
+
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+
+                new Object[] { STRING_EMPTY, (int) 'A', -1 },
+                new Object[] { STRING_L1, (int) 'A', 0 },
+                new Object[] { STRING_L2, (int) 'A', 0 },
+                new Object[] { STRING_L2, (int) 'B', 1 },
+                new Object[] { STRING_L4, (int) 'A', 0 },
+                new Object[] { STRING_L4, (int) 'D', 3 },
+                new Object[] { STRING_LLONG, (int) 'A', 0 },
+                new Object[] { STRING_LLONG, (int) 'H', 7 },
+                new Object[] { STRING_U1, (int) '\uFF21', 0 },
+                new Object[] { STRING_U1, (int) 'B', -1 },
+                new Object[] { STRING_U2, (int) '\uFF21', 0 },
+                new Object[] { STRING_U2, (int) '\uFF22', 1 },
+                new Object[] { STRING_M12, (int) '\uFF21', 0 },
+                new Object[] { STRING_M12, (int) 'A', 1 },
+                new Object[] { STRING_M11, (int) 'A', 0 },
+                new Object[] { STRING_M11, (int) '\uFF21', 1 },
+                new Object[] { STRING_UDUPLICATE, (int) '\uFF22', 9 },
+                new Object[] { STRING_UDUPLICATE, (int) '\uFF21', 8 },
+                new Object[] { STRING_SUPPLEMENTARY,
+                        Character.toCodePoint('\uD801', '\uDC01'), 2 }, };
+    }
+
+    @Test(dataProvider = "provider")
+    public void testLastIndexOf(String str, int ch, int expected) {
+        map.get(str)
+                .forEach(
+                        (source, data) -> {
+                            assertEquals(
+                                    data.lastIndexOf(ch),
+                                    expected,
+                                    String.format(
+                                            "testing String(%s).lastIndexOf(%d), source : %s, ",
+                                            escapeNonASCIIs(data), ch, source));
+                        });
+    }
+
+    @DataProvider
+    public Object[][] provider2() {
+        return new Object[][] {
+
+        new Object[] { STRING_EMPTY, (int) 'A', 0, -1 },
+                new Object[] { STRING_L1, (int) 'A', 0, 0 },
+                new Object[] { STRING_L1, (int) 'A', 1, 0 },
+                new Object[] { STRING_L2, (int) 'A', 0, 0 },
+                new Object[] { STRING_L2, (int) 'B', 1, 1 },
+                new Object[] { STRING_L2, (int) 'B', 2, 1 },
+                new Object[] { STRING_L4, (int) 'A', 0, 0 },
+                new Object[] { STRING_L4, (int) 'C', 2, 2 },
+                new Object[] { STRING_L4, (int) 'C', 1, -1 },
+                new Object[] { STRING_LLONG, (int) 'A', 0, 0 },
+                new Object[] { STRING_LLONG, (int) 'H', 7, 7 },
+                new Object[] { STRING_LLONG, (int) 'H', 6, -1 },
+                new Object[] { STRING_U1, (int) '\uFF21', 0, 0 },
+                new Object[] { STRING_U1, (int) '\uFF21', 7, 0 },
+                new Object[] { STRING_U2, (int) '\uFF21', 0, 0 },
+                new Object[] { STRING_U2, (int) '\uFF22', 0, -1 },
+                new Object[] { STRING_M12, (int) '\uFF21', 0, 0 },
+                new Object[] { STRING_M12, (int) 'A', 1, 1 },
+                new Object[] { STRING_M12, (int) 'A', 0, -1 },
+                new Object[] { STRING_M11, (int) 'A', 0, 0 },
+                new Object[] { STRING_M11, (int) '\uFF21', 1, 1 },
+                new Object[] { STRING_M11, (int) '\uFF21', 0, -1 },
+                new Object[] { STRING_UDUPLICATE, (int) '\uFF21', 5, 4 },
+                new Object[] { STRING_UDUPLICATE, (int) '\uFF21', 6, 6 },
+                new Object[] { STRING_UDUPLICATE, (int) '\uFF22', 5, 5 },
+                new Object[] { STRING_UDUPLICATE, (int) '\uFF22', 6, 5 }, };
+    }
+
+    @Test(dataProvider = "provider2")
+    public void testLastIndexOf(String str, int ch, int fromIndex, int expected) {
+        map.get(str)
+                .forEach(
+                        (source, data) -> {
+                            assertEquals(
+                                    data.lastIndexOf(ch, fromIndex),
+                                    expected,
+                                    String.format(
+                                            "testing String(%s).lastIndexOf(%d, %d), source : %s, ",
+                                            escapeNonASCIIs(data), ch,
+                                            fromIndex, source));
+                        });
+    }
+
+    @DataProvider
+    public Object[][] provider3() {
+        return new Object[][] {
+
+                new Object[] { STRING_EMPTY, "A", -1 },
+                new Object[] { STRING_L1, "A", 0 },
+                new Object[] { STRING_L1, "AB", -1 },
+
+                new Object[] { STRING_L2, "AB", 0 },
+                new Object[] { STRING_L2, "B", 1 },
+                new Object[] { STRING_L4, "ABCD", 0 },
+                new Object[] { STRING_L4, "B", 1 },
+                new Object[] { STRING_LLONG, "ABCD", 0 },
+                new Object[] { STRING_LLONG, "GH", 6 },
+                new Object[] { STRING_U1, "\uFF21", 0 },
+                new Object[] { STRING_U1, "\uFF22", -1 },
+                new Object[] { STRING_U2, "\uFF21\uFF22", 0 },
+                new Object[] { STRING_U2, "\uFF22", 1 },
+                new Object[] { STRING_M12, "\uFF21A", 0 },
+                new Object[] { STRING_M12, "A", 1 },
+                new Object[] { STRING_M11, "A\uFF21", 0 },
+                new Object[] { STRING_M11, "\uFF21", 1 },
+                new Object[] { STRING_UDUPLICATE, "\uFF21\uFF22\uFF21\uFF22", 6 },
+                new Object[] { STRING_UDUPLICATE, "\uFF21\uFF22", 8 }, };
+    }
+
+    @Test(dataProvider = "provider3")
+    public void testLastIndexOf(String str, String anotherString, int expected) {
+        map.get(str)
+                .forEach(
+                        (source, data) -> {
+                            assertEquals(
+                                    data.lastIndexOf(anotherString),
+                                    expected,
+                                    String.format(
+                                            "testing String(%s).lastIndexOf(%s), source : %s, ",
+                                            escapeNonASCIIs(data),
+                                            escapeNonASCIIs(anotherString),
+                                            source));
+                        });
+    }
+
+    @DataProvider
+    public Object[][] provider4() {
+        return new Object[][] {
+
+                new Object[] { STRING_EMPTY, "A", 0, -1 },
+                new Object[] { STRING_L2, "AB", 0, 0 },
+
+                new Object[] { STRING_L1, "AB", -1, -1 },
+
+                new Object[] { STRING_L2, "B", 1, 1 },
+                new Object[] { STRING_L2, "B", 0, -1 },
+                new Object[] { STRING_L4, "ABC", 3, 0 },
+                new Object[] { STRING_L4, "ABC", 0, 0 },
+                new Object[] { STRING_L4, "ABC", 1, 0 },
+                new Object[] { STRING_L4, "BC", 1, 1 },
+                new Object[] { STRING_L4, "BC", 0, -1 },
+                new Object[] { STRING_LLONG, "ABCDEFGH", 0, 0 },
+                new Object[] { STRING_LLONG, "EFGH", 7, 4 },
+                new Object[] { STRING_LLONG, "EFGH", 3, -1 },
+                new Object[] { STRING_U1, "\uFF21", 0, 0 },
+                new Object[] { STRING_U1, "\uFF21", 7, 0 },
+                new Object[] { STRING_U2, "\uFF21\uFF22", 0, 0 },
+                new Object[] { STRING_U2, "\uFF21\uFF22", 1, 0 },
+                new Object[] { STRING_M12, "\uFF21A", 0, 0 },
+                new Object[] { STRING_M12, "A", 1, 1 },
+                new Object[] { STRING_M12, "A", 0, -1 },
+                new Object[] { STRING_M11, "A\uFF21", 0, 0 },
+                new Object[] { STRING_M11, "A\uFF21", 1, 0 },
+                new Object[] { STRING_M11, "\uFF21", 0, -1 },
+                new Object[] {
+                        STRING_UDUPLICATE,
+                        "\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
+                        9, 0 },
+                new Object[] {
+                        STRING_UDUPLICATE,
+                        "\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
+                        0, 0 },
+                new Object[] { STRING_UDUPLICATE, "\uFF21\uFF22", 6, 6 },
+                new Object[] { STRING_UDUPLICATE, "\uFF21\uFF22\uFF21", 6, 6 }, };
+    }
+
+    @Test(dataProvider = "provider4")
+    public void testLastIndexOf(String str, String anotherString,
+            int fromIndex, int expected) {
+        map.get(str)
+                .forEach(
+                        (source, data) -> {
+                            assertEquals(
+                                    data.lastIndexOf(anotherString, fromIndex),
+                                    expected,
+                                    String.format(
+                                            "testing String(%s).lastIndexOf(%s, %d), source : %s, ",
+                                            escapeNonASCIIs(data),
+                                            escapeNonASCIIs(anotherString),
+                                            fromIndex, source));
+                        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/Length.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.length.
+ * @run testng/othervm -XX:+CompactStrings Length
+ * @run testng/othervm -XX:-CompactStrings Length
+ */
+
+public class Length extends CompactString {
+
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+
+        new Object[] { STRING_EMPTY, 0 }, new Object[] { STRING_L1, 1 },
+                new Object[] { STRING_L2, 2 },
+                new Object[] { STRING_LLONG, 8 },
+                new Object[] { STRING_U1, 1 }, new Object[] { STRING_U2, 2 },
+                new Object[] { STRING_M12, 2 }, new Object[] { STRING_M11, 2 },
+                new Object[] { STRING_UDUPLICATE, 10 },
+                new Object[] { STRING_SUPPLEMENTARY, 6 }, };
+    }
+
+    @Test(dataProvider = "provider")
+    public void testLength(String str, int expected) {
+        map.get(str).forEach(
+                (source, data) -> {
+                    assertEquals(data.length(), expected, String.format(
+                            "testing String(%s).length(), source : %s, ",
+                            escapeNonASCIIs(data), source));
+                });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/Numbers.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is testing
+ *          Integer/Long's methods related to String.
+ * @run testng/othervm -XX:+CompactStrings Numbers
+ * @run testng/othervm -XX:-CompactStrings Numbers
+ */
+
+public class Numbers {
+
+    /*
+     * Data provider for testIntegerLong
+     *
+     * @return input parameter for testIntegerLong
+     */
+    @DataProvider
+    public Object[][] numbers() {
+        return new Object[][] {
+                { Integer.toBinaryString(Integer.MAX_VALUE),
+                        "1111111111111111111111111111111" },
+                { Integer.toBinaryString(Integer.MIN_VALUE),
+                        "10000000000000000000000000000000" },
+                { Integer.toBinaryString(7), "111" },
+                { Integer.toBinaryString(0), "0" },
+                { Integer.toOctalString(Integer.MAX_VALUE), "17777777777" },
+                { Integer.toOctalString(Integer.MIN_VALUE), "20000000000" },
+                { Integer.toOctalString(9), "11" },
+                { Integer.toOctalString(0), "0" },
+                { Integer.toHexString(Integer.MAX_VALUE), "7fffffff" },
+                { Integer.toHexString(Integer.MIN_VALUE), "80000000" },
+                { Integer.toHexString(17), "11" },
+                { Integer.toHexString(0), "0" },
+                { Integer.toString(Integer.MAX_VALUE, 2),
+                        "1111111111111111111111111111111" },
+                { Integer.toString(Integer.MIN_VALUE, 2),
+                        "-10000000000000000000000000000000" },
+                { Integer.toString(7, 2), "111" },
+                { Integer.toString(0, 2), "0" },
+                { Integer.toString(Integer.MAX_VALUE, 8), "17777777777" },
+                { Integer.toString(Integer.MIN_VALUE, 8), "-20000000000" },
+                { Integer.toString(9, 8), "11" },
+                { Integer.toString(Integer.MAX_VALUE, 16), "7fffffff" },
+                { Integer.toString(Integer.MIN_VALUE, 16), "-80000000" },
+                { Integer.toString(17, 16), "11" },
+                { Long.toBinaryString(Long.MAX_VALUE),
+                        "111111111111111111111111111111111111111111111111111111111111111" },
+                { Long.toBinaryString(Long.MIN_VALUE),
+                        "1000000000000000000000000000000000000000000000000000000000000000" },
+                { Long.toOctalString(Long.MAX_VALUE), "777777777777777777777" },
+                { Long.toOctalString(Long.MIN_VALUE), "1000000000000000000000" },
+                { Long.toHexString(Long.MAX_VALUE), "7fffffffffffffff" },
+                { Long.toHexString(Long.MIN_VALUE), "8000000000000000" },
+                { Long.toString(Long.MAX_VALUE, 2),
+                        "111111111111111111111111111111111111111111111111111111111111111" },
+                { Long.toString(Long.MIN_VALUE, 2),
+                        "-1000000000000000000000000000000000000000000000000000000000000000" },
+                { Long.toString(Long.MAX_VALUE, 8), "777777777777777777777" },
+                { Long.toString(Long.MIN_VALUE, 8), "-1000000000000000000000" },
+                { Long.toString(Long.MAX_VALUE, 16), "7fffffffffffffff" },
+                { Long.toString(Long.MIN_VALUE, 16), "-8000000000000000" } };
+    }
+
+    /*
+     * test Integer/Long's methods related to String.
+     *
+     * @param res
+     *            real result
+     * @param expected
+     *            expected result
+     */
+    @Test(dataProvider = "numbers")
+    public void testIntegerLong(String res, String expected) {
+        assertEquals(res, expected);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/OffsetByCodePoints.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.offsetByCodePoints.
+ * @run testng/othervm -XX:+CompactStrings OffsetByCodePoints
+ * @run testng/othervm -XX:-CompactStrings OffsetByCodePoints
+ */
+
+public class OffsetByCodePoints extends CompactString {
+
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+
+        new Object[] { STRING_SUPPLEMENTARY, 0, 1, 2 },
+                new Object[] { STRING_SUPPLEMENTARY, 0, 3, 5 },
+                new Object[] { STRING_SUPPLEMENTARY, 1, 1, 2 },
+                new Object[] { STRING_SUPPLEMENTARY, 1, 3, 5 },
+                new Object[] { STRING_SUPPLEMENTARY, 2, 1, 4 },
+                new Object[] { STRING_SUPPLEMENTARY, 2, 2, 5 },
+                new Object[] { STRING_SUPPLEMENTARY, 2, 3, 6 },
+                new Object[] { STRING_SUPPLEMENTARY, 3, 1, 4 },
+                new Object[] { STRING_SUPPLEMENTARY, 3, 2, 5 },
+                new Object[] { STRING_SUPPLEMENTARY, 3, 3, 6 }, };
+    }
+
+    @Test(dataProvider = "provider")
+    public void testOffsetByCodePoints(String str, int index,
+            int codePointOffset, int expected) {
+        map.get(str)
+                .forEach(
+                        (source, data) -> {
+                            assertEquals(
+                                    data.offsetByCodePoints(index,
+                                            codePointOffset),
+                                    expected,
+                                    String.format(
+                                            "testing String(%s).offsetByCodePoints(%d, %d), source : %s, ",
+                                            escapeNonASCIIs(data), index,
+                                            codePointOffset, source));
+                        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/RegionMatches.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.regionMatches.
+ * @run testng/othervm -XX:+CompactStrings RegionMatches
+ * @run testng/othervm -XX:-CompactStrings RegionMatches
+ */
+
+public class RegionMatches extends CompactString {
+
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+
+                new Object[] { STRING_EMPTY, true, 0, "", 0, 0, true },
+                new Object[] { STRING_EMPTY, true, 0, "", 0, 1, false },
+                new Object[] { STRING_EMPTY, true, 0, "A", 0, 0, true },
+                new Object[] { STRING_EMPTY, true, 0, "", 0, 0, true },
+                new Object[] { STRING_EMPTY, true, 0, "", 0, 1, false },
+                new Object[] { STRING_L1, false, 0, "a", 0, 1, false },
+                new Object[] { STRING_L1, false, 0, "BA", 1, 1, true },
+                new Object[] { STRING_L1, false, 0, "Ba", 1, 1, false },
+                new Object[] { STRING_L1, true, 0, "a", 0, 1, true },
+                new Object[] { STRING_L1, true, 0, "BA", 1, 1, true },
+                new Object[] { STRING_L1, true, 0, "Ba", 1, 1, true },
+                new Object[] { STRING_L2, true, 1, "b", 0, 1, true },
+                new Object[] { STRING_L2, true, 1, "B", 0, 1, true },
+                new Object[] { STRING_L2, true, 0, "xaBc", 1, 2, true },
+                new Object[] { STRING_L2, false, 0, "AB", 0, 2, true },
+                new Object[] { STRING_L2, false, 0, "Ab", 0, 2, false },
+                new Object[] { STRING_L2, false, 1, "BAB", 2, 1, true },
+                new Object[] { STRING_LLONG, true, 1, "bCdEF", 0, 5, true },
+                new Object[] { STRING_LLONG, false, 2, "CDEFG", 0, 5, true },
+                new Object[] { STRING_LLONG, true, 2, "CDEFg", 0, 5, true },
+                new Object[] { STRING_U1, true, 0, "\uFF41", 0, 1, true },
+                new Object[] { STRING_U1, false, 0, "\uFF41", 0, 1, false },
+                new Object[] { STRING_MDUPLICATE1, true, 0, "\uFF41a\uFF41", 0,
+                        3, true },
+                new Object[] { STRING_MDUPLICATE1, false, 0, "\uFF21a\uFF21",
+                        0, 3, false },
+                new Object[] { STRING_SUPPLEMENTARY, true, 1, "\uDC00\uD801",
+                        0, 2, true },
+                new Object[] { STRING_SUPPLEMENTARY, true, 4, "\uFF21", 0, 1,
+                        true },
+                new Object[] { STRING_SUPPLEMENTARY, true, 5, "A", 0, 1, true },
+                new Object[] { STRING_SUPPLEMENTARY_LOWERCASE, false, 0,
+                        "\uD801\uDC28\uD801\uDC29", 0, 4, true },
+                new Object[] { STRING_SUPPLEMENTARY_LOWERCASE, true, 1,
+                        "\uDC28\uD801", 0, 2, true },
+                new Object[] { STRING_SUPPLEMENTARY_LOWERCASE, true, 1,
+                        "\uDC00\uD801", 0, 2, false },
+                new Object[] { STRING_SUPPLEMENTARY_LOWERCASE, true, 4,
+                        "\uFF21", 0, 1, true },
+                new Object[] { STRING_SUPPLEMENTARY_LOWERCASE, false, 4,
+                        "\uFF21", 0, 1, false },
+                new Object[] { STRING_SUPPLEMENTARY_LOWERCASE, false, 4,
+                        "\uFF41", 0, 1, true }, };
+    }
+
+    @Test(dataProvider = "provider")
+    public void testRegionMatches(String str, boolean ignoreCase, int toffset,
+            String other, int ooffset, int len, boolean expected) {
+        map.get(str)
+                .forEach(
+                        (source, data) -> {
+                            assertEquals(
+                                    data.regionMatches(ignoreCase, toffset,
+                                            other, ooffset, len),
+                                    expected,
+                                    String.format(
+                                            "testing String(%s).regionMatches(%b, %d, %s, %d, %d), source : %s, ",
+                                            escapeNonASCIIs(data), ignoreCase,
+                                            toffset, escapeNonASCIIs(other),
+                                            ooffset, len, source));
+                        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/Replace.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,117 @@
+/*
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.replace.
+ * @run testng/othervm -XX:+CompactStrings Replace
+ * @run testng/othervm -XX:-CompactStrings Replace
+ */
+
+public class Replace extends CompactString {
+
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+
+                new Object[] { STRING_L1, 'A', 'B', "B" },
+                new Object[] { STRING_L1, 'A', 'A', "A" },
+                new Object[] { STRING_L1, 'A', '\uFF21', "\uFF21" },
+                new Object[] { STRING_L2, 'A', 'B', "BB" },
+                new Object[] { STRING_L2, 'B', 'A', "AA" },
+                new Object[] { STRING_L2, 'C', 'A', "AB" },
+                new Object[] { STRING_L2, 'B', '\uFF21', "A\uFF21" },
+                new Object[] { STRING_U1, '\uFF21', 'A', "A" },
+                new Object[] { STRING_U1, '\uFF22', 'A', "\uFF21" },
+                new Object[] { STRING_U2, '\uFF22', 'A', "\uFF21A" },
+                new Object[] { STRING_M12, 'A', '\uFF21', "\uFF21\uFF21" },
+                new Object[] { STRING_M11, '\uFF21', 'A', "AA" },
+                new Object[] { STRING_UDUPLICATE, '\uFF21', 'A',
+                        "A\uFF22A\uFF22A\uFF22A\uFF22A\uFF22" },
+                new Object[] { STRING_MDUPLICATE1, '\uFF21', 'A', "AAAAAAAAAA" },
+                new Object[] { STRING_MDUPLICATE1, 'A', '\uFF21',
+                        "\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21" }, };
+    }
+
+    @Test(dataProvider = "provider")
+    public void testReplace(String str, char oldChar, char newChar,
+            String expected) {
+        map.get(str)
+                .forEach(
+                        (source, data) -> {
+                            assertEquals(
+                                    data.replace(oldChar, newChar),
+                                    expected,
+                                    String.format(
+                                            "testing String(%s).replace(%s, %s), source : %s, ",
+                                            escapeNonASCIIs(data),
+                                            escapeNonASCII(oldChar),
+                                            escapeNonASCII(newChar), source));
+                        });
+    }
+
+    @DataProvider
+    public Object[][] provider2() {
+        return new Object[][] {
+
+                new Object[] { STRING_EMPTY, "", "ABC", "ABC" },
+                new Object[] { STRING_EMPTY, "", "", "" },
+                new Object[] { STRING_L1, "A", "B", "B" },
+                new Object[] { STRING_L1, "A", "A", "A" },
+                new Object[] { STRING_L2, "B", "\uFF21", "A\uFF21" },
+                new Object[] { STRING_LLONG, "BCD", "\uFF21", "A\uFF21EFGH" },
+                new Object[] { STRING_U1, "\uFF21", "A", "A" },
+                new Object[] { STRING_U1, "\uFF21", "A\uFF21", "A\uFF21" },
+                new Object[] { STRING_U2, "\uFF21", "A", "A\uFF22" },
+                new Object[] { STRING_U2, "\uFF22", "A", "\uFF21A" },
+                new Object[] { STRING_UDUPLICATE, "\uFF21\uFF22", "AB",
+                        "ABABABABAB" },
+                new Object[] { STRING_MDUPLICATE1, "\uFF21", "A", "AAAAAAAAAA" },
+                new Object[] { STRING_MDUPLICATE1, "A", "\uFF21",
+                        "\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21" }, };
+    }
+
+    @Test(dataProvider = "provider2")
+    public void testReplace(String str, CharSequence target,
+            CharSequence replacement, String expected) {
+        map.get(str)
+                .forEach(
+                        (source, data) -> {
+                            assertEquals(
+                                    data.replace(target, replacement),
+                                    expected,
+                                    String.format(
+                                            "testing String(%s).replace(%s, %s), source : %s, ",
+                                            escapeNonASCIIs(data),
+                                            escapeNonASCIIs(target.toString()),
+                                            escapeNonASCIIs(replacement
+                                                    .toString()), source));
+                        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/SerializationTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static jdk.testlibrary.SerializationUtils.*;
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.SerializationUtils
+ * @summary Tests Compact String. This one is testing String serialization
+ *          among -XX:+CompactStrings/-XX:-CompactStrings/LegacyString
+ * @run testng/othervm -XX:+CompactStrings SerializationTest
+ * @run testng/othervm -XX:-CompactStrings SerializationTest
+ */
+
+public class SerializationTest {
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+                // every byte array is serialized from corresponding String object
+                // by previous JDK(build 1.8.0_45-b14).
+                new Object[] { "", new byte[] { -84, -19, 0, 5, 116, 0, 0 } },
+                new Object[] { "A", new byte[] { -84, -19, 0, 5, 116, 0, 1, 65 } },
+                new Object[] { "AB", new byte[] { -84, -19, 0, 5, 116, 0, 2, 65, 66 } },
+                new Object[] { "abcdefghijk",
+                        new byte[] {-84, -19, 0, 5, 116, 0, 11, 97, 98, 99, 100, 101,
+                        102, 103, 104, 105, 106, 107 } },
+                new Object[] { "\uff21", new byte[] { -84, -19, 0, 5, 116, 0, 3, -17, -68, -95 } },
+                new Object[] { "\uff21\uff22", new byte[] { -84, -19, 0, 5, 116, 0, 6, -17, -68,
+                        -95, -17, -68, -94 } },
+                new Object[] { "\uff21A\uff21A\uff21A\uff21A\uff21A",
+                        new byte[] { -84, -19, 0, 5, 116, 0, 20, -17, -68, -95, 65, -17, -68,
+                        -95, 65, -17, -68, -95, 65, -17, -68, -95, 65, -17, -68, -95, 65 } },
+                new Object[] { "A\uff21B\uff22C\uff23D\uff24E\uff25F\uff26G\uff27H\uff28",
+                        new byte[] { -84, -19, 0, 5, 116, 0, 32, 65, -17, -68, -95, 66, -17, -68,
+                        -94, 67, -17, -68, -93, 68, -17, -68, -92, 69, -17, -68, -91, 70, -17,
+                        -68, -90, 71, -17, -68, -89, 72, -17, -68, -88 } },
+                new Object[] { "\uff21A\uff22B\uff23C\uff24D\uff25E\uff26F\uff27G\uff28H",
+                        new byte[] { -84, -19, 0, 5, 116, 0, 32, -17, -68, -95, 65, -17, -68,
+                        -94, 66, -17, -68, -93, 67, -17, -68, -92, 68, -17, -68, -91, 69, -17,
+                        -68, -90, 70, -17, -68, -89, 71, -17, -68, -88, 72 } },
+                new Object[] { "\ud801\udc00\ud801\udc01\uff21A",
+                        new byte[] { -84, -19, 0, 5, 116, 0, 16, -19, -96, -127, -19, -80, -128,
+                        -19, -96, -127, -19, -80, -127, -17, -68, -95, 65 } },
+                new Object[] { "\uff21\uff22\uff21\uff22\uff21\uff22\uff21\uff22\uff21\uff22",
+                        new byte[] { -84, -19, 0, 5, 116, 0, 30, -17, -68, -95, -17, -68, -94, -17,
+                        -68, -95, -17, -68, -94, -17, -68, -95, -17, -68, -94, -17, -68, -95, -17,
+                        -68, -94, -17, -68, -95, -17, -68, -94 } } };
+    }
+
+    /*
+     * Verify serialization works between Compact String/Legacy String
+     */
+    @Test(dataProvider = "provider")
+    public void test(String strContent, byte[] baInJDK8) throws Exception {
+        // Serialize a String object into byte array.
+        byte[] ba = serialize(strContent);
+        assertEquals(ba, baInJDK8);
+        // Deserialize a String object from byte array which is generated by previous JDK(build 1.8.0_45-b14).
+        Object obj = deserialize(ba);
+        assertEquals(obj.getClass(), String.class);
+        assertEquals((String)obj, strContent);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/Split.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,181 @@
+/*
+ * 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.
+ */
+
+import java.util.Arrays;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertTrue;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.split.
+ * @run testng/othervm -XX:+CompactStrings Split
+ * @run testng/othervm -XX:-CompactStrings Split
+ */
+
+public class Split extends CompactString {
+
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+                new Object[] { STRING_L1, "", 0, new String[] { "A" } },
+                new Object[] { STRING_L1, "", 1, new String[] { "A" } },
+                new Object[] { STRING_L1, "", 2, new String[] { "A", "" } },
+                new Object[] { STRING_L1, "A", 0, new String[] {} },
+                new Object[] { STRING_L2, "A", 0, new String[] { "", "B" } },
+                new Object[] { STRING_L2, "B", 0, new String[] { "A" } },
+                new Object[] { STRING_LLONG, "D", 0,
+                        new String[] { "ABC", "EFGH" } },
+                new Object[] { STRING_LLONG, "[D]", 0,
+                        new String[] { "ABC", "EFGH" } },
+                new Object[] { STRING_LLONG, "CD", 0,
+                        new String[] { "AB", "EFGH" } },
+                new Object[] { STRING_LLONG, "DC", 0,
+                        new String[] { "ABCDEFGH" } },
+                new Object[] { STRING_LLONG, "[CF]", 0,
+                        new String[] { "AB", "DE", "GH" } },
+                new Object[] { STRING_LLONG, "[CF]", 1,
+                        new String[] { "ABCDEFGH" } },
+                new Object[] { STRING_LLONG, "[CF]", 2,
+                        new String[] { "AB", "DEFGH" } },
+                new Object[] { STRING_LLONG, "[FC]", 0,
+                        new String[] { "AB", "DE", "GH" } },
+                new Object[] { STRING_LLONG, "[FC]", 1,
+                        new String[] { "ABCDEFGH" } },
+                new Object[] { STRING_LLONG, "[FC]", 2,
+                        new String[] { "AB", "DEFGH" } },
+                new Object[] { STRING_U1, "", 0, new String[] { "\uFF21" } },
+                new Object[] { STRING_U1, "", 1, new String[] { "\uFF21" } },
+                new Object[] { STRING_U1, "", 2, new String[] { "\uFF21", "" } },
+                new Object[] { STRING_U1, "\uFF21", 0, new String[] {} },
+                new Object[] { STRING_M12, "\uFF21", 0,
+                        new String[] { "", "A" } },
+                new Object[] { STRING_M12, "A", 0, new String[] { "\uFF21" } },
+                new Object[] {
+                        STRING_UDUPLICATE,
+                        "\uFF21",
+                        0,
+                        new String[] { "", "\uFF22", "\uFF22", "\uFF22",
+                                "\uFF22", "\uFF22" } },
+                new Object[] {
+                        STRING_UDUPLICATE,
+                        "\uFF21",
+                        2,
+                        new String[] { "",
+                                "\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22" } },
+                new Object[] {
+                        STRING_UDUPLICATE,
+                        "\uFF21",
+                        4,
+                        new String[] { "", "\uFF22", "\uFF22",
+                                "\uFF22\uFF21\uFF22\uFF21\uFF22" } },
+                new Object[] {
+                        STRING_UDUPLICATE,
+                        "\uFF22",
+                        0,
+                        new String[] { "\uFF21", "\uFF21", "\uFF21", "\uFF21",
+                                "\uFF21" } },
+                new Object[] {
+                        STRING_UDUPLICATE,
+                        "\uFF22",
+                        3,
+                        new String[] { "\uFF21", "\uFF21",
+                                "\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22" } },
+
+                new Object[] { STRING_MDUPLICATE1, "\uFF21", 0,
+                        new String[] { "", "A", "A", "A", "A", "A" } },
+                new Object[] { STRING_MDUPLICATE1, "\uFF21", 3,
+                        new String[] { "", "A", "A\uFF21A\uFF21A\uFF21A" } },
+                new Object[] {
+                        STRING_MDUPLICATE1,
+                        "A",
+                        0,
+                        new String[] { "\uFF21", "\uFF21", "\uFF21", "\uFF21",
+                                "\uFF21" } },
+                new Object[] {
+                        STRING_MDUPLICATE1,
+                        "A",
+                        4,
+                        new String[] { "\uFF21", "\uFF21", "\uFF21",
+                                "\uFF21A\uFF21A" } },
+                new Object[] { STRING_SUPPLEMENTARY, "\uD801\uDC01", 0,
+                        new String[] { "\uD801\uDC00", "\uFF21A" } },
+                new Object[] { STRING_SUPPLEMENTARY, "\uDC01", 0,
+                        new String[] { "\uD801\uDC00\uD801\uDC01\uFF21A" } },
+                new Object[] { STRING_SUPPLEMENTARY, "\uD801\uDC01", 0,
+                        new String[] { "\uD801\uDC00", "\uFF21A" } },
+                new Object[] { STRING_SUPPLEMENTARY, "[\uD801\uDC01\uFF21]", 0,
+                        new String[] { "\uD801\uDC00", "", "A" } },
+                new Object[] { STRING_SUPPLEMENTARY, "[\uD801\uDC01\uFF21]", 1,
+                        new String[] { "\uD801\uDC00\uD801\uDC01\uFF21A" } },
+                new Object[] { STRING_SUPPLEMENTARY, "[\uD801\uDC01\uFF21]", 2,
+                        new String[] { "\uD801\uDC00", "\uFF21A" } },
+                new Object[] { STRING_SUPPLEMENTARY, "[\uFF21\uD801\uDC01]", 0,
+                        new String[] { "\uD801\uDC00", "", "A" } },
+                new Object[] { STRING_SUPPLEMENTARY, "[\uFF21\uD801\uDC01]", 1,
+                        new String[] { "\uD801\uDC00\uD801\uDC01\uFF21A" } },
+                new Object[] { STRING_SUPPLEMENTARY, "[\uFF21\uD801\uDC01]", 2,
+                        new String[] { "\uD801\uDC00", "\uFF21A" } },
+                new Object[] { STRING_SUPPLEMENTARY_LOWERCASE, "\uDC01", 0,
+                        new String[] { "\uD801\uDC28\uD801\uDC29\uFF41a" } },
+                new Object[] { STRING_SUPPLEMENTARY_LOWERCASE, "\uD801\uDC29",
+                        0, new String[] { "\uD801\uDC28", "\uFF41a" } },
+                new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
+                        "[\uD801\uDC29\uFF41]", 0,
+                        new String[] { "\uD801\uDC28", "", "a" } },
+                new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
+                        "[\uD801\uDC29\uFF41]", 1,
+                        new String[] { "\uD801\uDC28\uD801\uDC29\uFF41a" } },
+                new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
+                        "[\uD801\uDC29\uFF41]", 2,
+                        new String[] { "\uD801\uDC28", "\uFF41a" } },
+                new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
+                        "[\uFF41\uD801\uDC29]", 0,
+                        new String[] { "\uD801\uDC28", "", "a" } },
+                new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
+                        "[\uFF41\uD801\uDC29]", 1,
+                        new String[] { "\uD801\uDC28\uD801\uDC29\uFF41a" } },
+                new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
+                        "[\uFF41\uD801\uDC29]", 2,
+                        new String[] { "\uD801\uDC28", "\uFF41a" } }, };
+    }
+
+    @Test(dataProvider = "provider")
+    public void testSplit(String str, String regex, int limit, String[] expected) {
+        map.get(str)
+                .forEach(
+                        (source, data) -> {
+                            assertTrue(
+                                    Arrays.equals(data.split(regex, limit),
+                                            expected),
+                                    String.format(
+                                            "testing String(%s).split(%s, %d), source : %s, ",
+                                            escapeNonASCIIs(data),
+                                            escapeNonASCIIs(regex), limit,
+                                            source));
+                        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/StartsWith.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.startsWith.
+ * @run testng/othervm -XX:+CompactStrings StartsWith
+ * @run testng/othervm -XX:-CompactStrings StartsWith
+ */
+
+public class StartsWith extends CompactString {
+
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+                new Object[] {STRING_EMPTY, "", 0, true},
+                new Object[] {STRING_EMPTY, "A", 0, false},
+                new Object[] {STRING_EMPTY, "", 0, true},
+                new Object[] {STRING_EMPTY, "", -1, false},
+                new Object[] {STRING_L1, "A", 0, true},
+                new Object[] {STRING_L1, "A", -1, false},
+                new Object[] {STRING_L1, "A", 1, false},
+                new Object[] {STRING_L2, "B", 1, true},
+                new Object[] {STRING_L2, "B", 0, false},
+                new Object[] {STRING_L2, "A", 0, true},
+                new Object[] {STRING_L2, "AB", 1, false},
+                new Object[] {STRING_L4, "ABC", 0, true},
+                new Object[] {STRING_LLONG, "ABCDEFGH", 0, true},
+                new Object[] {STRING_LLONG, "ABCDE", 0, true},
+                new Object[] {STRING_LLONG, "CDE", 0, false},
+                new Object[] {STRING_LLONG, "FG", 5, true},
+                new Object[] {STRING_U1, "\uFF21", 0, true},
+                new Object[] {STRING_U1, "", 1, true},
+                new Object[] {STRING_U1, "\uFF21", 0, true},
+                new Object[] {STRING_U1, "A", 0, false},
+                new Object[] {STRING_U2, "\uFF21\uFF22", 0, true},
+                new Object[] {STRING_U2, "\uFF21", 0, true},
+                new Object[] {STRING_U2, "\uFF22", 0, false},
+                new Object[] {STRING_U2, "", 0, true},
+                new Object[] {STRING_M12, "\uFF21", 0, true},
+                new Object[] {STRING_M12, "\uFF21A", 0, true},
+                new Object[] {STRING_M12, "A", 0, false},
+                new Object[] {STRING_M12, "\uFF21A", 0, true},
+                new Object[] {STRING_M12, "A", 1, true},
+                new Object[] {STRING_M11, "A", 0, true},
+                new Object[] {STRING_M11, "A\uFF21", 0, true},
+                new Object[] {STRING_M11, "A\uFF21", 0, true},
+                new Object[] {STRING_M11, "\uFF21", 1, true},
+                new Object[] {STRING_UDUPLICATE,
+                        "\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
+                        0, true},
+                new Object[] {STRING_UDUPLICATE,
+                        "\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22", 0, true},
+                new Object[] {STRING_UDUPLICATE,
+                        "\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22", 2, true},
+                new Object[] {STRING_UDUPLICATE,
+                        "\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22", 5, false},
+                new Object[] {STRING_MDUPLICATE1,
+                        "\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A", 0, true},
+                new Object[] {STRING_MDUPLICATE1,
+                        "\uFF21A\uFF21A\uFF21A\uFF21A\uFF21", 0, true},
+                new Object[] {STRING_MDUPLICATE1, "A\uFF21A\uFF21A\uFF21A", 1, true},
+                new Object[] {STRING_SUPPLEMENTARY, "\uDC01\uFF21", 3, true},
+        };
+    }
+
+    @Test(dataProvider = "provider")
+    public void testStartsWith(String str, String prefix, int toffset,
+            boolean expected) {
+        map.get(str)
+                .forEach(
+                        (source, data) -> {
+                            assertEquals(
+                                    data.startsWith(prefix, toffset),
+                                    expected,
+                                    String.format(
+                                            "testing String(%s).startsWith(%s, %d), source : %s, ",
+                                            escapeNonASCIIs(data),
+                                            escapeNonASCIIs(prefix), toffset,
+                                            source));
+                        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/SubString.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.subString.
+ * @run testng/othervm -XX:+CompactStrings SubString
+ * @run testng/othervm -XX:-CompactStrings SubString
+ */
+
+public class SubString extends CompactString {
+
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+
+                new Object[] { STRING_EMPTY, 0, 0, "" },
+                new Object[] { STRING_L1, 0, 1, "A" },
+                new Object[] { STRING_L1, 1, 1, "" },
+                new Object[] { STRING_L2, 0, 2, "AB" },
+                new Object[] { STRING_L2, 1, 2, "B" },
+                new Object[] { STRING_LLONG, 0, 8, "ABCDEFGH" },
+                new Object[] { STRING_LLONG, 7, 8, "H" },
+                new Object[] { STRING_LLONG, 8, 8, "" },
+                new Object[] { STRING_LLONG, 3, 7, "DEFG" },
+                new Object[] { STRING_U1, 0, 1, "\uFF21" },
+                new Object[] { STRING_U1, 1, 1, "" },
+                new Object[] { STRING_U1, 0, 0, "" },
+                new Object[] { STRING_U2, 0, 2, "\uFF21\uFF22" },
+                new Object[] { STRING_U2, 1, 2, "\uFF22" },
+                new Object[] { STRING_U2, 2, 2, "" },
+                new Object[] { STRING_U2, 0, 2, "\uFF21\uFF22" },
+                new Object[] { STRING_U2, 1, 2, "\uFF22" },
+                new Object[] { STRING_M12, 1, 2, "A" },
+                new Object[] { STRING_M11, 0, 1, "A" },
+                new Object[] { STRING_M11, 1, 2, "\uFF21" },
+                new Object[] { STRING_UDUPLICATE, 1, 5,
+                        "\uFF22\uFF21\uFF22\uFF21" },
+                new Object[] { STRING_MDUPLICATE1, 9, 10, "A" },
+                new Object[] { STRING_MDUPLICATE1, 7, 8, "A" }, };
+    }
+
+    @Test(dataProvider = "provider")
+    public void testSubstring(String str, int beginIndex, int endIndex,
+            String expected) {
+        map.get(str)
+                .forEach(
+                        (source, data) -> {
+                            assertEquals(
+                                    data.substring(beginIndex, endIndex),
+                                    expected,
+                                    String.format(
+                                            "testing String(%s).substring(%d, %d), source : %s, ",
+                                            escapeNonASCIIs(data), beginIndex,
+                                            endIndex, source));
+                        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/ToCharArray.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+import java.util.Arrays;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertTrue;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.toCharArray.
+ * @run testng/othervm -XX:+CompactStrings ToCharArray
+ * @run testng/othervm -XX:-CompactStrings ToCharArray
+ */
+
+public class ToCharArray extends CompactString {
+
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+                new Object[] { STRING_EMPTY, new char[] {} },
+                new Object[] { STRING_L1, new char[] { 'A' } },
+                new Object[] { STRING_L2, new char[] { 'A', 'B' } },
+                new Object[] { STRING_LLONG,
+                        new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' } },
+                new Object[] { STRING_U1, new char[] { '\uFF21' } },
+                new Object[] { STRING_U2, new char[] { '\uFF21', '\uFF22' } },
+                new Object[] { STRING_M12, new char[] { '\uFF21', 'A' } },
+                new Object[] { STRING_M11, new char[] { 'A', '\uFF21' } }, };
+    }
+
+    @Test(dataProvider = "provider")
+    public void testToCharArray(String str, char[] expected) {
+        map.get(str)
+                .forEach(
+                        (source, data) -> {
+                            assertTrue(
+                                    Arrays.equals(data.toCharArray(), expected),
+                                    String.format(
+                                            "testing String(%s).toCharArray(), source : %s, ",
+                                            escapeNonASCIIs(data), source));
+                        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/ToLowerCase.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.toLowerCase.
+ * @run testng/othervm -XX:+CompactStrings ToLowerCase
+ * @run testng/othervm -XX:-CompactStrings ToLowerCase
+ */
+
+public class ToLowerCase extends CompactString {
+
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+                new Object[] { STRING_EMPTY, "" },
+                new Object[] { STRING_L1, "a" },
+                new Object[] { STRING_L2, "ab" },
+                new Object[] { STRING_U1, "\uFF41" },
+                new Object[] { STRING_MDUPLICATE1,
+                        "\uFF41a\uFF41a\uFF41a\uFF41a\uFF41a" },
+                new Object[] { STRING_SUPPLEMENTARY,
+                        "\uD801\uDC28\uD801\uDC29\uFF41a" },
+                new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
+                        "\uD801\uDC28\uD801\uDC29\uFF41a" },
+                new Object[] { STRING_SUPPLEMENTARY,
+                        STRING_SUPPLEMENTARY_LOWERCASE } };
+    }
+
+    @Test(dataProvider = "provider")
+    public void testToLowerCase(String str, String expected) {
+        map.get(str).forEach(
+                (source, data) -> {
+                    assertEquals(data.toLowerCase(), expected, String.format(
+                            "testing String(%s).toLowerCase(), source : %s, ",
+                            escapeNonASCIIs(data), source));
+                });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/ToUpperCase.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.toUpperCase.
+ * @run testng/othervm -XX:+CompactStrings ToUpperCase
+ * @run testng/othervm -XX:-CompactStrings ToUpperCase
+ */
+
+public class ToUpperCase extends CompactString {
+
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+
+                new Object[] { STRING_EMPTY, "" },
+                new Object[] { STRING_L1, "A" },
+                new Object[] { STRING_L2, "AB" },
+                new Object[] { STRING_U1, "\uFF21" },
+                new Object[] { STRING_MDUPLICATE1,
+                        "\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A" },
+                new Object[] { STRING_SUPPLEMENTARY,
+                        "\uD801\uDC00\uD801\uDC01\uFF21A" },
+
+                new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
+                        "\uD801\uDC00\uD801\uDC01\uFF21A" },
+                new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
+                        STRING_SUPPLEMENTARY }, };
+    }
+
+    @Test(dataProvider = "provider")
+    public void testToUpperCase(String str, String expected) {
+        map.get(str).forEach(
+                (source, data) -> {
+                    assertEquals(data.toUpperCase(), expected, String.format(
+                            "testing String(%s).toUpperCase(), source : %s, ",
+                            escapeNonASCIIs(data), source));
+                });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/Trim.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.trim.
+ * @run testng/othervm -XX:+CompactStrings Trim
+ * @run testng/othervm -XX:-CompactStrings Trim
+ */
+
+public class Trim {
+
+    /*
+     * Data provider for testTrim
+     *
+     * @return input parameter for testTrim
+     */
+    @DataProvider
+    public Object[][] trims() {
+        return new Object[][] {
+                { " \t \t".trim(), "" },
+                { "\t \t ".trim(), "" },
+                { "\t A B C\t ".trim(), "A B C" },
+                { " \t A B C \t".trim(), "A B C" },
+                { "\t \uFF21 \uFF22 \uFF23\t ".trim(), "\uFF21 \uFF22 \uFF23" },
+                { " \t \uFF21 \uFF22 \uFF23 \t".trim(), "\uFF21 \uFF22 \uFF23" },
+                { " \t \uFF41 \uFF42 \uFF43 \t".trim(), "\uFF41 \uFF42 \uFF43" },
+                { " \t A\uFF21 B\uFF22 C\uFF23 \t".trim(),
+                        "A\uFF21 B\uFF22 C\uFF23" } };
+    }
+
+    /*
+     * test trim().
+     *
+     * @param res
+     *            real result
+     * @param expected
+     *            expected result
+     */
+    @Test(dataProvider = "trims")
+    public void testTrim(String res, String expected) {
+        assertEquals(res, expected);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/VMOptionsTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+import java.io.*;
+import java.lang.reflect.Field;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.*;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is testing
+ *          if Compact String enable/disable VM Options is indeed working in String class,
+ *          it's verified by testing if the VM option affect coder and
+ *          COMPACT_STRINGS field in String class.
+ * @run testng/othervm -XX:+CompactStrings -DCompactStringEnabled=true VMOptionsTest
+ * @run testng/othervm -XX:-CompactStrings -DCompactStringEnabled=false VMOptionsTest
+ */
+
+public class VMOptionsTest {
+    boolean compactStringEnabled;
+    // corresponding "COMPACT_STRINGS" field in String class.
+    Field COMPACT_STRINGS;
+    // corresponding "coder" field in String class.
+    Field coder;
+
+    // corresponding coder type in String class.
+    final byte LATIN1 = 0;
+    final byte UTF16  = 1;
+
+    @BeforeClass
+    public void setUp() throws Exception {
+        compactStringEnabled = Boolean.valueOf(System.getProperty("CompactStringEnabled", null));
+        COMPACT_STRINGS = String.class.getDeclaredField("COMPACT_STRINGS");
+        COMPACT_STRINGS.setAccessible(true);
+        coder = String.class.getDeclaredField("coder");
+        coder.setAccessible(true);
+    }
+
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+                new Object[] {"", LATIN1},
+                new Object[] {"abc", LATIN1},
+                new Object[] {"A\uff21", UTF16},
+                new Object[] {"\uff21\uff22", UTF16}
+        };
+    }
+
+    /*
+     * verify the coder field in String objects.
+     */
+    @Test(dataProvider = "provider")
+    public void testCoder(String str, byte expected) throws Exception {
+        byte c = (byte) coder.get(str);
+        expected = compactStringEnabled ? expected : UTF16;
+        assertEquals(c, expected);
+    }
+
+    /*
+     * verify the COMPACT_STRINGS flag in String objects.
+     */
+    @Test(dataProvider = "provider")
+    public void testCompactStringFlag(String str, byte ignore) throws Exception {
+        assertTrue(COMPACT_STRINGS.get(str).equals(compactStringEnabled));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/ValueOf.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.valueOf.
+ *          valueOf(char[] data) is not tested here.
+ * @run testng/othervm -XX:+CompactStrings ValueOf
+ * @run testng/othervm -XX:-CompactStrings ValueOf
+ */
+
+public class ValueOf {
+
+    /*
+     * Data provider for testValueOf
+     *
+     * @return input parameter for testValueOf
+     */
+    @DataProvider
+    public Object[][] valueOfs() {
+        return new Object[][] { { String.valueOf(true), "true" },
+                { String.valueOf(false), "false" },
+                { String.valueOf(1.0f), "1.0" },
+                { String.valueOf(0.0f), "0.0" },
+                { String.valueOf(Float.MAX_VALUE), "3.4028235E38" },
+                { String.valueOf(Float.MIN_VALUE), "1.4E-45" },
+                { String.valueOf(1.0d), "1.0" },
+                { String.valueOf(0.0d), "0.0" },
+                { String.valueOf(Double.MAX_VALUE), "1.7976931348623157E308" },
+                { String.valueOf(Double.MIN_VALUE), "4.9E-324" },
+                { String.valueOf(1), "1" }, { String.valueOf(0), "0" },
+                { String.valueOf(Integer.MAX_VALUE), "2147483647" },
+                { String.valueOf(Integer.MIN_VALUE), "-2147483648" },
+                { String.valueOf(1L), "1" }, { String.valueOf(0L), "0" },
+                { String.valueOf(Long.MAX_VALUE), "9223372036854775807" },
+                { String.valueOf(Long.MIN_VALUE), "-9223372036854775808" } };
+    }
+
+    /*
+     * test String.valueOf(xxx).
+     *
+     * @param res
+     *            real result
+     * @param expected
+     *            expected result
+     */
+    @Test(dataProvider = "valueOfs")
+    public void testValueOf(String res, String expected) {
+        assertEquals(res, expected);
+    }
+
+}
--- a/jdk/test/java/lang/String/LiteralReplace.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/java/lang/String/LiteralReplace.java	Tue Nov 17 10:29:28 2015 -0800
@@ -22,7 +22,7 @@
  */
 
 /* @test
- * @bug 8058779
+ * @bug 8058779 8054307
  * @library /lib/testlibrary/
  * @build jdk.testlibrary.RandomFactory
  * @run testng LiteralReplace
@@ -104,6 +104,109 @@
             {"abcdefgh", "[a-h]", "X", "abcdefgh"},
             {"aa+", "a+", "", "a"},
             {"^abc$", "abc", "x", "^x$"},
+
+            // more with non-latin1 characters
+            {"\u4e00\u4e00\u4e00",
+             "\u4e00\u4e00",
+             "\u4e01",
+             "\u4e01\u4e00"},
+
+            {"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07\u4e08",
+             "\u4e03\u4e04\u4e05",
+             "\u4e10\u4e11\u4e12",
+             "\u4e00\u4e01\u4e02\u4e10\u4e11\u4e12\u4e06\u4e07\u4e08"},
+
+            {"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07\u4e08",
+             "ABC",
+             "\u4e10\u4e11\u4e12",
+             "\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07\u4e08"},
+
+            {"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e02\u4e03\u4e07\u4e08",
+             "\u4e02\u4e03",
+             "\u4e12\u4e13",
+             "\u4e00\u4e01\u4e12\u4e13\u4e04\u4e12\u4e13\u4e07\u4e08"},
+
+            {"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e02\u4e03\u4e07\u4e08",
+             "\u4e02\u4e03",
+             "ab",
+             "\u4e00\u4e01ab\u4e04ab\u4e07\u4e08"},
+
+            {"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07",
+             "",
+             "_",
+             "_\u4e00_\u4e01_\u4e02_\u4e03_\u4e04_\u4e05_\u4e06_\u4e07_"},
+            {"^\u4e00\u4e01\u4e02$",
+             "\u4e00\u4e01\u4e02",
+             "\u4e03",
+             "^\u4e03$"},
+
+            {"", "\u4e00", "\u4e01", ""},
+            {"", "", "\u4e00\u4e01\u4e02", "\u4e00\u4e01\u4e02"},
+
+            {"^\u4e00\u4e01\u4e02$",
+             "\u4e00\u4e01\u4e02",
+             "X",
+             "^X$"},
+
+            {"abcdefgh",
+             "def",
+             "\u4e01",
+             "abc\u4e01gh"},
+
+            {"abcdefgh",
+             "def",
+             "\u4e01\u4e02",
+             "abc\u4e01\u4e02gh"},
+
+            {"abcdefabcgh",
+             "abc",
+             "\u4e01\u4e02",
+             "\u4e01\u4e02def\u4e01\u4e02gh"},
+
+            {"abcdefabcghabc",
+             "abc",
+             "\u4e01\u4e02",
+             "\u4e01\u4e02def\u4e01\u4e02gh\u4e01\u4e02"},
+
+            {"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05",
+             "\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05",
+             "abcd",
+             "abcd"},
+
+            {"\u4e00\u4e01",
+             "\u4e00\u4e01",
+             "abcdefg",
+             "abcdefg"},
+
+            {"\u4e00\u4e01xyz",
+             "\u4e00\u4e01",
+             "abcdefg",
+             "abcdefgxyz"},
+
+            {"\u4e00\u4e00\u4e00\u4e00\u4e00\u4e00",
+             "\u4e00\u4e00",
+             "\u4e00\u4e00\u4e00",
+             "\u4e00\u4e00\u4e00\u4e00\u4e00\u4e00\u4e00\u4e00\u4e00"},
+
+            {"\u4e00\u4e00\u4e00\u4e00\u4e00\u4e00",
+             "\u4e00\u4e00\u4e00",
+             "\u4e00\u4e00",
+             "\u4e00\u4e00\u4e00\u4e00"},
+
+            {"\u4e00.\u4e01.\u4e02.\u4e03.\u4e04.",
+             ".",
+             "-",
+             "\u4e00-\u4e01-\u4e02-\u4e03-\u4e04-"},
+
+            {"\u4e00\u4e00\u4e00\u4e00\u4e00\u4e00",
+             "\u4e00",
+             "",
+             ""},
+
+            {"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05",
+             "\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05",
+             "",
+             ""},
         };
     }
 
--- a/jdk/test/java/lang/String/ToLowerCase.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/java/lang/String/ToLowerCase.java	Tue Nov 17 10:29:28 2015 -0800
@@ -23,7 +23,7 @@
 
 /*
     @test
-    @bug 4217441 4533872 4900935 8020037 8032012 8041791 8042589
+    @bug 4217441 4533872 4900935 8020037 8032012 8041791 8042589 8054307
     @summary toLowerCase should lower-case Greek Sigma correctly depending
              on the context (final/non-final).  Also it should handle
              Locale specific (lt, tr, and az) lowercasings and supplementary
@@ -134,14 +134,60 @@
         }
         test(src.toString(), Locale.US, exp.toString());
 
+        // test latin1
+        src = new StringBuilder(0x100);
+        exp = new StringBuilder(0x100);
+        for (int cp = 0; cp < 0x100; cp++) {
+            int lowerCase = Character.toLowerCase(cp);
+            if (lowerCase == -1) {    //Character.ERROR
+                continue;
+            }
+            src.appendCodePoint(cp);
+            exp.appendCodePoint(lowerCase);
+        }
+        test(src.toString(), Locale.US, exp.toString());
+
+        // test non-latin1 -> latin1
+        src = new StringBuilder(0x100).append("abc");
+        exp = new StringBuilder(0x100).append("abc");
+        for (int cp = 0x100; cp < 0x10000; cp++) {
+            int lowerCase  = Character.toLowerCase(cp);
+            if (lowerCase < 0x100 && cp != '\u0130') {
+                src.appendCodePoint(cp);
+                exp.appendCodePoint(lowerCase);
+            }
+        }
+        test(src.toString(), Locale.US, exp.toString());
     }
 
     static void test(String in, Locale locale, String expected) {
+        test0(in, locale,expected);
+        for (String[] ss :  new String[][] {
+                                new String[] {"abc",      "abc"},
+                                new String[] {"aBc",      "abc"},
+                                new String[] {"ABC",      "abc"},
+                                new String[] {"ab\u4e00", "ab\u4e00"},
+                                new String[] {"aB\u4e00", "ab\u4e00"},
+                                new String[] {"AB\u4e00", "ab\u4e00"},
+                                new String[] {"ab\uD800\uDC00", "ab\uD800\uDC00"},
+                                new String[] {"aB\uD800\uDC00", "ab\uD800\uDC00"},
+                                new String[] {"AB\uD800\uDC00", "ab\uD800\uDC00"},
+                                new String[] {"ab\uD801\uDC1C", "ab\uD801\uDC44"},
+                                new String[] {"aB\uD801\uDC1C", "ab\uD801\uDC44"},
+                                new String[] {"AB\uD801\uDC1C", "ab\uD801\uDC44"},
+
+                            }) {
+            test0(ss[0] + " " + in, locale, ss[1] + " " + expected);
+            test0(in + " " + ss[0], locale, expected + " " + ss[1]);
+        }
+    }
+
+    static void test0(String in, Locale locale, String expected) {
         String result = in.toLowerCase(locale);
         if (!result.equals(expected)) {
             System.err.println("input: " + in + ", locale: " + locale +
                     ", expected: " + expected + ", actual: " + result);
             throw new RuntimeException();
         }
-   }
+    }
 }
--- a/jdk/test/java/lang/String/ToUpperCase.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/java/lang/String/ToUpperCase.java	Tue Nov 17 10:29:28 2015 -0800
@@ -23,7 +23,7 @@
 
 /*
     @test
-    @bug 4219630 4304573 4533872 4900935 8042589
+    @bug 4219630 4304573 4533872 4900935 8042589 8054307
     @summary toUpperCase should upper-case German sharp s correctly even if
              it's the only character in the string. should also uppercase
              all of the 1:M char mappings correctly.  Also it should handle
@@ -97,14 +97,66 @@
         test("A\uD801\uDC44", Locale.ROOT, "A\uD801\uDC1c");
         test("a\uD801\uDC28\uD801\uDC29\uD801\uDC2A", Locale.US, "A\uD801\uDC00\uD801\uDC01\uD801\uDC02");
         test("A\uD801\uDC28a\uD801\uDC29b\uD801\uDC2Ac", Locale.US, "A\uD801\uDC00A\uD801\uDC01B\uD801\uDC02C");
+
+        // test latin1 only case
+        StringBuilder src = new StringBuilder(0x100);
+        StringBuilder exp = new StringBuilder(0x100);
+        for (int cp = 0; cp < 0x100; cp++) {
+            int upperCase = Character.toUpperCase(cp);
+            if (upperCase == -1) {    //Character.ERROR
+                continue;
+            }
+            src.appendCodePoint(cp);
+            if (cp == '\u00df') {
+                exp.append("SS");     // need Character.toUpperCaseEx()
+            } else {
+                exp.appendCodePoint(upperCase);
+            }
+        }
+        test(src.toString(), Locale.US, exp.toString());
+
+        // test non-latin1 -> latin1
+        src = new StringBuilder(0x100).append("ABC");
+        exp = new StringBuilder(0x100).append("ABC");
+        for (int cp = 0x100; cp < 0x10000; cp++) {
+            int upperCase  = Character.toUpperCase(cp);
+            if (upperCase < 0x100) {
+                src.appendCodePoint(cp);
+                exp.appendCodePoint(upperCase);
+            }
+        }
+        test(src.toString(), Locale.US, exp.toString());
+
     }
 
     static void test(String in, Locale locale, String expected) {
+        test0(in, locale,expected);
+        // trigger different code paths
+        for (String[] ss :  new String[][] {
+                                new String[] {"abc",      "ABC"},
+                                new String[] {"AbC",      "ABC"},
+                                new String[] {"ABC",      "ABC"},
+                                new String[] {"AB\u4e00", "AB\u4e00"},
+                                new String[] {"ab\u4e00", "AB\u4e00"},
+                                new String[] {"aB\u4e00", "AB\u4e00"},
+                                new String[] {"AB\uD800\uDC00", "AB\uD800\uDC00"},
+                                new String[] {"Ab\uD800\uDC00", "AB\uD800\uDC00"},
+                                new String[] {"ab\uD800\uDC00", "AB\uD800\uDC00"},
+                                new String[] {"AB\uD801\uDC44", "AB\uD801\uDC1C"},
+                                new String[] {"Ab\uD801\uDC44", "AB\uD801\uDC1C"},
+                                new String[] {"ab\uD801\uDC44", "AB\uD801\uDC1C"},
+                            }) {
+            test0(ss[0] + " " + in, locale, ss[1] + " " + expected);
+            test0(in + " " + ss[0], locale, expected + " " + ss[1]);
+        }
+    }
+
+    static void test0(String in, Locale locale, String expected) {
         String result = in.toUpperCase(locale);
         if (!result.equals(expected)) {
             System.err.println("input: " + in + ", locale: " + locale +
                     ", expected: " + expected + ", actual: " + result);
             throw new RuntimeException();
         }
-   }
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StringBuffer/CompactStringBuffer.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,489 @@
+/*
+ * 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.
+ */
+
+import java.util.Arrays;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This test is testing StringBuffer
+ *          behavior related to Compact String.
+ * @run testng/othervm -XX:+CompactStrings CompactStringBuffer
+ * @run testng/othervm -XX:-CompactStrings CompactStringBuffer
+ */
+
+public class CompactStringBuffer {
+
+    /*
+     * Tests for "A"
+     */
+    @Test
+    public void testCompactStringBufferForLatinA() {
+        final String ORIGIN = "A";
+        /*
+         * Because right now ASCII is the default encoding parameter for source
+         * code in JDK build environment, so we escape them. same as below.
+         */
+        check(new StringBuffer(ORIGIN).append(new char[] { '\uFF21' }),
+                "A\uFF21");
+        check(new StringBuffer(ORIGIN).append(new StringBuffer("\uFF21")),
+                "A\uFF21");
+        check(new StringBuffer(ORIGIN).append("\uFF21"), "A\uFF21");
+        check(new StringBuffer(ORIGIN).append(new StringBuffer("\uFF21")),
+                "A\uFF21");
+        check(new StringBuffer(ORIGIN).delete(0, 1), "");
+        check(new StringBuffer(ORIGIN).delete(0, 0), "A");
+        check(new StringBuffer(ORIGIN).deleteCharAt(0), "");
+        assertEquals(new StringBuffer(ORIGIN).indexOf("A", 0), 0);
+        assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21", 0), -1);
+        assertEquals(new StringBuffer(ORIGIN).indexOf("", 0), 0);
+        assertEquals(new StringBuffer(ORIGIN).insert(1, "\uD801\uDC00")
+                .indexOf("A", 0), 0);
+        assertEquals(new StringBuffer(ORIGIN).insert(0, "\uD801\uDC00")
+                .indexOf("A", 0), 2);
+        check(new StringBuffer(ORIGIN).insert(0, new char[] {}), "A");
+        check(new StringBuffer(ORIGIN).insert(1, new char[] { '\uFF21' }),
+                "A\uFF21");
+        check(new StringBuffer(ORIGIN).insert(0, new char[] { '\uFF21' }),
+                "\uFF21A");
+        check(new StringBuffer(ORIGIN).insert(0, new StringBuffer("\uFF21")),
+                "\uFF21A");
+        check(new StringBuffer(ORIGIN).insert(1, new StringBuffer("\uFF21")),
+                "A\uFF21");
+        check(new StringBuffer(ORIGIN).insert(0, ""), "A");
+        check(new StringBuffer(ORIGIN).insert(0, "\uFF21"), "\uFF21A");
+        check(new StringBuffer(ORIGIN).insert(1, "\uFF21"), "A\uFF21");
+        assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), 0);
+        assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), -1);
+        assertEquals(new StringBuffer(ORIGIN).lastIndexOf(""), 1);
+        check(new StringBuffer(ORIGIN).replace(0, 0, "\uFF21"), "\uFF21A");
+        check(new StringBuffer(ORIGIN).replace(0, 1, "\uFF21"), "\uFF21");
+        checkSetCharAt(new StringBuffer(ORIGIN), 0, '\uFF21', "\uFF21");
+        checkSetLength(new StringBuffer(ORIGIN), 0, "");
+        checkSetLength(new StringBuffer(ORIGIN), 1, "A");
+        check(new StringBuffer(ORIGIN).substring(0), "A");
+        check(new StringBuffer(ORIGIN).substring(1), "");
+    }
+
+    /*
+     * Tests for "\uFF21"
+     */
+    @Test
+    public void testCompactStringBufferForNonLatinA() {
+        final String ORIGIN = "\uFF21";
+        check(new StringBuffer(ORIGIN).append(new char[] { 'A' }), "\uFF21A");
+        check(new StringBuffer(ORIGIN).append(new StringBuffer("A")), "\uFF21A");
+        check(new StringBuffer(ORIGIN).append("A"), "\uFF21A");
+        check(new StringBuffer(ORIGIN).append(new StringBuffer("A")), "\uFF21A");
+        check(new StringBuffer(ORIGIN).delete(0, 1), "");
+        check(new StringBuffer(ORIGIN).delete(0, 0), "\uFF21");
+        check(new StringBuffer(ORIGIN).deleteCharAt(0), "");
+        assertEquals(new StringBuffer(ORIGIN).indexOf("A", 0), -1);
+        assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21", 0), 0);
+        assertEquals(new StringBuffer(ORIGIN).indexOf("", 0), 0);
+        check(new StringBuffer(ORIGIN).insert(0, new char[] {}), "\uFF21");
+        check(new StringBuffer(ORIGIN).insert(1, new char[] { 'A' }), "\uFF21A");
+        check(new StringBuffer(ORIGIN).insert(0, new char[] { 'A' }), "A\uFF21");
+        check(new StringBuffer(ORIGIN).insert(0, new StringBuffer("A")),
+                "A\uFF21");
+        check(new StringBuffer(ORIGIN).insert(1, new StringBuffer("A")),
+                "\uFF21A");
+        check(new StringBuffer(ORIGIN).insert(0, ""), "\uFF21");
+        check(new StringBuffer(ORIGIN).insert(0, "A"), "A\uFF21");
+        check(new StringBuffer(ORIGIN).insert(1, "A"), "\uFF21A");
+        assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), -1);
+        assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), 0);
+        assertEquals(new StringBuffer(ORIGIN).lastIndexOf(""), 1);
+        check(new StringBuffer(ORIGIN).replace(0, 0, "A"), "A\uFF21");
+        check(new StringBuffer(ORIGIN).replace(0, 1, "A"), "A");
+        checkSetCharAt(new StringBuffer(ORIGIN), 0, 'A', "A");
+        checkSetLength(new StringBuffer(ORIGIN), 0, "");
+        checkSetLength(new StringBuffer(ORIGIN), 1, "\uFF21");
+        check(new StringBuffer(ORIGIN).substring(0), "\uFF21");
+        check(new StringBuffer(ORIGIN).substring(1), "");
+    }
+
+    /*
+     * Tests for "\uFF21A"
+     */
+    @Test
+    public void testCompactStringBufferForMixedA1() {
+        final String ORIGIN = "\uFF21A";
+        check(new StringBuffer(ORIGIN).delete(0, 1), "A");
+        check(new StringBuffer(ORIGIN).delete(1, 2), "\uFF21");
+        check(new StringBuffer(ORIGIN).deleteCharAt(1), "\uFF21");
+        check(new StringBuffer(ORIGIN).deleteCharAt(0), "A");
+        assertEquals(new StringBuffer(ORIGIN).indexOf("A", 0), 1);
+        assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21", 0), 0);
+        assertEquals(new StringBuffer(ORIGIN).indexOf("", 0), 0);
+        check(new StringBuffer(ORIGIN).insert(1, new char[] { 'A' }), "\uFF21AA");
+        check(new StringBuffer(ORIGIN).insert(0, new char[] { '\uFF21' }),
+                "\uFF21\uFF21A");
+        assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), 1);
+        assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), 0);
+        assertEquals(new StringBuffer(ORIGIN).lastIndexOf(""), 2);
+        check(new StringBuffer(ORIGIN).replace(0, 0, "A"), "A\uFF21A");
+        check(new StringBuffer(ORIGIN).replace(0, 1, "A"), "AA");
+        checkSetCharAt(new StringBuffer(ORIGIN), 0, 'A', "AA");
+        checkSetLength(new StringBuffer(ORIGIN), 0, "");
+        checkSetLength(new StringBuffer(ORIGIN), 1, "\uFF21");
+        check(new StringBuffer(ORIGIN).substring(0), "\uFF21A");
+        check(new StringBuffer(ORIGIN).substring(1), "A");
+    }
+
+    /*
+     * Tests for "A\uFF21"
+     */
+    @Test
+    public void testCompactStringBufferForMixedA2() {
+        final String ORIGIN = "A\uFF21";
+        check(new StringBuffer(ORIGIN).replace(1, 2, "A"), "AA");
+        checkSetLength(new StringBuffer(ORIGIN), 1, "A");
+        check(new StringBuffer(ORIGIN).substring(0), "A\uFF21");
+        check(new StringBuffer(ORIGIN).substring(1), "\uFF21");
+        check(new StringBuffer(ORIGIN).substring(0, 1), "A");
+    }
+
+    /*
+     * Tests for "\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A"
+     */
+    @Test
+    public void testCompactStringBufferForDuplicatedMixedA1() {
+        final String ORIGIN = "\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A";
+        checkSetLength(new StringBuffer(ORIGIN), 1, "\uFF21");
+        assertEquals(new StringBuffer(ORIGIN).indexOf("A", 5), 5);
+        assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21", 5), 6);
+        assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), 9);
+        assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), 8);
+        assertEquals(new StringBuffer(ORIGIN).lastIndexOf(""), 10);
+        check(new StringBuffer(ORIGIN).substring(9), "A");
+        check(new StringBuffer(ORIGIN).substring(8), "\uFF21A");
+    }
+
+    /*
+     * Tests for "A\uFF21A\uFF21A\uFF21A\uFF21A\uFF21"
+     */
+    @Test
+    public void testCompactStringBufferForDuplicatedMixedA2() {
+        final String ORIGIN = "A\uFF21A\uFF21A\uFF21A\uFF21A\uFF21";
+        checkSetLength(new StringBuffer(ORIGIN), 1, "A");
+        assertEquals(new StringBuffer(ORIGIN).indexOf("A", 5), 6);
+        assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21", 5), 5);
+        assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), 8);
+        assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), 9);
+        check(new StringBuffer(ORIGIN).substring(9), "\uFF21");
+        check(new StringBuffer(ORIGIN).substring(8), "A\uFF21");
+    }
+
+    /*
+     * Tests for "\uD801\uDC00\uD801\uDC01"
+     */
+    @Test
+    public void testCompactStringForSupplementaryCodePoint() {
+        final String ORIGIN = "\uD801\uDC00\uD801\uDC01";
+        check(new StringBuffer(ORIGIN).append("A"), "\uD801\uDC00\uD801\uDC01A");
+        check(new StringBuffer(ORIGIN).append("\uFF21"),
+                "\uD801\uDC00\uD801\uDC01\uFF21");
+        check(new StringBuffer(ORIGIN).appendCodePoint('A'),
+                "\uD801\uDC00\uD801\uDC01A");
+        check(new StringBuffer(ORIGIN).appendCodePoint('\uFF21'),
+                "\uD801\uDC00\uD801\uDC01\uFF21");
+        assertEquals(new StringBuffer(ORIGIN).charAt(0), '\uD801');
+        assertEquals(new StringBuffer(ORIGIN).codePointAt(0),
+                Character.codePointAt(ORIGIN, 0));
+        assertEquals(new StringBuffer(ORIGIN).codePointAt(1),
+                Character.codePointAt(ORIGIN, 1));
+        assertEquals(new StringBuffer(ORIGIN).codePointBefore(2),
+                Character.codePointAt(ORIGIN, 0));
+        assertEquals(new StringBuffer(ORIGIN).codePointCount(1, 3), 2);
+        check(new StringBuffer(ORIGIN).delete(0, 2), "\uD801\uDC01");
+        check(new StringBuffer(ORIGIN).delete(0, 3), "\uDC01");
+        check(new StringBuffer(ORIGIN).deleteCharAt(1), "\uD801\uD801\uDC01");
+        checkGetChars(new StringBuffer(ORIGIN), 0, 3, new char[] { '\uD801',
+                '\uDC00', '\uD801' });
+        assertEquals(new StringBuffer(ORIGIN).indexOf("\uD801\uDC01"), 2);
+        assertEquals(new StringBuffer(ORIGIN).indexOf("\uDC01"), 3);
+        assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21"), -1);
+        assertEquals(new StringBuffer(ORIGIN).indexOf("A"), -1);
+        check(new StringBuffer(ORIGIN).insert(0, "\uFF21"),
+                "\uFF21\uD801\uDC00\uD801\uDC01");
+        check(new StringBuffer(ORIGIN).insert(1, "\uFF21"),
+                "\uD801\uFF21\uDC00\uD801\uDC01");
+        check(new StringBuffer(ORIGIN).insert(1, "A"),
+                "\uD801A\uDC00\uD801\uDC01");
+        assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uDC00\uD801"), 1);
+        assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uD801"), 2);
+        assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), -1);
+        assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), -1);
+        assertEquals(new StringBuffer(ORIGIN).length(), 4);
+        assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(1, 1), 2);
+        assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(0, 1), 2);
+        check(new StringBuffer(ORIGIN).replace(0, 2, "A"), "A\uD801\uDC01");
+        check(new StringBuffer(ORIGIN).replace(0, 3, "A"), "A\uDC01");
+        check(new StringBuffer(ORIGIN).replace(0, 2, "\uFF21"),
+                "\uFF21\uD801\uDC01");
+        check(new StringBuffer(ORIGIN).replace(0, 3, "\uFF21"), "\uFF21\uDC01");
+        check(new StringBuffer(ORIGIN).reverse(), "\uD801\uDC01\uD801\uDC00");
+        checkSetCharAt(new StringBuffer(ORIGIN), 1, '\uDC01',
+                "\uD801\uDC01\uD801\uDC01");
+        checkSetCharAt(new StringBuffer(ORIGIN), 1, 'A', "\uD801A\uD801\uDC01");
+        checkSetLength(new StringBuffer(ORIGIN), 2, "\uD801\uDC00");
+        checkSetLength(new StringBuffer(ORIGIN), 3, "\uD801\uDC00\uD801");
+        check(new StringBuffer(ORIGIN).substring(1, 3), "\uDC00\uD801");
+    }
+
+    /*
+     * Tests for "A\uD801\uDC00\uFF21"
+     */
+    @Test
+    public void testCompactStringForSupplementaryCodePointMixed1() {
+        final String ORIGIN = "A\uD801\uDC00\uFF21";
+        assertEquals(new StringBuffer(ORIGIN).codePointBefore(3),
+                Character.codePointAt(ORIGIN, 1));
+        assertEquals(new StringBuffer(ORIGIN).codePointBefore(2), '\uD801');
+        assertEquals(new StringBuffer(ORIGIN).codePointBefore(1), 'A');
+        assertEquals(new StringBuffer(ORIGIN).codePointCount(0, 3), 2);
+        assertEquals(new StringBuffer(ORIGIN).codePointCount(0, 4), 3);
+        check(new StringBuffer(ORIGIN).delete(0, 1), "\uD801\uDC00\uFF21");
+        check(new StringBuffer(ORIGIN).delete(0, 1).delete(2, 3), "\uD801\uDC00");
+        check(new StringBuffer(ORIGIN).deleteCharAt(3).deleteCharAt(0),
+                "\uD801\uDC00");
+        assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21"), 3);
+        assertEquals(new StringBuffer(ORIGIN).indexOf("A"), 0);
+        assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), 3);
+        assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), 0);
+        assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(0, 1), 1);
+        assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(1, 1), 3);
+        check(new StringBuffer(ORIGIN).replace(1, 3, "A"), "AA\uFF21");
+        check(new StringBuffer(ORIGIN).replace(1, 4, "A"), "AA");
+        check(new StringBuffer(ORIGIN).replace(1, 4, ""), "A");
+        check(new StringBuffer(ORIGIN).reverse(), "\uFF21\uD801\uDC00A");
+        checkSetLength(new StringBuffer(ORIGIN), 1, "A");
+        check(new StringBuffer(ORIGIN).substring(0, 1), "A");
+    }
+
+    /*
+     * Tests for "\uD801\uDC00\uFF21A"
+     */
+    @Test
+    public void testCompactStringForSupplementaryCodePointMixed2() {
+        final String ORIGIN = "\uD801\uDC00\uFF21A";
+        assertEquals(new StringBuffer(ORIGIN).codePointBefore(3),
+                Character.codePointAt(ORIGIN, 2));
+        assertEquals(new StringBuffer(ORIGIN).codePointBefore(2),
+                Character.codePointAt(ORIGIN, 0));
+        assertEquals(new StringBuffer(ORIGIN).codePointBefore(1), '\uD801');
+        assertEquals(new StringBuffer(ORIGIN).codePointCount(0, 3), 2);
+        assertEquals(new StringBuffer(ORIGIN).codePointCount(0, 4), 3);
+        check(new StringBuffer(ORIGIN).delete(0, 2), "\uFF21A");
+        check(new StringBuffer(ORIGIN).delete(0, 3), "A");
+        check(new StringBuffer(ORIGIN).deleteCharAt(0).deleteCharAt(0)
+                .deleteCharAt(0), "A");
+        assertEquals(new StringBuffer(ORIGIN).indexOf("A"), 3);
+        assertEquals(new StringBuffer(ORIGIN).delete(0, 3).indexOf("A"), 0);
+        assertEquals(new StringBuffer(ORIGIN).replace(0, 3, "B").indexOf("A"),
+                1);
+        assertEquals(new StringBuffer(ORIGIN).substring(3, 4).indexOf("A"), 0);
+        assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(1, 1), 2);
+        assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(0, 1), 2);
+        assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(2, 1), 3);
+        check(new StringBuffer(ORIGIN).replace(0, 3, "B"), "BA");
+        check(new StringBuffer(ORIGIN).reverse(), "A\uFF21\uD801\uDC00");
+    }
+
+    /*
+     * Tests for "\uD801A\uDC00\uFF21"
+     */
+    @Test
+    public void testCompactStringForSupplementaryCodePointMixed3() {
+        final String ORIGIN = "\uD801A\uDC00\uFF21";
+        assertEquals(new StringBuffer(ORIGIN).codePointAt(1), 'A');
+        assertEquals(new StringBuffer(ORIGIN).codePointAt(3), '\uFF21');
+        assertEquals(new StringBuffer(ORIGIN).codePointBefore(1), '\uD801');
+        assertEquals(new StringBuffer(ORIGIN).codePointBefore(2), 'A');
+        assertEquals(new StringBuffer(ORIGIN).codePointBefore(3), '\uDC00');
+        assertEquals(new StringBuffer(ORIGIN).codePointCount(0, 3), 3);
+        assertEquals(new StringBuffer(ORIGIN).codePointCount(1, 3), 2);
+        assertEquals(new StringBuffer(ORIGIN).delete(0, 1).delete(1, 3)
+                .indexOf("A"), 0);
+        assertEquals(
+                new StringBuffer(ORIGIN).replace(0, 1, "B").replace(2, 4, "C")
+                        .indexOf("A"), 1);
+        assertEquals(new StringBuffer(ORIGIN).substring(1, 4).substring(0, 1)
+                .indexOf("A"), 0);
+        assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(0, 1), 1);
+        assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(1, 1), 2);
+        assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(2, 1), 3);
+        check(new StringBuffer(ORIGIN).reverse(), "\uFF21\uDC00A\uD801");
+    }
+
+    /*
+     * Tests for "A\uDC01\uFF21\uD801"
+     */
+    @Test
+    public void testCompactStringForSupplementaryCodePointMixed4() {
+        final String ORIGIN = "A\uDC01\uFF21\uD801";
+        assertEquals(new StringBuffer(ORIGIN).codePointAt(1), '\uDC01');
+        assertEquals(new StringBuffer(ORIGIN).codePointAt(3), '\uD801');
+        assertEquals(new StringBuffer(ORIGIN).codePointBefore(1), 'A');
+        assertEquals(new StringBuffer(ORIGIN).codePointBefore(2), '\uDC01');
+        assertEquals(new StringBuffer(ORIGIN).codePointBefore(3), '\uFF21');
+        assertEquals(new StringBuffer(ORIGIN).codePointCount(0, 3), 3);
+        assertEquals(new StringBuffer(ORIGIN).codePointCount(1, 3), 2);
+        assertEquals(new StringBuffer(ORIGIN).delete(1, 4).indexOf("A"), 0);
+        assertEquals(new StringBuffer(ORIGIN).replace(1, 4, "B").indexOf("A"),
+                0);
+        assertEquals(new StringBuffer(ORIGIN).substring(0, 1).indexOf("A"), 0);
+        assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(0, 1), 1);
+        assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(1, 1), 2);
+        assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(2, 1), 3);
+        check(new StringBuffer(ORIGIN).reverse(), "\uD801\uFF21\uDC01A");
+    }
+
+    @Test
+    public void testCompactStringMisc() {
+        String ascii = "abcdefgh";
+        String asciiMixed = "abc" + "\u4e00\u4e01\u4e02" + "fgh";
+        String bmp = "\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07\u4e08";
+        String bmpMixed = "\u4e00\u4e01\u4e02" + "ABC" + "\u4e06\u4e07\u4e08";
+
+        check(new StringBuffer().append(ascii).delete(0, 20).toString(),
+              "");
+        check(new StringBuffer().append(ascii).delete(3, 20).toString(),
+              "abc");
+        check(new StringBuffer().append(ascii).delete(3, 6).toString(),
+              "abcgh");
+        check(new StringBuffer().append(ascii).deleteCharAt(0).toString(),
+              "bcdefgh");
+        check(new StringBuffer().append(ascii).deleteCharAt(3).toString(),
+              "abcefgh");
+        check(new StringBuffer().append(asciiMixed).delete(3, 6).toString(),
+              "abcfgh");
+        check(new StringBuffer().append(asciiMixed).deleteCharAt(3).toString(),
+              "abc\u4e01\u4e02fgh");
+        check(new StringBuffer().append(asciiMixed).deleteCharAt(3)
+                                                   .deleteCharAt(3)
+                                                   .deleteCharAt(3).toString(),
+              "abcfgh");
+        check(new StringBuffer().append(bmp).delete(0, 20).toString(),
+              "");
+        check(new StringBuffer().append(bmp).delete(3, 20).toString(),
+              "\u4e00\u4e01\u4e02");
+        check(new StringBuffer().append(bmp).delete(3, 6).toString(),
+              "\u4e00\u4e01\u4e02\u4e06\u4e07\u4e08");
+        check(new StringBuffer().append(bmp).deleteCharAt(0).toString(),
+              "\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07\u4e08");
+        check(new StringBuffer().append(bmp).deleteCharAt(3).toString(),
+              "\u4e00\u4e01\u4e02\u4e04\u4e05\u4e06\u4e07\u4e08");
+        check(new StringBuffer().append(bmpMixed).delete(3, 6).toString(),
+              "\u4e00\u4e01\u4e02\u4e06\u4e07\u4e08");
+
+        ////////////////////////////////////////////////////////////////////
+        check(new StringBuffer().append(ascii).replace(3, 6, "AB").toString(),
+              "abcABgh");
+        check(new StringBuffer().append(asciiMixed).replace(3, 6, "AB").toString(),
+              "abcABfgh");
+        check(new StringBuffer().append(bmp).replace(3, 6, "AB").toString(),
+              "\u4e00\u4e01\u4e02AB\u4e06\u4e07\u4e08");
+
+        check(new StringBuffer().append(bmpMixed).replace(3, 6, "").toString(),
+              "\u4e00\u4e01\u4e02\u4e06\u4e07\u4e08");
+
+        check(new StringBuffer().append(ascii).replace(3, 6, "\u4e01\u4e02").toString(),
+              "abc\u4e01\u4e02gh");
+
+        ////////////////////////////////////////////////////////////////////
+        check(new StringBuffer().append(ascii).insert(3, "").toString(),
+              "abcdefgh");
+        check(new StringBuffer().append(ascii).insert(3, "AB").toString(),
+              "abcABdefgh");
+        check(new StringBuffer().append(ascii).insert(3, "\u4e01\u4e02").toString(),
+              "abc\u4e01\u4e02defgh");
+
+        check(new StringBuffer().append(asciiMixed).insert(0, 'A').toString(),
+              "Aabc\u4e00\u4e01\u4e02fgh");
+        check(new StringBuffer().append(asciiMixed).insert(3, "A").toString(),
+              "abcA\u4e00\u4e01\u4e02fgh");
+
+        check(new StringBuffer().append(ascii).insert(3, 1234567).toString(),
+              "abc1234567defgh");
+        check(new StringBuffer().append(bmp).insert(3, 1234567).toString(),
+              "\u4e00\u4e01\u4e021234567\u4e03\u4e04\u4e05\u4e06\u4e07\u4e08");
+
+        ////////////////////////////////////////////////////////////////////
+        check(new StringBuffer().append(ascii).append(1.23456).toString(),
+              "abcdefgh1.23456");
+        check(new StringBuffer().append(bmp).append(1.23456).toString(),
+              "\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07\u4e081.23456");
+    }
+
+    private void checkGetChars(StringBuffer sb, int srcBegin, int srcEnd,
+            char expected[]) {
+        char[] dst = new char[srcEnd - srcBegin];
+        sb.getChars(srcBegin, srcEnd, dst, 0);
+        assertTrue(Arrays.equals(dst, expected));
+    }
+
+    private void checkSetCharAt(StringBuffer sb, int index, char ch,
+            String expected) {
+        sb.setCharAt(index, ch);
+        check(sb, expected);
+    }
+
+    private void checkSetLength(StringBuffer sb, int newLength, String expected) {
+        sb.setLength(newLength);
+        check(sb, expected);
+    }
+
+    private void check(StringBuffer sb, String expected) {
+        check(sb.toString(), expected);
+    }
+
+    private void check(String str, String expected) {
+        assertTrue(str.equals(expected), String.format(
+                "Get (%s) but expect (%s), ", escapeNonASCIIs(str),
+                escapeNonASCIIs(expected)));
+    }
+
+    /*
+     * Because right now system default charset in JPRT environment is only
+     * guaranteed to support ASCII characters in log, so we escape them.
+     */
+    private String escapeNonASCIIs(String str) {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < str.length(); i++) {
+            char c = str.charAt(i);
+            if (c > 0x7F) {
+                sb.append("\\u").append(Integer.toHexString((int) c));
+            } else {
+                sb.append(c);
+            }
+        }
+        return sb.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StringBuffer/CompactStringBufferSerialization.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,152 @@
+/*
+ * 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.
+ */
+
+import java.io.*;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static jdk.testlibrary.SerializationUtils.*;
+import static org.testng.Assert.*;
+
+/*
+ * @test
+ * @bug 8077559
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.SerializationUtils
+ * @summary Tests Compact String. This one is testing StringBuffer serialization
+ *          among -XX:+CompactStrings/-XX:-CompactStrings/LegacyStringBuffer
+ * @run testng/othervm -XX:+CompactStrings CompactStringBufferSerialization
+ * @run testng/othervm -XX:-CompactStrings CompactStringBufferSerialization
+ */
+
+public class CompactStringBufferSerialization {
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+                // every byte array is serialized from corresponding StringBuilder object
+                // by previous JDK(build 1.8.0_45-b14).
+                new Object[] {
+                        new StringBuffer(""),
+                        new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
+                                102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
+                                100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 0, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
+                                -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                                0, 0, 0, 0, 0, 0, 0, 120 } },
+                new Object[] {
+                        new StringBuffer("A"),
+                        new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
+                                102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
+                                100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 1, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
+                                -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 17, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                                0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+                new Object[] {
+                        new StringBuffer("AB"),
+                        new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
+                                102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
+                                100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 2, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
+                                -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 18, 0, 65, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+                new Object[] {
+                        new StringBuffer("abcdefghijk"),
+                        new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
+                                102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
+                                100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 11, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
+                                -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 27, 0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102, 0, 103, 0, 104, 0, 105, 0,
+                                106, 0, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+                new Object[] {
+                        new StringBuffer("\uff21"),
+                        new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
+                                102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
+                                100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 1, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
+                                -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 17, -1, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+                new Object[] {
+                        new StringBuffer("\uff21\uff22"),
+                        new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
+                                102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
+                                100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 2, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
+                                -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 18, -1, 33, -1, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+                new Object[] {
+                        new StringBuffer("\uff21A\uff21A\uff21A\uff21A\uff21A"),
+                        new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
+                                102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
+                                100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 10, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
+                                -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 26, -1, 33, 0, 65, -1, 33, 0, 65, -1, 33, 0, 65, -1, 33, 0, 65, -1, 33, 0, 65,
+                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+                new Object[] {
+                        new StringBuffer("A\uff21B\uff22C\uff23D\uff24E\uff25F\uff26G\uff27H\uff28"),
+                        new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
+                                102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
+                                100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 16, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
+                                -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 32, 0, 65, -1, 33, 0, 66, -1, 34, 0, 67, -1, 35, 0, 68, -1, 36, 0, 69, -1, 37,
+                                0, 70, -1, 38, 0, 71, -1, 39, 0, 72, -1, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                                0, 0, 0, 0, 0, 120 } },
+                new Object[] {
+                        new StringBuffer("\uff21A\uff22B\uff23C\uff24D\uff25E\uff26F\uff27G\uff28H"),
+                        new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
+                                102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
+                                100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 16, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
+                                -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 32, -1, 33, 0, 65, -1, 34, 0, 66, -1, 35, 0, 67, -1, 36, 0, 68, -1, 37, 0, 69,
+                                -1, 38, 0, 70, -1, 39, 0, 71, -1, 40, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                                0, 0, 0, 0, 0, 120 } },
+                new Object[] {
+                        new StringBuffer("\ud801\udc00\ud801\udc01\uff21A"),
+                        new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
+                                102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
+                                100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 6, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
+                                -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 22, -40, 1, -36, 0, -40, 1, -36, 1, -1, 33, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+                new Object[] {
+                        new StringBuffer("\uff21\uff22\uff21\uff22\uff21\uff22\uff21\uff22\uff21\uff22"),
+                        new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
+                                102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
+                                100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 10, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
+                                -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 26, -1, 33, -1, 34, -1, 33, -1, 34, -1, 33, -1, 34, -1, 33, -1, 34, -1, 33, -1,
+                                34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } } };
+    }
+
+    /*
+     * Verify serialization works between Compact StringBuffer/Legacy StringBuffer
+     */
+    @Test(dataProvider = "provider")
+    public void test(StringBuffer sbContent, byte[] baInJDK8) throws Exception {
+        // Serialize a StringBuffer object into byte array.
+        byte[] ba = serialize(sbContent);
+        assertEquals(ba, baInJDK8);
+        // Deserialize a StringBuffer object from byte array which is generated by previous JDK(build 1.8.0_45-b14).
+        Object obj = deserialize(ba);
+        assertEquals(obj.getClass(), StringBuffer.class);
+        assertTrue(equals((StringBuffer)obj, sbContent));
+    }
+
+    boolean equals(StringBuffer sb, StringBuffer expected) {
+        if(sb.length() == expected.length()
+                && sb.capacity() == expected.capacity()
+                && sb.toString().equals(expected.toString())) {
+            return true;
+        }
+        return false;
+    }
+}
--- a/jdk/test/java/lang/StringBuffer/Exceptions.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/java/lang/StringBuffer/Exceptions.java	Tue Nov 17 10:29:28 2015 -0800
@@ -94,7 +94,7 @@
 
         System.out.println("StringBuffer.replace(int start, int end, String str)");
         tryCatch("  -1, 2, \" \"",
-                 new StringIndexOutOfBoundsException(-1),
+                 new StringIndexOutOfBoundsException("start -1, end 2, length 7"),
                  new Runnable() {
                 public void run() {
                     StringBuffer sb = new StringBuffer("hilbert");
@@ -102,14 +102,14 @@
                 }});
 
         tryCatch("  7, 8, \" \"",
-                 new StringIndexOutOfBoundsException("start > length()"),
+                 new StringIndexOutOfBoundsException("start 7, end 6, length 6"),
                  new Runnable() {
                 public void run() {
                     StringBuffer sb = new StringBuffer("banach");
                     sb.replace(7, 8, " ");
                 }});
         tryCatch("  2, 1, \" \"",
-                 new StringIndexOutOfBoundsException("start > end"),
+                 new StringIndexOutOfBoundsException("start 2, end 1, length 7"),
                  new Runnable() {
                 public void run() {
                     StringBuffer sb = new StringBuffer("riemann");
--- a/jdk/test/java/lang/StringBuilder/BuilderForwarding.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/java/lang/StringBuilder/BuilderForwarding.java	Tue Nov 17 10:29:28 2015 -0800
@@ -264,4 +264,3 @@
         }
     }
 }
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StringBuilder/CompactStringBuilder.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,414 @@
+/*
+ * 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.
+ */
+
+import java.util.Arrays;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+/*
+ * @test
+ * @bug 8054307 8077559
+ * @summary Tests Compact String. This test is testing StringBuilder
+ *          behavior related to Compact String.
+ * @run testng/othervm -XX:+CompactStrings CompactStringBuilder
+ * @run testng/othervm -XX:-CompactStrings CompactStringBuilder
+ */
+
+public class CompactStringBuilder {
+
+    /*
+     * Tests for "A"
+     */
+    @Test
+    public void testCompactStringBuilderForLatinA() {
+        final String ORIGIN = "A";
+        /*
+         * Because right now ASCII is the default encoding parameter for source
+         * code in JDK build environment, so we escape them. same as below.
+         */
+        check(new StringBuilder(ORIGIN).append(new char[] { '\uFF21' }),
+                "A\uFF21");
+        check(new StringBuilder(ORIGIN).append(new StringBuffer("\uFF21")),
+                "A\uFF21");
+        check(new StringBuilder(ORIGIN).append("\uFF21"), "A\uFF21");
+        check(new StringBuilder(ORIGIN).append(new StringBuffer("\uFF21")),
+                "A\uFF21");
+        check(new StringBuilder(ORIGIN).delete(0, 1), "");
+        check(new StringBuilder(ORIGIN).delete(0, 0), "A");
+        check(new StringBuilder(ORIGIN).deleteCharAt(0), "");
+        assertEquals(new StringBuilder(ORIGIN).indexOf("A", 0), 0);
+        assertEquals(new StringBuilder(ORIGIN).indexOf("\uFF21", 0), -1);
+        assertEquals(new StringBuilder(ORIGIN).indexOf("", 0), 0);
+        assertEquals(new StringBuilder(ORIGIN).insert(1, "\uD801\uDC00")
+                .indexOf("A", 0), 0);
+        assertEquals(new StringBuilder(ORIGIN).insert(0, "\uD801\uDC00")
+                .indexOf("A", 0), 2);
+        check(new StringBuilder(ORIGIN).insert(0, new char[] {}), "A");
+        check(new StringBuilder(ORIGIN).insert(1, new char[] { '\uFF21' }),
+                "A\uFF21");
+        check(new StringBuilder(ORIGIN).insert(0, new char[] { '\uFF21' }),
+                "\uFF21A");
+        check(new StringBuilder(ORIGIN).insert(0, new StringBuffer("\uFF21")),
+                "\uFF21A");
+        check(new StringBuilder(ORIGIN).insert(1, new StringBuffer("\uFF21")),
+                "A\uFF21");
+        check(new StringBuilder(ORIGIN).insert(0, ""), "A");
+        check(new StringBuilder(ORIGIN).insert(0, "\uFF21"), "\uFF21A");
+        check(new StringBuilder(ORIGIN).insert(1, "\uFF21"), "A\uFF21");
+        assertEquals(new StringBuilder(ORIGIN).lastIndexOf("A"), 0);
+        assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uFF21"), -1);
+        assertEquals(new StringBuilder(ORIGIN).lastIndexOf(""), 1);
+        check(new StringBuilder(ORIGIN).replace(0, 0, "\uFF21"), "\uFF21A");
+        check(new StringBuilder(ORIGIN).replace(0, 1, "\uFF21"), "\uFF21");
+        checkSetCharAt(new StringBuilder(ORIGIN), 0, '\uFF21', "\uFF21");
+        checkSetLength(new StringBuilder(ORIGIN), 0, "");
+        checkSetLength(new StringBuilder(ORIGIN), 1, "A");
+        check(new StringBuilder(ORIGIN).substring(0), "A");
+        check(new StringBuilder(ORIGIN).substring(1), "");
+    }
+
+    /*
+     * Tests for "\uFF21"
+     */
+    @Test
+    public void testCompactStringBuilderForNonLatinA() {
+        final String ORIGIN = "\uFF21";
+        check(new StringBuilder(ORIGIN).append(new char[] { 'A' }), "\uFF21A");
+        check(new StringBuilder(ORIGIN).append(new StringBuffer("A")), "\uFF21A");
+        check(new StringBuilder(ORIGIN).append("A"), "\uFF21A");
+        check(new StringBuilder(ORIGIN).append(new StringBuffer("A")), "\uFF21A");
+        check(new StringBuilder(ORIGIN).delete(0, 1), "");
+        check(new StringBuilder(ORIGIN).delete(0, 0), "\uFF21");
+        check(new StringBuilder(ORIGIN).deleteCharAt(0), "");
+        assertEquals(new StringBuilder(ORIGIN).indexOf("A", 0), -1);
+        assertEquals(new StringBuilder(ORIGIN).indexOf("\uFF21", 0), 0);
+        assertEquals(new StringBuilder(ORIGIN).indexOf("", 0), 0);
+        check(new StringBuilder(ORIGIN).insert(0, new char[] {}), "\uFF21");
+        check(new StringBuilder(ORIGIN).insert(1, new char[] { 'A' }), "\uFF21A");
+        check(new StringBuilder(ORIGIN).insert(0, new char[] { 'A' }), "A\uFF21");
+        check(new StringBuilder(ORIGIN).insert(0, new StringBuffer("A")),
+                "A\uFF21");
+        check(new StringBuilder(ORIGIN).insert(1, new StringBuffer("A")),
+                "\uFF21A");
+        check(new StringBuilder(ORIGIN).insert(0, ""), "\uFF21");
+        check(new StringBuilder(ORIGIN).insert(0, "A"), "A\uFF21");
+        check(new StringBuilder(ORIGIN).insert(1, "A"), "\uFF21A");
+        assertEquals(new StringBuilder(ORIGIN).lastIndexOf("A"), -1);
+        assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uFF21"), 0);
+        assertEquals(new StringBuilder(ORIGIN).lastIndexOf(""), 1);
+        check(new StringBuilder(ORIGIN).replace(0, 0, "A"), "A\uFF21");
+        check(new StringBuilder(ORIGIN).replace(0, 1, "A"), "A");
+        checkSetCharAt(new StringBuilder(ORIGIN), 0, 'A', "A");
+        checkSetLength(new StringBuilder(ORIGIN), 0, "");
+        checkSetLength(new StringBuilder(ORIGIN), 1, "\uFF21");
+        check(new StringBuilder(ORIGIN).substring(0), "\uFF21");
+        check(new StringBuilder(ORIGIN).substring(1), "");
+    }
+
+    /*
+     * Tests for "\uFF21A"
+     */
+    @Test
+    public void testCompactStringBuilderForMixedA1() {
+        final String ORIGIN = "\uFF21A";
+        check(new StringBuilder(ORIGIN).delete(0, 1), "A");
+        check(new StringBuilder(ORIGIN).delete(1, 2), "\uFF21");
+        check(new StringBuilder(ORIGIN).deleteCharAt(1), "\uFF21");
+        check(new StringBuilder(ORIGIN).deleteCharAt(0), "A");
+        assertEquals(new StringBuilder(ORIGIN).indexOf("A", 0), 1);
+        assertEquals(new StringBuilder(ORIGIN).indexOf("\uFF21", 0), 0);
+        assertEquals(new StringBuilder(ORIGIN).indexOf("", 0), 0);
+        check(new StringBuilder(ORIGIN).insert(1, new char[] { 'A' }),
+                "\uFF21AA");
+        check(new StringBuilder(ORIGIN).insert(0, new char[] { '\uFF21' }),
+                "\uFF21\uFF21A");
+        assertEquals(new StringBuilder(ORIGIN).lastIndexOf("A"), 1);
+        assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uFF21"), 0);
+        assertEquals(new StringBuilder(ORIGIN).lastIndexOf(""), 2);
+        check(new StringBuilder(ORIGIN).replace(0, 0, "A"), "A\uFF21A");
+        check(new StringBuilder(ORIGIN).replace(0, 1, "A"), "AA");
+        checkSetCharAt(new StringBuilder(ORIGIN), 0, 'A', "AA");
+        checkSetLength(new StringBuilder(ORIGIN), 0, "");
+        checkSetLength(new StringBuilder(ORIGIN), 1, "\uFF21");
+        check(new StringBuilder(ORIGIN).substring(0), "\uFF21A");
+        check(new StringBuilder(ORIGIN).substring(1), "A");
+    }
+
+    /*
+     * Tests for "A\uFF21"
+     */
+    @Test
+    public void testCompactStringBuilderForMixedA2() {
+        final String ORIGIN = "A\uFF21";
+        check(new StringBuilder(ORIGIN).replace(1, 2, "A"), "AA");
+        checkSetLength(new StringBuilder(ORIGIN), 1, "A");
+        check(new StringBuilder(ORIGIN).substring(0), "A\uFF21");
+        check(new StringBuilder(ORIGIN).substring(1), "\uFF21");
+        check(new StringBuilder(ORIGIN).substring(0, 1), "A");
+    }
+
+    /*
+     * Tests for "\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A"
+     */
+    @Test
+    public void testCompactStringBuilderForDuplicatedMixedA1() {
+        final String ORIGIN = "\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A";
+        checkSetLength(new StringBuilder(ORIGIN), 1, "\uFF21");
+        assertEquals(new StringBuilder(ORIGIN).indexOf("A", 5), 5);
+        assertEquals(new StringBuilder(ORIGIN).indexOf("\uFF21", 5), 6);
+        assertEquals(new StringBuilder(ORIGIN).lastIndexOf("A"), 9);
+        assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uFF21"), 8);
+        assertEquals(new StringBuilder(ORIGIN).lastIndexOf(""), 10);
+        check(new StringBuilder(ORIGIN).substring(9), "A");
+        check(new StringBuilder(ORIGIN).substring(8), "\uFF21A");
+    }
+
+    /*
+     * Tests for "A\uFF21A\uFF21A\uFF21A\uFF21A\uFF21"
+     */
+    @Test
+    public void testCompactStringBuilderForDuplicatedMixedA2() {
+        final String ORIGIN = "A\uFF21A\uFF21A\uFF21A\uFF21A\uFF21";
+        checkSetLength(new StringBuilder(ORIGIN), 1, "A");
+        assertEquals(new StringBuilder(ORIGIN).indexOf("A", 5), 6);
+        assertEquals(new StringBuilder(ORIGIN).indexOf("\uFF21", 5), 5);
+        assertEquals(new StringBuilder(ORIGIN).lastIndexOf("A"), 8);
+        assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uFF21"), 9);
+        check(new StringBuilder(ORIGIN).substring(9), "\uFF21");
+        check(new StringBuilder(ORIGIN).substring(8), "A\uFF21");
+    }
+
+    /*
+     * Tests for "\uD801\uDC00\uD801\uDC01"
+     */
+    @Test
+    public void testCompactStringForSupplementaryCodePoint() {
+        final String ORIGIN = "\uD801\uDC00\uD801\uDC01";
+        check(new StringBuilder(ORIGIN).append("A"), "\uD801\uDC00\uD801\uDC01A");
+        check(new StringBuilder(ORIGIN).append("\uFF21"),
+                "\uD801\uDC00\uD801\uDC01\uFF21");
+        check(new StringBuilder(ORIGIN).appendCodePoint('A'),
+                "\uD801\uDC00\uD801\uDC01A");
+        check(new StringBuilder(ORIGIN).appendCodePoint('\uFF21'),
+                "\uD801\uDC00\uD801\uDC01\uFF21");
+        assertEquals(new StringBuilder(ORIGIN).charAt(0), '\uD801');
+        assertEquals(new StringBuilder(ORIGIN).codePointAt(0),
+                Character.codePointAt(ORIGIN, 0));
+        assertEquals(new StringBuilder(ORIGIN).codePointAt(1),
+                Character.codePointAt(ORIGIN, 1));
+        assertEquals(new StringBuilder(ORIGIN).codePointBefore(2),
+                Character.codePointAt(ORIGIN, 0));
+        assertEquals(new StringBuilder(ORIGIN).codePointCount(1, 3), 2);
+        check(new StringBuilder(ORIGIN).delete(0, 2), "\uD801\uDC01");
+        check(new StringBuilder(ORIGIN).delete(0, 3), "\uDC01");
+        check(new StringBuilder(ORIGIN).deleteCharAt(1), "\uD801\uD801\uDC01");
+        checkGetChars(new StringBuilder(ORIGIN), 0, 3, new char[] { '\uD801',
+                '\uDC00', '\uD801' });
+        assertEquals(new StringBuilder(ORIGIN).indexOf("\uD801\uDC01"), 2);
+        assertEquals(new StringBuilder(ORIGIN).indexOf("\uDC01"), 3);
+        assertEquals(new StringBuilder(ORIGIN).indexOf("\uFF21"), -1);
+        assertEquals(new StringBuilder(ORIGIN).indexOf("A"), -1);
+        check(new StringBuilder(ORIGIN).insert(0, "\uFF21"),
+                "\uFF21\uD801\uDC00\uD801\uDC01");
+        check(new StringBuilder(ORIGIN).insert(1, "\uFF21"),
+                "\uD801\uFF21\uDC00\uD801\uDC01");
+        check(new StringBuilder(ORIGIN).insert(1, "A"),
+                "\uD801A\uDC00\uD801\uDC01");
+        assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uDC00\uD801"), 1);
+        assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uD801"), 2);
+        assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uFF21"), -1);
+        assertEquals(new StringBuilder(ORIGIN).lastIndexOf("A"), -1);
+        assertEquals(new StringBuilder(ORIGIN).length(), 4);
+        assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(1, 1), 2);
+        assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(0, 1), 2);
+        check(new StringBuilder(ORIGIN).replace(0, 2, "A"), "A\uD801\uDC01");
+        check(new StringBuilder(ORIGIN).replace(0, 3, "A"), "A\uDC01");
+        check(new StringBuilder(ORIGIN).replace(0, 2, "\uFF21"),
+                "\uFF21\uD801\uDC01");
+        check(new StringBuilder(ORIGIN).replace(0, 3, "\uFF21"), "\uFF21\uDC01");
+        check(new StringBuilder(ORIGIN).reverse(), "\uD801\uDC01\uD801\uDC00");
+        checkSetCharAt(new StringBuilder(ORIGIN), 1, '\uDC01',
+                "\uD801\uDC01\uD801\uDC01");
+        checkSetCharAt(new StringBuilder(ORIGIN), 1, 'A', "\uD801A\uD801\uDC01");
+        checkSetLength(new StringBuilder(ORIGIN), 2, "\uD801\uDC00");
+        checkSetLength(new StringBuilder(ORIGIN), 3, "\uD801\uDC00\uD801");
+        check(new StringBuilder(ORIGIN).substring(1, 3), "\uDC00\uD801");
+    }
+
+    /*
+     * Tests for "A\uD801\uDC00\uFF21"
+     */
+    @Test
+    public void testCompactStringForSupplementaryCodePointMixed1() {
+        final String ORIGIN = "A\uD801\uDC00\uFF21";
+        assertEquals(new StringBuilder(ORIGIN).codePointBefore(3),
+                Character.codePointAt(ORIGIN, 1));
+        assertEquals(new StringBuilder(ORIGIN).codePointBefore(2), '\uD801');
+        assertEquals(new StringBuilder(ORIGIN).codePointBefore(1), 'A');
+        assertEquals(new StringBuilder(ORIGIN).codePointCount(0, 3), 2);
+        assertEquals(new StringBuilder(ORIGIN).codePointCount(0, 4), 3);
+        check(new StringBuilder(ORIGIN).delete(0, 1), "\uD801\uDC00\uFF21");
+        check(new StringBuilder(ORIGIN).delete(0, 1).delete(2, 3),
+                "\uD801\uDC00");
+        check(new StringBuilder(ORIGIN).deleteCharAt(3).deleteCharAt(0),
+                "\uD801\uDC00");
+        assertEquals(new StringBuilder(ORIGIN).indexOf("\uFF21"), 3);
+        assertEquals(new StringBuilder(ORIGIN).indexOf("A"), 0);
+        assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uFF21"), 3);
+        assertEquals(new StringBuilder(ORIGIN).lastIndexOf("A"), 0);
+        assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(0, 1), 1);
+        assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(1, 1), 3);
+        check(new StringBuilder(ORIGIN).replace(1, 3, "A"), "AA\uFF21");
+        check(new StringBuilder(ORIGIN).replace(1, 4, "A"), "AA");
+        check(new StringBuilder(ORIGIN).replace(1, 4, ""), "A");
+        check(new StringBuilder(ORIGIN).reverse(), "\uFF21\uD801\uDC00A");
+        checkSetLength(new StringBuilder(ORIGIN), 1, "A");
+        check(new StringBuilder(ORIGIN).substring(0, 1), "A");
+    }
+
+    /*
+     * Tests for "\uD801\uDC00\uFF21A"
+     */
+    @Test
+    public void testCompactStringForSupplementaryCodePointMixed2() {
+        final String ORIGIN = "\uD801\uDC00\uFF21A";
+        assertEquals(new StringBuilder(ORIGIN).codePointBefore(3),
+                Character.codePointAt(ORIGIN, 2));
+        assertEquals(new StringBuilder(ORIGIN).codePointBefore(2),
+                Character.codePointAt(ORIGIN, 0));
+        assertEquals(new StringBuilder(ORIGIN).codePointBefore(1), '\uD801');
+        assertEquals(new StringBuilder(ORIGIN).codePointCount(0, 3), 2);
+        assertEquals(new StringBuilder(ORIGIN).codePointCount(0, 4), 3);
+        check(new StringBuilder(ORIGIN).delete(0, 2), "\uFF21A");
+        check(new StringBuilder(ORIGIN).delete(0, 3), "A");
+        check(new StringBuilder(ORIGIN).deleteCharAt(0).deleteCharAt(0)
+                .deleteCharAt(0), "A");
+        assertEquals(new StringBuilder(ORIGIN).indexOf("A"), 3);
+        assertEquals(new StringBuilder(ORIGIN).delete(0, 3).indexOf("A"), 0);
+        assertEquals(new StringBuilder(ORIGIN).replace(0, 3, "B").indexOf("A"),
+                1);
+        assertEquals(new StringBuilder(ORIGIN).substring(3, 4).indexOf("A"), 0);
+        assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(1, 1), 2);
+        assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(0, 1), 2);
+        assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(2, 1), 3);
+        check(new StringBuilder(ORIGIN).replace(0, 3, "B"), "BA");
+        check(new StringBuilder(ORIGIN).reverse(), "A\uFF21\uD801\uDC00");
+    }
+
+    /*
+     * Tests for "\uD801A\uDC00\uFF21"
+     */
+    @Test
+    public void testCompactStringForSupplementaryCodePointMixed3() {
+        final String ORIGIN = "\uD801A\uDC00\uFF21";
+        assertEquals(new StringBuilder(ORIGIN).codePointAt(1), 'A');
+        assertEquals(new StringBuilder(ORIGIN).codePointAt(3), '\uFF21');
+        assertEquals(new StringBuilder(ORIGIN).codePointBefore(1), '\uD801');
+        assertEquals(new StringBuilder(ORIGIN).codePointBefore(2), 'A');
+        assertEquals(new StringBuilder(ORIGIN).codePointBefore(3), '\uDC00');
+        assertEquals(new StringBuilder(ORIGIN).codePointCount(0, 3), 3);
+        assertEquals(new StringBuilder(ORIGIN).codePointCount(1, 3), 2);
+        assertEquals(new StringBuilder(ORIGIN).delete(0, 1).delete(1, 3)
+                .indexOf("A"), 0);
+        assertEquals(
+                new StringBuilder(ORIGIN).replace(0, 1, "B").replace(2, 4, "C")
+                        .indexOf("A"), 1);
+        assertEquals(new StringBuilder(ORIGIN).substring(1, 4).substring(0, 1)
+                .indexOf("A"), 0);
+        assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(0, 1), 1);
+        assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(1, 1), 2);
+        assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(2, 1), 3);
+        check(new StringBuilder(ORIGIN).reverse(), "\uFF21\uDC00A\uD801");
+    }
+
+    /*
+     * Tests for "A\uDC01\uFF21\uD801"
+     */
+    @Test
+    public void testCompactStringForSupplementaryCodePointMixed4() {
+        final String ORIGIN = "A\uDC01\uFF21\uD801";
+        assertEquals(new StringBuilder(ORIGIN).codePointAt(1), '\uDC01');
+        assertEquals(new StringBuilder(ORIGIN).codePointAt(3), '\uD801');
+        assertEquals(new StringBuilder(ORIGIN).codePointBefore(1), 'A');
+        assertEquals(new StringBuilder(ORIGIN).codePointBefore(2), '\uDC01');
+        assertEquals(new StringBuilder(ORIGIN).codePointBefore(3), '\uFF21');
+        assertEquals(new StringBuilder(ORIGIN).codePointCount(0, 3), 3);
+        assertEquals(new StringBuilder(ORIGIN).codePointCount(1, 3), 2);
+        assertEquals(new StringBuilder(ORIGIN).delete(1, 4).indexOf("A"), 0);
+        assertEquals(new StringBuilder(ORIGIN).replace(1, 4, "B").indexOf("A"),
+                0);
+        assertEquals(new StringBuilder(ORIGIN).substring(0, 1).indexOf("A"), 0);
+        assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(0, 1), 1);
+        assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(1, 1), 2);
+        assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(2, 1), 3);
+        check(new StringBuilder(ORIGIN).reverse(), "\uD801\uFF21\uDC01A");
+    }
+
+    private void checkGetChars(StringBuilder sb, int srcBegin, int srcEnd,
+            char expected[]) {
+        char[] dst = new char[srcEnd - srcBegin];
+        sb.getChars(srcBegin, srcEnd, dst, 0);
+        assertTrue(Arrays.equals(dst, expected));
+    }
+
+    private void checkSetCharAt(StringBuilder sb, int index, char ch,
+            String expected) {
+        sb.setCharAt(index, ch);
+        check(sb, expected);
+    }
+
+    private void checkSetLength(StringBuilder sb, int newLength, String expected) {
+        sb.setLength(newLength);
+        check(sb, expected);
+    }
+
+    private void check(StringBuilder sb, String expected) {
+        check(sb.toString(), expected);
+    }
+
+    private void check(String str, String expected) {
+        assertTrue(str.equals(expected), String.format(
+                "Get (%s) but expect (%s), ", escapeNonASCIIs(str),
+                escapeNonASCIIs(expected)));
+    }
+
+    /*
+     * Because right now system default charset in JPRT environment is only
+     * guaranteed to support ASCII characters in log, so we escape them.
+     */
+    private String escapeNonASCIIs(String str) {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < str.length(); i++) {
+            char c = str.charAt(i);
+            if (c > 0x7F) {
+                sb.append("\\u").append(Integer.toHexString((int) c));
+            } else {
+                sb.append(c);
+            }
+        }
+        return sb.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StringBuilder/CompactStringBuilderSerialization.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,141 @@
+/*
+ * 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.
+ */
+
+import java.io.*;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static jdk.testlibrary.SerializationUtils.*;
+import static org.testng.Assert.*;
+
+/*
+ * @test
+ * @bug 8077559
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.SerializationUtils
+ * @summary Tests Compact String. This one is testing StringBuilder serialization
+ *          among -XX:+CompactStrings/-XX:-CompactStrings/LegacyStringBuilder
+ * @run testng/othervm -XX:+CompactStrings CompactStringBuilderSerialization
+ * @run testng/othervm -XX:-CompactStrings CompactStringBuilderSerialization
+ */
+
+public class CompactStringBuilderSerialization {
+    @DataProvider
+    public Object[][] provider() {
+        return new Object[][] {
+                // every byte array is serialized from corresponding StringBuffer object
+                // by previous JDK(build 1.8.0_45-b14).
+                new Object[] {
+                        new StringBuilder(""),
+                        new byte[] { -84, -19, 0, 5, 115, 114, 0, 23, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 105,
+                                108, 100, 101, 114, 60, -43, -5, 20, 90, 76, 106, -53, 3, 0, 0, 120, 112, 119, 4, 0, 0, 0, 0, 117, 114, 0, 2, 91, 67, -80, 38,
+                                102, -80, -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+                new Object[] {
+                        new StringBuilder("A"),
+                        new byte[] { -84, -19, 0, 5, 115, 114, 0, 23, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 105,
+                                108, 100, 101, 114, 60, -43, -5, 20, 90, 76, 106, -53, 3, 0, 0, 120, 112, 119, 4, 0, 0, 0, 1, 117, 114, 0, 2, 91, 67, -80, 38,
+                                102, -80, -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 17, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+                new Object[] {
+                        new StringBuilder("AB"),
+                        new byte[] { -84, -19, 0, 5, 115, 114, 0, 23, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 105,
+                                108, 100, 101, 114, 60, -43, -5, 20, 90, 76, 106, -53, 3, 0, 0, 120, 112, 119, 4, 0, 0, 0, 2, 117, 114, 0, 2, 91, 67, -80, 38,
+                                102, -80, -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 18, 0, 65, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+                new Object[] {
+                        new StringBuilder("abcdefghijk"),
+                        new byte[] { -84, -19, 0, 5, 115, 114, 0, 23, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 105,
+                                108, 100, 101, 114, 60, -43, -5, 20, 90, 76, 106, -53, 3, 0, 0, 120, 112, 119, 4, 0, 0, 0, 11, 117, 114, 0, 2, 91, 67, -80, 38,
+                                102, -80, -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 27, 0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102, 0, 103, 0, 104, 0,
+                                105, 0, 106, 0, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+                new Object[] {
+                        new StringBuilder("\uff21"),
+                        new byte[] { -84, -19, 0, 5, 115, 114, 0, 23, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 105,
+                                108, 100, 101, 114, 60, -43, -5, 20, 90, 76, 106, -53, 3, 0, 0, 120, 112, 119, 4, 0, 0, 0, 1, 117, 114, 0, 2, 91, 67, -80, 38,
+                                102, -80, -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 17, -1, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+                new Object[] {
+                        new StringBuilder("\uff21\uff22"),
+                        new byte[] { -84, -19, 0, 5, 115, 114, 0, 23, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 105,
+                                108, 100, 101, 114, 60, -43, -5, 20, 90, 76, 106, -53, 3, 0, 0, 120, 112, 119, 4, 0, 0, 0, 2, 117, 114, 0, 2, 91, 67, -80, 38,
+                                102, -80, -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 18, -1, 33, -1, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+                new Object[] {
+                        new StringBuilder("\uff21A\uff21A\uff21A\uff21A\uff21A"),
+                        new byte[] { -84, -19, 0, 5, 115, 114, 0, 23, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 105,
+                                108, 100, 101, 114, 60, -43, -5, 20, 90, 76, 106, -53, 3, 0, 0, 120, 112, 119, 4, 0, 0, 0, 10, 117, 114, 0, 2, 91, 67, -80, 38,
+                                102, -80, -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 26, -1, 33, 0, 65, -1, 33, 0, 65, -1, 33, 0, 65, -1, 33, 0, 65, -1,
+                                33, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+                new Object[] {
+                        new StringBuilder("A\uff21B\uff22C\uff23D\uff24E\uff25F\uff26G\uff27H\uff28"),
+                        new byte[] { -84, -19, 0, 5, 115, 114, 0, 23, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 105,
+                                108, 100, 101, 114, 60, -43, -5, 20, 90, 76, 106, -53, 3, 0, 0, 120, 112, 119, 4, 0, 0, 0, 16, 117, 114, 0, 2, 91, 67, -80, 38,
+                                102, -80, -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 32, 0, 65, -1, 33, 0, 66, -1, 34, 0, 67, -1, 35, 0, 68, -1, 36, 0,
+                                69, -1, 37, 0, 70, -1, 38, 0, 71, -1, 39, 0, 72, -1, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                                0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+                new Object[] {
+                        new StringBuilder("\uff21A\uff22B\uff23C\uff24D\uff25E\uff26F\uff27G\uff28H"),
+                        new byte[] { -84, -19, 0, 5, 115, 114, 0, 23, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 105,
+                                108, 100, 101, 114, 60, -43, -5, 20, 90, 76, 106, -53, 3, 0, 0, 120, 112, 119, 4, 0, 0, 0, 16, 117, 114, 0, 2, 91, 67, -80, 38,
+                                102, -80, -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 32, -1, 33, 0, 65, -1, 34, 0, 66, -1, 35, 0, 67, -1, 36, 0, 68, -1,
+                                37, 0, 69, -1, 38, 0, 70, -1, 39, 0, 71, -1, 40, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                                0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+                new Object[] {
+                        new StringBuilder("\ud801\udc00\ud801\udc01\uff21A"),
+                        new byte[] { -84, -19, 0, 5, 115, 114, 0, 23, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 105,
+                                108, 100, 101, 114, 60, -43, -5, 20, 90, 76, 106, -53, 3, 0, 0, 120, 112, 119, 4, 0, 0, 0, 6, 117, 114, 0, 2, 91, 67, -80, 38,
+                                102, -80, -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 22, -40, 1, -36, 0, -40, 1, -36, 1, -1, 33, 0, 65, 0, 0, 0, 0, 0, 0,
+                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+                new Object[] {
+                        new StringBuilder("\uff21\uff22\uff21\uff22\uff21\uff22\uff21\uff22\uff21\uff22"),
+                        new byte[] { -84, -19, 0, 5, 115, 114, 0, 23, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 105,
+                                108, 100, 101, 114, 60, -43, -5, 20, 90, 76, 106, -53, 3, 0, 0, 120, 112, 119, 4, 0, 0, 0, 10, 117, 114, 0, 2, 91, 67, -80, 38,
+                                102, -80, -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 26, -1, 33, -1, 34, -1, 33, -1, 34, -1, 33, -1, 34, -1, 33, -1, 34,
+                                -1, 33, -1, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } } };
+    }
+
+    /*
+     * Verify serialization works between Compact StringBuilder/Legacy StringBuilder
+     */
+    @Test(dataProvider = "provider")
+    public void test(StringBuilder sbContent, byte[] baInJDK8) throws Exception {
+        // Serialize a StringBuilder object into byte array.
+        byte[] ba = serialize(sbContent);
+        assertEquals(ba, baInJDK8);
+        // Deserialize a StringBuilder object from byte array which is generated by previous JDK(build 1.8.0_45-b14).
+        Object obj = deserialize(ba);
+        assertEquals(obj.getClass(), StringBuilder.class);
+        assertTrue(equals((StringBuilder)obj, sbContent));
+    }
+
+    boolean equals(StringBuilder sb, StringBuilder expected) {
+        if(sb.length() == expected.length()
+                && sb.capacity() == expected.capacity()
+                && sb.toString().equals(expected.toString())) {
+            return true;
+        }
+        return false;
+    }
+}
--- a/jdk/test/java/lang/StringBuilder/Exceptions.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/java/lang/StringBuilder/Exceptions.java	Tue Nov 17 10:29:28 2015 -0800
@@ -94,21 +94,21 @@
 
         System.out.println("StringBuilder.replace(int start, int end, String str)");
         tryCatch("  -1, 2, \" \"",
-                 new StringIndexOutOfBoundsException(-1),
+                 new StringIndexOutOfBoundsException("start -1, end 2, length 7"),
                  new Runnable() {
                 public void run() {
                     StringBuilder sb = new StringBuilder("hilbert");
                     sb.replace(-1, 2, " ");
                 }});
         tryCatch("  7, 8, \" \"",
-                 new StringIndexOutOfBoundsException("start > length()"),
+                 new StringIndexOutOfBoundsException("start 7, end 6, length 6"),
                  new Runnable() {
                 public void run() {
                     StringBuilder sb = new StringBuilder("banach");
                     sb.replace(7, 8, " ");
                 }});
         tryCatch("  2, 1, \" \"",
-                 new StringIndexOutOfBoundsException("start > end"),
+                 new StringIndexOutOfBoundsException("start 2, end 1, length 7"),
                  new Runnable() {
                 public void run() {
                     StringBuilder sb = new StringBuilder("riemann");
--- a/jdk/test/java/net/NetworkInterface/NetworkInterfaceStreamTest.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/java/net/NetworkInterface/NetworkInterfaceStreamTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -24,7 +24,7 @@
 /* @test
  * @bug 8081678
  * @summary Tests for stream returning methods
- * @library ../../util/stream/bootlib
+ * @library ../../util/stream/bootlib/java.base
  * @build java.util.stream.OpTestCase
  * @run testng/othervm NetworkInterfaceStreamTest
  * @run testng/othervm -Djava.net.preferIPv4Stack=true NetworkInterfaceStreamTest
--- a/jdk/test/java/nio/file/Files/StreamLinesTest.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/java/nio/file/Files/StreamLinesTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -23,7 +23,7 @@
 
 /* @test
  * @bug 8072773
- * @library /lib/testlibrary/ ../../../util/stream/bootlib
+ * @library /lib/testlibrary/ ../../../util/stream/bootlib/java.base
  * @build java.util.stream.OpTestCase
  * @build jdk.testlibrary.RandomFactory
  * @run testng/othervm StreamLinesTest
--- a/jdk/test/java/security/PermissionCollection/PermissionCollectionStreamTest.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/java/security/PermissionCollection/PermissionCollectionStreamTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -24,7 +24,7 @@
 /* @test
  * @bug 8081678
  * @summary Tests for stream returning methods
- * @library ../../util/stream/bootlib
+ * @library ../../util/stream/bootlib/java.base
  * @build java.util.stream.OpTestCase
  * @run testng/othervm PermissionCollectionStreamTest
  */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/SecureRandom/DefaultProvider.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ */
+
+import static java.lang.System.out;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
+/**
+ * @test
+ * @bug 8048356
+ * @summary Assert default provider used on all OS for SecureRandom
+ */
+public class DefaultProvider {
+
+    private static final String OS_NAME = System.getProperty("os.name");
+    private static final String SUNOS = "SunOS";
+    private static final String WINDOWS = "Windows";
+
+    public static void main(String[] args) throws NoSuchAlgorithmException {
+        out.println("Operating System: " + OS_NAME);
+
+        /* Test default provider used with constructor */
+        out.println("TEST: Default provider with constructor");
+        SecureRandom secureRandom = new SecureRandom();
+        String provider = secureRandom.getProvider().getName();
+        if (OS_NAME.startsWith(SUNOS)) {
+            if (!provider.startsWith("SunPKCS11-")) {
+                throw new RuntimeException("Unexpected provider name: "
+                        + provider);
+            }
+        } else if (!provider.equals("SUN")) {
+            throw new RuntimeException("Unexpected provider name: "
+                    + provider);
+        }
+        out.println("Passed, default provider with constructor: " + provider);
+
+        /* Test default provider with getInstance(String algorithm) */
+        out.println("TEST: SHA1PRNG supported on all platforms by SUN provider");
+        String algorithm = "SHA1PRNG";
+        provider = "SUN";
+
+        SecureRandom instance = SecureRandom.getInstance(algorithm);
+        assertInstance(instance, algorithm, provider);
+        out.println("Passed.");
+
+        if (!OS_NAME.startsWith(WINDOWS)) {
+            out.println("TEST: NativePRNG supported on all platforms"
+                    + "(except Windows), by SUN provider");
+            algorithm = "NativePRNG";
+            provider = "SUN";
+        } else {
+            out.println(
+                    "TEST: Windows-PRNG supported on windows by SunMSCAPI provider");
+            algorithm = "Windows-PRNG";
+            provider = "SunMSCAPI";
+        }
+        instance = SecureRandom.getInstance(algorithm);
+        assertInstance(instance, algorithm, provider);
+        out.println("Passed.");
+
+        if (OS_NAME.startsWith(SUNOS)) {
+            out.println(
+                    "TEST: PKCS11 is supported on Solaris by SunPKCS11 provider");
+            algorithm = "PKCS11";
+            provider = "SunPKCS11-Solaris";
+            instance = SecureRandom.getInstance(algorithm);
+            assertInstance(instance, algorithm, provider);
+            out.println("Passed.");
+        }
+    }
+
+    private static void assertInstance(SecureRandom instance,
+            String expectedAlgorithm,
+            String expectedProvider) {
+        if (instance != null) {
+            if (!expectedAlgorithm.equalsIgnoreCase(instance.getAlgorithm())) {
+                throw new RuntimeException("Expected algorithm:"
+                        + expectedAlgorithm + " actual: " + instance.getAlgorithm());
+            }
+
+            if (!expectedProvider.equalsIgnoreCase(instance.getProvider().getName())) {
+                throw new RuntimeException("Expected provider: "
+                        + expectedProvider + " actual: "
+                        + instance.getProvider().getName());
+            }
+        } else {
+            throw new RuntimeException("Secure instance is not created");
+        }
+    }
+}
--- a/jdk/test/java/time/tck/java/time/TCKClock_Tick.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/java/time/tck/java/time/TCKClock_Tick.java	Tue Nov 17 10:29:28 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
@@ -160,6 +160,17 @@
     }
 
     //-----------------------------------------------------------------------
+    public void test_tickMillis_ZoneId() throws Exception {
+        Clock test = Clock.tickMillis(PARIS);
+        assertEquals(test.getZone(), PARIS);
+        assertEquals(test.instant().getNano() % 1000_000, 0);
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void test_tickMillis_ZoneId_nullZoneId() {
+        Clock.tickMillis(null);
+    }
+    //-----------------------------------------------------------------------
     public void test_tickSeconds_ZoneId() throws Exception {
         Clock test = Clock.tickSeconds(PARIS);
         assertEquals(test.getZone(), PARIS);
--- a/jdk/test/java/time/tck/java/time/TCKDuration.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/java/time/tck/java/time/TCKDuration.java	Tue Nov 17 10:29:28 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
@@ -521,6 +521,8 @@
                 {"PT-123456789S", -123456789, 0},
                 {"PT" + Long.MIN_VALUE + "S", Long.MIN_VALUE, 0},
 
+
+                {"PT0.1S", 0, 100000000},
                 {"PT1.1S", 1, 100000000},
                 {"PT1.12S", 1, 120000000},
                 {"PT1.123S", 1, 123000000},
@@ -531,6 +533,7 @@
                 {"PT1.12345678S", 1, 123456780},
                 {"PT1.123456789S", 1, 123456789},
 
+                {"PT-0.1S", -1, 1000000000 - 100000000},
                 {"PT-1.1S", -2, 1000000000 - 100000000},
                 {"PT-1.12S", -2, 1000000000 - 120000000},
                 {"PT-1.123S", -2, 1000000000 - 123000000},
@@ -544,6 +547,24 @@
                 {"PT" + Long.MAX_VALUE + ".123456789S", Long.MAX_VALUE, 123456789},
                 {"PT" + Long.MIN_VALUE + ".000000000S", Long.MIN_VALUE, 0},
 
+                {"PT12M", 12 * 60, 0},
+                {"PT12M0.35S", 12 * 60, 350000000},
+                {"PT12M1.35S", 12 * 60 + 1, 350000000},
+                {"PT12M-0.35S", 12 * 60 - 1, 1000000000 - 350000000},
+                {"PT12M-1.35S", 12 * 60 - 2, 1000000000 - 350000000},
+
+                {"PT12H", 12 * 3600, 0},
+                {"PT12H0.35S", 12 * 3600, 350000000},
+                {"PT12H1.35S", 12 * 3600 + 1, 350000000},
+                {"PT12H-0.35S", 12 * 3600 - 1, 1000000000 - 350000000},
+                {"PT12H-1.35S", 12 * 3600 - 2, 1000000000 - 350000000},
+
+                {"P12D", 12 * 24 * 3600, 0},
+                {"P12DT0.35S", 12 * 24 * 3600, 350000000},
+                {"P12DT1.35S", 12 * 24 * 3600 + 1, 350000000},
+                {"P12DT-0.35S", 12 * 24 * 3600 - 1, 1000000000 - 350000000},
+                {"P12DT-1.35S", 12 * 24 * 3600 - 2, 1000000000 - 350000000},
+
                 {"PT01S", 1, 0},
                 {"PT001S", 1, 0},
                 {"PT000S", 0, 0},
--- a/jdk/test/java/time/tck/java/time/TCKLocalDate.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/java/time/tck/java/time/TCKLocalDate.java	Tue Nov 17 10:29:28 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
@@ -86,8 +86,6 @@
 import static org.testng.Assert.assertSame;
 import static org.testng.Assert.assertTrue;
 
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
 import java.time.Clock;
 import java.time.DateTimeException;
 import java.time.DayOfWeek;
@@ -104,6 +102,7 @@
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
 import java.time.chrono.IsoChronology;
+import java.time.chrono.IsoEra;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeParseException;
 import java.time.temporal.ChronoField;
@@ -135,6 +134,7 @@
 
     private static final ZoneOffset OFFSET_PONE = ZoneOffset.ofHours(1);
     private static final ZoneOffset OFFSET_PTWO = ZoneOffset.ofHours(2);
+    private static final ZoneOffset OFFSET_MTWO = ZoneOffset.ofHours(-2);
     private static final ZoneId ZONE_PARIS = ZoneId.of("Europe/Paris");
     private static final ZoneId ZONE_GAZA = ZoneId.of("Asia/Gaza");
 
@@ -475,6 +475,48 @@
         return date.withDayOfMonth(date.getMonth().length(isIsoLeap(date.getYear())));
     }
 
+     //-----------------------------------------------------------------------
+     // ofInstant()
+     //-----------------------------------------------------------------------
+     @DataProvider(name="instantFactory")
+     Object[][] data_instantFactory() {
+         return new Object[][] {
+                 {Instant.ofEpochSecond(86400 + 3600 + 120 + 4, 500), ZONE_PARIS, LocalDate.of(1970, 1, 2)},
+                 {Instant.ofEpochSecond(86400 + 3600 + 120 + 4, 500), OFFSET_MTWO, LocalDate.of(1970, 1, 1)},
+                 {Instant.ofEpochSecond(-86400 + 4, 500), OFFSET_PTWO, LocalDate.of(1969, 12, 31)},
+                 {OffsetDateTime.of(LocalDateTime.of(Year.MIN_VALUE, 1, 1, 0, 0), ZoneOffset.UTC).toInstant(),
+                         ZoneOffset.UTC, LocalDate.MIN},
+                 {OffsetDateTime.of(LocalDateTime.of(Year.MAX_VALUE, 12, 31, 23, 59, 59, 999_999_999), ZoneOffset.UTC).toInstant(),
+                         ZoneOffset.UTC, LocalDate.MAX},
+         };
+     }
+
+     @Test(dataProvider="instantFactory")
+     public void factory_ofInstant(Instant instant, ZoneId zone, LocalDate expected) {
+         LocalDate test = LocalDate.ofInstant(instant, zone);
+         assertEquals(test, expected);
+     }
+
+     @Test(expectedExceptions=DateTimeException.class)
+     public void factory_ofInstant_instantTooBig() {
+         LocalDate.ofInstant(Instant.MAX, OFFSET_PONE);
+     }
+
+     @Test(expectedExceptions=DateTimeException.class)
+     public void factory_ofInstant_instantTooSmall() {
+         LocalDate.ofInstant(Instant.MIN, OFFSET_PONE);
+     }
+
+     @Test(expectedExceptions=NullPointerException.class)
+     public void factory_ofInstant_nullInstant() {
+         LocalDate.ofInstant((Instant) null, ZONE_GAZA);
+     }
+
+     @Test(expectedExceptions=NullPointerException.class)
+     public void factory_ofInstant_nullZone() {
+         LocalDate.ofInstant(Instant.EPOCH, (ZoneId) null);
+     }
+
     //-----------------------------------------------------------------------
     // ofEpochDay()
     //-----------------------------------------------------------------------
@@ -2285,4 +2327,13 @@
         return LocalDate.of(year, month, day);
     }
 
+    //-----------------------------------------------------------------
+    // getEra()
+    // ----------------------------------------------------------------
+    @Test
+    public void test_getEra() {
+        IsoEra isoEra = LocalDate.MAX.getEra();
+        assertSame(isoEra,IsoEra.CE);
+        assertSame(LocalDate.MIN.getEra(),IsoEra.BCE);
+    }
 }
--- a/jdk/test/java/time/tck/java/time/TCKLocalTime.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/java/time/tck/java/time/TCKLocalTime.java	Tue Nov 17 10:29:28 2015 -0800
@@ -102,6 +102,7 @@
 import java.time.OffsetDateTime;
 import java.time.OffsetTime;
 import java.time.Period;
+import java.time.Year;
 import java.time.ZoneId;
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
@@ -137,6 +138,7 @@
 public class TCKLocalTime extends AbstractDateTimeTest {
 
     private static final ZoneOffset OFFSET_PTWO = ZoneOffset.ofHours(2);
+    private static final ZoneOffset OFFSET_MTWO = ZoneOffset.ofHours(-2);
     private static final ZoneId ZONE_PARIS = ZoneId.of("Europe/Paris");
 
     private LocalTime TEST_12_30_40_987654321;
@@ -420,6 +422,38 @@
         LocalTime.of(0, 0, 0, 1000000000);
     }
 
+     //-----------------------------------------------------------------------
+     // ofInstant()
+     //-----------------------------------------------------------------------
+     @DataProvider(name="instantFactory")
+     Object[][] data_instantFactory() {
+         return new Object[][] {
+                 {Instant.ofEpochSecond(86400 + 3600 + 120 + 4, 500), ZONE_PARIS, LocalTime.of(2, 2, 4, 500)},
+                 {Instant.ofEpochSecond(86400 + 3600 + 120 + 4, 500), OFFSET_MTWO, LocalTime.of(23, 2, 4, 500)},
+                 {Instant.ofEpochSecond(-86400 + 4, 500), OFFSET_PTWO, LocalTime.of(2, 0, 4, 500)},
+                 {OffsetDateTime.of(LocalDateTime.of(Year.MIN_VALUE, 1, 1, 0, 0), ZoneOffset.UTC).toInstant(),
+                         ZoneOffset.UTC, LocalTime.MIN},
+                 {OffsetDateTime.of(LocalDateTime.of(Year.MAX_VALUE, 12, 31, 23, 59, 59, 999_999_999), ZoneOffset.UTC).toInstant(),
+                         ZoneOffset.UTC, LocalTime.MAX},
+         };
+     }
+
+     @Test(dataProvider="instantFactory")
+     public void factory_ofInstant(Instant instant, ZoneId zone, LocalTime expected) {
+         LocalTime test = LocalTime.ofInstant(instant, zone);
+         assertEquals(test, expected);
+     }
+
+     @Test(expectedExceptions=NullPointerException.class)
+     public void factory_ofInstant_nullInstant() {
+         LocalTime.ofInstant((Instant) null, ZONE_PARIS);
+     }
+
+     @Test(expectedExceptions=NullPointerException.class)
+     public void factory_ofInstant_nullZone() {
+         LocalTime.ofInstant(Instant.EPOCH, (ZoneId) null);
+     }
+
     //-----------------------------------------------------------------------
     // ofSecondOfDay(long)
     //-----------------------------------------------------------------------
--- a/jdk/test/java/time/tck/java/time/format/TCKZoneIdPrinterParser.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/java/time/tck/java/time/format/TCKZoneIdPrinterParser.java	Tue Nov 17 10:29:28 2015 -0800
@@ -156,6 +156,7 @@
                 {"UTC", 3, -1, ZoneId.of("UTC"), false},
                 {"UT", 2, -1, ZoneId.of("UT"), false},
                 {"GMT", 3, -1, ZoneId.of("GMT"), false},
+                {"GMT0", 4, -1, ZoneId.of("GMT0"), false},
 
                 {"+00:00", 6, -1, ZoneOffset.UTC, true},
                 {"UTC+00:00", 9, -1, ZoneId.of("UTC"), false},
--- a/jdk/test/java/time/test/java/time/temporal/TestIsoWeekFields.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/java/time/test/java/time/temporal/TestIsoWeekFields.java	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014,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
@@ -121,6 +121,14 @@
         assertEquals(IsoFields.WEEK_BASED_YEAR.isSupportedBy(ThaiBuddhistDate.now()), false);
     }
 
+    @Test
+    public void test_Unit_isSupportedBy_ISO() {
+        assertEquals(IsoFields.WEEK_BASED_YEARS.isSupportedBy(LocalDate.now()),true);
+        assertEquals(IsoFields.WEEK_BASED_YEARS.isSupportedBy(ThaiBuddhistDate.now()),false);
+        assertEquals(IsoFields.QUARTER_YEARS.isSupportedBy(LocalDate.now()),true);
+        assertEquals(IsoFields.QUARTER_YEARS.isSupportedBy(ThaiBuddhistDate.now()),false);
+    }
+
     @Test(dataProvider = "fields")
     public void test_WBY_range(TemporalField weekField, TemporalField yearField) {
         assertEquals(yearField.range(), ValueRange.of(Year.MIN_VALUE, Year.MAX_VALUE));
--- a/jdk/test/java/util/Arrays/ArraysEqCmpTest.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/java/util/Arrays/ArraysEqCmpTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8033148
+ * @bug 8033148 8141409
  * @summary tests for array equals and compare
  * @run testng ArraysEqCmpTest
 */
@@ -312,6 +312,8 @@
                 return Integer.compare(b, a);
             };
 
+            final MethodHandle eqc;
+            final MethodHandle eqcr;
             final MethodHandle cmpc;
             final MethodHandle cmpcr;
             final MethodHandle mismatchc;
@@ -327,6 +329,8 @@
                             int.class, Object[].class, int.class, int.class,
                             Object[].class, int.class, int.class, Comparator.class);
 
+                    eqc = l.findStatic(Arrays.class, "equals", cmpt.changeReturnType(boolean.class));
+                    eqcr = l.findStatic(Arrays.class, "equals", cmprt.changeReturnType(boolean.class));
                     cmpc = l.findStatic(Arrays.class, "compare", cmpt);
                     cmpcr = l.findStatic(Arrays.class, "compare", cmprt);
                     mismatchc = l.findStatic(Arrays.class, "mismatch", cmpt);
@@ -338,6 +342,33 @@
             }
 
             @Override
+            boolean equals(Object a, Object b) {
+                try {
+                    return (boolean) eqc.invoke(a, b, c);
+                }
+                catch (RuntimeException | Error e) {
+                    throw e;
+                }
+                catch (Throwable t) {
+                    throw new Error(t);
+                }
+            }
+
+            @Override
+            boolean equals(Object a, int aFromIndex, int aToIndex,
+                           Object b, int bFromIndex, int bToIndex) {
+                try {
+                    return (boolean) eqcr.invoke(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex, c);
+                }
+                catch (RuntimeException | Error e) {
+                    throw e;
+                }
+                catch (Throwable t) {
+                    throw new Error(t);
+                }
+            }
+
+            @Override
             int compare(Object a, Object b) {
                 try {
                     return (int) cmpc.invoke(a, b, c);
@@ -1002,10 +1033,12 @@
                         continue;
 
                     if (o3 == null) {
+                        testNPE(() -> Arrays.equals(o1, o2, o3));
                         testNPE(() -> Arrays.compare(o1, o2, o3));
                         testNPE(() -> Arrays.mismatch(o1, o2, o3));
                     }
 
+                    testNPE(() -> Arrays.equals(o1, 0, 0, o2, 0, 0, o3));
                     testNPE(() -> Arrays.compare(o1, 0, 0, o2, 0, 0, o3));
                     testNPE(() -> Arrays.mismatch(o1, 0, 0, o2, 0, 0, o3));
                 }
--- a/jdk/test/java/util/Arrays/TimSortStackSize2.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/java/util/Arrays/TimSortStackSize2.java	Tue Nov 17 10:29:28 2015 -0800
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8072909
- * @library /lib/testlibrary /../../test/lib
+ * @library /lib/testlibrary /test/lib
  * @build jdk.testlibrary.*
  * @build TimSortStackSize2
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
--- a/jdk/test/java/util/Objects/BasicObjectsTest.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/java/util/Objects/BasicObjectsTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -241,12 +241,12 @@
         String nonNullString = "non-null";
 
         // Confirm the compile time return type matches
-        String result = Objects.nonNullElse(nullString, defString);
+        String result = Objects.requireNonNullElse(nullString, defString);
         errors += (result == defString) ? 0 : 1;
-        errors += (Objects.nonNullElse(nonNullString, defString) == nonNullString) ? 0 : 1;
-        errors += (Objects.nonNullElse(nonNullString, null) == nonNullString) ? 0 : 1;
+        errors += (Objects.requireNonNullElse(nonNullString, defString) == nonNullString) ? 0 : 1;
+        errors += (Objects.requireNonNullElse(nonNullString, null) == nonNullString) ? 0 : 1;
         try {
-            Objects.nonNullElse(null, null);
+            Objects.requireNonNullElse(null, null);
             errors += 1;
         } catch (NullPointerException npe) {
             // expected
@@ -254,20 +254,20 @@
         }
 
 
-        // Test nonNullElseGet with a supplier
-        errors += (Objects.nonNullElseGet(nullString, () -> defString) == defString) ? 0 : 1;
-        errors += (Objects.nonNullElseGet(nonNullString, () -> defString) == nonNullString) ? 0 : 1;
-        errors += (Objects.nonNullElseGet(nonNullString, () -> null) == nonNullString) ? 0 : 1;
+        // Test requireNonNullElseGet with a supplier
+        errors += (Objects.requireNonNullElseGet(nullString, () -> defString) == defString) ? 0 : 1;
+        errors += (Objects.requireNonNullElseGet(nonNullString, () -> defString) == nonNullString) ? 0 : 1;
+        errors += (Objects.requireNonNullElseGet(nonNullString, () -> null) == nonNullString) ? 0 : 1;
 
         try {
-            Objects.nonNullElseGet(null, () -> null);
+            Objects.requireNonNullElseGet(null, () -> null);
             errors += 1;
         } catch (NullPointerException npe) {
             // expected
             errors += npe.getMessage().equals("supplier.get()") ? 0 : 1;
         }
         try {       // supplier is null
-            Objects.nonNullElseGet(null, null);
+            Objects.requireNonNullElseGet(null, null);
             errors += 1;
         } catch (NullPointerException npe) {
             // expected
--- a/jdk/test/java/util/Objects/CheckIndex.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/java/util/Objects/CheckIndex.java	Tue Nov 17 10:29:28 2015 -0800
@@ -25,7 +25,7 @@
  * @test
  * @summary IndexOutOfBoundsException check index tests
  * @run testng CheckIndex
- * @bug 8135248
+ * @bug 8135248 8142493
  */
 
 import org.testng.annotations.DataProvider;
@@ -54,6 +54,15 @@
         };
     }
 
+    static BiFunction<Integer, Integer, AssertingOutOfBoundsException> assertingOutOfBoundsReturnNull(
+            int expFromIndex, int expToIndexOrSizeOrLength) {
+        return (fromIndex, toIndexOrSizeorLength) -> {
+            assertEquals(fromIndex, Integer.valueOf(expFromIndex));
+            assertEquals(toIndexOrSizeorLength, Integer.valueOf(expToIndexOrSizeOrLength));
+            return null;
+        };
+    }
+
     static final int[] VALUES = {0, 1, Integer.MAX_VALUE - 1, Integer.MAX_VALUE, -1, Integer.MIN_VALUE + 1, Integer.MIN_VALUE};
 
     @DataProvider
@@ -95,6 +104,8 @@
         check.accept(AssertingOutOfBoundsException.class,
                      () -> Objects.checkIndex(index, length, assertingOutOfBounds(index, length)));
         check.accept(IndexOutOfBoundsException.class,
+                     () -> Objects.checkIndex(index, length, assertingOutOfBoundsReturnNull(index, length)));
+        check.accept(IndexOutOfBoundsException.class,
                      () -> Objects.checkIndex(index, length, null));
         check.accept(IndexOutOfBoundsException.class,
                      () -> Objects.checkIndex(index, length));
@@ -140,6 +151,8 @@
         check.accept(AssertingOutOfBoundsException.class,
                      () -> Objects.checkFromToIndex(fromIndex, toIndex, length, assertingOutOfBounds(fromIndex, toIndex)));
         check.accept(IndexOutOfBoundsException.class,
+                     () -> Objects.checkFromToIndex(fromIndex, toIndex, length, assertingOutOfBoundsReturnNull(fromIndex, toIndex)));
+        check.accept(IndexOutOfBoundsException.class,
                      () -> Objects.checkFromToIndex(fromIndex, toIndex, length, null));
         check.accept(IndexOutOfBoundsException.class,
                      () -> Objects.checkFromToIndex(fromIndex, toIndex, length));
@@ -192,6 +205,8 @@
         check.accept(AssertingOutOfBoundsException.class,
                      () -> Objects.checkFromIndexSize(fromIndex, size, length, assertingOutOfBounds(fromIndex, size)));
         check.accept(IndexOutOfBoundsException.class,
+                     () -> Objects.checkFromIndexSize(fromIndex, size, length, assertingOutOfBoundsReturnNull(fromIndex, size)));
+        check.accept(IndexOutOfBoundsException.class,
                      () -> Objects.checkFromIndexSize(fromIndex, size, length, null));
         check.accept(IndexOutOfBoundsException.class,
                      () -> Objects.checkFromIndexSize(fromIndex, size, length));
--- a/jdk/test/java/util/Scanner/ScannerStreamTest.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/java/util/Scanner/ScannerStreamTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -46,7 +46,7 @@
  * @test
  * @bug 8072722
  * @summary Tests of stream support in java.util.Scanner
- * @library ../stream/bootlib
+ * @library ../stream/bootlib/java.base
  * @build java.util.stream.OpTestCase
  * @run testng/othervm ScannerStreamTest
  */
--- a/jdk/test/java/util/concurrent/Phaser/Basic.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/java/util/concurrent/Phaser/Basic.java	Tue Nov 17 10:29:28 2015 -0800
@@ -34,6 +34,7 @@
 /*
  * @test
  * @bug 6445158
+ * @key intermittent
  * @summary Basic tests for Phaser
  * @author Chris Hegarty
  */
--- a/jdk/test/java/util/regex/PatternStreamTest.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/java/util/regex/PatternStreamTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -25,7 +25,7 @@
  * @test
  * @bug 8016846 8024341 8071479
  * @summary Unit tests stream and lambda-based methods on Pattern and Matcher
- * @library ../stream/bootlib
+ * @library ../stream/bootlib/java.base
  * @build java.util.stream.OpTestCase
  * @run testng/othervm PatternStreamTest
  */
--- a/jdk/test/java/util/stream/bootlib/TEST.properties	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/java/util/stream/bootlib/TEST.properties	Tue Nov 17 10:29:28 2015 -0800
@@ -1,3 +1,3 @@
 # This file identifies root(s) of the test-ng hierarchy.
 
-bootclasspath.dirs = .
+bootclasspath.dirs = java.base
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/CollectorOps.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,113 @@
+/*
+ * 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 java.util.stream;
+
+import org.testng.Assert;
+
+import java.util.Spliterator;
+import java.util.function.IntFunction;
+
+/** Test helper class for java.util.stream test framework */
+public final class CollectorOps {
+    private CollectorOps() { }
+
+    public static <E_IN> StatefulTestOp<E_IN> collector() {
+        return new StatefulCollector<>(0, StreamShape.REFERENCE);
+    }
+
+    /* Utility classes for collecting output of intermediate pipeline stages */
+    public static class StatefulCollector<E_IN> implements StatefulTestOp<E_IN> {
+        private final int opFlags;
+        private final StreamShape inputShape;
+
+        public StatefulCollector(int opFlags, StreamShape inputShape) {
+            this.opFlags = opFlags;
+            this.inputShape = inputShape;
+        }
+
+        @Override
+        public StreamShape inputShape() {
+            return inputShape;
+        }
+
+        @Override
+        public StreamShape outputShape() {
+            return inputShape;
+        }
+
+        @Override
+        public int opGetFlags() {
+            return opFlags;
+        }
+
+        @Override
+        public Sink<E_IN> opWrapSink(int flags, boolean parallel, Sink<E_IN> sink) {
+            return sink;
+        }
+
+        @Override
+        public <P_IN> Node<E_IN> opEvaluateParallel(PipelineHelper<E_IN> helper,
+                                                    Spliterator<P_IN> spliterator,
+                                                    IntFunction<E_IN[]> generator) {
+            return helper.evaluate(spliterator, false, generator);
+        }
+    }
+
+    public static class TestParallelSizedOp<T> extends StatefulCollector<T> {
+        public TestParallelSizedOp() {
+            this(StreamShape.REFERENCE);
+        }
+
+        protected TestParallelSizedOp(StreamShape shape) {
+            super(0, shape);
+        }
+
+        @Override
+        public <P_IN> Node<T> opEvaluateParallel(PipelineHelper<T> helper,
+                                                 Spliterator<P_IN> spliterator,
+                                                 IntFunction<T[]> generator) {
+            int flags = helper.getStreamAndOpFlags();
+
+            Assert.assertTrue(StreamOpFlag.SIZED.isKnown(flags));
+            return super.opEvaluateParallel(helper, spliterator, generator);
+        }
+
+        public static class OfInt extends TestParallelSizedOp<Integer> {
+            public OfInt() {
+                super(StreamShape.INT_VALUE);
+            }
+        }
+
+        public static class OfLong extends TestParallelSizedOp<Long> {
+            public OfLong() {
+                super(StreamShape.LONG_VALUE);
+            }
+        }
+
+        public static class OfDouble extends TestParallelSizedOp<Double> {
+            public OfDouble() {
+                super(StreamShape.DOUBLE_VALUE);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/DefaultMethodStreams.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,984 @@
+/*
+ * 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.
+ */
+package java.util.stream;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Comparator;
+import java.util.DoubleSummaryStatistics;
+import java.util.IntSummaryStatistics;
+import java.util.Iterator;
+import java.util.LongSummaryStatistics;
+import java.util.Optional;
+import java.util.OptionalDouble;
+import java.util.OptionalInt;
+import java.util.OptionalLong;
+import java.util.PrimitiveIterator;
+import java.util.Set;
+import java.util.Spliterator;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.BinaryOperator;
+import java.util.function.Consumer;
+import java.util.function.DoubleBinaryOperator;
+import java.util.function.DoubleConsumer;
+import java.util.function.DoubleFunction;
+import java.util.function.DoublePredicate;
+import java.util.function.DoubleToIntFunction;
+import java.util.function.DoubleToLongFunction;
+import java.util.function.DoubleUnaryOperator;
+import java.util.function.Function;
+import java.util.function.IntBinaryOperator;
+import java.util.function.IntConsumer;
+import java.util.function.IntFunction;
+import java.util.function.IntPredicate;
+import java.util.function.IntToDoubleFunction;
+import java.util.function.IntToLongFunction;
+import java.util.function.IntUnaryOperator;
+import java.util.function.LongBinaryOperator;
+import java.util.function.LongConsumer;
+import java.util.function.LongFunction;
+import java.util.function.LongPredicate;
+import java.util.function.LongToDoubleFunction;
+import java.util.function.LongToIntFunction;
+import java.util.function.LongUnaryOperator;
+import java.util.function.ObjDoubleConsumer;
+import java.util.function.ObjIntConsumer;
+import java.util.function.ObjLongConsumer;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+import java.util.function.ToDoubleFunction;
+
+import java.util.function.ToIntFunction;
+import java.util.function.ToLongFunction;
+
+import static java.util.stream.Collectors.*;
+
+public final class DefaultMethodStreams {
+
+    static {
+        // Verify that default methods are not overridden
+        verify(DefaultMethodRefStream.class);
+        verify(DefaultMethodIntStream.class);
+        verify(DefaultMethodLongStream.class);
+        verify(DefaultMethodDoubleStream.class);
+    }
+
+    static void verify(Class<?> del) {
+        // Find the stream interface
+        Class<?> s = Stream.of(del.getInterfaces())
+                .filter(c -> BaseStream.class.isAssignableFrom(c))
+                .findFirst().get();
+
+        // Get all default methods on the stream class
+        Set<String> dms = Stream.of(s.getMethods())
+                .filter(m -> !Modifier.isStatic(m.getModifiers()))
+                .filter(m -> !m.isBridge())
+                .filter(Method::isDefault)
+                .map(Method::getName)
+                .collect(toSet());
+
+        // Get all methods on the delegating class
+        Set<String> ims = Stream.of(del.getMethods())
+                .filter(m -> !Modifier.isStatic(m.getModifiers()))
+                .filter(m -> m.getDeclaringClass() == del)
+                .map(Method::getName)
+                .collect(toSet());
+
+        if (ims.stream().anyMatch(dms::contains)) {
+            throw new AssertionError(String.format("%s overrides default methods of %s\n", del, s));
+        }
+    }
+
+    /**
+     * Creates a stream that for the next operation either delegates to
+     * a default method on {@link Stream}, if present for that operation,
+     * otherwise delegates to an underlying stream.
+     *
+     * @param s the underlying stream to be delegated to for non-default
+     * methods.
+     * @param <T> the type of the stream elements
+     * @return the delegating stream
+     */
+    public static <T> Stream<T> delegateTo(Stream<T> s) {
+        return new DefaultMethodRefStream<>(s);
+    }
+
+    /**
+     * Creates a stream that for the next operation either delegates to
+     * a default method on {@link IntStream}, if present for that operation,
+     * otherwise delegates to an underlying stream.
+     *
+     * @param s the underlying stream to be delegated to for non-default
+     * methods.
+     * @return the delegating stream
+     */
+    public static IntStream delegateTo(IntStream s) {
+        return new DefaultMethodIntStream(s);
+    }
+
+    /**
+     * Creates a stream that for the next operation either delegates to
+     * a default method on {@link LongStream}, if present for that operation,
+     * otherwise delegates to an underlying stream.
+     *
+     * @param s the underlying stream to be delegated to for non-default
+     * methods.
+     * @return the delegating stream
+     */
+    public static LongStream delegateTo(LongStream s) {
+        return new DefaultMethodLongStream(s);
+    }
+
+    /**
+     * Creates a stream that for the next operation either delegates to
+     * a default method on {@link DoubleStream}, if present for that operation,
+     * otherwise delegates to an underlying stream.
+     *
+     * @param s the underlying stream to be delegated to for non-default
+     * methods.
+     * @return the delegating stream
+     */
+    public static DoubleStream delegateTo(DoubleStream s) {
+        return new DefaultMethodDoubleStream(s);
+    }
+
+    /**
+     * A stream that delegates the next operation to a default method, if
+     * present, or to the same operation of an underlying stream.
+     *
+     * @param <T> the type of the stream elements
+     */
+    static final class DefaultMethodRefStream<T> implements Stream<T> {
+        final Stream<T> s;
+
+        DefaultMethodRefStream(Stream<T> s) {
+            this.s = s;
+        }
+
+
+        // Delegating non-default methods
+
+        @Override
+        public Stream<T> filter(Predicate<? super T> predicate) {
+            return s.filter(predicate);
+        }
+
+        @Override
+        public <R> Stream<R> map(Function<? super T, ? extends R> mapper) {
+            return s.map(mapper);
+        }
+
+        @Override
+        public IntStream mapToInt(ToIntFunction<? super T> mapper) {
+            return s.mapToInt(mapper);
+        }
+
+        @Override
+        public LongStream mapToLong(ToLongFunction<? super T> mapper) {
+            return s.mapToLong(mapper);
+        }
+
+        @Override
+        public DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper) {
+            return s.mapToDouble(mapper);
+        }
+
+        @Override
+        public <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper) {
+            return s.flatMap(mapper);
+        }
+
+        @Override
+        public IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper) {
+            return s.flatMapToInt(mapper);
+        }
+
+        @Override
+        public LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper) {
+            return s.flatMapToLong(mapper);
+        }
+
+        @Override
+        public DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper) {
+            return s.flatMapToDouble(mapper);
+        }
+
+        @Override
+        public Stream<T> distinct() {
+            return s.distinct();
+        }
+
+        @Override
+        public Stream<T> sorted() {
+            return s.sorted();
+        }
+
+        @Override
+        public Stream<T> sorted(Comparator<? super T> comparator) {
+            return s.sorted(comparator);
+        }
+
+        @Override
+        public Stream<T> peek(Consumer<? super T> action) {
+            return s.peek(action);
+        }
+
+        @Override
+        public Stream<T> limit(long maxSize) {
+            return s.limit(maxSize);
+        }
+
+        @Override
+        public Stream<T> skip(long n) {
+            return s.skip(n);
+        }
+
+        @Override
+        public void forEach(Consumer<? super T> action) {
+            s.forEach(action);
+        }
+
+        @Override
+        public void forEachOrdered(Consumer<? super T> action) {
+            s.forEachOrdered(action);
+        }
+
+        @Override
+        public Object[] toArray() {
+            return s.toArray();
+        }
+
+        @Override
+        public <A> A[] toArray(IntFunction<A[]> generator) {
+            return s.toArray(generator);
+        }
+
+        @Override
+        public T reduce(T identity, BinaryOperator<T> accumulator) {
+            return s.reduce(identity, accumulator);
+        }
+
+        @Override
+        public Optional<T> reduce(BinaryOperator<T> accumulator) {
+            return s.reduce(accumulator);
+        }
+
+        @Override
+        public <U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner) {
+            return s.reduce(identity, accumulator, combiner);
+        }
+
+        @Override
+        public <R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner) {
+            return s.collect(supplier, accumulator, combiner);
+        }
+
+        @Override
+        public <R, A> R collect(Collector<? super T, A, R> collector) {
+            return s.collect(collector);
+        }
+
+        @Override
+        public Optional<T> min(Comparator<? super T> comparator) {
+            return s.min(comparator);
+        }
+
+        @Override
+        public Optional<T> max(Comparator<? super T> comparator) {
+            return s.max(comparator);
+        }
+
+        @Override
+        public long count() {
+            return s.count();
+        }
+
+        @Override
+        public boolean anyMatch(Predicate<? super T> predicate) {
+            return s.anyMatch(predicate);
+        }
+
+        @Override
+        public boolean allMatch(Predicate<? super T> predicate) {
+            return s.allMatch(predicate);
+        }
+
+        @Override
+        public boolean noneMatch(Predicate<? super T> predicate) {
+            return s.noneMatch(predicate);
+        }
+
+        @Override
+        public Optional<T> findFirst() {
+            return s.findFirst();
+        }
+
+        @Override
+        public Optional<T> findAny() {
+            return s.findAny();
+        }
+
+        @Override
+        public Iterator<T> iterator() {
+            return s.iterator();
+        }
+
+        @Override
+        public Spliterator<T> spliterator() {
+            return s.spliterator();
+        }
+
+        @Override
+        public boolean isParallel() {
+            return s.isParallel();
+        }
+
+        @Override
+        public Stream<T> sequential() {
+            return s.sequential();
+        }
+
+        @Override
+        public Stream<T> parallel() {
+            return s.parallel();
+        }
+
+        @Override
+        public Stream<T> unordered() {
+            return s.unordered();
+        }
+
+        @Override
+        public Stream<T> onClose(Runnable closeHandler) {
+            return s.onClose(closeHandler);
+        }
+
+        @Override
+        public void close() {
+            s.close();
+        }
+    }
+
+    static final class DefaultMethodIntStream implements IntStream {
+        final IntStream s;
+
+        public DefaultMethodIntStream(IntStream s) {
+            this.s = s;
+        }
+
+
+        // Delegating non-default methods
+
+        @Override
+        public IntStream filter(IntPredicate predicate) {
+            return s.filter(predicate);
+        }
+
+        @Override
+        public IntStream map(IntUnaryOperator mapper) {
+            return s.map(mapper);
+        }
+
+        @Override
+        public <U> Stream<U> mapToObj(IntFunction<? extends U> mapper) {
+            return s.mapToObj(mapper);
+        }
+
+        @Override
+        public LongStream mapToLong(IntToLongFunction mapper) {
+            return s.mapToLong(mapper);
+        }
+
+        @Override
+        public DoubleStream mapToDouble(IntToDoubleFunction mapper) {
+            return s.mapToDouble(mapper);
+        }
+
+        @Override
+        public IntStream flatMap(IntFunction<? extends IntStream> mapper) {
+            return s.flatMap(mapper);
+        }
+
+        @Override
+        public IntStream distinct() {
+            return s.distinct();
+        }
+
+        @Override
+        public IntStream sorted() {
+            return s.sorted();
+        }
+
+        @Override
+        public IntStream peek(IntConsumer action) {
+            return s.peek(action);
+        }
+
+        @Override
+        public IntStream limit(long maxSize) {
+            return s.limit(maxSize);
+        }
+
+        @Override
+        public IntStream skip(long n) {
+            return s.skip(n);
+        }
+
+        @Override
+        public void forEach(IntConsumer action) {
+            s.forEach(action);
+        }
+
+        @Override
+        public void forEachOrdered(IntConsumer action) {
+            s.forEachOrdered(action);
+        }
+
+        @Override
+        public int[] toArray() {
+            return s.toArray();
+        }
+
+        @Override
+        public int reduce(int identity, IntBinaryOperator op) {
+            return s.reduce(identity, op);
+        }
+
+        @Override
+        public OptionalInt reduce(IntBinaryOperator op) {
+            return s.reduce(op);
+        }
+
+        @Override
+        public <R> R collect(Supplier<R> supplier, ObjIntConsumer<R> accumulator, BiConsumer<R, R> combiner) {
+            return s.collect(supplier, accumulator, combiner);
+        }
+
+        @Override
+        public int sum() {
+            return s.sum();
+        }
+
+        @Override
+        public OptionalInt min() {
+            return s.min();
+        }
+
+        @Override
+        public OptionalInt max() {
+            return s.max();
+        }
+
+        @Override
+        public long count() {
+            return s.count();
+        }
+
+        @Override
+        public OptionalDouble average() {
+            return s.average();
+        }
+
+        @Override
+        public IntSummaryStatistics summaryStatistics() {
+            return s.summaryStatistics();
+        }
+
+        @Override
+        public boolean anyMatch(IntPredicate predicate) {
+            return s.anyMatch(predicate);
+        }
+
+        @Override
+        public boolean allMatch(IntPredicate predicate) {
+            return s.allMatch(predicate);
+        }
+
+        @Override
+        public boolean noneMatch(IntPredicate predicate) {
+            return s.noneMatch(predicate);
+        }
+
+        @Override
+        public OptionalInt findFirst() {
+            return s.findFirst();
+        }
+
+        @Override
+        public OptionalInt findAny() {
+            return s.findAny();
+        }
+
+        @Override
+        public LongStream asLongStream() {
+            return s.asLongStream();
+        }
+
+        @Override
+        public DoubleStream asDoubleStream() {
+            return s.asDoubleStream();
+        }
+
+        @Override
+        public Stream<Integer> boxed() {
+            return s.boxed();
+        }
+
+        @Override
+        public IntStream sequential() {
+            return s.sequential();
+        }
+
+        @Override
+        public IntStream parallel() {
+            return s.parallel();
+        }
+
+        @Override
+        public PrimitiveIterator.OfInt iterator() {
+            return s.iterator();
+        }
+
+        @Override
+        public Spliterator.OfInt spliterator() {
+            return s.spliterator();
+        }
+
+        @Override
+        public boolean isParallel() {
+            return s.isParallel();
+        }
+
+        @Override
+        public IntStream unordered() {
+            return s.unordered();
+        }
+
+        @Override
+        public IntStream onClose(Runnable closeHandler) {
+            return s.onClose(closeHandler);
+        }
+
+        @Override
+        public void close() {
+            s.close();
+        }
+    }
+
+    static final class DefaultMethodLongStream implements LongStream {
+        final LongStream s;
+
+        public DefaultMethodLongStream(LongStream s) {
+            this.s = s;
+        }
+
+
+        // Delegating non-default methods
+
+        @Override
+        public void forEach(LongConsumer action) {
+            s.forEach(action);
+        }
+
+        @Override
+        public LongStream filter(LongPredicate predicate) {
+            return s.filter(predicate);
+        }
+
+        @Override
+        public LongStream map(LongUnaryOperator mapper) {
+            return s.map(mapper);
+        }
+
+        @Override
+        public <U> Stream<U> mapToObj(LongFunction<? extends U> mapper) {
+            return s.mapToObj(mapper);
+        }
+
+        @Override
+        public IntStream mapToInt(LongToIntFunction mapper) {
+            return s.mapToInt(mapper);
+        }
+
+        @Override
+        public DoubleStream mapToDouble(LongToDoubleFunction mapper) {
+            return s.mapToDouble(mapper);
+        }
+
+        @Override
+        public LongStream flatMap(LongFunction<? extends LongStream> mapper) {
+            return s.flatMap(mapper);
+        }
+
+        @Override
+        public LongStream distinct() {
+            return s.distinct();
+        }
+
+        @Override
+        public LongStream sorted() {
+            return s.sorted();
+        }
+
+        @Override
+        public LongStream peek(LongConsumer action) {
+            return s.peek(action);
+        }
+
+        @Override
+        public LongStream limit(long maxSize) {
+            return s.limit(maxSize);
+        }
+
+        @Override
+        public LongStream skip(long n) {
+            return s.skip(n);
+        }
+
+        @Override
+        public void forEachOrdered(LongConsumer action) {
+            s.forEachOrdered(action);
+        }
+
+        @Override
+        public long[] toArray() {
+            return s.toArray();
+        }
+
+        @Override
+        public long reduce(long identity, LongBinaryOperator op) {
+            return s.reduce(identity, op);
+        }
+
+        @Override
+        public OptionalLong reduce(LongBinaryOperator op) {
+            return s.reduce(op);
+        }
+
+        @Override
+        public <R> R collect(Supplier<R> supplier, ObjLongConsumer<R> accumulator, BiConsumer<R, R> combiner) {
+            return s.collect(supplier, accumulator, combiner);
+        }
+
+        @Override
+        public long sum() {
+            return s.sum();
+        }
+
+        @Override
+        public OptionalLong min() {
+            return s.min();
+        }
+
+        @Override
+        public OptionalLong max() {
+            return s.max();
+        }
+
+        @Override
+        public long count() {
+            return s.count();
+        }
+
+        @Override
+        public OptionalDouble average() {
+            return s.average();
+        }
+
+        @Override
+        public LongSummaryStatistics summaryStatistics() {
+            return s.summaryStatistics();
+        }
+
+        @Override
+        public boolean anyMatch(LongPredicate predicate) {
+            return s.anyMatch(predicate);
+        }
+
+        @Override
+        public boolean allMatch(LongPredicate predicate) {
+            return s.allMatch(predicate);
+        }
+
+        @Override
+        public boolean noneMatch(LongPredicate predicate) {
+            return s.noneMatch(predicate);
+        }
+
+        @Override
+        public OptionalLong findFirst() {
+            return s.findFirst();
+        }
+
+        @Override
+        public OptionalLong findAny() {
+            return s.findAny();
+        }
+
+        @Override
+        public DoubleStream asDoubleStream() {
+            return s.asDoubleStream();
+        }
+
+        @Override
+        public Stream<Long> boxed() {
+            return s.boxed();
+        }
+
+        @Override
+        public LongStream sequential() {
+            return s.sequential();
+        }
+
+        @Override
+        public LongStream parallel() {
+            return s.parallel();
+        }
+
+        @Override
+        public PrimitiveIterator.OfLong iterator() {
+            return s.iterator();
+        }
+
+        @Override
+        public Spliterator.OfLong spliterator() {
+            return s.spliterator();
+        }
+
+        @Override
+        public boolean isParallel() {
+            return s.isParallel();
+        }
+
+        @Override
+        public LongStream unordered() {
+            return s.unordered();
+        }
+
+        @Override
+        public LongStream onClose(Runnable closeHandler) {
+            return s.onClose(closeHandler);
+        }
+
+        @Override
+        public void close() {
+            s.close();
+        }
+    }
+
+    static final class DefaultMethodDoubleStream implements DoubleStream {
+        final DoubleStream s;
+
+        public DefaultMethodDoubleStream(DoubleStream s) {
+            this.s = s;
+        }
+
+        @Override
+        public DoubleStream filter(DoublePredicate predicate) {
+            return s.filter(predicate);
+        }
+
+        @Override
+        public DoubleStream map(DoubleUnaryOperator mapper) {
+            return s.map(mapper);
+        }
+
+        @Override
+        public <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper) {
+            return s.mapToObj(mapper);
+        }
+
+        @Override
+        public IntStream mapToInt(DoubleToIntFunction mapper) {
+            return s.mapToInt(mapper);
+        }
+
+        @Override
+        public LongStream mapToLong(DoubleToLongFunction mapper) {
+            return s.mapToLong(mapper);
+        }
+
+        @Override
+        public DoubleStream flatMap(DoubleFunction<? extends DoubleStream> mapper) {
+            return s.flatMap(mapper);
+        }
+
+        @Override
+        public DoubleStream distinct() {
+            return s.distinct();
+        }
+
+        @Override
+        public DoubleStream sorted() {
+            return s.sorted();
+        }
+
+        @Override
+        public DoubleStream peek(DoubleConsumer action) {
+            return s.peek(action);
+        }
+
+        @Override
+        public DoubleStream limit(long maxSize) {
+            return s.limit(maxSize);
+        }
+
+        @Override
+        public DoubleStream skip(long n) {
+            return s.skip(n);
+        }
+
+        @Override
+        public void forEach(DoubleConsumer action) {
+            s.forEach(action);
+        }
+
+        @Override
+        public void forEachOrdered(DoubleConsumer action) {
+            s.forEachOrdered(action);
+        }
+
+        @Override
+        public double[] toArray() {
+            return s.toArray();
+        }
+
+        @Override
+        public double reduce(double identity, DoubleBinaryOperator op) {
+            return s.reduce(identity, op);
+        }
+
+        @Override
+        public OptionalDouble reduce(DoubleBinaryOperator op) {
+            return s.reduce(op);
+        }
+
+        @Override
+        public <R> R collect(Supplier<R> supplier, ObjDoubleConsumer<R> accumulator, BiConsumer<R, R> combiner) {
+            return s.collect(supplier, accumulator, combiner);
+        }
+
+        @Override
+        public double sum() {
+            return s.sum();
+        }
+
+        @Override
+        public OptionalDouble min() {
+            return s.min();
+        }
+
+        @Override
+        public OptionalDouble max() {
+            return s.max();
+        }
+
+        @Override
+        public long count() {
+            return s.count();
+        }
+
+        @Override
+        public OptionalDouble average() {
+            return s.average();
+        }
+
+        @Override
+        public DoubleSummaryStatistics summaryStatistics() {
+            return s.summaryStatistics();
+        }
+
+        @Override
+        public boolean anyMatch(DoublePredicate predicate) {
+            return s.anyMatch(predicate);
+        }
+
+        @Override
+        public boolean allMatch(DoublePredicate predicate) {
+            return s.allMatch(predicate);
+        }
+
+        @Override
+        public boolean noneMatch(DoublePredicate predicate) {
+            return s.noneMatch(predicate);
+        }
+
+        @Override
+        public OptionalDouble findFirst() {
+            return s.findFirst();
+        }
+
+        @Override
+        public OptionalDouble findAny() {
+            return s.findAny();
+        }
+
+        @Override
+        public Stream<Double> boxed() {
+            return s.boxed();
+        }
+
+        @Override
+        public DoubleStream sequential() {
+            return s.sequential();
+        }
+
+        @Override
+        public DoubleStream parallel() {
+            return s.parallel();
+        }
+
+        @Override
+        public PrimitiveIterator.OfDouble iterator() {
+            return s.iterator();
+        }
+
+        @Override
+        public Spliterator.OfDouble spliterator() {
+            return s.spliterator();
+        }
+
+        @Override
+        public boolean isParallel() {
+            return s.isParallel();
+        }
+
+        @Override
+        public DoubleStream unordered() {
+            return s.unordered();
+        }
+
+        @Override
+        public DoubleStream onClose(Runnable closeHandler) {
+            return s.onClose(closeHandler);
+        }
+
+        @Override
+        public void close() {
+            s.close();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/DoubleStreamTestDataProvider.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 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 java.util.stream;
+
+import org.testng.annotations.DataProvider;
+
+import java.util.*;
+import java.util.Spliterators;
+import java.util.function.Supplier;
+
+/** TestNG DataProvider for double-valued streams */
+public class DoubleStreamTestDataProvider {
+    private static final double[] to0 = new double[0];
+    private static final double[] to1 = new double[1];
+    private static final double[] to10 = new double[10];
+    private static final double[] to100 = new double[100];
+    private static final double[] to1000 = new double[1000];
+    private static final double[] reversed = new double[100];
+    private static final double[] ones = new double[100];
+    private static final double[] twice = new double[200];
+    private static final double[] pseudoRandom;
+
+    private static final Object[][] testData;
+    private static final Object[][] spliteratorTestData;
+
+    static {
+        double[][] arrays = {to0, to1, to10, to100, to1000};
+        for (double[] arr : arrays) {
+            for (int i = 0; i < arr.length; i++) {
+                arr[i] = i;
+            }
+        }
+        for (int i = 0; i < reversed.length; i++) {
+            reversed[i] = reversed.length - i;
+        }
+        for (int i = 0; i < ones.length; i++) {
+            ones[i] = 1;
+        }
+        System.arraycopy(to100, 0, twice, 0, to100.length);
+        System.arraycopy(to100, 0, twice, to100.length, to100.length);
+        pseudoRandom = new double[LambdaTestHelpers.LONG_STRING.length()];
+        for (int i = 0; i < LambdaTestHelpers.LONG_STRING.length(); i++) {
+            pseudoRandom[i] = (double) LambdaTestHelpers.LONG_STRING.charAt(i);
+        }
+    }
+
+    static final Object[][] arrays = {
+            {"empty", to0},
+            {"0..1", to1},
+            {"0..10", to10},
+            {"0..100", to100},
+            {"0..1000", to1000},
+            {"100x[1]", ones},
+            {"2x[0..100]", twice},
+            {"reverse 0..100", reversed},
+            {"pseudorandom", pseudoRandom}
+    };
+
+    static {
+        {
+            List<Object[]> list = new ArrayList<>();
+            for (Object[] data : arrays) {
+                final Object name = data[0];
+                final double[] doubles = (double[]) data[1];
+
+                list.add(new Object[]{"array:" + name,
+                        TestData.Factory.ofArray("array:" + name, doubles)});
+
+                SpinedBuffer.OfDouble isl = new SpinedBuffer.OfDouble();
+                for (double i : doubles) {
+                    isl.accept(i);
+                }
+                list.add(new Object[]{"SpinedList:" + name,
+                        TestData.Factory.ofSpinedBuffer("SpinedList:" + name, isl)});
+            }
+            testData = list.toArray(new Object[0][]);
+        }
+
+        {
+            List<Object[]> spliterators = new ArrayList<>();
+            for (Object[] data : arrays) {
+                final Object name = data[0];
+                final double[] doubles = (double[]) data[1];
+
+                SpinedBuffer.OfDouble isl = new SpinedBuffer.OfDouble();
+                for (double i : doubles) {
+                    isl.accept(i);
+                }
+
+                spliterators.add(splitDescr("Arrays.s(array):" + name,
+                                            () -> Arrays.spliterator(doubles)));
+                spliterators.add(splitDescr("Arrays.s(array,o,l):" + name,
+                                            () -> Arrays.spliterator(doubles, 0, doubles.length / 2)));
+
+                spliterators.add(splitDescr("SpinedBuffer.s():" + name,
+                                            () -> isl.spliterator()));
+
+                spliterators.add(splitDescr("Primitives.s(SpinedBuffer.iterator(), size):" + name,
+                                            () -> Spliterators.spliterator(isl.iterator(), doubles.length, 0)));
+                spliterators.add(splitDescr("Primitives.s(SpinedBuffer.iterator()):" + name,
+                                            () -> Spliterators.spliteratorUnknownSize(isl.iterator(), 0)));
+                // Need more!
+            }
+            spliteratorTestData = spliterators.toArray(new Object[0][]);
+        }
+
+    }
+
+    static <T> Object[] splitDescr(String description, Supplier<Spliterator.OfDouble> s) {
+        return new Object[] { description, s };
+    }
+
+    // Return an array of ( String name, DoubleStreamTestData )
+    @DataProvider(name = "DoubleStreamTestData")
+    public static Object[][] makeDoubleStreamTestData() {
+        return testData;
+    }
+
+    // returns an array of (String name, Supplier<PrimitiveSpliterator<Double>>)
+    @DataProvider(name = "DoubleSpliterator")
+    public static Object[][] spliteratorProvider() {
+        return spliteratorTestData;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/DoubleStreamTestScenario.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,232 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.PrimitiveIterator;
+import java.util.Set;
+import java.util.Spliterator;
+import java.util.function.Consumer;
+import java.util.function.DoubleConsumer;
+import java.util.function.Function;
+
+/**
+ * Test scenarios for double streams.
+ *
+ * Each scenario is provided with a data source, a function that maps a fresh
+ * stream (as provided by the data source) to a new stream, and a sink to
+ * receive results.  Each scenario describes a different way of computing the
+ * stream contents.  The test driver will ensure that all scenarios produce
+ * the same output (modulo allowable differences in ordering).
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+public enum DoubleStreamTestScenario implements OpTestCase.BaseStreamTestScenario {
+
+    STREAM_FOR_EACH(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            DoubleStream s = m.apply(source);
+            if (s.isParallel()) {
+                s = s.sequential();
+            }
+            s.forEach(b);
+        }
+    },
+
+    STREAM_TO_ARRAY(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            for (double t : m.apply(source).toArray()) {
+                b.accept(t);
+            }
+        }
+    },
+
+    STREAM_ITERATOR(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            for (PrimitiveIterator.OfDouble seqIter = m.apply(source).iterator(); seqIter.hasNext(); )
+                b.accept(seqIter.nextDouble());
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate in pull mode
+    STREAM_SPLITERATOR(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            for (Spliterator.OfDouble spl = m.apply(source).spliterator(); spl.tryAdvance(b); ) {
+            }
+        }
+    },
+
+    // Wrap as stream, spliterate, then split a few times mixing advances with forEach
+    STREAM_SPLITERATOR_WITH_MIXED_TRAVERSE_AND_SPLIT(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            SpliteratorTestHelper.mixedTraverseAndSplit(b, m.apply(source).spliterator());
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate in pull mode
+    STREAM_SPLITERATOR_FOREACH(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            m.apply(source).spliterator().forEachRemaining(b);
+        }
+    },
+
+    PAR_STREAM_SEQUENTIAL_FOR_EACH(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            m.apply(source).sequential().forEach(b);
+        }
+    },
+
+    // Wrap as parallel stream + forEachOrdered
+    PAR_STREAM_FOR_EACH_ORDERED(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            // @@@ Want to explicitly select ordered equalator
+            m.apply(source).forEachOrdered(b);
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate sequentially
+    PAR_STREAM_SPLITERATOR(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            for (Spliterator.OfDouble spl = m.apply(source).spliterator(); spl.tryAdvance(b); ) {
+            }
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate sequentially
+    PAR_STREAM_SPLITERATOR_FOREACH(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            m.apply(source).spliterator().forEachRemaining(b);
+        }
+    },
+
+    PAR_STREAM_TO_ARRAY(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            for (double t : m.apply(source).toArray())
+                b.accept(t);
+        }
+    },
+
+    // Wrap as parallel stream, get the spliterator, wrap as a stream + toArray
+    PAR_STREAM_SPLITERATOR_STREAM_TO_ARRAY(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            DoubleStream s = m.apply(source);
+            Spliterator.OfDouble sp = s.spliterator();
+            DoubleStream ss = StreamSupport.doubleStream(() -> sp,
+                                                         StreamOpFlag.toCharacteristics(OpTestCase.getStreamFlags(s))
+                                                         | (sp.getExactSizeIfKnown() < 0 ? 0 : Spliterator.SIZED), true);
+            for (double t : ss.toArray())
+                b.accept(t);
+        }
+    },
+
+    PAR_STREAM_TO_ARRAY_CLEAR_SIZED(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            S_IN pipe1 = (S_IN) OpTestCase.chain(source,
+                                                 new FlagDeclaringOp(StreamOpFlag.NOT_SIZED, data.getShape()));
+            DoubleStream pipe2 = m.apply(pipe1);
+
+            for (double t : pipe2.toArray())
+                b.accept(t);
+        }
+    },
+
+    // Wrap as parallel stream + forEach synchronizing
+    PAR_STREAM_FOR_EACH(true, false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            m.apply(source).forEach(e -> {
+                synchronized (data) {
+                    b.accept(e);
+                }
+            });
+        }
+    },
+
+    // Wrap as parallel stream + forEach synchronizing and clear SIZED flag
+    PAR_STREAM_FOR_EACH_CLEAR_SIZED(true, false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
+            S_IN pipe1 = (S_IN) OpTestCase.chain(source,
+                                                 new FlagDeclaringOp(StreamOpFlag.NOT_SIZED, data.getShape()));
+            m.apply(pipe1).forEach(e -> {
+                synchronized (data) {
+                    b.accept(e);
+                }
+            });
+        }
+    },
+    ;
+
+    // The set of scenarios that clean the SIZED flag
+    public static final Set<DoubleStreamTestScenario> CLEAR_SIZED_SCENARIOS = Collections.unmodifiableSet(
+            EnumSet.of(PAR_STREAM_TO_ARRAY_CLEAR_SIZED, PAR_STREAM_FOR_EACH_CLEAR_SIZED));
+
+    private boolean isParallel;
+
+    private final boolean isOrdered;
+
+    DoubleStreamTestScenario(boolean isParallel) {
+        this(isParallel, true);
+    }
+
+    DoubleStreamTestScenario(boolean isParallel, boolean isOrdered) {
+        this.isParallel = isParallel;
+        this.isOrdered = isOrdered;
+    }
+
+    public StreamShape getShape() {
+        return StreamShape.DOUBLE_VALUE;
+    }
+
+    public boolean isParallel() {
+        return isParallel;
+    }
+
+    public boolean isOrdered() {
+        return isOrdered;
+    }
+
+    public <T, U, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>>
+    void run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, S_OUT> m) {
+        try (S_IN source = getStream(data)) {
+            run(data, source, (DoubleConsumer) b, (Function<S_IN, DoubleStream>) m);
+        }
+    }
+
+    abstract <T, S_IN extends BaseStream<T, S_IN>>
+    void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/FlagDeclaringOp.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,61 @@
+/*
+ * 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 java.util.stream;
+
+/**
+ * An operation that injects or clears flags but otherwise performs no operation on elements.
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class FlagDeclaringOp<T> implements StatelessTestOp<T, T> {
+    private final int flags;
+    private final StreamShape shape;
+
+    public FlagDeclaringOp(int flags) {
+        this(flags, StreamShape.REFERENCE);
+    }
+
+    public FlagDeclaringOp(int flags, StreamShape shape) {
+        this.flags = flags;
+        this.shape = shape;
+    }
+
+    @Override
+    public StreamShape outputShape() {
+        return shape;
+    }
+
+    @Override
+    public StreamShape inputShape() {
+        return shape;
+    }
+
+    @Override
+    public int opGetFlags() {
+        return flags;
+    }
+
+    @Override
+    public Sink<T> opWrapSink(int flags, boolean parallel, Sink sink) {
+        return sink;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/IntStreamTestDataProvider.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,158 @@
+/*
+ * 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 java.util.stream;
+
+import org.testng.annotations.DataProvider;
+
+import java.util.*;
+import java.util.Spliterators;
+import java.util.function.Supplier;
+
+/** TestNG DataProvider for int-valued streams */
+public class IntStreamTestDataProvider {
+    private static final int[] to0 = new int[0];
+    private static final int[] to1 = new int[1];
+    private static final int[] to10 = new int[10];
+    private static final int[] to100 = new int[100];
+    private static final int[] to1000 = new int[1000];
+    private static final int[] reversed = new int[100];
+    private static final int[] ones = new int[100];
+    private static final int[] twice = new int[200];
+    private static final int[] pseudoRandom;
+
+    private static final Object[][] testData;
+    private static final Object[][] spliteratorTestData;
+
+    static {
+        int[][] arrays = {to0, to1, to10, to100, to1000};
+        for (int[] arr : arrays) {
+            for (int i = 0; i < arr.length; i++) {
+                arr[i] = i;
+            }
+        }
+        for (int i = 0; i < reversed.length; i++) {
+            reversed[i] = reversed.length - i;
+        }
+        for (int i = 0; i < ones.length; i++) {
+            ones[i] = 1;
+        }
+        System.arraycopy(to100, 0, twice, 0, to100.length);
+        System.arraycopy(to100, 0, twice, to100.length, to100.length);
+        pseudoRandom = new int[LambdaTestHelpers.LONG_STRING.length()];
+        for (int i = 0; i < LambdaTestHelpers.LONG_STRING.length(); i++) {
+            pseudoRandom[i] = (int) LambdaTestHelpers.LONG_STRING.charAt(i);
+        }
+    }
+
+    static final Object[][] arrays = {
+            {"empty", to0},
+            {"0..1", to1},
+            {"0..10", to10},
+            {"0..100", to100},
+            {"0..1000", to1000},
+            {"100x[1]", ones},
+            {"2x[0..100]", twice},
+            {"reverse 0..100", reversed},
+            {"pseudorandom", pseudoRandom}
+    };
+
+    static {
+        {
+            List<Object[]> list = new ArrayList<>();
+            for (Object[] data : arrays) {
+                final Object name = data[0];
+                final int[] ints = (int[]) data[1];
+
+                list.add(new Object[]{"array:" +
+                                      name, TestData.Factory.ofArray("array:" + name, ints)});
+
+                SpinedBuffer.OfInt isl = new SpinedBuffer.OfInt();
+                for (int i : ints) {
+                    isl.accept(i);
+                }
+                list.add(new Object[]{"SpinedList:" + name,
+                         TestData.Factory.ofSpinedBuffer("SpinedList:" + name, isl)});
+
+                list.add(streamDataDescr("IntStream.intRange(0,l): " + ints.length,
+                                         () -> IntStream.range(0, ints.length)));
+                list.add(streamDataDescr("IntStream.rangeClosed(0,l): " + ints.length,
+                                         () -> IntStream.rangeClosed(0, ints.length)));
+            }
+            testData = list.toArray(new Object[0][]);
+        }
+
+        {
+            List<Object[]> spliterators = new ArrayList<>();
+            for (Object[] data : arrays) {
+                final Object name = data[0];
+                final int[] ints = (int[]) data[1];
+
+                SpinedBuffer.OfInt isl = new SpinedBuffer.OfInt();
+                for (int i : ints) {
+                    isl.accept(i);
+                }
+
+                spliterators.add(splitDescr("Arrays.s(array):" + name,
+                                            () -> Arrays.spliterator(ints)));
+                spliterators.add(splitDescr("Arrays.s(array,o,l):" + name,
+                                            () -> Arrays.spliterator(ints, 0, ints.length / 2)));
+
+                spliterators.add(splitDescr("SpinedBuffer.s():" + name,
+                                            () -> isl.spliterator()));
+
+                spliterators.add(splitDescr("Primitives.s(SpinedBuffer.iterator(), size):" + name,
+                                            () -> Spliterators.spliterator(isl.iterator(), ints.length, 0)));
+                spliterators.add(splitDescr("Primitives.s(SpinedBuffer.iterator()):" + name,
+                                            () -> Spliterators.spliteratorUnknownSize(isl.iterator(), 0)));
+
+                spliterators.add(splitDescr("IntStream.intRange(0,l):" + name,
+                                            () -> IntStream.range(0, ints.length).spliterator()));
+                spliterators.add(splitDescr("IntStream.intRangeClosed(0,l):" + name,
+                                            () -> IntStream.rangeClosed(0, ints.length).spliterator()));
+                // Need more!
+            }
+            spliteratorTestData = spliterators.toArray(new Object[0][]);
+        }
+
+    }
+
+    static <T> Object[] streamDataDescr(String description, Supplier<IntStream> s) {
+        return new Object[] { description, TestData.Factory.ofIntSupplier(description, s) };
+    }
+
+    static <T> Object[] splitDescr(String description, Supplier<Spliterator.OfInt> s) {
+        return new Object[] { description, s };
+    }
+
+    // Return an array of ( String name, IntStreamTestData )
+    @DataProvider(name = "IntStreamTestData")
+    public static Object[][] makeIntStreamTestData() {
+        return testData;
+    }
+
+    // returns an array of (String name, Supplier<PrimitiveSpliterator<Integer>>)
+    @DataProvider(name = "IntSpliterator")
+    public static Object[][] spliteratorProvider() {
+        return spliteratorTestData;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/IntStreamTestScenario.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,233 @@
+/*
+ * 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 java.util.stream;
+
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.PrimitiveIterator;
+import java.util.Set;
+import java.util.Spliterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.IntConsumer;
+
+/**
+ * Test scenarios for int streams.
+ *
+ * Each scenario is provided with a data source, a function that maps a fresh
+ * stream (as provided by the data source) to a new stream, and a sink to
+ * receive results.  Each scenario describes a different way of computing the
+ * stream contents.  The test driver will ensure that all scenarios produce
+ * the same output (modulo allowable differences in ordering).
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+public enum IntStreamTestScenario implements OpTestCase.BaseStreamTestScenario {
+
+    STREAM_FOR_EACH(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
+            IntStream s = m.apply(source);
+            if (s.isParallel()) {
+                s = s.sequential();
+            }
+            s.forEach(b);
+        }
+    },
+
+    STREAM_TO_ARRAY(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
+            for (int t : m.apply(source).toArray()) {
+                b.accept(t);
+            }
+        }
+    },
+
+    STREAM_ITERATOR(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
+            for (PrimitiveIterator.OfInt seqIter = m.apply(source).iterator(); seqIter.hasNext(); )
+                b.accept(seqIter.nextInt());
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate in pull mode
+    STREAM_SPLITERATOR(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
+            for (Spliterator.OfInt spl = m.apply(source).spliterator(); spl.tryAdvance(b); ) {
+            }
+        }
+    },
+
+    // Wrap as stream, spliterate, then split a few times mixing advances with forEach
+    STREAM_SPLITERATOR_WITH_MIXED_TRAVERSE_AND_SPLIT(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
+            SpliteratorTestHelper.mixedTraverseAndSplit(b, m.apply(source).spliterator());
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate in pull mode
+    STREAM_SPLITERATOR_FOREACH(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
+            m.apply(source).spliterator().forEachRemaining(b);
+        }
+    },
+
+    PAR_STREAM_SEQUENTIAL_FOR_EACH(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
+            m.apply(source).sequential().forEach(b);
+        }
+    },
+
+    // Wrap as parallel stream + forEachOrdered
+    PAR_STREAM_FOR_EACH_ORDERED(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
+            // @@@ Want to explicitly select ordered equalator
+            m.apply(source).forEachOrdered(b);
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate sequentially
+    PAR_STREAM_SPLITERATOR(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
+            for (Spliterator.OfInt spl = m.apply(source).spliterator(); spl.tryAdvance(b); ) {
+            }
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate sequentially
+    PAR_STREAM_SPLITERATOR_FOREACH(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
+            m.apply(source).spliterator().forEachRemaining(b);
+        }
+    },
+
+    PAR_STREAM_TO_ARRAY(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
+            for (int t : m.apply(source).toArray())
+                b.accept(t);
+        }
+    },
+
+    // Wrap as parallel stream, get the spliterator, wrap as a stream + toArray
+    PAR_STREAM_SPLITERATOR_STREAM_TO_ARRAY(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
+            IntStream s = m.apply(source);
+            Spliterator.OfInt sp = s.spliterator();
+            IntStream ss = StreamSupport.intStream(() -> sp,
+                                                   StreamOpFlag.toCharacteristics(OpTestCase.getStreamFlags(s))
+                                                   | (sp.getExactSizeIfKnown() < 0 ? 0 : Spliterator.SIZED),
+                                                   true);
+            for (int t : ss.toArray())
+                b.accept(t);
+        }
+    },
+
+    PAR_STREAM_TO_ARRAY_CLEAR_SIZED(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
+            S_IN pipe1 = (S_IN) OpTestCase.chain(source,
+                                                 new FlagDeclaringOp(StreamOpFlag.NOT_SIZED, data.getShape()));
+            IntStream pipe2 = m.apply(pipe1);
+
+            for (int t : pipe2.toArray())
+                b.accept(t);
+        }
+    },
+
+    // Wrap as parallel stream + forEach synchronizing
+    PAR_STREAM_FOR_EACH(true, false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
+            m.apply(source).forEach(e -> {
+                synchronized (data) {
+                    b.accept(e);
+                }
+            });
+        }
+    },
+
+    // Wrap as parallel stream + forEach synchronizing and clear SIZED flag
+    PAR_STREAM_FOR_EACH_CLEAR_SIZED(true, false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
+            S_IN pipe1 = (S_IN) OpTestCase.chain(source,
+                                                 new FlagDeclaringOp(StreamOpFlag.NOT_SIZED, data.getShape()));
+            m.apply(pipe1).forEach(e -> {
+                synchronized (data) {
+                    b.accept(e);
+                }
+            });
+        }
+    },
+    ;
+
+    // The set of scenarios that clean the SIZED flag
+    public static final Set<IntStreamTestScenario> CLEAR_SIZED_SCENARIOS = Collections.unmodifiableSet(
+            EnumSet.of(PAR_STREAM_TO_ARRAY_CLEAR_SIZED, PAR_STREAM_FOR_EACH_CLEAR_SIZED));
+
+    private final boolean isParallel;
+
+    private final boolean isOrdered;
+
+    IntStreamTestScenario(boolean isParallel) {
+        this(isParallel, true);
+    }
+
+    IntStreamTestScenario(boolean isParallel, boolean isOrdered) {
+        this.isParallel = isParallel;
+        this.isOrdered = isOrdered;
+    }
+
+    public StreamShape getShape() {
+        return StreamShape.INT_VALUE;
+    }
+
+    public boolean isParallel() {
+        return isParallel;
+    }
+
+    public boolean isOrdered() {
+        return isOrdered;
+    }
+
+    public <T, U, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>>
+    void run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, S_OUT> m) {
+        try (S_IN source = getStream(data)) {
+            run(data, source, (IntConsumer) b, (Function<S_IN, IntStream>) m);
+        }
+    }
+
+    abstract <T, S_IN extends BaseStream<T, S_IN>>
+    void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/IntermediateTestOp.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,41 @@
+/*
+ * 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 java.util.stream;
+
+/**
+ * A base type for test operations
+ */
+interface IntermediateTestOp<E_IN, E_OUT> {
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public static<T> AbstractPipeline chain(AbstractPipeline upstream,
+                                            IntermediateTestOp<?, T> op) {
+        if (op instanceof StatelessTestOp)
+            return StatelessTestOp.chain(upstream, (StatelessTestOp) op);
+
+        if (op instanceof StatefulTestOp)
+            return StatefulTestOp.chain(upstream, (StatefulTestOp) op);
+
+        throw new IllegalStateException("Unknown test op type: " + op.getClass().getName());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/LambdaTestHelpers.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,462 @@
+/*
+ * Copyright (c) 1997, 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 java.util.stream;
+
+import java.util.*;
+import java.util.function.BiConsumer;
+import java.util.function.BiPredicate;
+import java.util.function.BinaryOperator;
+import java.util.function.Consumer;
+import java.util.function.DoubleBinaryOperator;
+import java.util.function.DoubleConsumer;
+import java.util.function.DoublePredicate;
+import java.util.function.Function;
+import java.util.function.IntBinaryOperator;
+import java.util.function.IntConsumer;
+import java.util.function.IntFunction;
+import java.util.function.IntPredicate;
+import java.util.function.IntUnaryOperator;
+import java.util.function.LongBinaryOperator;
+import java.util.function.LongConsumer;
+import java.util.function.LongPredicate;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+import java.util.function.ToDoubleFunction;
+import java.util.function.ToIntFunction;
+import java.util.function.ToLongFunction;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * LambdaTestHelpers -- assertion methods and useful objects for lambda test cases
+ */
+public class LambdaTestHelpers {
+    public static final String LONG_STRING = "When in the Course of human events it becomes necessary for one people to dissolve the political bands which have connected them with another and to assume among the powers of the earth, the separate and equal station to which the Laws of Nature and of Nature's God entitle them, a decent respect to the opinions of mankind requires that they should declare the causes which impel them to the separation.";
+
+    @SuppressWarnings("rawtypes")
+    public static final Consumer bEmpty = x -> {  };
+    @SuppressWarnings("rawtypes")
+    public static final IntConsumer bIntEmpty = x -> {  };
+    @SuppressWarnings("rawtypes")
+    public static final BiConsumer bBiEmpty = (x,y) -> { };
+    @SuppressWarnings("rawtypes")
+    public static final Consumer bHashCode = x -> { Objects.hashCode(x); };
+    @SuppressWarnings("rawtypes")
+    public static final BiConsumer bBiHashCode = (x,y) -> { Objects.hash(x, y); };
+    public static final Function<Integer, Integer> mZero = x -> 0;
+    public static final Function<Integer, Integer> mId = x -> x;
+    public static final Function<Integer, Integer> mDoubler = x -> x * 2;
+    public static final Function<Integer, Stream<Integer>> mfId = e -> Collections.singletonList(e).stream();
+    public static final Function<Integer, Stream<Integer>> mfNull = e -> Collections.<Integer>emptyList().stream();
+    public static final Function<Integer, Stream<Integer>> mfLt = e -> {
+        List<Integer> l = new ArrayList<>();
+        for (int i=0; i<e; i++)
+            l.add(i);
+        return l.stream();
+    };
+    public static final ToIntFunction<Integer> imDoubler = x -> x * 2;
+    public static final ToLongFunction<Long> lmDoubler = x -> x * 2;
+    public static final ToDoubleFunction<Double> dmDoubler = x -> x * 2;
+    public static final Predicate<Integer> pFalse = x -> false;
+    public static final Predicate<Integer> pTrue = x -> true;
+    public static final Predicate<Integer> pEven = x -> 0 == x % 2;
+    public static final Predicate<Integer> pOdd = x -> 1 == x % 2;
+    public static final IntPredicate ipFalse = x -> false;
+    public static final IntPredicate ipTrue = x -> true;
+    public static final IntPredicate ipEven = x -> 0 == x % 2;
+    public static final IntPredicate ipOdd = x -> 1 == x % 2;
+    public static final LongPredicate lpFalse = x -> false;
+    public static final LongPredicate lpTrue = x -> true;
+    public static final LongPredicate lpEven = x -> 0 == x % 2;
+    public static final LongPredicate lpOdd = x -> 1 == x % 2;
+    public static final DoublePredicate dpFalse = x -> false;
+    public static final DoublePredicate dpTrue = x -> true;
+    public static final DoublePredicate dpEven = x -> 0 == ((long) x) % 2;
+    public static final DoublePredicate dpOdd = x -> 1 == ((long) x) % 2;
+    public static final BinaryOperator<Integer> rPlus = (x, y) -> x+y;
+    public static final BinaryOperator<Integer> rMax = (x, y) -> Math.max(x, y);
+    public static final BinaryOperator<Integer> rMin = (x, y) -> Math.min(x,y);
+    public static final IntBinaryOperator irPlus = (x, y) -> x+y;
+    public static final IntBinaryOperator irMax = (x, y) -> Math.max(x, y);
+    public static final IntBinaryOperator irMin = (x, y) -> Math.min(x,y);
+    public static final IntUnaryOperator irDoubler = x -> x * 2;
+    public static final LongBinaryOperator lrPlus = (x, y) -> x+y;
+    public static final DoubleBinaryOperator drPlus = (x, y) -> x+y;
+    public static final Comparator<Integer> cInteger = (a, b) -> Integer.compare(a, b);
+    public static final BiPredicate<?, ?> bipFalse = (x, y) -> false;
+    public static final BiPredicate<?, ?> bipTrue = (x, y) -> true;
+    public static final BiPredicate<Integer, Integer> bipBothEven = (x, y) -> 0 == (x % 2 + y % 2);
+    public static final BiPredicate<Integer, Integer> bipBothOdd = (x, y) -> 2 == (x % 2 + y % 2);
+    public static final BiPredicate<?, ?> bipSameString = (x, y) -> String.valueOf(x).equals(String.valueOf(y));
+
+    public static final IntFunction<Integer[]> integerArrayGenerator = s -> new Integer[s];
+
+    public static final IntFunction<Object[]> objectArrayGenerator = s -> new Object[s];
+
+    public static final Function<String, Stream<Character>> flattenChars = string -> {
+        List<Character> l = new ArrayList<>();
+        for (int i=0; i<string.length(); i++)
+            l.add(string.charAt(i));
+        return l.stream();
+    };
+
+    public static final Function<String, IntStream> flattenInt
+            = string -> IntStream.range(0, string.length()).map(string::charAt);
+
+    public static <T, R> Function<T, R> forPredicate(Predicate<? super T> predicate, R forTrue, R forFalse) {
+        Objects.requireNonNull(predicate);
+
+        return t -> predicate.test(t) ? forTrue : forFalse;
+    }
+
+    public static <T> Function<T, T> identity() {
+        return t -> t;
+    }
+
+    public static<V, T, R> Function<V, R> compose(Function<? super T, ? extends R> after, Function<? super V, ? extends T> before) {
+        Objects.requireNonNull(before);
+        return (V v) -> after.apply(before.apply(v));
+    }
+
+    public static List<Integer> empty() {
+        ArrayList<Integer> list = new ArrayList<>();
+        list.add(null);
+        return list;
+    }
+
+    public static List<Integer> countTo(int n) {
+        return range(1, n);
+    }
+
+    public static List<Integer> range(int l, int u) {
+        ArrayList<Integer> list = new ArrayList<>(u - l + 1);
+        for (int i=l; i<=u; i++) {
+            list.add(i);
+        }
+        return list;
+    }
+
+    public static List<Integer> repeat(int value, int n) {
+        ArrayList<Integer> list = new ArrayList<>(n);
+        for (int i=1; i<=n; i++) {
+            list.add(value);
+        }
+        return list;
+    }
+
+    public static List<Double> asDoubles(List<Integer> integers) {
+        ArrayList<Double> list = new ArrayList<>();
+        for (Integer i : integers) {
+            list.add((double) i);
+        }
+        return list;
+    }
+
+    public static List<Long> asLongs(List<Integer> integers) {
+        ArrayList<Long> list = new ArrayList<>();
+        for (Integer i : integers) {
+            list.add((long) i);
+        }
+        return list;
+    }
+
+    public static void assertCountSum(Stream<? super Integer> it, int count, int sum) {
+        assertCountSum(it.iterator(), count, sum);
+    }
+
+    public static void assertCountSum(Iterable<? super Integer> it, int count, int sum) {
+        assertCountSum(it.iterator(), count, sum);
+    }
+
+    public static void assertCountSum(Iterator<? super Integer> it, int count, int sum) {
+        int c = 0;
+        int s = 0;
+        while (it.hasNext()) {
+            int i = (Integer) it.next();
+            c++;
+            s += i;
+        }
+
+        assertEquals(c, count);
+        assertEquals(s, sum);
+    }
+
+    public static void assertConcat(Iterator<Character> it, String result) {
+        StringBuilder sb = new StringBuilder();
+        while (it.hasNext()) {
+            sb.append(it.next());
+        }
+
+        assertEquals(result, sb.toString());
+    }
+
+    public static<T extends Comparable<? super T>> void assertSorted(Iterator<T> i) {
+        i = toBoxedList(i).iterator();
+
+        if (!i.hasNext())
+            return;
+        T last = i.next();
+        while (i.hasNext()) {
+            T t = i.next();
+            assertTrue(last.compareTo(t) <= 0);
+            assertTrue(t.compareTo(last) >= 0);
+            last = t;
+        }
+    }
+
+    public static<T> void assertSorted(Iterator<T> i, Comparator<? super T> comp) {
+        if (i instanceof PrimitiveIterator.OfInt
+                || i instanceof PrimitiveIterator.OfDouble
+                || i instanceof PrimitiveIterator.OfLong) {
+            i = toBoxedList(i).iterator();
+        }
+
+        if (!i.hasNext())
+            return;
+        T last = i.next();
+        while (i.hasNext()) {
+            T t = i.next();
+            assertTrue(comp.compare(last, t) <= 0);
+            assertTrue(comp.compare(t, last) >= 0);
+            last = t;
+        }
+    }
+
+    public static<T extends Comparable<? super T>> void assertSorted(Iterable<T> iter) {
+        assertSorted(iter.iterator());
+    }
+
+    public static<T> void assertSorted(Iterable<T> iter, Comparator<? super T> comp) {
+        assertSorted(iter.iterator(), comp);
+    }
+
+    public static <T> void assertUnique(Iterable<T> iter) {
+        assertUnique(iter.iterator());
+    }
+
+    public static<T> void assertUnique(Iterator<T> iter) {
+        if (!iter.hasNext()) {
+            return;
+        }
+
+        if (iter instanceof PrimitiveIterator.OfInt
+            || iter instanceof PrimitiveIterator.OfDouble
+            || iter instanceof PrimitiveIterator.OfLong) {
+            iter = toBoxedList(iter).iterator();
+        }
+
+        Set<T> uniq = new HashSet<>();
+        while(iter.hasNext()) {
+            T each = iter.next();
+            assertTrue(!uniq.contains(each), "Not unique");
+            uniq.add(each);
+        }
+    }
+
+    public static<T> void assertContents(Iterable<T> actual, Iterable<T> expected) {
+        if (actual instanceof Collection && expected instanceof Collection) {
+            assertEquals(actual, expected);
+        } else {
+            assertContents(actual.iterator(), expected.iterator());
+        }
+    }
+
+    public static<T> void assertContents(Iterator<T> actual, Iterator<T> expected) {
+        assertEquals(toBoxedList(actual), toBoxedList(expected));
+    }
+
+    @SafeVarargs
+    @SuppressWarnings("varargs")
+    public static<T> void assertContents(Iterator<T> actual, T... expected) {
+        assertContents(actual, Arrays.asList(expected).iterator());
+    }
+
+    /**
+     * The all consuming consumer (rampant capitalist) that can accepting a reference or any primitive value.
+     */
+    private static interface OmnivorousConsumer<T>
+            extends Consumer<T>, IntConsumer, LongConsumer, DoubleConsumer { }
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public static<T> Consumer<T> toBoxingConsumer(Consumer<? super T> c) {
+        return (Consumer<T>) new OmnivorousConsumer() {
+            @Override
+            public void accept(Object t) {
+                c.accept((T) t);
+            }
+
+            @Override
+            public void accept(int t) {
+                accept((Object) t);
+            }
+
+            @Override
+            public void accept(long t) {
+                accept((Object) t);
+            }
+
+            @Override
+            public void accept(double t) {
+                accept((Object) t);
+            }
+        };
+    }
+
+    /**
+     * Convert an iterator to a list using forEach with an implementation of
+     * {@link java.util.stream.LambdaTestHelpers.OmnivorousConsumer}.
+     *
+     * This ensures equality comparisons for test results do not trip
+     * the boxing trip-wires.
+     */
+    private static<T> List<T> toBoxedList(Iterator<T> it) {
+        List<T> l = new ArrayList<>();
+        it.forEachRemaining(toBoxingConsumer(l::add));
+        return l;
+    }
+
+    /**
+     * Convert a spliterator to a list using forEach with an implementation of
+     * {@link java.util.stream.LambdaTestHelpers.OmnivorousConsumer}.
+     *
+     * This ensures equality comparisons for test results do not trip
+     * the boxing trip-wires.
+     */
+    public static<T> List<T> toBoxedList(Spliterator<T> sp) {
+        List<T> l = new ArrayList<>();
+        sp.forEachRemaining(toBoxingConsumer(l::add));
+        return l;
+    }
+
+    /**
+     * Convert an iterator to a multi-set, represented as a Map, using forEach with an implementation of
+     * {@link java.util.stream.LambdaTestHelpers.OmnivorousConsumer}.
+     *
+     * This ensures equality comparisons for test results do not trip
+     * the boxing trip-wires.
+     */
+    @SuppressWarnings("unchecked")
+    private static<T> Map<T, Integer> toBoxedMultiset(Iterator<T> it) {
+        Map<Object, Integer> result = new HashMap<>();
+
+        it.forEachRemaining(toBoxingConsumer(o -> {
+                if (result.containsKey(o))
+                    result.put(o, result.get(o) + 1);
+                else
+                    result.put(o, 1);
+            }));
+
+        return (Map<T, Integer>) result;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static<T> Map<T, Integer> toBoxedMultiset(Spliterator<T> it) {
+        Map<Object, Integer> result = new HashMap<>();
+
+        it.forEachRemaining(toBoxingConsumer(o -> {
+                if (result.containsKey(o))
+                    result.put(o, result.get(o) + 1);
+                else
+                    result.put(o, 1);
+            }));
+
+        return (Map<T, Integer>) result;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static void assertContentsEqual(Object a, Object b) {
+        if (a instanceof Iterable && b instanceof Iterable)
+            assertContents((Iterable) a, (Iterable) b);
+        else
+            assertEquals(a, b);
+    }
+
+    public static<T> void assertContentsUnordered(Iterable<T> actual, Iterable<T> expected) {
+        assertContentsUnordered(actual.iterator(), expected.iterator());
+    }
+
+    public static<T> void assertContentsUnordered(Iterator<T> actual, Iterator<T> expected) {
+        assertEquals(toBoxedMultiset(actual), toBoxedMultiset(expected));
+    }
+
+    public static void launderAssertion(Runnable r, Supplier<String> additionalInfo) {
+        try {
+            r.run();
+        }
+        catch (AssertionError ae) {
+            AssertionError cloned = new AssertionError(ae.getMessage() + String.format("%n%s", additionalInfo.get()));
+            cloned.setStackTrace(ae.getStackTrace());
+            if (ae.getCause() != null)
+                cloned.initCause(ae.getCause());
+            throw cloned;
+        }
+    }
+
+    public static <T, S extends BaseStream<T, S>>
+    List<Function<S, S>> permuteStreamFunctions(List<Function<S, S>> opFunctions) {
+        List<List<Function<S, S>>> opFunctionPermutations = perm(opFunctions);
+
+        List<Function<S, S>> appliedFunctions = new ArrayList<>();
+        for (List<Function<S, S>> fs : opFunctionPermutations) {
+            Function<S, S> applied = s -> {
+                for (Function<S, S> f : fs) {
+                    s = f.apply(s);
+                }
+                return s;
+            };
+            appliedFunctions.add(applied);
+        }
+
+        return appliedFunctions;
+    }
+
+    private static <T> List<T> sub(List<T> l, int index) {
+        List<T> subL = new ArrayList<>(l);
+        subL.remove(index);
+        return subL;
+    }
+
+    public static <T> List<List<T>> perm(List<T> l) {
+        List<List<T>> result = new ArrayList<>();
+        for (int i = 0; i < l.size(); i++) {
+            for (List<T> perm : perm(sub(l, i))) {
+                perm.add(0, l.get(i));
+                result.add(perm);
+            }
+        }
+        result.add(new ArrayList<T>());
+
+        return result;
+    }
+
+    public static String flagsToString(int flags) {
+        StringJoiner sj = new StringJoiner(", ", "StreamOpFlag[", "]");
+        if (StreamOpFlag.DISTINCT.isKnown(flags)) sj.add("IS_DISTINCT");
+        if (StreamOpFlag.ORDERED.isKnown(flags)) sj.add("IS_ORDERED");
+        if (StreamOpFlag.SIZED.isKnown(flags)) sj.add("IS_SIZED");
+        if (StreamOpFlag.SORTED.isKnown(flags)) sj.add("IS_SORTED");
+        if (StreamOpFlag.SHORT_CIRCUIT.isKnown(flags)) sj.add("IS_SHORT_CIRCUIT");
+        return sj.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/LambdaTestMode.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 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 java.util.stream;
+
+/**
+ * Runtime modes of test execution.
+ */
+public enum LambdaTestMode {
+    /**
+     * Execution mode with no particular runtime constraints.
+     */
+    NORMAL,
+
+    /**
+     * Execution mode where tests are executed for testing lambda serialization
+     * and deserialization.
+     *
+     * <p>This mode may be queried by tests or data supplied by data
+     * providers, which cannot otherwise be assigned to the test group
+     * <em>serialization-hostile</em>, to not execute or declare
+     * serialization-hostile code or data.
+     *
+     * <p>This mode is enabled if the boolean system property
+     * {@code org.openjdk.java.util.stream.sand.mode} is declared with a
+     * {@code true} value.
+     */
+    SERIALIZATION;
+
+    /**
+     * {@code true} if tests are executed in the mode for testing lambda
+     * Serialization ANd Deserialization (SAND).
+     */
+    private static final boolean IS_LAMBDA_SERIALIZATION_MODE =
+            Boolean.getBoolean("org.openjdk.java.util.stream.sand.mode");
+
+    /**
+     *
+     * @return the mode of test execution.
+     */
+    public static LambdaTestMode getMode() {
+        return IS_LAMBDA_SERIALIZATION_MODE ? SERIALIZATION : NORMAL;
+    }
+
+    /**
+     *
+     * @return {@code true} if normal test mode.
+     */
+    public static boolean isNormalMode() {
+        return getMode() == NORMAL;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/LoggingTestCase.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 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 java.util.stream;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.testng.Assert;
+import org.testng.ITestResult;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/**
+ * LoggingTestCase
+ *
+ */
+@Test
+public class LoggingTestCase extends Assert {
+    private Map<String, Object> context = new HashMap<>();
+
+    @BeforeMethod
+    public void before() {
+        context.clear();
+    }
+
+    @AfterMethod
+    public void after(ITestResult result) {
+        if (!result.isSuccess()) {
+            List<Object> list = new ArrayList<>();
+            Collections.addAll(list, result.getParameters());
+            list.add(context.toString());
+            result.setParameters(list.toArray(new Object[list.size()]));
+        }
+    }
+
+    protected void setContext(String key, Object value) {
+        context.put(key, value);
+    }
+
+    protected void clearContext(String key) {
+        context.remove(key);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/LongStreamTestDataProvider.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 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 java.util.stream;
+
+import org.testng.annotations.DataProvider;
+
+import java.util.*;
+import java.util.Spliterators;
+import java.util.function.Supplier;
+
+/** TestNG DataProvider for long-valued streams */
+public class LongStreamTestDataProvider {
+    private static final long[] to0 = new long[0];
+    private static final long[] to1 = new long[1];
+    private static final long[] to10 = new long[10];
+    private static final long[] to100 = new long[100];
+    private static final long[] to1000 = new long[1000];
+    private static final long[] reversed = new long[100];
+    private static final long[] ones = new long[100];
+    private static final long[] twice = new long[200];
+    private static final long[] pseudoRandom;
+
+    private static final Object[][] testData;
+    private static final Object[][] spliteratorTestData;
+
+    static {
+        long[][] arrays = {to0, to1, to10, to100, to1000};
+        for (long[] arr : arrays) {
+            for (int i = 0; i < arr.length; i++) {
+                arr[i] = i;
+            }
+        }
+        for (int i = 0; i < reversed.length; i++) {
+            reversed[i] = reversed.length - i;
+        }
+        for (int i = 0; i < ones.length; i++) {
+            ones[i] = 1;
+        }
+        System.arraycopy(to100, 0, twice, 0, to100.length);
+        System.arraycopy(to100, 0, twice, to100.length, to100.length);
+        pseudoRandom = new long[LambdaTestHelpers.LONG_STRING.length()];
+        for (int i = 0; i < LambdaTestHelpers.LONG_STRING.length(); i++) {
+            pseudoRandom[i] = (long) LambdaTestHelpers.LONG_STRING.charAt(i);
+        }
+    }
+
+    static final Object[][] arrays = {
+            {"empty", to0},
+            {"0..1", to1},
+            {"0..10", to10},
+            {"0..100", to100},
+            {"0..1000", to1000},
+            {"100x[1]", ones},
+            {"2x[0..100]", twice},
+            {"reverse 0..100", reversed},
+            {"pseudorandom", pseudoRandom}
+    };
+
+    static {
+        {
+            List<Object[]> list = new ArrayList<>();
+            for (Object[] data : arrays) {
+                final Object name = data[0];
+                final long[] longs = (long[]) data[1];
+
+                list.add(new Object[]{"array:" + name,
+                        TestData.Factory.ofArray("array:" + name, longs)});
+
+                SpinedBuffer.OfLong isl = new SpinedBuffer.OfLong();
+                for (long i : longs) {
+                    isl.accept(i);
+                }
+                list.add(new Object[]{"SpinedList:" + name,
+                        TestData.Factory.ofSpinedBuffer("SpinedList:" + name, isl)});
+
+                list.add(streamDataDescr("LongStream.longRange(0,l): " + longs.length,
+                                         () -> LongStream.range(0, longs.length)));
+                list.add(streamDataDescr("LongStream.longRangeClosed(0,l): " + longs.length,
+                                         () -> LongStream.rangeClosed(0, longs.length)));
+            }
+            testData = list.toArray(new Object[0][]);
+        }
+
+        {
+            List<Object[]> spliterators = new ArrayList<>();
+            for (Object[] data : arrays) {
+                final Object name = data[0];
+                final long[] longs = (long[]) data[1];
+
+                SpinedBuffer.OfLong isl = new SpinedBuffer.OfLong();
+                for (long i : longs) {
+                    isl.accept(i);
+                }
+
+                spliterators.add(splitDescr("Arrays.s(array):" + name,
+                                            () -> Arrays.spliterator(longs)));
+                spliterators.add(splitDescr("Arrays.s(array,o,l):" + name,
+                                            () -> Arrays.spliterator(longs, 0, longs.length / 2)));
+
+                spliterators.add(splitDescr("SpinedBuffer.s():" + name,
+                                            () -> isl.spliterator()));
+
+                spliterators.add(splitDescr("Primitives.s(SpinedBuffer.iterator(), size):" + name,
+                                            () -> Spliterators.spliterator(isl.iterator(), longs.length, 0)));
+                spliterators.add(splitDescr("Primitives.s(SpinedBuffer.iterator()):" + name,
+                                            () -> Spliterators.spliteratorUnknownSize(isl.iterator(), 0)));
+
+                spliterators.add(splitDescr("LongStream.longRange(0,l):" + name,
+                                            () -> LongStream.range(0, longs.length).spliterator()));
+                spliterators.add(splitDescr("LongStream.longRangeClosed(0,l):" + name,
+                                            () -> LongStream.rangeClosed(0, longs.length).spliterator()));
+                // Need more!
+            }
+            spliteratorTestData = spliterators.toArray(new Object[0][]);
+        }
+
+    }
+
+    static <T> Object[] streamDataDescr(String description, Supplier<LongStream> s) {
+        return new Object[] { description, TestData.Factory.ofLongSupplier(description, s) };
+    }
+
+    static <T> Object[] splitDescr(String description, Supplier<Spliterator.OfLong> s) {
+        return new Object[] { description, s };
+    }
+
+    // Return an array of ( String name, LongStreamTestData )
+    @DataProvider(name = "LongStreamTestData")
+    public static Object[][] makeLongStreamTestData() {
+        return testData;
+    }
+
+    // returns an array of (String name, Supplier<PrimitiveSpliterator<Long>>)
+    @DataProvider(name = "LongSpliterator")
+    public static Object[][] spliteratorProvider() {
+        return spliteratorTestData;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/LongStreamTestScenario.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,232 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.PrimitiveIterator;
+import java.util.Set;
+import java.util.Spliterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.LongConsumer;
+
+/**
+ * Test scenarios for long streams.
+ *
+ * Each scenario is provided with a data source, a function that maps a fresh
+ * stream (as provided by the data source) to a new stream, and a sink to
+ * receive results.  Each scenario describes a different way of computing the
+ * stream contents.  The test driver will ensure that all scenarios produce
+ * the same output (modulo allowable differences in ordering).
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+public enum LongStreamTestScenario implements OpTestCase.BaseStreamTestScenario {
+
+    STREAM_FOR_EACH(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
+            LongStream s = m.apply(source);
+            if (s.isParallel()) {
+                s = s.sequential();
+            }
+            s.forEach(b);
+        }
+    },
+
+    STREAM_TO_ARRAY(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
+            for (long t : m.apply(source).toArray()) {
+                b.accept(t);
+            }
+        }
+    },
+
+    STREAM_ITERATOR(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
+            for (PrimitiveIterator.OfLong seqIter = m.apply(source).iterator(); seqIter.hasNext(); )
+                b.accept(seqIter.nextLong());
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate in pull mode
+    STREAM_SPLITERATOR(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
+            for (Spliterator.OfLong spl = m.apply(source).spliterator(); spl.tryAdvance(b); ) {
+            }
+        }
+    },
+
+    // Wrap as stream, spliterate, then split a few times mixing advances with forEach
+    STREAM_SPLITERATOR_WITH_MIXED_TRAVERSE_AND_SPLIT(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
+            SpliteratorTestHelper.mixedTraverseAndSplit(b, m.apply(source).spliterator());
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate in pull mode
+    STREAM_SPLITERATOR_FOREACH(false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
+            m.apply(source).spliterator().forEachRemaining(b);
+        }
+    },
+
+    PAR_STREAM_SEQUENTIAL_FOR_EACH(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
+            m.apply(source).sequential().forEach(b);
+        }
+    },
+
+    // Wrap as parallel stream + forEachOrdered
+    PAR_STREAM_FOR_EACH_ORDERED(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
+            // @@@ Want to explicitly select ordered equalator
+            m.apply(source).forEachOrdered(b);
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate sequentially
+    PAR_STREAM_SPLITERATOR(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
+            for (Spliterator.OfLong spl = m.apply(source).spliterator(); spl.tryAdvance(b); ) {
+            }
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate sequentially
+    PAR_STREAM_SPLITERATOR_FOREACH(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
+            m.apply(source).spliterator().forEachRemaining(b);
+        }
+    },
+
+    PAR_STREAM_TO_ARRAY(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
+            for (long t : m.apply(source).toArray())
+                b.accept(t);
+        }
+    },
+
+    // Wrap as parallel stream, get the spliterator, wrap as a stream + toArray
+    PAR_STREAM_SPLITERATOR_STREAM_TO_ARRAY(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
+            LongStream s = m.apply(source);
+            Spliterator.OfLong sp = s.spliterator();
+            LongStream ss = StreamSupport.longStream(() -> sp,
+                                                     StreamOpFlag.toCharacteristics(OpTestCase.getStreamFlags(s))
+                                                     | (sp.getExactSizeIfKnown() < 0 ? 0 : Spliterator.SIZED), true);
+            for (long t : ss.toArray())
+                b.accept(t);
+        }
+    },
+
+    PAR_STREAM_TO_ARRAY_CLEAR_SIZED(true) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
+            S_IN pipe1 = (S_IN) OpTestCase.chain(source,
+                                                 new FlagDeclaringOp(StreamOpFlag.NOT_SIZED, data.getShape()));
+            LongStream pipe2 = m.apply(pipe1);
+
+            for (long t : pipe2.toArray())
+                b.accept(t);
+        }
+    },
+
+    // Wrap as parallel stream + forEach synchronizing
+    PAR_STREAM_FOR_EACH(true, false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
+            m.apply(source).forEach(e -> {
+                synchronized (data) {
+                    b.accept(e);
+                }
+            });
+        }
+    },
+
+    // Wrap as parallel stream + forEach synchronizing and clear SIZED flag
+    PAR_STREAM_FOR_EACH_CLEAR_SIZED(true, false) {
+        <T, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
+            S_IN pipe1 = (S_IN) OpTestCase.chain(source,
+                                                 new FlagDeclaringOp(StreamOpFlag.NOT_SIZED, data.getShape()));
+            m.apply(pipe1).forEach(e -> {
+                synchronized (data) {
+                    b.accept(e);
+                }
+            });
+        }
+    },
+    ;
+
+    // The set of scenarios that clean the SIZED flag
+    public static final Set<LongStreamTestScenario> CLEAR_SIZED_SCENARIOS = Collections.unmodifiableSet(
+            EnumSet.of(PAR_STREAM_TO_ARRAY_CLEAR_SIZED, PAR_STREAM_FOR_EACH_CLEAR_SIZED));
+
+    private boolean isParallel;
+
+    private final boolean isOrdered;
+
+    LongStreamTestScenario(boolean isParallel) {
+        this(isParallel, true);
+    }
+
+    LongStreamTestScenario(boolean isParallel, boolean isOrdered) {
+        this.isParallel = isParallel;
+        this.isOrdered = isOrdered;
+    }
+
+    public StreamShape getShape() {
+        return StreamShape.LONG_VALUE;
+    }
+
+    public boolean isParallel() {
+        return isParallel;
+    }
+
+    public boolean isOrdered() {
+        return isOrdered;
+    }
+
+    public <T, U, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>>
+    void run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, S_OUT> m) {
+        try (S_IN source = getStream(data)) {
+            run(data, source, (LongConsumer) b, (Function<S_IN, LongStream>) m);
+        }
+    }
+
+    abstract <T, S_IN extends BaseStream<T, S_IN>>
+    void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/OpTestCase.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,682 @@
+/*
+ * 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 java.util.stream;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.Spliterator;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import org.testng.annotations.Test;
+
+/**
+ * Base class for streams test cases.  Provides 'exercise' methods for taking
+ * lambdas that construct and modify streams, and evaluates them in different
+ * ways and asserts that they produce equivalent results.
+ */
+@Test
+public abstract class OpTestCase extends LoggingTestCase {
+
+    private final Map<StreamShape, Set<? extends BaseStreamTestScenario>> testScenarios;
+
+    protected OpTestCase() {
+        testScenarios = new EnumMap<>(StreamShape.class);
+        testScenarios.put(StreamShape.REFERENCE, Collections.unmodifiableSet(EnumSet.allOf(StreamTestScenario.class)));
+        testScenarios.put(StreamShape.INT_VALUE, Collections.unmodifiableSet(EnumSet.allOf(IntStreamTestScenario.class)));
+        testScenarios.put(StreamShape.LONG_VALUE, Collections.unmodifiableSet(EnumSet.allOf(LongStreamTestScenario.class)));
+        testScenarios.put(StreamShape.DOUBLE_VALUE, Collections.unmodifiableSet(EnumSet.allOf(DoubleStreamTestScenario.class)));
+    }
+
+    @SuppressWarnings("rawtypes")
+    public static int getStreamFlags(BaseStream s) {
+        return ((AbstractPipeline) s).getStreamFlags();
+    }
+
+    /**
+     * An asserter for results produced when exercising of stream or terminal
+     * tests.
+     *
+     * @param <R> the type of result to assert on
+     */
+    public interface ResultAsserter<R> {
+        /**
+         * Assert a result produced when exercising of stream or terminal
+         * test.
+         *
+         * @param actual the actual result
+         * @param expected the expected result
+         * @param isOrdered true if the pipeline is ordered
+         * @param isParallel true if the pipeline is parallel
+         */
+        void assertResult(R actual, R expected, boolean isOrdered, boolean isParallel);
+    }
+
+    // Exercise stream operations
+
+    public interface BaseStreamTestScenario {
+        StreamShape getShape();
+
+        boolean isParallel();
+
+        boolean isOrdered();
+
+        default <T, S_IN extends BaseStream<T, S_IN>>
+        S_IN getStream(TestData<T, S_IN> data) {
+            return isParallel()
+                   ? data.parallelStream()
+                   : data.stream();
+        }
+
+        <T, U, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>>
+        void run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, S_OUT> m);
+    }
+
+    protected <T, U, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>>
+    Collection<U> exerciseOps(TestData<T, S_IN> data, Function<S_IN, S_OUT> m) {
+        return withData(data).stream(m).exercise();
+    }
+
+    // Run multiple versions of exercise(), returning the result of the first, and asserting that others return the same result
+    // If the first version is s -> s.foo(), can be used with s -> s.mapToInt(i -> i).foo().mapToObj(i -> i) to test all shape variants
+    @SafeVarargs
+    protected final<T, U, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>>
+    Collection<U> exerciseOpsMulti(TestData<T, S_IN> data,
+                                   Function<S_IN, S_OUT>... ms) {
+        Collection<U> result = null;
+        for (Function<S_IN, S_OUT> m : ms) {
+            if (result == null)
+                result = withData(data).stream(m).exercise();
+            else {
+                Collection<U> r2 = withData(data).stream(m).exercise();
+                assertEquals(result, r2);
+            }
+        }
+        return result;
+    }
+
+    // Run multiple versions of exercise() for an Integer stream, returning the result of the first, and asserting that others return the same result
+    // Automates the conversion between Stream<Integer> and {Int,Long,Double}Stream and back, so client sites look like you are passing the same
+    // lambda four times, but in fact they are four different lambdas since they are transforming four different kinds of streams
+    protected final
+    Collection<Integer> exerciseOpsInt(TestData.OfRef<Integer> data,
+                                       Function<Stream<Integer>, Stream<Integer>> mRef,
+                                       Function<IntStream, IntStream> mInt,
+                                       Function<LongStream, LongStream> mLong,
+                                       Function<DoubleStream, DoubleStream> mDouble) {
+        @SuppressWarnings({ "rawtypes", "unchecked" })
+        Function<Stream<Integer>, Stream<Integer>>[] ms = new Function[4];
+        ms[0] = mRef;
+        ms[1] = s -> mInt.apply(s.mapToInt(e -> e)).mapToObj(e -> e);
+        ms[2] = s -> mLong.apply(s.mapToLong(e -> e)).mapToObj(e -> (int) e);
+        ms[3] = s -> mDouble.apply(s.mapToDouble(e -> e)).mapToObj(e -> (int) e);
+        return exerciseOpsMulti(data, ms);
+    }
+
+    // Run multiple versions of exercise() with multiple terminal operations for all kinds of stream, , and asserting against the expected result
+    // If the first version is s -> s.foo(), can be used with s -> s.mapToInt(i -> i).foo().mapToObj(i -> i) to test all shape variants
+    protected final<T, U, R, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>>
+    void exerciseTerminalOpsMulti(TestData<T, S_IN> data,
+                                  R expected,
+                                  Map<String, Function<S_IN, S_OUT>> streams,
+                                  Map<String, Function<S_OUT, R>> terminals) {
+        for (Map.Entry<String, Function<S_IN, S_OUT>> se : streams.entrySet()) {
+            setContext("Intermediate stream", se.getKey());
+            for (Map.Entry<String, Function<S_OUT, R>> te : terminals.entrySet()) {
+                setContext("Terminal stream", te.getKey());
+                withData(data)
+                        .terminal(se.getValue(), te.getValue())
+                        .expectedResult(expected)
+                        .exercise();
+
+            }
+        }
+    }
+
+    // Run multiple versions of exercise() with multiple terminal operation for all kinds of stream, and asserting against the expected result
+    // Automates the conversion between Stream<Integer> and {Int,Long,Double}Stream and back, so client sites look like you are passing the same
+    // lambda four times, but in fact they are four different lambdas since they are transforming four different kinds of streams
+    protected final
+    void exerciseTerminalOpsInt(TestData<Integer, Stream<Integer>> data,
+                                Collection<Integer> expected,
+                                String desc,
+                                Function<Stream<Integer>, Stream<Integer>> mRef,
+                                Function<IntStream, IntStream> mInt,
+                                Function<LongStream, LongStream> mLong,
+                                Function<DoubleStream, DoubleStream> mDouble,
+                                Map<String, Function<Stream<Integer>, Collection<Integer>>> terminals) {
+
+        Map<String, Function<Stream<Integer>, Stream<Integer>>> m = new HashMap<>();
+        m.put("Ref " + desc, mRef);
+        m.put("Int " + desc, s -> mInt.apply(s.mapToInt(e -> e)).mapToObj(e -> e));
+        m.put("Long " + desc, s -> mLong.apply(s.mapToLong(e -> e)).mapToObj(e -> (int) e));
+        m.put("Double " + desc, s -> mDouble.apply(s.mapToDouble(e -> e)).mapToObj(e -> (int) e));
+
+        exerciseTerminalOpsMulti(data, expected, m, terminals);
+    }
+
+
+    protected <T, U, S_OUT extends BaseStream<U, S_OUT>>
+    Collection<U> exerciseOps(Collection<T> data, Function<Stream<T>, S_OUT> m) {
+        TestData.OfRef<T> data1 = TestData.Factory.ofCollection("Collection of type " + data.getClass().getName(), data);
+        return withData(data1).stream(m).exercise();
+    }
+
+    protected <T, U, S_OUT extends BaseStream<U, S_OUT>, I extends Iterable<U>>
+    Collection<U> exerciseOps(Collection<T> data, Function<Stream<T>, S_OUT> m, I expected) {
+        TestData.OfRef<T> data1 = TestData.Factory.ofCollection("Collection of type " + data.getClass().getName(), data);
+        return withData(data1).stream(m).expectedResult(expected).exercise();
+    }
+
+    @SuppressWarnings("unchecked")
+    protected <U, S_OUT extends BaseStream<U, S_OUT>>
+    Collection<U> exerciseOps(int[] data, Function<IntStream, S_OUT> m) {
+        return withData(TestData.Factory.ofArray("int array", data)).stream(m).exercise();
+    }
+
+    protected Collection<Integer> exerciseOps(int[] data, Function<IntStream, IntStream> m, int[] expected) {
+        TestData.OfInt data1 = TestData.Factory.ofArray("int array", data);
+        return withData(data1).stream(m).expectedResult(expected).exercise();
+    }
+
+    protected <T, S_IN extends BaseStream<T, S_IN>> DataStreamBuilder<T, S_IN> withData(TestData<T, S_IN> data) {
+        Objects.requireNonNull(data);
+        return new DataStreamBuilder<>(data);
+    }
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public class DataStreamBuilder<T, S_IN extends BaseStream<T, S_IN>> {
+        final TestData<T, S_IN> data;
+
+        private DataStreamBuilder(TestData<T, S_IN> data) {
+            this.data = Objects.requireNonNull(data);
+        }
+
+        public <U, S_OUT extends BaseStream<U, S_OUT>>
+        ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> ops(IntermediateTestOp... ops) {
+            return new ExerciseDataStreamBuilder<>(data, (S_IN s) -> (S_OUT) chain(s, ops));
+        }
+
+        public <U, S_OUT extends BaseStream<U, S_OUT>> ExerciseDataStreamBuilder<T, U, S_IN, S_OUT>
+        stream(Function<S_IN, S_OUT> m) {
+            return new ExerciseDataStreamBuilder<>(data, m);
+        }
+
+        public <U, S_OUT extends BaseStream<U, S_OUT>> ExerciseDataStreamBuilder<T, U, S_IN, S_OUT>
+        stream(Function<S_IN, S_OUT> m, IntermediateTestOp<U, U> additionalOp) {
+            return new ExerciseDataStreamBuilder<>(data, s -> (S_OUT) chain(m.apply(s), additionalOp));
+        }
+
+        public <R> ExerciseDataTerminalBuilder<T, T, R, S_IN, S_IN>
+        terminal(Function<S_IN, R> terminalF) {
+            return new ExerciseDataTerminalBuilder<>(data, s -> s, terminalF);
+        }
+
+        public <U, R, S_OUT extends BaseStream<U, S_OUT>> ExerciseDataTerminalBuilder<T, U, R, S_IN, S_OUT>
+        terminal(Function<S_IN, S_OUT> streamF, Function<S_OUT, R> terminalF) {
+            return new ExerciseDataTerminalBuilder<>(data, streamF, terminalF);
+        }
+    }
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public class ExerciseDataStreamBuilder<T, U, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>> {
+        final TestData<T, S_IN> data;
+        final Function<S_IN, S_OUT> m;
+        final StreamShape shape;
+
+        Set<BaseStreamTestScenario> testSet = new HashSet<>();
+
+        Collection<U> refResult;
+
+        Consumer<TestData<T, S_IN>> before = LambdaTestHelpers.bEmpty;
+
+        Consumer<TestData<T, S_IN>> after = LambdaTestHelpers.bEmpty;
+
+        ResultAsserter<Iterable<U>> resultAsserter = (act, exp, ord, par) -> {
+            if (par & !ord) {
+                LambdaTestHelpers.assertContentsUnordered(act, exp);
+            }
+            else {
+                LambdaTestHelpers.assertContentsEqual(act, exp);
+            }
+        };
+
+        private ExerciseDataStreamBuilder(TestData<T, S_IN> data, Function<S_IN, S_OUT> m) {
+            this.data = data;
+
+            this.m = Objects.requireNonNull(m);
+
+            this.shape = ((AbstractPipeline<?, U, ?>) m.apply(data.stream())).getOutputShape();
+
+            // Have to initiate from the output shape of the last stream
+            // This means the stream mapper is required first rather than last
+            testSet.addAll(testScenarios.get(shape));
+        }
+
+        //
+
+        public <I extends Iterable<U>> ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> expectedResult(I expectedResult) {
+            List<U> l = new ArrayList<>();
+            expectedResult.forEach(l::add);
+            refResult = l;
+            return this;
+        }
+
+        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> expectedResult(int[] expectedResult) {
+            List l = new ArrayList();
+            for (int anExpectedResult : expectedResult) {
+                l.add(anExpectedResult);
+            }
+            refResult = l;
+            return this;
+        }
+
+        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> expectedResult(long[] expectedResult) {
+            List l = new ArrayList();
+            for (long anExpectedResult : expectedResult) {
+                l.add(anExpectedResult);
+            }
+            refResult = l;
+            return this;
+        }
+
+        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> expectedResult(double[] expectedResult) {
+            List l = new ArrayList();
+            for (double anExpectedResult : expectedResult) {
+                l.add(anExpectedResult);
+            }
+            refResult = l;
+            return this;
+        }
+
+        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> before(Consumer<TestData<T, S_IN>> before) {
+            this.before = Objects.requireNonNull(before);
+            return this;
+        }
+
+        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> after(Consumer<TestData<T, S_IN>> after) {
+            this.after = Objects.requireNonNull(after);
+            return this;
+        }
+
+        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> without(BaseStreamTestScenario... tests) {
+            return without(Arrays.asList(tests));
+        }
+
+        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> without(Collection<? extends BaseStreamTestScenario> tests) {
+            for (BaseStreamTestScenario ts : tests) {
+                if (ts.getShape() == shape) {
+                    testSet.remove(ts);
+                }
+            }
+
+            if (testSet.isEmpty()) {
+                throw new IllegalStateException("Test scenario set is empty");
+            }
+
+            return this;
+        }
+
+        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> with(BaseStreamTestScenario... tests) {
+            return with(Arrays.asList(tests));
+        }
+
+        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> with(Collection<? extends BaseStreamTestScenario> tests) {
+            testSet = new HashSet<>();
+
+            for (BaseStreamTestScenario ts : tests) {
+                if (ts.getShape() == shape) {
+                    testSet.add(ts);
+                }
+            }
+
+            if (testSet.isEmpty()) {
+                throw new IllegalStateException("Test scenario set is empty");
+            }
+
+            return this;
+        }
+
+        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> resultAsserter(ResultAsserter<Iterable<U>> resultAsserter) {
+            this.resultAsserter = resultAsserter;
+            return this;
+        }
+
+        // Build method
+
+        public Collection<U> exercise() {
+            final boolean isStreamOrdered;
+            if (refResult == null) {
+                // Induce the reference result
+                before.accept(data);
+                try (S_OUT sOut = m.apply(data.stream())) {
+                    isStreamOrdered = StreamOpFlag.ORDERED.isKnown(((AbstractPipeline) sOut).getStreamFlags());
+                    Node<U> refNodeResult = ((AbstractPipeline<?, U, ?>) sOut).evaluateToArrayNode(size -> (U[]) new Object[size]);
+                    refResult = LambdaTestHelpers.toBoxedList(refNodeResult.spliterator());
+                }
+                after.accept(data);
+            }
+            else {
+                try (S_OUT sOut = m.apply(data.stream())) {
+                    isStreamOrdered = StreamOpFlag.ORDERED.isKnown(((AbstractPipeline) sOut).getStreamFlags());
+                }
+            }
+
+            List<Error> errors = new ArrayList<>();
+            for (BaseStreamTestScenario test : testSet) {
+                try {
+                    before.accept(data);
+
+                    List<U> result = new ArrayList<>();
+                    test.run(data, LambdaTestHelpers.<U>toBoxingConsumer(result::add), m);
+
+                    Runnable asserter = () -> resultAsserter.assertResult(result, refResult, isStreamOrdered && test.isOrdered(), test.isParallel());
+
+                    if (refResult.size() > 1000) {
+                        LambdaTestHelpers.launderAssertion(
+                                asserter,
+                                () -> String.format("%n%s: [actual size=%d] != [expected size=%d]", test, result.size(), refResult.size()));
+                    }
+                    else {
+                        LambdaTestHelpers.launderAssertion(
+                                asserter,
+                                () -> String.format("%n%s: [actual] %s != [expected] %s", test, result, refResult));
+                    }
+
+                    after.accept(data);
+                } catch (Throwable t) {
+                    errors.add(new Error(String.format("%s: %s", test, t), t));
+                }
+            }
+
+            if (!errors.isEmpty()) {
+                StringBuilder sb = new StringBuilder();
+                int i = 1;
+                for (Error t : errors) {
+                    sb.append(i++).append(": ");
+                    if (t instanceof AssertionError) {
+                        sb.append(t).append("\n");
+                    }
+                    else {
+                        StringWriter sw = new StringWriter();
+                        PrintWriter pw = new PrintWriter(sw);
+
+                        t.getCause().printStackTrace(pw);
+                        pw.flush();
+                        sb.append(t).append("\n").append(sw);
+                    }
+                }
+                sb.append("--");
+
+                fail(String.format("%d failure(s) for test data: %s\n%s", i - 1, data.toString(), sb));
+            }
+
+            return refResult;
+        }
+    }
+
+    // Exercise terminal operations
+
+    interface BaseTerminalTestScenario<U, R, S_OUT extends BaseStream<U, S_OUT>> {
+        boolean requiresSingleStageSource();
+
+        boolean requiresParallelSource();
+
+        default R run(Function<S_OUT, R> terminalF, S_OUT source, StreamShape shape) {
+            return terminalF.apply(source);
+        }
+    }
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    enum TerminalTestScenario implements BaseTerminalTestScenario {
+        SINGLE_SEQUENTIAL(true, false),
+
+        SINGLE_SEQUENTIAL_SHORT_CIRCUIT(true, false) {
+            @Override
+            public Object run(Function terminalF, BaseStream source, StreamShape shape) {
+                source = (BaseStream) chain(source, new ShortCircuitOp(shape));
+                return terminalF.apply(source);
+            }
+        },
+
+        SINGLE_PARALLEL(true, true),
+
+        ALL_SEQUENTIAL(false, false),
+
+        ALL_SEQUENTIAL_SHORT_CIRCUIT(false, false) {
+            @Override
+            public Object run(Function terminalF, BaseStream source, StreamShape shape) {
+                source = (BaseStream) chain(source, new ShortCircuitOp(shape));
+                return terminalF.apply(source);
+            }
+        },
+
+        ALL_PARALLEL(false, true),
+
+        ALL_PARALLEL_SEQUENTIAL(false, false) {
+            @Override
+            public Object run(Function terminalF, BaseStream source, StreamShape shape) {
+                return terminalF.apply(source.sequential());
+            }
+        },
+        ;
+
+        private final boolean requiresSingleStageSource;
+        private final boolean isParallel;
+
+        TerminalTestScenario(boolean requiresSingleStageSource, boolean isParallel) {
+            this.requiresSingleStageSource = requiresSingleStageSource;
+            this.isParallel = isParallel;
+        }
+
+        @Override
+        public boolean requiresSingleStageSource() {
+            return requiresSingleStageSource;
+        }
+
+        @Override
+        public boolean requiresParallelSource() {
+            return isParallel;
+        }
+
+    }
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public class ExerciseDataTerminalBuilder<T, U, R, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>> {
+        final TestData<T, S_IN> data;
+        final Function<S_IN, S_OUT> streamF;
+        final Function<S_OUT, R> terminalF;
+
+        R refResult;
+
+        ResultAsserter<R> resultAsserter = (act, exp, ord, par) -> LambdaTestHelpers.assertContentsEqual(act, exp);
+
+        private ExerciseDataTerminalBuilder(TestData<T, S_IN> data, Function<S_IN, S_OUT> streamF, Function<S_OUT, R> terminalF) {
+            this.data = data;
+            this.streamF = Objects.requireNonNull(streamF);
+            this.terminalF = Objects.requireNonNull(terminalF);
+        }
+
+        //
+
+        public ExerciseDataTerminalBuilder<T, U, R, S_IN, S_OUT> expectedResult(R expectedResult) {
+            this.refResult = expectedResult;
+            return this;
+        }
+
+        public ExerciseDataTerminalBuilder<T, U, R, S_IN, S_OUT> equalator(BiConsumer<R, R> equalityAsserter) {
+            resultAsserter = (act, exp, ord, par) -> equalityAsserter.accept(act, exp);
+            return this;
+        }
+
+        public ExerciseDataTerminalBuilder<T, U, R, S_IN, S_OUT> resultAsserter(ResultAsserter<R> resultAsserter) {
+            this.resultAsserter = resultAsserter;
+            return this;
+        }
+
+        // Build method
+
+        public R exercise() {
+            boolean isOrdered;
+            StreamShape shape;
+            Node<U> node;
+            try (S_OUT out = streamF.apply(data.stream()).sequential()) {
+                AbstractPipeline ap = (AbstractPipeline) out;
+                isOrdered = StreamOpFlag.ORDERED.isKnown(ap.getStreamFlags());
+                shape = ap.getOutputShape();
+                // Sequentially collect the output that will be input to the terminal op
+                node = ap.evaluateToArrayNode(size -> (U[]) new Object[size]);
+            }
+
+            EnumSet<TerminalTestScenario> tests = EnumSet.allOf(TerminalTestScenario.class);
+            if (refResult == null) {
+                // Induce the reference result
+                S_OUT source = (S_OUT) createPipeline(shape, node.spliterator(),
+                                                      StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SIZED,
+                                                      false);
+
+                refResult = (R) TerminalTestScenario.SINGLE_SEQUENTIAL.run(terminalF, source, shape);
+                tests.remove(TerminalTestScenario.SINGLE_SEQUENTIAL);
+            }
+
+            for (BaseTerminalTestScenario test : tests) {
+                S_OUT source;
+                if (test.requiresSingleStageSource()) {
+                    source = (S_OUT) createPipeline(shape, node.spliterator(),
+                                                    StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SIZED,
+                                                    test.requiresParallelSource());
+                }
+                else {
+                    source = streamF.apply(test.requiresParallelSource()
+                                           ? data.parallelStream() : data.stream());
+                }
+
+                R result;
+                try (source) {
+                    result = (R) test.run(terminalF, source, shape);
+                }
+                LambdaTestHelpers.launderAssertion(
+                        () -> resultAsserter.assertResult(result, refResult, isOrdered, test.requiresParallelSource()),
+                        () -> String.format("%s: %s != %s", test, refResult, result));
+            }
+
+            return refResult;
+        }
+
+        AbstractPipeline createPipeline(StreamShape shape, Spliterator s, int flags, boolean parallel) {
+            switch (shape) {
+                case REFERENCE:    return new ReferencePipeline.Head<>(s, flags, parallel);
+                case INT_VALUE:    return new IntPipeline.Head(s, flags, parallel);
+                case LONG_VALUE:   return new LongPipeline.Head(s, flags, parallel);
+                case DOUBLE_VALUE: return new DoublePipeline.Head(s, flags, parallel);
+                default: throw new IllegalStateException("Unknown shape: " + shape);
+            }
+        }
+    }
+
+    protected <T, R> R exerciseTerminalOps(Collection<T> data, Function<Stream<T>, R> m, R expected) {
+        TestData.OfRef<T> data1
+                = TestData.Factory.ofCollection("Collection of type " + data.getClass().getName(), data);
+        return withData(data1).terminal(m).expectedResult(expected).exercise();
+    }
+
+    protected <T, R, S_IN extends BaseStream<T, S_IN>> R
+    exerciseTerminalOps(TestData<T, S_IN> data,
+                        Function<S_IN, R> terminalF) {
+        return withData(data).terminal(terminalF).exercise();
+    }
+
+    protected <T, U, R, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>> R
+    exerciseTerminalOps(TestData<T, S_IN> data,
+                        Function<S_IN, S_OUT> streamF,
+                        Function<S_OUT, R> terminalF) {
+        return withData(data).terminal(streamF, terminalF).exercise();
+    }
+
+    //
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    private static <T> AbstractPipeline<?, T, ?> chain(AbstractPipeline upstream, IntermediateTestOp<?, T> op) {
+        return (AbstractPipeline<?, T, ?>) IntermediateTestOp.chain(upstream, op);
+    }
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    private static AbstractPipeline<?, ?, ?> chain(AbstractPipeline pipe, IntermediateTestOp... ops) {
+        for (IntermediateTestOp op : ops)
+            pipe = chain(pipe, op);
+        return pipe;
+    }
+
+    @SuppressWarnings("rawtypes")
+    private static <T> AbstractPipeline<?, T, ?> chain(BaseStream pipe, IntermediateTestOp<?, T> op) {
+        return chain((AbstractPipeline) pipe, op);
+    }
+
+    @SuppressWarnings("rawtypes")
+    public static AbstractPipeline<?, ?, ?> chain(BaseStream pipe, IntermediateTestOp... ops) {
+        return chain((AbstractPipeline) pipe, ops);
+    }
+
+    // Test data
+
+    static class ShortCircuitOp<T> implements StatelessTestOp<T,T> {
+        private final StreamShape shape;
+
+        ShortCircuitOp(StreamShape shape) {
+            this.shape = shape;
+        }
+
+        @Override
+        public Sink<T> opWrapSink(int flags, boolean parallel, Sink<T> sink) {
+            return sink;
+        }
+
+        @Override
+        public int opGetFlags() {
+            return StreamOpFlag.IS_SHORT_CIRCUIT;
+        }
+
+        @Override
+        public StreamShape outputShape() {
+            return shape;
+        }
+
+        @Override
+        public StreamShape inputShape() {
+            return shape;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/SpliteratorTestHelper.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,715 @@
+/*
+ * 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 java.util.stream;
+
+import org.testng.annotations.Test;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Spliterator;
+import java.util.function.*;
+
+import static org.testng.Assert.*;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+
+/**
+ * Assertion methods for spliterators, to be called from other tests
+ */
+public class SpliteratorTestHelper {
+
+    public interface ContentAsserter<T> {
+        void assertContents(Collection<T> actual, Collection<T> expected, boolean isOrdered);
+    }
+
+    private static ContentAsserter<Object> DEFAULT_CONTENT_ASSERTER
+            = SpliteratorTestHelper::assertContents;
+
+    @SuppressWarnings("unchecked")
+    private static <T> ContentAsserter<T> defaultContentAsserter() {
+        return (ContentAsserter<T>) DEFAULT_CONTENT_ASSERTER;
+    }
+
+    public static void testSpliterator(Supplier<Spliterator<Integer>> supplier) {
+        testSpliterator(supplier, defaultContentAsserter());
+    }
+
+    public static void testSpliterator(Supplier<Spliterator<Integer>> supplier,
+                                       ContentAsserter<Integer> asserter) {
+        testSpliterator(supplier, (Consumer<Integer> b) -> b, asserter);
+    }
+
+    public static void testIntSpliterator(Supplier<Spliterator.OfInt> supplier) {
+        testIntSpliterator(supplier, defaultContentAsserter());
+    }
+
+    public static void testIntSpliterator(Supplier<Spliterator.OfInt> supplier,
+                                          ContentAsserter<Integer> asserter) {
+        class BoxingAdapter implements Consumer<Integer>, IntConsumer {
+            private final Consumer<Integer> b;
+
+            BoxingAdapter(Consumer<Integer> b) {
+                this.b = b;
+            }
+
+            @Override
+            public void accept(Integer value) {
+                throw new IllegalStateException();
+            }
+
+            @Override
+            public void accept(int value) {
+                b.accept(value);
+            }
+        }
+
+        testSpliterator(supplier, BoxingAdapter::new, asserter);
+    }
+
+    public static void testLongSpliterator(Supplier<Spliterator.OfLong> supplier) {
+        testLongSpliterator(supplier, defaultContentAsserter());
+    }
+
+    public static void testLongSpliterator(Supplier<Spliterator.OfLong> supplier,
+                                           ContentAsserter<Long> asserter) {
+        class BoxingAdapter implements Consumer<Long>, LongConsumer {
+            private final Consumer<Long> b;
+
+            BoxingAdapter(Consumer<Long> b) {
+                this.b = b;
+            }
+
+            @Override
+            public void accept(Long value) {
+                throw new IllegalStateException();
+            }
+
+            @Override
+            public void accept(long value) {
+                b.accept(value);
+            }
+        }
+
+        testSpliterator(supplier, BoxingAdapter::new, asserter);
+    }
+
+    public static void testDoubleSpliterator(Supplier<Spliterator.OfDouble> supplier) {
+        testDoubleSpliterator(supplier, defaultContentAsserter());
+    }
+
+    public static void testDoubleSpliterator(Supplier<Spliterator.OfDouble> supplier,
+                                             ContentAsserter<Double> asserter) {
+        class BoxingAdapter implements Consumer<Double>, DoubleConsumer {
+            private final Consumer<Double> b;
+
+            BoxingAdapter(Consumer<Double> b) {
+                this.b = b;
+            }
+
+            @Override
+            public void accept(Double value) {
+                throw new IllegalStateException();
+            }
+
+            @Override
+            public void accept(double value) {
+                b.accept(value);
+            }
+        }
+
+        testSpliterator(supplier, BoxingAdapter::new, asserter);
+    }
+
+    static <T, S extends Spliterator<T>> void testSpliterator(Supplier<S> supplier,
+                                                              UnaryOperator<Consumer<T>> boxingAdapter,
+                                                              ContentAsserter<T> asserter) {
+        ArrayList<T> fromForEach = new ArrayList<>();
+        Spliterator<T> spliterator = supplier.get();
+        Consumer<T> addToFromForEach = boxingAdapter.apply(fromForEach::add);
+        spliterator.forEachRemaining(addToFromForEach);
+
+        Collection<T> exp = Collections.unmodifiableList(fromForEach);
+
+        testNullPointerException(supplier);
+        testForEach(exp, supplier, boxingAdapter, asserter);
+        testTryAdvance(exp, supplier, boxingAdapter, asserter);
+        testMixedTryAdvanceForEach(exp, supplier, boxingAdapter, asserter);
+        testMixedTraverseAndSplit(exp, supplier, boxingAdapter, asserter);
+        testSplitAfterFullTraversal(supplier, boxingAdapter);
+        testSplitOnce(exp, supplier, boxingAdapter, asserter);
+        testSplitSixDeep(exp, supplier, boxingAdapter, asserter);
+        testSplitUntilNull(exp, supplier, boxingAdapter, asserter);
+    }
+
+    //
+
+    private static <T, S extends Spliterator<T>> void testNullPointerException(Supplier<S> s) {
+        S sp = s.get();
+        // Have to check instances and use casts to avoid tripwire messages and
+        // directly test the primitive methods
+        if (sp instanceof Spliterator.OfInt) {
+            Spliterator.OfInt psp = (Spliterator.OfInt) sp;
+            executeAndCatch(NullPointerException.class, () -> psp.forEachRemaining((IntConsumer) null));
+            executeAndCatch(NullPointerException.class, () -> psp.tryAdvance((IntConsumer) null));
+        }
+        else if (sp instanceof Spliterator.OfLong) {
+            Spliterator.OfLong psp = (Spliterator.OfLong) sp;
+            executeAndCatch(NullPointerException.class, () -> psp.forEachRemaining((LongConsumer) null));
+            executeAndCatch(NullPointerException.class, () -> psp.tryAdvance((LongConsumer) null));
+        }
+        else if (sp instanceof Spliterator.OfDouble) {
+            Spliterator.OfDouble psp = (Spliterator.OfDouble) sp;
+            executeAndCatch(NullPointerException.class, () -> psp.forEachRemaining((DoubleConsumer) null));
+            executeAndCatch(NullPointerException.class, () -> psp.tryAdvance((DoubleConsumer) null));
+        }
+        else {
+            executeAndCatch(NullPointerException.class, () -> sp.forEachRemaining(null));
+            executeAndCatch(NullPointerException.class, () -> sp.tryAdvance(null));
+        }
+    }
+
+    private static <T, S extends Spliterator<T>> void testForEach(
+            Collection<T> exp,
+            Supplier<S> supplier,
+            UnaryOperator<Consumer<T>> boxingAdapter,
+            ContentAsserter<T> asserter) {
+        S spliterator = supplier.get();
+        long sizeIfKnown = spliterator.getExactSizeIfKnown();
+        boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
+
+        ArrayList<T> fromForEach = new ArrayList<>();
+        spliterator = supplier.get();
+        Consumer<T> addToFromForEach = boxingAdapter.apply(fromForEach::add);
+        spliterator.forEachRemaining(addToFromForEach);
+
+        // Assert that forEach now produces no elements
+        spliterator.forEachRemaining(boxingAdapter.apply(
+                e -> fail("Spliterator.forEach produced an element after spliterator exhausted: " + e)));
+        // Assert that tryAdvance now produce no elements
+        spliterator.tryAdvance(boxingAdapter.apply(
+                e -> fail("Spliterator.tryAdvance produced an element after spliterator exhausted: " + e)));
+
+        // assert that size, tryAdvance, and forEach are consistent
+        if (sizeIfKnown >= 0) {
+            assertEquals(sizeIfKnown, exp.size());
+        }
+        assertEquals(fromForEach.size(), exp.size());
+
+        asserter.assertContents(fromForEach, exp, isOrdered);
+    }
+
+    private static <T, S extends Spliterator<T>> void testTryAdvance(
+            Collection<T> exp,
+            Supplier<S> supplier,
+            UnaryOperator<Consumer<T>> boxingAdapter,
+            ContentAsserter<T> asserter) {
+        S spliterator = supplier.get();
+        long sizeIfKnown = spliterator.getExactSizeIfKnown();
+        boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
+
+        spliterator = supplier.get();
+        ArrayList<T> fromTryAdvance = new ArrayList<>();
+        Consumer<T> addToFromTryAdvance = boxingAdapter.apply(fromTryAdvance::add);
+        while (spliterator.tryAdvance(addToFromTryAdvance)) { }
+
+        // Assert that forEach now produces no elements
+        spliterator.forEachRemaining(boxingAdapter.apply(
+                e -> fail("Spliterator.forEach produced an element after spliterator exhausted: " + e)));
+        // Assert that tryAdvance now produce no elements
+        spliterator.tryAdvance(boxingAdapter.apply(
+                e -> fail("Spliterator.tryAdvance produced an element after spliterator exhausted: " + e)));
+
+        // assert that size, tryAdvance, and forEach are consistent
+        if (sizeIfKnown >= 0) {
+            assertEquals(sizeIfKnown, exp.size());
+        }
+        assertEquals(fromTryAdvance.size(), exp.size());
+
+        asserter.assertContents(fromTryAdvance, exp, isOrdered);
+    }
+
+    private static <T, S extends Spliterator<T>> void testMixedTryAdvanceForEach(
+            Collection<T> exp,
+            Supplier<S> supplier,
+            UnaryOperator<Consumer<T>> boxingAdapter,
+            ContentAsserter<T> asserter) {
+        S spliterator = supplier.get();
+        long sizeIfKnown = spliterator.getExactSizeIfKnown();
+        boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
+
+        // tryAdvance first few elements, then forEach rest
+        ArrayList<T> dest = new ArrayList<>();
+        spliterator = supplier.get();
+        Consumer<T> addToDest = boxingAdapter.apply(dest::add);
+        for (int i = 0; i < 10 && spliterator.tryAdvance(addToDest); i++) { }
+        spliterator.forEachRemaining(addToDest);
+
+        // Assert that forEach now produces no elements
+        spliterator.forEachRemaining(boxingAdapter.apply(
+                e -> fail("Spliterator.forEach produced an element after spliterator exhausted: " + e)));
+        // Assert that tryAdvance now produce no elements
+        spliterator.tryAdvance(boxingAdapter.apply(
+                e -> fail("Spliterator.tryAdvance produced an element after spliterator exhausted: " + e)));
+
+        if (sizeIfKnown >= 0) {
+            assertEquals(sizeIfKnown, dest.size());
+        }
+        assertEquals(dest.size(), exp.size());
+
+        asserter.assertContents(dest, exp, isOrdered);
+    }
+
+    private static <T, S extends Spliterator<T>> void testMixedTraverseAndSplit(
+            Collection<T> exp,
+            Supplier<S> supplier,
+            UnaryOperator<Consumer<T>> boxingAdapter,
+            ContentAsserter<T> asserter) {
+        S spliterator = supplier.get();
+        long sizeIfKnown = spliterator.getExactSizeIfKnown();
+        boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
+
+        // tryAdvance first few elements, then forEach rest
+        ArrayList<T> dest = new ArrayList<>();
+        spliterator = supplier.get();
+        Consumer<T> b = boxingAdapter.apply(dest::add);
+
+        Spliterator<T> spl1, spl2, spl3;
+        spliterator.tryAdvance(b);
+        spl2 = spliterator.trySplit();
+        if (spl2 != null) {
+            spl2.tryAdvance(b);
+            spl1 = spl2.trySplit();
+            if (spl1 != null) {
+                spl1.tryAdvance(b);
+                spl1.forEachRemaining(b);
+            }
+            spl2.tryAdvance(b);
+            spl2.forEachRemaining(b);
+        }
+        spliterator.tryAdvance(b);
+        spl3 = spliterator.trySplit();
+        if (spl3 != null) {
+            spl3.tryAdvance(b);
+            spl3.forEachRemaining(b);
+        }
+        spliterator.tryAdvance(b);
+        spliterator.forEachRemaining(b);
+
+        if (sizeIfKnown >= 0) {
+            assertEquals(sizeIfKnown, dest.size());
+        }
+        assertEquals(dest.size(), exp.size());
+
+        asserter.assertContents(dest, exp, isOrdered);
+    }
+
+    private static <T, S extends Spliterator<T>> void testSplitAfterFullTraversal(
+            Supplier<S> supplier,
+            UnaryOperator<Consumer<T>> boxingAdapter) {
+        // Full traversal using tryAdvance
+        Spliterator<T> spliterator = supplier.get();
+        while (spliterator.tryAdvance(boxingAdapter.apply(e -> { }))) { }
+        Spliterator<T> split = spliterator.trySplit();
+        assertNull(split);
+
+        // Full traversal using forEach
+        spliterator = supplier.get();
+        spliterator.forEachRemaining(boxingAdapter.apply(e -> { }));
+        split = spliterator.trySplit();
+        assertNull(split);
+
+        // Full traversal using tryAdvance then forEach
+        spliterator = supplier.get();
+        spliterator.tryAdvance(boxingAdapter.apply(e -> { }));
+        spliterator.forEachRemaining(boxingAdapter.apply(e -> { }));
+        split = spliterator.trySplit();
+        assertNull(split);
+    }
+
+    private static <T, S extends Spliterator<T>> void testSplitOnce(
+            Collection<T> exp,
+            Supplier<S> supplier,
+            UnaryOperator<Consumer<T>> boxingAdapter,
+            ContentAsserter<T> asserter) {
+        S spliterator = supplier.get();
+        long sizeIfKnown = spliterator.getExactSizeIfKnown();
+        boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
+
+        ArrayList<T> fromSplit = new ArrayList<>();
+        Spliterator<T> s1 = supplier.get();
+        Spliterator<T> s2 = s1.trySplit();
+        long s1Size = s1.getExactSizeIfKnown();
+        long s2Size = (s2 != null) ? s2.getExactSizeIfKnown() : 0;
+        Consumer<T> addToFromSplit = boxingAdapter.apply(fromSplit::add);
+        if (s2 != null)
+            s2.forEachRemaining(addToFromSplit);
+        s1.forEachRemaining(addToFromSplit);
+
+        if (sizeIfKnown >= 0) {
+            assertEquals(sizeIfKnown, fromSplit.size());
+            if (s1Size >= 0 && s2Size >= 0)
+                assertEquals(sizeIfKnown, s1Size + s2Size);
+        }
+
+        asserter.assertContents(fromSplit, exp, isOrdered);
+    }
+
+    private static <T, S extends Spliterator<T>> void testSplitSixDeep(
+            Collection<T> exp,
+            Supplier<S> supplier,
+            UnaryOperator<Consumer<T>> boxingAdapter,
+            ContentAsserter<T> asserter) {
+        S spliterator = supplier.get();
+        boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
+
+        for (int depth=0; depth < 6; depth++) {
+            List<T> dest = new ArrayList<>();
+            spliterator = supplier.get();
+
+            assertSpliterator(spliterator);
+
+            // verify splitting with forEach
+            splitSixDeepVisitor(depth, 0, dest, spliterator, boxingAdapter, spliterator.characteristics(), false);
+            asserter.assertContents(dest, exp, isOrdered);
+
+            // verify splitting with tryAdvance
+            dest.clear();
+            spliterator = supplier.get();
+            splitSixDeepVisitor(depth, 0, dest, spliterator, boxingAdapter, spliterator.characteristics(), true);
+            asserter.assertContents(dest, exp, isOrdered);
+        }
+    }
+
+    private static <T, S extends Spliterator<T>>
+    void splitSixDeepVisitor(int depth, int curLevel,
+                             List<T> dest, S spliterator, UnaryOperator<Consumer<T>> boxingAdapter,
+                             int rootCharacteristics, boolean useTryAdvance) {
+        if (curLevel < depth) {
+            long beforeSize = spliterator.getExactSizeIfKnown();
+            Spliterator<T> split = spliterator.trySplit();
+            if (split != null) {
+                assertSpliterator(split, rootCharacteristics);
+                assertSpliterator(spliterator, rootCharacteristics);
+
+                if ((rootCharacteristics & Spliterator.SUBSIZED) != 0 &&
+                    (rootCharacteristics & Spliterator.SIZED) != 0) {
+                    assertEquals(beforeSize, split.estimateSize() + spliterator.estimateSize());
+                }
+                splitSixDeepVisitor(depth, curLevel + 1, dest, split, boxingAdapter, rootCharacteristics, useTryAdvance);
+            }
+            splitSixDeepVisitor(depth, curLevel + 1, dest, spliterator, boxingAdapter, rootCharacteristics, useTryAdvance);
+        }
+        else {
+            long sizeIfKnown = spliterator.getExactSizeIfKnown();
+            if (useTryAdvance) {
+                Consumer<T> addToDest = boxingAdapter.apply(dest::add);
+                int count = 0;
+                while (spliterator.tryAdvance(addToDest)) {
+                    ++count;
+                }
+
+                if (sizeIfKnown >= 0)
+                    assertEquals(sizeIfKnown, count);
+
+                // Assert that forEach now produces no elements
+                spliterator.forEachRemaining(boxingAdapter.apply(
+                        e -> fail("Spliterator.forEach produced an element after spliterator exhausted: " + e)));
+
+                Spliterator<T> split = spliterator.trySplit();
+                assertNull(split);
+            }
+            else {
+                List<T> leafDest = new ArrayList<>();
+                Consumer<T> addToLeafDest = boxingAdapter.apply(leafDest::add);
+                spliterator.forEachRemaining(addToLeafDest);
+
+                if (sizeIfKnown >= 0)
+                    assertEquals(sizeIfKnown, leafDest.size());
+
+                // Assert that forEach now produces no elements
+                spliterator.tryAdvance(boxingAdapter.apply(
+                        e -> fail("Spliterator.tryAdvance produced an element after spliterator exhausted: " + e)));
+
+                Spliterator<T> split = spliterator.trySplit();
+                assertNull(split);
+
+                dest.addAll(leafDest);
+            }
+        }
+    }
+
+    private static <T, S extends Spliterator<T>> void testSplitUntilNull(
+            Collection<T> exp,
+            Supplier<S> supplier,
+            UnaryOperator<Consumer<T>> boxingAdapter,
+            ContentAsserter<T> asserter) {
+        Spliterator<T> s = supplier.get();
+        boolean isOrdered = s.hasCharacteristics(Spliterator.ORDERED);
+        assertSpliterator(s);
+
+        List<T> splits = new ArrayList<>();
+        Consumer<T> c = boxingAdapter.apply(splits::add);
+
+        testSplitUntilNull(new SplitNode<T>(c, s));
+        asserter.assertContents(splits, exp, isOrdered);
+    }
+
+    private static class SplitNode<T> {
+        // Constant for every node
+        final Consumer<T> c;
+        final int rootCharacteristics;
+
+        final Spliterator<T> s;
+
+        SplitNode(Consumer<T> c, Spliterator<T> s) {
+            this(c, s.characteristics(), s);
+        }
+
+        private SplitNode(Consumer<T> c, int rootCharacteristics, Spliterator<T> s) {
+            this.c = c;
+            this.rootCharacteristics = rootCharacteristics;
+            this.s = s;
+        }
+
+        SplitNode<T> fromSplit(Spliterator<T> split) {
+            return new SplitNode<>(c, rootCharacteristics, split);
+        }
+    }
+
+    /**
+     * Set the maximum stack capacity to 0.25MB. This should be more than enough to detect a bad spliterator
+     * while not unduly disrupting test infrastructure given the test data sizes that are used are small.
+     * Note that j.u.c.ForkJoinPool sets the max queue size to 64M (1 << 26).
+     */
+    private static final int MAXIMUM_STACK_CAPACITY = 1 << 18; // 0.25MB
+
+    private static <T> void testSplitUntilNull(SplitNode<T> e) {
+        // Use an explicit stack to avoid a StackOverflowException when testing a Spliterator
+        // that when repeatedly split produces a right-balanced (and maybe degenerate) tree, or
+        // for a spliterator that is badly behaved.
+        Deque<SplitNode<T>> stack = new ArrayDeque<>();
+        stack.push(e);
+
+        int iteration = 0;
+        while (!stack.isEmpty()) {
+            assertTrue(iteration++ < MAXIMUM_STACK_CAPACITY, "Exceeded maximum stack modification count of 1 << 18");
+
+            e = stack.pop();
+            Spliterator<T> parentAndRightSplit = e.s;
+
+            long parentEstimateSize = parentAndRightSplit.estimateSize();
+            assertTrue(parentEstimateSize >= 0,
+                       String.format("Split size estimate %d < 0", parentEstimateSize));
+
+            long parentSize = parentAndRightSplit.getExactSizeIfKnown();
+            Spliterator<T> leftSplit = parentAndRightSplit.trySplit();
+            if (leftSplit == null) {
+                parentAndRightSplit.forEachRemaining(e.c);
+                continue;
+            }
+
+            assertSpliterator(leftSplit, e.rootCharacteristics);
+            assertSpliterator(parentAndRightSplit, e.rootCharacteristics);
+
+            if (parentEstimateSize != Long.MAX_VALUE && leftSplit.estimateSize() > 0
+                && parentAndRightSplit.estimateSize() > 0) {
+                assertTrue(leftSplit.estimateSize() < parentEstimateSize,
+                           String.format("Left split size estimate %d >= parent split size estimate %d",
+                                         leftSplit.estimateSize(), parentEstimateSize));
+                assertTrue(parentAndRightSplit.estimateSize() < parentEstimateSize,
+                           String.format("Right split size estimate %d >= parent split size estimate %d",
+                                         leftSplit.estimateSize(), parentEstimateSize));
+            }
+            else {
+                assertTrue(leftSplit.estimateSize() <= parentEstimateSize,
+                           String.format("Left split size estimate %d > parent split size estimate %d",
+                                         leftSplit.estimateSize(), parentEstimateSize));
+                assertTrue(parentAndRightSplit.estimateSize() <= parentEstimateSize,
+                           String.format("Right split size estimate %d > parent split size estimate %d",
+                                         leftSplit.estimateSize(), parentEstimateSize));
+            }
+
+            long leftSize = leftSplit.getExactSizeIfKnown();
+            long rightSize = parentAndRightSplit.getExactSizeIfKnown();
+            if (parentSize >= 0 && leftSize >= 0 && rightSize >= 0)
+                assertEquals(parentSize, leftSize + rightSize,
+                             String.format("exact left split size %d + exact right split size %d != parent exact split size %d",
+                                           leftSize, rightSize, parentSize));
+
+            // Add right side to stack first so left side is popped off first
+            stack.push(e.fromSplit(parentAndRightSplit));
+            stack.push(e.fromSplit(leftSplit));
+        }
+    }
+
+    private static void assertSpliterator(Spliterator<?> s, int rootCharacteristics) {
+        if ((rootCharacteristics & Spliterator.SUBSIZED) != 0) {
+            assertTrue(s.hasCharacteristics(Spliterator.SUBSIZED),
+                       "Child split is not SUBSIZED when root split is SUBSIZED");
+        }
+        assertSpliterator(s);
+    }
+
+    private static void assertSpliterator(Spliterator<?> s) {
+        if (s.hasCharacteristics(Spliterator.SUBSIZED)) {
+            assertTrue(s.hasCharacteristics(Spliterator.SIZED));
+        }
+        if (s.hasCharacteristics(Spliterator.SIZED)) {
+            assertTrue(s.estimateSize() != Long.MAX_VALUE);
+            assertTrue(s.getExactSizeIfKnown() >= 0);
+        }
+        try {
+            s.getComparator();
+            assertTrue(s.hasCharacteristics(Spliterator.SORTED));
+        } catch (IllegalStateException e) {
+            assertFalse(s.hasCharacteristics(Spliterator.SORTED));
+        }
+    }
+
+    private static<T> void assertContents(Collection<T> actual, Collection<T> expected, boolean isOrdered) {
+        if (isOrdered) {
+            assertEquals(actual, expected);
+        }
+        else {
+            LambdaTestHelpers.assertContentsUnordered(actual, expected);
+        }
+    }
+
+    private static void executeAndCatch(Class<? extends Exception> expected, Runnable r) {
+        Exception caught = null;
+        try {
+            r.run();
+        }
+        catch (Exception e) {
+            caught = e;
+        }
+
+        assertNotNull(caught,
+                      String.format("No Exception was thrown, expected an Exception of %s to be thrown",
+                                    expected.getName()));
+        assertTrue(expected.isInstance(caught),
+                   String.format("Exception thrown %s not an instance of %s",
+                                 caught.getClass().getName(), expected.getName()));
+    }
+
+    static<U> void mixedTraverseAndSplit(Consumer<U> b, Spliterator<U> splTop) {
+        Spliterator<U> spl1, spl2, spl3;
+        splTop.tryAdvance(b);
+        spl2 = splTop.trySplit();
+        if (spl2 != null) {
+            spl2.tryAdvance(b);
+            spl1 = spl2.trySplit();
+            if (spl1 != null) {
+                spl1.tryAdvance(b);
+                spl1.forEachRemaining(b);
+            }
+            spl2.tryAdvance(b);
+            spl2.forEachRemaining(b);
+        }
+        splTop.tryAdvance(b);
+        spl3 = splTop.trySplit();
+        if (spl3 != null) {
+            spl3.tryAdvance(b);
+            spl3.forEachRemaining(b);
+        }
+        splTop.tryAdvance(b);
+        splTop.forEachRemaining(b);
+    }
+
+    static void mixedTraverseAndSplit(IntConsumer b, Spliterator.OfInt splTop) {
+        Spliterator.OfInt spl1, spl2, spl3;
+        splTop.tryAdvance(b);
+        spl2 = splTop.trySplit();
+        if (spl2 != null) {
+            spl2.tryAdvance(b);
+            spl1 = spl2.trySplit();
+            if (spl1 != null) {
+                spl1.tryAdvance(b);
+                spl1.forEachRemaining(b);
+            }
+            spl2.tryAdvance(b);
+            spl2.forEachRemaining(b);
+        }
+        splTop.tryAdvance(b);
+        spl3 = splTop.trySplit();
+        if (spl3 != null) {
+            spl3.tryAdvance(b);
+            spl3.forEachRemaining(b);
+        }
+        splTop.tryAdvance(b);
+        splTop.forEachRemaining(b);
+    }
+    static void mixedTraverseAndSplit(LongConsumer b, Spliterator.OfLong splTop) {
+        Spliterator.OfLong spl1, spl2, spl3;
+        splTop.tryAdvance(b);
+        spl2 = splTop.trySplit();
+        if (spl2 != null) {
+            spl2.tryAdvance(b);
+            spl1 = spl2.trySplit();
+            if (spl1 != null) {
+                spl1.tryAdvance(b);
+                spl1.forEachRemaining(b);
+            }
+            spl2.tryAdvance(b);
+            spl2.forEachRemaining(b);
+        }
+        splTop.tryAdvance(b);
+        spl3 = splTop.trySplit();
+        if (spl3 != null) {
+            spl3.tryAdvance(b);
+            spl3.forEachRemaining(b);
+        }
+        splTop.tryAdvance(b);
+        splTop.forEachRemaining(b);
+    }
+
+    static void mixedTraverseAndSplit(DoubleConsumer b, Spliterator.OfDouble splTop) {
+        Spliterator.OfDouble spl1, spl2, spl3;
+        splTop.tryAdvance(b);
+        spl2 = splTop.trySplit();
+        if (spl2 != null) {
+            spl2.tryAdvance(b);
+            spl1 = spl2.trySplit();
+            if (spl1 != null) {
+                spl1.tryAdvance(b);
+                spl1.forEachRemaining(b);
+            }
+            spl2.tryAdvance(b);
+            spl2.forEachRemaining(b);
+        }
+        splTop.tryAdvance(b);
+        spl3 = splTop.trySplit();
+        if (spl3 != null) {
+            spl3.tryAdvance(b);
+            spl3.forEachRemaining(b);
+        }
+        splTop.tryAdvance(b);
+        splTop.forEachRemaining(b);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/StatefulTestOp.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,138 @@
+/*
+ * 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 java.util.stream;
+
+import java.util.Spliterator;
+import java.util.function.IntFunction;
+
+/**
+ * The base type for a stateful test operation.
+ */
+interface StatefulTestOp<E> extends IntermediateTestOp<E, E> {
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public static<T> AbstractPipeline chain(AbstractPipeline upstream,
+                                            StatefulTestOp op) {
+        switch (op.outputShape()) {
+            case REFERENCE:
+                return new ReferencePipeline.StatefulOp<Object, T>(upstream, op.inputShape(), op.opGetFlags()) {
+                    @Override
+                    Sink opWrapSink(int flags, Sink sink) {
+                        return op.opWrapSink(flags, isParallel(), sink);
+                    }
+
+                    @Override
+                    <P_IN> Spliterator<T> opEvaluateParallelLazy(PipelineHelper<T> helper,
+                                                                 Spliterator<P_IN> spliterator) {
+                        return op.opEvaluateParallelLazy(helper, spliterator);
+                    }
+
+                    @Override
+                    <P_IN> Node<T> opEvaluateParallel(PipelineHelper<T> helper,
+                                                      Spliterator<P_IN> spliterator,
+                                                      IntFunction<T[]> generator) {
+                        return op.opEvaluateParallel(helper, spliterator, generator);
+                    }
+                };
+            case INT_VALUE:
+                return new IntPipeline.StatefulOp<Object>(upstream, op.inputShape(), op.opGetFlags()) {
+                    @Override
+                    Sink opWrapSink(int flags, Sink sink) {
+                        return op.opWrapSink(flags, isParallel(), sink);
+                    }
+
+                    @Override
+                    <P_IN> Spliterator<Integer> opEvaluateParallelLazy(PipelineHelper<Integer> helper,
+                                                                 Spliterator<P_IN> spliterator) {
+                        return op.opEvaluateParallelLazy(helper, spliterator);
+                    }
+
+                    @Override
+                    <P_IN> Node<Integer> opEvaluateParallel(PipelineHelper<Integer> helper,
+                                                            Spliterator<P_IN> spliterator,
+                                                            IntFunction<Integer[]> generator) {
+                        return (Node<Integer>) op.opEvaluateParallel(helper, spliterator, generator);
+                    }
+                };
+            case LONG_VALUE:
+                return new LongPipeline.StatefulOp<Object>(upstream, op.inputShape(), op.opGetFlags()) {
+                    @Override
+                    Sink opWrapSink(int flags, Sink sink) {
+                        return op.opWrapSink(flags, isParallel(), sink);
+                    }
+
+                    @Override
+                    <P_IN> Spliterator<Long> opEvaluateParallelLazy(PipelineHelper<Long> helper,
+                                                                 Spliterator<P_IN> spliterator) {
+                        return op.opEvaluateParallelLazy(helper, spliterator);
+                    }
+
+                    @Override
+                    <P_IN> Node<Long> opEvaluateParallel(PipelineHelper<Long> helper,
+                                                         Spliterator<P_IN> spliterator,
+                                                         IntFunction<Long[]> generator) {
+                        return (Node<Long>) op.opEvaluateParallel(helper, spliterator, generator);
+                    }
+                };
+            case DOUBLE_VALUE:
+                return new DoublePipeline.StatefulOp<Object>(upstream, op.inputShape(), op.opGetFlags()) {
+                    @Override
+                    Sink opWrapSink(int flags, Sink sink) {
+                        return op.opWrapSink(flags, isParallel(), sink);
+                    }
+
+                    @Override
+                    <P_IN> Spliterator<Double> opEvaluateParallelLazy(PipelineHelper<Double> helper,
+                                                                    Spliterator<P_IN> spliterator) {
+                        return op.opEvaluateParallelLazy(helper, spliterator);
+                    }
+
+                    @Override
+                    <P_IN> Node<Double> opEvaluateParallel(PipelineHelper<Double> helper,
+                                                           Spliterator<P_IN> spliterator,
+                                                           IntFunction<Double[]> generator) {
+                        return (Node<Double>) op.opEvaluateParallel(helper, spliterator, generator);
+                    }
+                };
+            default: throw new IllegalStateException(op.outputShape().toString());
+        }
+    }
+
+    default StreamShape inputShape() { return StreamShape.REFERENCE; }
+
+    default StreamShape outputShape() { return StreamShape.REFERENCE; }
+
+    default int opGetFlags() { return 0; }
+
+    Sink<E> opWrapSink(int flags, boolean parallel, Sink<E> sink);
+
+    @SuppressWarnings("unchecked")
+    default <P_IN> Spliterator<E> opEvaluateParallelLazy(PipelineHelper<E> helper,
+                                                         Spliterator<P_IN> spliterator) {
+        return opEvaluateParallel(helper, spliterator, i -> (E[]) new Object[i]).spliterator();
+    }
+
+    <P_IN> Node<E> opEvaluateParallel(PipelineHelper<E> helper,
+                                      Spliterator<P_IN> spliterator,
+                                      IntFunction<E[]> generator);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/StatelessTestOp.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 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 java.util.stream;
+
+/**
+ * The base type of a stateless test operation
+ */
+interface StatelessTestOp<E_IN, E_OUT> extends IntermediateTestOp<E_IN, E_OUT> {
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public static<T> AbstractPipeline chain(AbstractPipeline upstream,
+                                            StatelessTestOp<?, T> op) {
+        int flags = op.opGetFlags();
+        switch (op.outputShape()) {
+            case REFERENCE:
+                return new ReferencePipeline.StatelessOp<Object, T>(upstream, op.inputShape(), flags) {
+                    public Sink opWrapSink(int flags, Sink<T> sink) {
+                        return op.opWrapSink(flags, isParallel(), sink);
+                    }
+                };
+            case INT_VALUE:
+                return new IntPipeline.StatelessOp<Object>(upstream, op.inputShape(), flags) {
+                    public Sink opWrapSink(int flags, Sink sink) {
+                        return op.opWrapSink(flags, isParallel(), sink);
+                    }
+                };
+            case LONG_VALUE:
+                return new LongPipeline.StatelessOp<Object>(upstream, op.inputShape(), flags) {
+                    @Override
+                    Sink opWrapSink(int flags, Sink sink) {
+                        return op.opWrapSink(flags, isParallel(), sink);
+                    }
+                };
+            case DOUBLE_VALUE:
+                return new DoublePipeline.StatelessOp<Object>(upstream, op.inputShape(), flags) {
+                    @Override
+                    Sink opWrapSink(int flags, Sink sink) {
+                        return op.opWrapSink(flags, isParallel(), sink);
+                    }
+                };
+            default: throw new IllegalStateException(op.outputShape().toString());
+        }
+    }
+
+    default StreamShape inputShape() { return StreamShape.REFERENCE; }
+
+    default StreamShape outputShape() { return StreamShape.REFERENCE; }
+
+    default int opGetFlags() { return 0; }
+
+    Sink<E_IN> opWrapSink(int flags, boolean parallel, Sink<E_OUT> sink);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/StreamOpFlagTestHelper.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,48 @@
+/*
+ * 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 java.util.stream;
+
+import java.util.EnumSet;
+
+public class StreamOpFlagTestHelper {
+
+    /** EnumSet containing stream flags */
+    private static final EnumSet<StreamOpFlag> allStreamFlags;
+
+    static {
+        allStreamFlags = EnumSet.allOf(StreamOpFlag.class);
+        for (StreamOpFlag f : EnumSet.allOf(StreamOpFlag.class))
+            if (!f.isStreamFlag())
+                allStreamFlags.remove(f);
+    }
+
+
+    static EnumSet<StreamOpFlag> allStreamFlags() {
+        // EnumSet is mutable
+        return allStreamFlags.clone();
+    }
+
+    public static boolean isStreamOrdered(Stream<?> s) {
+        return StreamOpFlag.ORDERED.isKnown(OpTestCase.getStreamFlags(s));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/StreamTestDataProvider.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,205 @@
+/*
+ * 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 java.util.stream;
+
+import org.testng.annotations.DataProvider;
+
+import java.util.*;
+import java.util.Spliterators;
+import java.util.function.Supplier;
+
+/**
+ * StreamTestDataProvider
+ *
+ * @author Brian Goetz
+ */
+/** TestNG DataProvider for ref-valued streams */
+public class StreamTestDataProvider {
+    private static final Integer[] to0 = new Integer[0];
+    private static final Integer[] to1 = new Integer[1];
+    private static final Integer[] to10 = new Integer[10];
+    private static final Integer[] to100 = new Integer[100];
+    private static final Integer[] to1000 = new Integer[1000];
+    private static final Integer[] reversed = new Integer[100];
+    private static final Integer[] ones = new Integer[100];
+    private static final Integer[] twice = new Integer[200];
+    private static final Integer[] pseudoRandom;
+
+    private static final Object[][] testData;
+    private static final Object[][] withNullTestData;
+    private static final Object[][] spliteratorTestData;
+
+    static {
+        Integer[][] arrays = {to0, to1, to10, to100, to1000};
+        for (Integer[] arr : arrays) {
+            for (int i = 0; i < arr.length; i++) {
+                arr[i] = i;
+            }
+        }
+        for (int i = 0; i < reversed.length; i++) {
+            reversed[i] = reversed.length - i;
+        }
+        for (int i = 0; i < ones.length; i++) {
+            ones[i] = 1;
+        }
+        System.arraycopy(to100, 0, twice, 0, to100.length);
+        System.arraycopy(to100, 0, twice, to100.length, to100.length);
+        pseudoRandom = new Integer[LambdaTestHelpers.LONG_STRING.length()];
+        for (int i = 0; i < LambdaTestHelpers.LONG_STRING.length(); i++) {
+            pseudoRandom[i] = (int) LambdaTestHelpers.LONG_STRING.charAt(i);
+        }
+    }
+
+    static final Object[][] arrays = {
+            {"empty", to0},
+            {"0..1", to1},
+            {"0..10", to10},
+            {"0..100", to100},
+            {"0..1000", to1000},
+            {"100x[1]", ones},
+            {"2x[0..100]", twice},
+            {"reverse 0..100", reversed},
+            {"pseudorandom", pseudoRandom}
+    };
+
+    static {
+        {
+            List<Object[]> list = new ArrayList<>();
+            for (Object[] data : arrays) {
+                final Object name = data[0];
+                final Integer[] ints = (Integer[])data[1];
+                final List<Integer> intsAsList = Arrays.asList(ints);
+
+                list.add(arrayDataDescr("array:" + name, ints));
+                list.add(collectionDataDescr("ArrayList.asList:" + name, intsAsList));
+                list.add(collectionDataDescr("ArrayList:" + name, new ArrayList<>(intsAsList)));
+                list.add(streamDataDescr("DelegatingStream(ArrayList):" + name,
+                                         () -> new ArrayList<>(intsAsList).stream()));
+                List<Integer> aList = new ArrayList<>(intsAsList);
+                if (LambdaTestMode.isNormalMode()) {
+                    // Only include sub-lists for normal test execution mode
+                    // This data is serialization-hostile since the state of the
+                    // deserialized sub-list will be out of sync with the
+                    // enclosing list.
+                    list.add(collectionDataDescr("ArrayList.Sublist:" + name,
+                                                 (ints.length) <= 1 ? aList.subList(0, 0) : aList.subList(1, ints.length / 2)));
+                }
+                list.add(collectionDataDescr("LinkedList:" + name, new LinkedList<>(intsAsList)));
+                list.add(collectionDataDescr("HashSet:" + name, new HashSet<>(intsAsList)));
+                list.add(collectionDataDescr("LinkedHashSet:" + name, new LinkedHashSet<>(intsAsList)));
+                list.add(collectionDataDescr("TreeSet:" + name, new TreeSet<>(intsAsList)));
+                SpinedBuffer<Integer> spinedBuffer = new SpinedBuffer<>();
+                intsAsList.forEach(spinedBuffer);
+                list.add(sbDataDescr("SpinedBuffer:" + name, spinedBuffer));
+
+                // @@@ Add more
+            }
+            testData = list.toArray(new Object[0][]);
+        }
+
+        // Simple combination of numbers and null values, probably excessive but may catch
+        // errors for initialization/termination/sequence
+        // @@@ This is separate from the other data for now until nulls are consistently supported by
+        // all operations
+        {
+            List<Object[]> list = new ArrayList<>();
+            int size = 5;
+            for (int i = 0; i < (1 << size) - 2; i++) {
+                Integer[] content = new Integer[size];
+                for (int e = 0; e < size; e++) {
+                    content[e] = (i & (1 << e)) > 0 ? e + 1 : null;
+                }
+
+                // ORDERED
+                list.add(arrayDataDescr("array:" + i, content));
+                // not ORDERED, DISTINCT
+                list.add(collectionDataDescr("HashSet:" + i, new HashSet<>(Arrays.asList(content))));
+            }
+
+            withNullTestData = list.toArray(new Object[0][]);
+        }
+
+        {
+            List<Object[]> spliterators = new ArrayList<>();
+            for (Object[] data : arrays) {
+                final Object name = data[0];
+                final Integer[] ints = (Integer[])data[1];
+
+                spliterators.add(splitDescr("Arrays.s(array):" + name,
+                                            () -> Arrays.spliterator(ints)));
+                spliterators.add(splitDescr("arrays.s(array,o,l):" + name,
+                                            () -> Arrays.spliterator(ints, 0, ints.length/2)));
+                spliterators.add(splitDescr("SpinedBuffer.s():" + name,
+                                            () -> {
+                                                SpinedBuffer<Integer> sb = new SpinedBuffer<>();
+                                                for (Integer i : ints)
+                                                    sb.accept(i);
+                                                return sb.spliterator();
+                                            }));
+                spliterators.add(splitDescr("Iterators.s(Arrays.s(array).iterator(), size):" + name,
+                                            () -> Spliterators.spliterator(Arrays.asList(ints).iterator(), ints.length, 0)));
+                spliterators.add(splitDescr("Iterators.s(Arrays.s(array).iterator()):" + name,
+                                            () -> Spliterators.spliteratorUnknownSize(Arrays.asList(ints).iterator(), 0)));
+                // @@@ Add map and collection spliterators when spliterator() is exposed on Collection or Iterable
+            }
+            spliteratorTestData = spliterators.toArray(new Object[0][]);
+        }
+    }
+
+    static <T> Object[] arrayDataDescr(String description, T[] data) {
+        return new Object[] { description, TestData.Factory.ofArray(description, data)};
+    }
+
+    static <T> Object[] streamDataDescr(String description, Supplier<Stream<T>> supplier) {
+        return new Object[] { description, TestData.Factory.ofSupplier(description, supplier)};
+    }
+
+    static <T> Object[] collectionDataDescr(String description, Collection<T> data) {
+        return new Object[] { description, TestData.Factory.ofCollection(description, data)};
+    }
+
+    static <T> Object[] sbDataDescr(String description, SpinedBuffer<T> data) {
+        return new Object[] { description, TestData.Factory.ofSpinedBuffer(description, data)};
+    }
+
+    static <T> Object[] splitDescr(String description, Supplier<Spliterator<T>> ss) {
+        return new Object[] { description, ss };
+    }
+
+    // Return an array of ( String name, StreamTestData<Integer> )
+    @DataProvider(name = "StreamTestData<Integer>")
+    public static Object[][] makeStreamTestData() {
+        return testData;
+    }
+
+    @DataProvider(name = "withNull:StreamTestData<Integer>")
+    public static Object[][] makeStreamWithNullTestData() {
+        return withNullTestData;
+    }
+
+    // returns an array of (String name, Supplier<Spliterator<Integer>>)
+    @DataProvider(name = "Spliterator<Integer>")
+    public static Object[][] spliteratorProvider() {
+        return spliteratorTestData;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/StreamTestScenario.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,278 @@
+/*
+ * 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 java.util.stream;
+
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.Spliterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+/**
+ * Test scenarios for reference streams.
+ *
+ * Each scenario is provided with a data source, a function that maps a fresh
+ * stream (as provided by the data source) to a new stream, and a sink to
+ * receive results.  Each scenario describes a different way of computing the
+ * stream contents.  The test driver will ensure that all scenarios produce
+ * the same output (modulo allowable differences in ordering).
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+public enum StreamTestScenario implements OpTestCase.BaseStreamTestScenario {
+
+    STREAM_FOR_EACH(false) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            Stream<U> s = m.apply(source);
+            if (s.isParallel()) {
+                s = s.sequential();
+            }
+            s.forEach(b);
+        }
+    },
+
+    // Collec to list
+    STREAM_COLLECT(false) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            for (U t : m.apply(source).collect(Collectors.toList())) {
+                b.accept(t);
+            }
+        }
+    },
+
+    // To array
+    STREAM_TO_ARRAY(false) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            for (Object t : m.apply(source).toArray()) {
+                b.accept((U) t);
+            }
+        }
+    },
+
+    // Wrap as stream, and iterate in pull mode
+    STREAM_ITERATOR(false) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            for (Iterator<U> seqIter = m.apply(source).iterator(); seqIter.hasNext(); )
+                b.accept(seqIter.next());
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate in pull mode
+    STREAM_SPLITERATOR(false) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            for (Spliterator<U> spl = m.apply(source).spliterator(); spl.tryAdvance(b); ) {
+            }
+        }
+    },
+
+    // Wrap as stream, spliterate, then split a few times mixing advances with forEach
+    STREAM_SPLITERATOR_WITH_MIXED_TRAVERSE_AND_SPLIT(false) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            SpliteratorTestHelper.mixedTraverseAndSplit(b, m.apply(source).spliterator());
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate in pull mode
+    STREAM_SPLITERATOR_FOREACH(false) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            m.apply(source).spliterator().forEachRemaining(b);
+        }
+    },
+
+    // Wrap as parallel stream + sequential
+    PAR_STREAM_SEQUENTIAL_FOR_EACH(true) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            m.apply(source).sequential().forEach(b);
+        }
+    },
+
+    // Wrap as parallel stream + forEachOrdered
+    PAR_STREAM_FOR_EACH_ORDERED(true) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            // @@@ Want to explicitly select ordered equalator
+            m.apply(source).forEachOrdered(b);
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate sequentially
+    PAR_STREAM_SPLITERATOR(true) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            for (Spliterator<U> spl = m.apply(source).spliterator(); spl.tryAdvance(b); ) {
+            }
+        }
+    },
+
+    // Wrap as stream, and spliterate then iterate sequentially
+    PAR_STREAM_SPLITERATOR_FOREACH(true) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            m.apply(source).spliterator().forEachRemaining(b);
+        }
+    },
+
+    // Wrap as parallel stream + toArray
+    PAR_STREAM_TO_ARRAY(true) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            for (Object t : m.apply(source).toArray())
+                b.accept((U) t);
+        }
+    },
+
+    // Wrap as parallel stream, get the spliterator, wrap as a stream + toArray
+    PAR_STREAM_SPLITERATOR_STREAM_TO_ARRAY(true) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            Stream<U> s = m.apply(source);
+            Spliterator<U> sp = s.spliterator();
+            Stream<U> ss = StreamSupport.stream(() -> sp,
+                                                StreamOpFlag.toCharacteristics(OpTestCase.getStreamFlags(s))
+                                                | (sp.getExactSizeIfKnown() < 0 ? 0 : Spliterator.SIZED), true);
+            for (Object t : ss.toArray())
+                b.accept((U) t);
+        }
+    },
+
+    // Wrap as parallel stream + toArray and clear SIZED flag
+    PAR_STREAM_TO_ARRAY_CLEAR_SIZED(true) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            S_IN pipe1 = (S_IN) OpTestCase.chain(source,
+                                                 new FlagDeclaringOp(StreamOpFlag.NOT_SIZED, data.getShape()));
+            Stream<U> pipe2 = m.apply(pipe1);
+
+            for (Object t : pipe2.toArray())
+                b.accept((U) t);
+        }
+    },
+
+    // Wrap as parallel + collect to list
+    PAR_STREAM_COLLECT_TO_LIST(true) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            for (U u : m.apply(source).collect(Collectors.toList()))
+                b.accept(u);
+        }
+    },
+
+    // Wrap sequential as parallel, + collect to list
+    STREAM_TO_PAR_STREAM_COLLECT_TO_LIST(true) {
+        public <T, S_IN extends BaseStream<T, S_IN>>
+        S_IN getStream(TestData<T, S_IN> data) {
+            return data.stream().parallel();
+        }
+
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            for (U u : m.apply(source).collect(Collectors.toList()))
+                b.accept(u);
+        }
+    },
+
+    // Wrap parallel as sequential,, + collect
+    PAR_STREAM_TO_STREAM_COLLECT_TO_LIST(true) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            for (U u : m.apply(source).collect(Collectors.toList()))
+                b.accept(u);
+        }
+    },
+
+    // Wrap as parallel stream + forEach synchronizing
+    PAR_STREAM_FOR_EACH(true, false) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            m.apply(source).forEach(e -> {
+                synchronized (data) {
+                    b.accept(e);
+                }
+            });
+        }
+    },
+
+    // Wrap as parallel stream + forEach synchronizing and clear SIZED flag
+    PAR_STREAM_FOR_EACH_CLEAR_SIZED(true, false) {
+        <T, U, S_IN extends BaseStream<T, S_IN>>
+        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
+            S_IN pipe1 = (S_IN) OpTestCase.chain(source,
+                                                 new FlagDeclaringOp(StreamOpFlag.NOT_SIZED, data.getShape()));
+            m.apply(pipe1).forEach(e -> {
+                synchronized (data) {
+                    b.accept(e);
+                }
+            });
+        }
+    },
+    ;
+
+    // The set of scenarios that clean the SIZED flag
+    public static final Set<StreamTestScenario> CLEAR_SIZED_SCENARIOS = Collections.unmodifiableSet(
+            EnumSet.of(PAR_STREAM_TO_ARRAY_CLEAR_SIZED, PAR_STREAM_FOR_EACH_CLEAR_SIZED));
+
+    private final boolean isParallel;
+
+    private final boolean isOrdered;
+
+    StreamTestScenario(boolean isParallel) {
+        this(isParallel, true);
+    }
+
+    StreamTestScenario(boolean isParallel, boolean isOrdered) {
+        this.isParallel = isParallel;
+        this.isOrdered = isOrdered;
+    }
+
+    public StreamShape getShape() {
+        return StreamShape.REFERENCE;
+    }
+
+    public boolean isParallel() {
+        return isParallel;
+    }
+
+    public boolean isOrdered() {
+        return isOrdered;
+    }
+
+    public <T, U, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>>
+    void run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, S_OUT> m) {
+        try (S_IN source = getStream(data)) {
+            run(data, source, b, (Function<S_IN, Stream<U>>) m);
+        }
+    }
+
+    abstract <T, U, S_IN extends BaseStream<T, S_IN>>
+    void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/TestData.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,355 @@
+/*
+ * 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 java.util.stream;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.PrimitiveIterator;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.DoubleConsumer;
+import java.util.function.Function;
+import java.util.function.IntConsumer;
+import java.util.function.LongConsumer;
+import java.util.function.Supplier;
+import java.util.function.ToIntFunction;
+
+/** Describes a test data set for use in stream tests */
+public interface TestData<T, S extends BaseStream<T, S>>
+        extends Iterable<T> {
+
+    default int size() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    default Iterator<T> iterator() {
+        return Spliterators.iterator(spliterator());
+    }
+
+    Spliterator<T> spliterator();
+
+    default boolean isOrdered() {
+        return spliterator().hasCharacteristics(Spliterator.ORDERED);
+    }
+
+    StreamShape getShape();
+
+    default <A extends Collection<? super T>> A into(A target) {
+        spliterator().forEachRemaining(target::add);
+        return target;
+    }
+
+    S stream();
+
+    S parallelStream();
+
+    public interface OfRef<T> extends TestData<T, Stream<T>> { }
+
+    public interface OfInt extends TestData<Integer, IntStream> { }
+
+    public interface OfLong extends TestData<Long, LongStream> { }
+
+    public interface OfDouble extends TestData<Double, DoubleStream> { }
+
+    // @@@ Temporary garbage class to avoid triggering bugs with lambdas in static methods in interfaces
+    public static class Factory {
+        public static <T> OfRef<T> ofArray(String name, T[] array) {
+            return new AbstractTestData.RefTestData<>(name, array, Arrays::stream, a -> Arrays.stream(a).parallel(),
+                                                      Arrays::spliterator, a -> a.length);
+        }
+
+        public static <T> OfRef<T> ofCollection(String name, Collection<T> collection) {
+            return new AbstractTestData.RefTestData<>(name, collection, Collection::stream, Collection::parallelStream,
+                                                      Collection::spliterator, Collection::size);
+        }
+
+        public static <T> OfRef<T> ofSpinedBuffer(String name, SpinedBuffer<T> buffer) {
+            return new AbstractTestData.RefTestData<>(name, buffer,
+                                                      b -> StreamSupport.stream(b.spliterator(), false),
+                                                      b -> StreamSupport.stream(b.spliterator(), true),
+                                                      SpinedBuffer::spliterator,
+                                                      b -> (int) b.count());
+        }
+
+        public static <T> OfRef<T> ofSupplier(String name, Supplier<Stream<T>> supplier) {
+            return new AbstractTestData.RefTestData<>(name, supplier,
+                                                      Supplier::get,
+                                                      s -> s.get().parallel(),
+                                                      s -> s.get().spliterator(),
+                                                      s -> (int) s.get().spliterator().getExactSizeIfKnown());
+        }
+
+        public static <T> OfRef<T> ofRefNode(String name, Node<T> node) {
+            return new AbstractTestData.RefTestData<>(name, node,
+                                                      n -> StreamSupport.stream(n::spliterator, Spliterator.SIZED | Spliterator.ORDERED, false),
+                                                      n -> StreamSupport.stream(n::spliterator, Spliterator.SIZED | Spliterator.ORDERED, true),
+                                                      Node::spliterator,
+                                                      n -> (int) n.count());
+        }
+
+        // int factories
+        public static <T> OfInt ofArray(String name, int[] array) {
+            return new AbstractTestData.IntTestData<>(name, array, Arrays::stream, a -> Arrays.stream(a).parallel(),
+                                                      Arrays::spliterator, a -> a.length);
+        }
+
+        public static OfInt ofSpinedBuffer(String name, SpinedBuffer.OfInt buffer) {
+            return new AbstractTestData.IntTestData<>(name, buffer,
+                                                      b -> StreamSupport.intStream(b.spliterator(), false),
+                                                      b -> StreamSupport.intStream(b.spliterator(), true),
+                                                      SpinedBuffer.OfInt::spliterator,
+                                                      b -> (int) b.count());
+        }
+
+        public static OfInt ofIntSupplier(String name, Supplier<IntStream> supplier) {
+            return new AbstractTestData.IntTestData<>(name, supplier,
+                                                      Supplier::get,
+                                                      s -> s.get().parallel(),
+                                                      s -> s.get().spliterator(),
+                                                      s -> (int) s.get().spliterator().getExactSizeIfKnown());
+        }
+
+        public static OfInt ofNode(String name, Node.OfInt node) {
+            int characteristics = Spliterator.SIZED | Spliterator.ORDERED;
+            return new AbstractTestData.IntTestData<>(name, node,
+                                                      n -> StreamSupport.intStream(n::spliterator, characteristics, false),
+                                                      n -> StreamSupport.intStream(n::spliterator, characteristics, true),
+                                                      Node.OfInt::spliterator,
+                                                      n -> (int) n.count());
+        }
+
+        // long factories
+        public static <T> OfLong ofArray(String name, long[] array) {
+            return new AbstractTestData.LongTestData<>(name, array, Arrays::stream, a -> Arrays.stream(a).parallel(),
+                                                       Arrays::spliterator, a -> a.length);
+        }
+
+        public static OfLong ofSpinedBuffer(String name, SpinedBuffer.OfLong buffer) {
+            return new AbstractTestData.LongTestData<>(name, buffer,
+                                                      b -> StreamSupport.longStream(b.spliterator(), false),
+                                                      b -> StreamSupport.longStream(b.spliterator(), true),
+                                                      SpinedBuffer.OfLong::spliterator,
+                                                      b -> (int) b.count());
+        }
+
+        public static OfLong ofLongSupplier(String name, Supplier<LongStream> supplier) {
+            return new AbstractTestData.LongTestData<>(name, supplier,
+                                                      Supplier::get,
+                                                      s -> s.get().parallel(),
+                                                      s -> s.get().spliterator(),
+                                                      s -> (int) s.get().spliterator().getExactSizeIfKnown());
+        }
+
+        public static OfLong ofNode(String name, Node.OfLong node) {
+            int characteristics = Spliterator.SIZED | Spliterator.ORDERED;
+            return new AbstractTestData.LongTestData<>(name, node,
+                                                      n -> StreamSupport.longStream(n::spliterator, characteristics, false),
+                                                      n -> StreamSupport.longStream(n::spliterator, characteristics, true),
+                                                      Node.OfLong::spliterator,
+                                                      n -> (int) n.count());
+        }
+
+        // double factories
+        public static <T> OfDouble ofArray(String name, double[] array) {
+            return new AbstractTestData.DoubleTestData<>(name, array, Arrays::stream, a -> Arrays.stream(a).parallel(),
+                                                         Arrays::spliterator, a -> a.length);
+        }
+
+        public static OfDouble ofSpinedBuffer(String name, SpinedBuffer.OfDouble buffer) {
+            return new AbstractTestData.DoubleTestData<>(name, buffer,
+                                                         b -> StreamSupport.doubleStream(b.spliterator(), false),
+                                                         b -> StreamSupport.doubleStream(b.spliterator(), true),
+                                                         SpinedBuffer.OfDouble::spliterator,
+                                                         b -> (int) b.count());
+        }
+
+        public static OfDouble ofDoubleSupplier(String name, Supplier<DoubleStream> supplier) {
+            return new AbstractTestData.DoubleTestData<>(name, supplier,
+                                                         Supplier::get,
+                                                         s -> s.get().parallel(),
+                                                         s -> s.get().spliterator(),
+                                                         s -> (int) s.get().spliterator().getExactSizeIfKnown());
+        }
+
+        public static OfDouble ofNode(String name, Node.OfDouble node) {
+            int characteristics = Spliterator.SIZED | Spliterator.ORDERED;
+            return new AbstractTestData.DoubleTestData<>(name, node,
+                                                         n -> StreamSupport.doubleStream(n::spliterator, characteristics, false),
+                                                         n -> StreamSupport.doubleStream(n::spliterator, characteristics, true),
+                                                         Node.OfDouble::spliterator,
+                                                         n -> (int) n.count());
+        }
+    }
+
+
+    abstract class AbstractTestData<T, S extends BaseStream<T, S>,
+            T_STATE,
+                                    T_SPLITR extends Spliterator<T>>
+            implements TestData<T, S> {
+        private final String name;
+        private final StreamShape shape;
+        protected final T_STATE state;
+        private final ToIntFunction<T_STATE> sizeFn;
+        private final Function<T_STATE, S> streamFn;
+        private final Function<T_STATE, S> parStreamFn;
+        private final Function<T_STATE, T_SPLITR> splitrFn;
+
+        AbstractTestData(String name,
+                         StreamShape shape,
+                         T_STATE state,
+                         Function<T_STATE, S> streamFn,
+                         Function<T_STATE, S> parStreamFn,
+                         Function<T_STATE, T_SPLITR> splitrFn,
+                         ToIntFunction<T_STATE> sizeFn) {
+            this.name = name;
+            this.shape = shape;
+            this.state = state;
+            this.streamFn = streamFn;
+            this.parStreamFn = parStreamFn;
+            this.splitrFn = splitrFn;
+            this.sizeFn = sizeFn;
+        }
+
+        @Override
+        public StreamShape getShape() {
+            return shape;
+        }
+
+        @Override
+        public String toString() {
+            return getClass().getSimpleName() + "[" + name + "]";
+        }
+
+        @Override
+        public int size() {
+            return sizeFn.applyAsInt(state);
+        }
+
+        @Override
+        public T_SPLITR spliterator() {
+            return splitrFn.apply(state);
+        }
+
+        @Override
+        public S stream() {
+            return streamFn.apply(state);
+        }
+
+        @Override
+        public S parallelStream() {
+            return parStreamFn.apply(state);
+        }
+
+        public static class RefTestData<T, I>
+                extends AbstractTestData<T, Stream<T>, I, Spliterator<T>>
+                implements TestData.OfRef<T> {
+
+            protected RefTestData(String name,
+                                  I state,
+                                  Function<I, Stream<T>> streamFn,
+                                  Function<I, Stream<T>> parStreamFn,
+                                  Function<I, Spliterator<T>> splitrFn,
+                                  ToIntFunction<I> sizeFn) {
+                super(name, StreamShape.REFERENCE, state, streamFn, parStreamFn, splitrFn, sizeFn);
+            }
+
+        }
+
+        static class IntTestData<I>
+                extends AbstractTestData<Integer, IntStream, I, Spliterator.OfInt>
+                implements TestData.OfInt {
+
+            protected IntTestData(String name,
+                                  I state,
+                                  Function<I, IntStream> streamFn,
+                                  Function<I, IntStream> parStreamFn,
+                                  Function<I, Spliterator.OfInt> splitrFn,
+                                  ToIntFunction<I> sizeFn) {
+                super(name, StreamShape.INT_VALUE, state, streamFn, parStreamFn, splitrFn, sizeFn);
+            }
+
+            @Override
+            public PrimitiveIterator.OfInt iterator() {
+                return Spliterators.iterator(spliterator());
+            }
+
+            @Override
+            public <A extends Collection<? super Integer>> A into(A target) {
+                spliterator().forEachRemaining((IntConsumer) target::add);
+                return target;
+            }
+        }
+
+        static class LongTestData<I>
+                extends AbstractTestData<Long, LongStream, I, Spliterator.OfLong>
+                implements TestData.OfLong {
+
+            protected LongTestData(String name,
+                                   I state,
+                                   Function<I, LongStream> streamFn,
+                                   Function<I, LongStream> parStreamFn,
+                                   Function<I, Spliterator.OfLong> splitrFn,
+                                   ToIntFunction<I> sizeFn) {
+                super(name, StreamShape.LONG_VALUE, state, streamFn, parStreamFn, splitrFn, sizeFn);
+            }
+
+            @Override
+            public PrimitiveIterator.OfLong iterator() {
+                return Spliterators.iterator(spliterator());
+            }
+
+            @Override
+            public <A extends Collection<? super Long>> A into(A target) {
+                spliterator().forEachRemaining((LongConsumer) target::add);
+                return target;
+            }
+        }
+
+        static class DoubleTestData<I>
+                extends AbstractTestData<Double, DoubleStream, I, Spliterator.OfDouble>
+                implements OfDouble {
+
+            protected DoubleTestData(String name,
+                                     I state,
+                                     Function<I, DoubleStream> streamFn,
+                                     Function<I, DoubleStream> parStreamFn,
+                                     Function<I, Spliterator.OfDouble> splitrFn,
+                                     ToIntFunction<I> sizeFn) {
+                super(name, StreamShape.DOUBLE_VALUE, state, streamFn, parStreamFn, splitrFn, sizeFn);
+            }
+
+            @Override
+            public PrimitiveIterator.OfDouble iterator() {
+                return Spliterators.iterator(spliterator());
+            }
+
+            @Override
+            public <A extends Collection<? super Double>> A into(A target) {
+                spliterator().forEachRemaining((DoubleConsumer) target::add);
+                return target;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/TestFlagExpectedOp.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,125 @@
+/*
+ * 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 java.util.stream;
+
+import org.testng.Assert;
+
+import java.util.EnumSet;
+
+class TestFlagExpectedOp<T> extends FlagDeclaringOp<T> {
+
+    static class Builder<T> {
+        final int flags;
+        StreamShape shape = StreamShape.REFERENCE;
+
+        EnumSet<StreamOpFlag> known = EnumSet.noneOf(StreamOpFlag.class);
+        EnumSet<StreamOpFlag> preserve = EnumSet.noneOf(StreamOpFlag.class);
+        EnumSet<StreamOpFlag> notKnown = EnumSet.noneOf(StreamOpFlag.class);
+
+        Builder(int flags) {
+            this.flags = flags;
+        }
+
+        Builder<T> known(EnumSet<StreamOpFlag> known) {
+            this.known = known;
+            return this;
+        }
+
+        Builder<T> preserve(EnumSet<StreamOpFlag> preserve) {
+            this.preserve = preserve;
+            return this;
+        }
+
+        Builder<T> notKnown(EnumSet<StreamOpFlag> notKnown) {
+            this.notKnown = notKnown;
+            return this;
+        }
+
+        Builder<T> shape(StreamShape shape) {
+            this.shape = shape;
+            return this;
+        }
+
+        TestFlagExpectedOp<T> build() {
+            return new TestFlagExpectedOp<>(flags, known, preserve, notKnown, shape);
+        }
+    }
+
+    final EnumSet<StreamOpFlag> known;
+    final EnumSet<StreamOpFlag> preserve;
+    final EnumSet<StreamOpFlag> notKnown;
+    final StreamShape shape;
+
+    TestFlagExpectedOp(int flags,
+                       EnumSet<StreamOpFlag> known,
+                       EnumSet<StreamOpFlag> preserve,
+                       EnumSet<StreamOpFlag> notKnown) {
+        this(flags, known, preserve, notKnown, StreamShape.REFERENCE);
+    }
+
+    TestFlagExpectedOp(int flags,
+                       EnumSet<StreamOpFlag> known,
+                       EnumSet<StreamOpFlag> preserve,
+                       EnumSet<StreamOpFlag> notKnown,
+                       StreamShape shape) {
+        super(flags);
+        this.known = known;
+        this.preserve = preserve;
+        this.notKnown = notKnown;
+        this.shape = shape;
+    }
+
+    @Override
+    public StreamShape outputShape() {
+        return shape;
+    }
+
+    @Override
+    public StreamShape inputShape() {
+        return shape;
+    }
+
+    @Override
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public Sink<T> opWrapSink(int flags, boolean parallel, Sink upstream) {
+        assertFlags(flags);
+        return upstream;
+    }
+
+    private void assertFlags(int flags) {
+        for (StreamOpFlag f : known) {
+            Assert.assertTrue(f.isKnown(flags),
+                              String.format("Flag %s is not known, but should be known.", f.toString()));
+        }
+
+        for (StreamOpFlag f : preserve) {
+            Assert.assertTrue(f.isPreserved(flags),
+                              String.format("Flag %s is not preserved, but should be preserved.", f.toString()));
+        }
+
+        for (StreamOpFlag f : notKnown) {
+            Assert.assertFalse(f.isKnown(flags),
+                               String.format("Flag %s is known, but should be not known.", f.toString()));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/ThowableHelper.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util.stream;
+
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+public final class ThowableHelper {
+
+    public static void checkException(Class<? extends Exception> ce, Runnable r) {
+        Exception caught = null;
+        try {
+            r.run();
+        } catch (Exception e) {
+            caught = e;
+        }
+
+        assertNotNull(caught);
+        assertTrue(ce.isInstance(caught));
+    }
+
+    public static void checkNPE(Runnable r) {
+        checkException(NullPointerException.class, r);
+    }
+
+    public static void checkISE(Runnable r) {
+        checkException(IllegalStateException.class, r);
+    }
+}
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/CollectorOps.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +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 java.util.stream;
-
-import org.testng.Assert;
-
-import java.util.Spliterator;
-import java.util.function.IntFunction;
-
-/** Test helper class for java.util.stream test framework */
-public final class CollectorOps {
-    private CollectorOps() { }
-
-    public static <E_IN> StatefulTestOp<E_IN> collector() {
-        return new StatefulCollector<>(0, StreamShape.REFERENCE);
-    }
-
-    /* Utility classes for collecting output of intermediate pipeline stages */
-    public static class StatefulCollector<E_IN> implements StatefulTestOp<E_IN> {
-        private final int opFlags;
-        private final StreamShape inputShape;
-
-        public StatefulCollector(int opFlags, StreamShape inputShape) {
-            this.opFlags = opFlags;
-            this.inputShape = inputShape;
-        }
-
-        @Override
-        public StreamShape inputShape() {
-            return inputShape;
-        }
-
-        @Override
-        public StreamShape outputShape() {
-            return inputShape;
-        }
-
-        @Override
-        public int opGetFlags() {
-            return opFlags;
-        }
-
-        @Override
-        public Sink<E_IN> opWrapSink(int flags, boolean parallel, Sink<E_IN> sink) {
-            return sink;
-        }
-
-        @Override
-        public <P_IN> Node<E_IN> opEvaluateParallel(PipelineHelper<E_IN> helper,
-                                                    Spliterator<P_IN> spliterator,
-                                                    IntFunction<E_IN[]> generator) {
-            return helper.evaluate(spliterator, false, generator);
-        }
-    }
-
-    public static class TestParallelSizedOp<T> extends StatefulCollector<T> {
-        public TestParallelSizedOp() {
-            this(StreamShape.REFERENCE);
-        }
-
-        protected TestParallelSizedOp(StreamShape shape) {
-            super(0, shape);
-        }
-
-        @Override
-        public <P_IN> Node<T> opEvaluateParallel(PipelineHelper<T> helper,
-                                                 Spliterator<P_IN> spliterator,
-                                                 IntFunction<T[]> generator) {
-            int flags = helper.getStreamAndOpFlags();
-
-            Assert.assertTrue(StreamOpFlag.SIZED.isKnown(flags));
-            return super.opEvaluateParallel(helper, spliterator, generator);
-        }
-
-        public static class OfInt extends TestParallelSizedOp<Integer> {
-            public OfInt() {
-                super(StreamShape.INT_VALUE);
-            }
-        }
-
-        public static class OfLong extends TestParallelSizedOp<Long> {
-            public OfLong() {
-                super(StreamShape.LONG_VALUE);
-            }
-        }
-
-        public static class OfDouble extends TestParallelSizedOp<Double> {
-            public OfDouble() {
-                super(StreamShape.DOUBLE_VALUE);
-            }
-        }
-    }
-}
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/DefaultMethodStreams.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,984 +0,0 @@
-/*
- * 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.
- */
-package java.util.stream;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Comparator;
-import java.util.DoubleSummaryStatistics;
-import java.util.IntSummaryStatistics;
-import java.util.Iterator;
-import java.util.LongSummaryStatistics;
-import java.util.Optional;
-import java.util.OptionalDouble;
-import java.util.OptionalInt;
-import java.util.OptionalLong;
-import java.util.PrimitiveIterator;
-import java.util.Set;
-import java.util.Spliterator;
-import java.util.function.BiConsumer;
-import java.util.function.BiFunction;
-import java.util.function.BinaryOperator;
-import java.util.function.Consumer;
-import java.util.function.DoubleBinaryOperator;
-import java.util.function.DoubleConsumer;
-import java.util.function.DoubleFunction;
-import java.util.function.DoublePredicate;
-import java.util.function.DoubleToIntFunction;
-import java.util.function.DoubleToLongFunction;
-import java.util.function.DoubleUnaryOperator;
-import java.util.function.Function;
-import java.util.function.IntBinaryOperator;
-import java.util.function.IntConsumer;
-import java.util.function.IntFunction;
-import java.util.function.IntPredicate;
-import java.util.function.IntToDoubleFunction;
-import java.util.function.IntToLongFunction;
-import java.util.function.IntUnaryOperator;
-import java.util.function.LongBinaryOperator;
-import java.util.function.LongConsumer;
-import java.util.function.LongFunction;
-import java.util.function.LongPredicate;
-import java.util.function.LongToDoubleFunction;
-import java.util.function.LongToIntFunction;
-import java.util.function.LongUnaryOperator;
-import java.util.function.ObjDoubleConsumer;
-import java.util.function.ObjIntConsumer;
-import java.util.function.ObjLongConsumer;
-import java.util.function.Predicate;
-import java.util.function.Supplier;
-import java.util.function.ToDoubleFunction;
-
-import java.util.function.ToIntFunction;
-import java.util.function.ToLongFunction;
-
-import static java.util.stream.Collectors.*;
-
-public final class DefaultMethodStreams {
-
-    static {
-        // Verify that default methods are not overridden
-        verify(DefaultMethodRefStream.class);
-        verify(DefaultMethodIntStream.class);
-        verify(DefaultMethodLongStream.class);
-        verify(DefaultMethodDoubleStream.class);
-    }
-
-    static void verify(Class<?> del) {
-        // Find the stream interface
-        Class<?> s = Stream.of(del.getInterfaces())
-                .filter(c -> BaseStream.class.isAssignableFrom(c))
-                .findFirst().get();
-
-        // Get all default methods on the stream class
-        Set<String> dms = Stream.of(s.getMethods())
-                .filter(m -> !Modifier.isStatic(m.getModifiers()))
-                .filter(m -> !m.isBridge())
-                .filter(Method::isDefault)
-                .map(Method::getName)
-                .collect(toSet());
-
-        // Get all methods on the delegating class
-        Set<String> ims = Stream.of(del.getMethods())
-                .filter(m -> !Modifier.isStatic(m.getModifiers()))
-                .filter(m -> m.getDeclaringClass() == del)
-                .map(Method::getName)
-                .collect(toSet());
-
-        if (ims.stream().anyMatch(dms::contains)) {
-            throw new AssertionError(String.format("%s overrides default methods of %s\n", del, s));
-        }
-    }
-
-    /**
-     * Creates a stream that for the next operation either delegates to
-     * a default method on {@link Stream}, if present for that operation,
-     * otherwise delegates to an underlying stream.
-     *
-     * @param s the underlying stream to be delegated to for non-default
-     * methods.
-     * @param <T> the type of the stream elements
-     * @return the delegating stream
-     */
-    public static <T> Stream<T> delegateTo(Stream<T> s) {
-        return new DefaultMethodRefStream<>(s);
-    }
-
-    /**
-     * Creates a stream that for the next operation either delegates to
-     * a default method on {@link IntStream}, if present for that operation,
-     * otherwise delegates to an underlying stream.
-     *
-     * @param s the underlying stream to be delegated to for non-default
-     * methods.
-     * @return the delegating stream
-     */
-    public static IntStream delegateTo(IntStream s) {
-        return new DefaultMethodIntStream(s);
-    }
-
-    /**
-     * Creates a stream that for the next operation either delegates to
-     * a default method on {@link LongStream}, if present for that operation,
-     * otherwise delegates to an underlying stream.
-     *
-     * @param s the underlying stream to be delegated to for non-default
-     * methods.
-     * @return the delegating stream
-     */
-    public static LongStream delegateTo(LongStream s) {
-        return new DefaultMethodLongStream(s);
-    }
-
-    /**
-     * Creates a stream that for the next operation either delegates to
-     * a default method on {@link DoubleStream}, if present for that operation,
-     * otherwise delegates to an underlying stream.
-     *
-     * @param s the underlying stream to be delegated to for non-default
-     * methods.
-     * @return the delegating stream
-     */
-    public static DoubleStream delegateTo(DoubleStream s) {
-        return new DefaultMethodDoubleStream(s);
-    }
-
-    /**
-     * A stream that delegates the next operation to a default method, if
-     * present, or to the same operation of an underlying stream.
-     *
-     * @param <T> the type of the stream elements
-     */
-    static final class DefaultMethodRefStream<T> implements Stream<T> {
-        final Stream<T> s;
-
-        DefaultMethodRefStream(Stream<T> s) {
-            this.s = s;
-        }
-
-
-        // Delegating non-default methods
-
-        @Override
-        public Stream<T> filter(Predicate<? super T> predicate) {
-            return s.filter(predicate);
-        }
-
-        @Override
-        public <R> Stream<R> map(Function<? super T, ? extends R> mapper) {
-            return s.map(mapper);
-        }
-
-        @Override
-        public IntStream mapToInt(ToIntFunction<? super T> mapper) {
-            return s.mapToInt(mapper);
-        }
-
-        @Override
-        public LongStream mapToLong(ToLongFunction<? super T> mapper) {
-            return s.mapToLong(mapper);
-        }
-
-        @Override
-        public DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper) {
-            return s.mapToDouble(mapper);
-        }
-
-        @Override
-        public <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper) {
-            return s.flatMap(mapper);
-        }
-
-        @Override
-        public IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper) {
-            return s.flatMapToInt(mapper);
-        }
-
-        @Override
-        public LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper) {
-            return s.flatMapToLong(mapper);
-        }
-
-        @Override
-        public DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper) {
-            return s.flatMapToDouble(mapper);
-        }
-
-        @Override
-        public Stream<T> distinct() {
-            return s.distinct();
-        }
-
-        @Override
-        public Stream<T> sorted() {
-            return s.sorted();
-        }
-
-        @Override
-        public Stream<T> sorted(Comparator<? super T> comparator) {
-            return s.sorted(comparator);
-        }
-
-        @Override
-        public Stream<T> peek(Consumer<? super T> action) {
-            return s.peek(action);
-        }
-
-        @Override
-        public Stream<T> limit(long maxSize) {
-            return s.limit(maxSize);
-        }
-
-        @Override
-        public Stream<T> skip(long n) {
-            return s.skip(n);
-        }
-
-        @Override
-        public void forEach(Consumer<? super T> action) {
-            s.forEach(action);
-        }
-
-        @Override
-        public void forEachOrdered(Consumer<? super T> action) {
-            s.forEachOrdered(action);
-        }
-
-        @Override
-        public Object[] toArray() {
-            return s.toArray();
-        }
-
-        @Override
-        public <A> A[] toArray(IntFunction<A[]> generator) {
-            return s.toArray(generator);
-        }
-
-        @Override
-        public T reduce(T identity, BinaryOperator<T> accumulator) {
-            return s.reduce(identity, accumulator);
-        }
-
-        @Override
-        public Optional<T> reduce(BinaryOperator<T> accumulator) {
-            return s.reduce(accumulator);
-        }
-
-        @Override
-        public <U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner) {
-            return s.reduce(identity, accumulator, combiner);
-        }
-
-        @Override
-        public <R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner) {
-            return s.collect(supplier, accumulator, combiner);
-        }
-
-        @Override
-        public <R, A> R collect(Collector<? super T, A, R> collector) {
-            return s.collect(collector);
-        }
-
-        @Override
-        public Optional<T> min(Comparator<? super T> comparator) {
-            return s.min(comparator);
-        }
-
-        @Override
-        public Optional<T> max(Comparator<? super T> comparator) {
-            return s.max(comparator);
-        }
-
-        @Override
-        public long count() {
-            return s.count();
-        }
-
-        @Override
-        public boolean anyMatch(Predicate<? super T> predicate) {
-            return s.anyMatch(predicate);
-        }
-
-        @Override
-        public boolean allMatch(Predicate<? super T> predicate) {
-            return s.allMatch(predicate);
-        }
-
-        @Override
-        public boolean noneMatch(Predicate<? super T> predicate) {
-            return s.noneMatch(predicate);
-        }
-
-        @Override
-        public Optional<T> findFirst() {
-            return s.findFirst();
-        }
-
-        @Override
-        public Optional<T> findAny() {
-            return s.findAny();
-        }
-
-        @Override
-        public Iterator<T> iterator() {
-            return s.iterator();
-        }
-
-        @Override
-        public Spliterator<T> spliterator() {
-            return s.spliterator();
-        }
-
-        @Override
-        public boolean isParallel() {
-            return s.isParallel();
-        }
-
-        @Override
-        public Stream<T> sequential() {
-            return s.sequential();
-        }
-
-        @Override
-        public Stream<T> parallel() {
-            return s.parallel();
-        }
-
-        @Override
-        public Stream<T> unordered() {
-            return s.unordered();
-        }
-
-        @Override
-        public Stream<T> onClose(Runnable closeHandler) {
-            return s.onClose(closeHandler);
-        }
-
-        @Override
-        public void close() {
-            s.close();
-        }
-    }
-
-    static final class DefaultMethodIntStream implements IntStream {
-        final IntStream s;
-
-        public DefaultMethodIntStream(IntStream s) {
-            this.s = s;
-        }
-
-
-        // Delegating non-default methods
-
-        @Override
-        public IntStream filter(IntPredicate predicate) {
-            return s.filter(predicate);
-        }
-
-        @Override
-        public IntStream map(IntUnaryOperator mapper) {
-            return s.map(mapper);
-        }
-
-        @Override
-        public <U> Stream<U> mapToObj(IntFunction<? extends U> mapper) {
-            return s.mapToObj(mapper);
-        }
-
-        @Override
-        public LongStream mapToLong(IntToLongFunction mapper) {
-            return s.mapToLong(mapper);
-        }
-
-        @Override
-        public DoubleStream mapToDouble(IntToDoubleFunction mapper) {
-            return s.mapToDouble(mapper);
-        }
-
-        @Override
-        public IntStream flatMap(IntFunction<? extends IntStream> mapper) {
-            return s.flatMap(mapper);
-        }
-
-        @Override
-        public IntStream distinct() {
-            return s.distinct();
-        }
-
-        @Override
-        public IntStream sorted() {
-            return s.sorted();
-        }
-
-        @Override
-        public IntStream peek(IntConsumer action) {
-            return s.peek(action);
-        }
-
-        @Override
-        public IntStream limit(long maxSize) {
-            return s.limit(maxSize);
-        }
-
-        @Override
-        public IntStream skip(long n) {
-            return s.skip(n);
-        }
-
-        @Override
-        public void forEach(IntConsumer action) {
-            s.forEach(action);
-        }
-
-        @Override
-        public void forEachOrdered(IntConsumer action) {
-            s.forEachOrdered(action);
-        }
-
-        @Override
-        public int[] toArray() {
-            return s.toArray();
-        }
-
-        @Override
-        public int reduce(int identity, IntBinaryOperator op) {
-            return s.reduce(identity, op);
-        }
-
-        @Override
-        public OptionalInt reduce(IntBinaryOperator op) {
-            return s.reduce(op);
-        }
-
-        @Override
-        public <R> R collect(Supplier<R> supplier, ObjIntConsumer<R> accumulator, BiConsumer<R, R> combiner) {
-            return s.collect(supplier, accumulator, combiner);
-        }
-
-        @Override
-        public int sum() {
-            return s.sum();
-        }
-
-        @Override
-        public OptionalInt min() {
-            return s.min();
-        }
-
-        @Override
-        public OptionalInt max() {
-            return s.max();
-        }
-
-        @Override
-        public long count() {
-            return s.count();
-        }
-
-        @Override
-        public OptionalDouble average() {
-            return s.average();
-        }
-
-        @Override
-        public IntSummaryStatistics summaryStatistics() {
-            return s.summaryStatistics();
-        }
-
-        @Override
-        public boolean anyMatch(IntPredicate predicate) {
-            return s.anyMatch(predicate);
-        }
-
-        @Override
-        public boolean allMatch(IntPredicate predicate) {
-            return s.allMatch(predicate);
-        }
-
-        @Override
-        public boolean noneMatch(IntPredicate predicate) {
-            return s.noneMatch(predicate);
-        }
-
-        @Override
-        public OptionalInt findFirst() {
-            return s.findFirst();
-        }
-
-        @Override
-        public OptionalInt findAny() {
-            return s.findAny();
-        }
-
-        @Override
-        public LongStream asLongStream() {
-            return s.asLongStream();
-        }
-
-        @Override
-        public DoubleStream asDoubleStream() {
-            return s.asDoubleStream();
-        }
-
-        @Override
-        public Stream<Integer> boxed() {
-            return s.boxed();
-        }
-
-        @Override
-        public IntStream sequential() {
-            return s.sequential();
-        }
-
-        @Override
-        public IntStream parallel() {
-            return s.parallel();
-        }
-
-        @Override
-        public PrimitiveIterator.OfInt iterator() {
-            return s.iterator();
-        }
-
-        @Override
-        public Spliterator.OfInt spliterator() {
-            return s.spliterator();
-        }
-
-        @Override
-        public boolean isParallel() {
-            return s.isParallel();
-        }
-
-        @Override
-        public IntStream unordered() {
-            return s.unordered();
-        }
-
-        @Override
-        public IntStream onClose(Runnable closeHandler) {
-            return s.onClose(closeHandler);
-        }
-
-        @Override
-        public void close() {
-            s.close();
-        }
-    }
-
-    static final class DefaultMethodLongStream implements LongStream {
-        final LongStream s;
-
-        public DefaultMethodLongStream(LongStream s) {
-            this.s = s;
-        }
-
-
-        // Delegating non-default methods
-
-        @Override
-        public void forEach(LongConsumer action) {
-            s.forEach(action);
-        }
-
-        @Override
-        public LongStream filter(LongPredicate predicate) {
-            return s.filter(predicate);
-        }
-
-        @Override
-        public LongStream map(LongUnaryOperator mapper) {
-            return s.map(mapper);
-        }
-
-        @Override
-        public <U> Stream<U> mapToObj(LongFunction<? extends U> mapper) {
-            return s.mapToObj(mapper);
-        }
-
-        @Override
-        public IntStream mapToInt(LongToIntFunction mapper) {
-            return s.mapToInt(mapper);
-        }
-
-        @Override
-        public DoubleStream mapToDouble(LongToDoubleFunction mapper) {
-            return s.mapToDouble(mapper);
-        }
-
-        @Override
-        public LongStream flatMap(LongFunction<? extends LongStream> mapper) {
-            return s.flatMap(mapper);
-        }
-
-        @Override
-        public LongStream distinct() {
-            return s.distinct();
-        }
-
-        @Override
-        public LongStream sorted() {
-            return s.sorted();
-        }
-
-        @Override
-        public LongStream peek(LongConsumer action) {
-            return s.peek(action);
-        }
-
-        @Override
-        public LongStream limit(long maxSize) {
-            return s.limit(maxSize);
-        }
-
-        @Override
-        public LongStream skip(long n) {
-            return s.skip(n);
-        }
-
-        @Override
-        public void forEachOrdered(LongConsumer action) {
-            s.forEachOrdered(action);
-        }
-
-        @Override
-        public long[] toArray() {
-            return s.toArray();
-        }
-
-        @Override
-        public long reduce(long identity, LongBinaryOperator op) {
-            return s.reduce(identity, op);
-        }
-
-        @Override
-        public OptionalLong reduce(LongBinaryOperator op) {
-            return s.reduce(op);
-        }
-
-        @Override
-        public <R> R collect(Supplier<R> supplier, ObjLongConsumer<R> accumulator, BiConsumer<R, R> combiner) {
-            return s.collect(supplier, accumulator, combiner);
-        }
-
-        @Override
-        public long sum() {
-            return s.sum();
-        }
-
-        @Override
-        public OptionalLong min() {
-            return s.min();
-        }
-
-        @Override
-        public OptionalLong max() {
-            return s.max();
-        }
-
-        @Override
-        public long count() {
-            return s.count();
-        }
-
-        @Override
-        public OptionalDouble average() {
-            return s.average();
-        }
-
-        @Override
-        public LongSummaryStatistics summaryStatistics() {
-            return s.summaryStatistics();
-        }
-
-        @Override
-        public boolean anyMatch(LongPredicate predicate) {
-            return s.anyMatch(predicate);
-        }
-
-        @Override
-        public boolean allMatch(LongPredicate predicate) {
-            return s.allMatch(predicate);
-        }
-
-        @Override
-        public boolean noneMatch(LongPredicate predicate) {
-            return s.noneMatch(predicate);
-        }
-
-        @Override
-        public OptionalLong findFirst() {
-            return s.findFirst();
-        }
-
-        @Override
-        public OptionalLong findAny() {
-            return s.findAny();
-        }
-
-        @Override
-        public DoubleStream asDoubleStream() {
-            return s.asDoubleStream();
-        }
-
-        @Override
-        public Stream<Long> boxed() {
-            return s.boxed();
-        }
-
-        @Override
-        public LongStream sequential() {
-            return s.sequential();
-        }
-
-        @Override
-        public LongStream parallel() {
-            return s.parallel();
-        }
-
-        @Override
-        public PrimitiveIterator.OfLong iterator() {
-            return s.iterator();
-        }
-
-        @Override
-        public Spliterator.OfLong spliterator() {
-            return s.spliterator();
-        }
-
-        @Override
-        public boolean isParallel() {
-            return s.isParallel();
-        }
-
-        @Override
-        public LongStream unordered() {
-            return s.unordered();
-        }
-
-        @Override
-        public LongStream onClose(Runnable closeHandler) {
-            return s.onClose(closeHandler);
-        }
-
-        @Override
-        public void close() {
-            s.close();
-        }
-    }
-
-    static final class DefaultMethodDoubleStream implements DoubleStream {
-        final DoubleStream s;
-
-        public DefaultMethodDoubleStream(DoubleStream s) {
-            this.s = s;
-        }
-
-        @Override
-        public DoubleStream filter(DoublePredicate predicate) {
-            return s.filter(predicate);
-        }
-
-        @Override
-        public DoubleStream map(DoubleUnaryOperator mapper) {
-            return s.map(mapper);
-        }
-
-        @Override
-        public <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper) {
-            return s.mapToObj(mapper);
-        }
-
-        @Override
-        public IntStream mapToInt(DoubleToIntFunction mapper) {
-            return s.mapToInt(mapper);
-        }
-
-        @Override
-        public LongStream mapToLong(DoubleToLongFunction mapper) {
-            return s.mapToLong(mapper);
-        }
-
-        @Override
-        public DoubleStream flatMap(DoubleFunction<? extends DoubleStream> mapper) {
-            return s.flatMap(mapper);
-        }
-
-        @Override
-        public DoubleStream distinct() {
-            return s.distinct();
-        }
-
-        @Override
-        public DoubleStream sorted() {
-            return s.sorted();
-        }
-
-        @Override
-        public DoubleStream peek(DoubleConsumer action) {
-            return s.peek(action);
-        }
-
-        @Override
-        public DoubleStream limit(long maxSize) {
-            return s.limit(maxSize);
-        }
-
-        @Override
-        public DoubleStream skip(long n) {
-            return s.skip(n);
-        }
-
-        @Override
-        public void forEach(DoubleConsumer action) {
-            s.forEach(action);
-        }
-
-        @Override
-        public void forEachOrdered(DoubleConsumer action) {
-            s.forEachOrdered(action);
-        }
-
-        @Override
-        public double[] toArray() {
-            return s.toArray();
-        }
-
-        @Override
-        public double reduce(double identity, DoubleBinaryOperator op) {
-            return s.reduce(identity, op);
-        }
-
-        @Override
-        public OptionalDouble reduce(DoubleBinaryOperator op) {
-            return s.reduce(op);
-        }
-
-        @Override
-        public <R> R collect(Supplier<R> supplier, ObjDoubleConsumer<R> accumulator, BiConsumer<R, R> combiner) {
-            return s.collect(supplier, accumulator, combiner);
-        }
-
-        @Override
-        public double sum() {
-            return s.sum();
-        }
-
-        @Override
-        public OptionalDouble min() {
-            return s.min();
-        }
-
-        @Override
-        public OptionalDouble max() {
-            return s.max();
-        }
-
-        @Override
-        public long count() {
-            return s.count();
-        }
-
-        @Override
-        public OptionalDouble average() {
-            return s.average();
-        }
-
-        @Override
-        public DoubleSummaryStatistics summaryStatistics() {
-            return s.summaryStatistics();
-        }
-
-        @Override
-        public boolean anyMatch(DoublePredicate predicate) {
-            return s.anyMatch(predicate);
-        }
-
-        @Override
-        public boolean allMatch(DoublePredicate predicate) {
-            return s.allMatch(predicate);
-        }
-
-        @Override
-        public boolean noneMatch(DoublePredicate predicate) {
-            return s.noneMatch(predicate);
-        }
-
-        @Override
-        public OptionalDouble findFirst() {
-            return s.findFirst();
-        }
-
-        @Override
-        public OptionalDouble findAny() {
-            return s.findAny();
-        }
-
-        @Override
-        public Stream<Double> boxed() {
-            return s.boxed();
-        }
-
-        @Override
-        public DoubleStream sequential() {
-            return s.sequential();
-        }
-
-        @Override
-        public DoubleStream parallel() {
-            return s.parallel();
-        }
-
-        @Override
-        public PrimitiveIterator.OfDouble iterator() {
-            return s.iterator();
-        }
-
-        @Override
-        public Spliterator.OfDouble spliterator() {
-            return s.spliterator();
-        }
-
-        @Override
-        public boolean isParallel() {
-            return s.isParallel();
-        }
-
-        @Override
-        public DoubleStream unordered() {
-            return s.unordered();
-        }
-
-        @Override
-        public DoubleStream onClose(Runnable closeHandler) {
-            return s.onClose(closeHandler);
-        }
-
-        @Override
-        public void close() {
-            s.close();
-        }
-    }
-}
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/DoubleStreamTestDataProvider.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,144 +0,0 @@
-/*
- * Copyright (c) 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 java.util.stream;
-
-import org.testng.annotations.DataProvider;
-
-import java.util.*;
-import java.util.Spliterators;
-import java.util.function.Supplier;
-
-/** TestNG DataProvider for double-valued streams */
-public class DoubleStreamTestDataProvider {
-    private static final double[] to0 = new double[0];
-    private static final double[] to1 = new double[1];
-    private static final double[] to10 = new double[10];
-    private static final double[] to100 = new double[100];
-    private static final double[] to1000 = new double[1000];
-    private static final double[] reversed = new double[100];
-    private static final double[] ones = new double[100];
-    private static final double[] twice = new double[200];
-    private static final double[] pseudoRandom;
-
-    private static final Object[][] testData;
-    private static final Object[][] spliteratorTestData;
-
-    static {
-        double[][] arrays = {to0, to1, to10, to100, to1000};
-        for (double[] arr : arrays) {
-            for (int i = 0; i < arr.length; i++) {
-                arr[i] = i;
-            }
-        }
-        for (int i = 0; i < reversed.length; i++) {
-            reversed[i] = reversed.length - i;
-        }
-        for (int i = 0; i < ones.length; i++) {
-            ones[i] = 1;
-        }
-        System.arraycopy(to100, 0, twice, 0, to100.length);
-        System.arraycopy(to100, 0, twice, to100.length, to100.length);
-        pseudoRandom = new double[LambdaTestHelpers.LONG_STRING.length()];
-        for (int i = 0; i < LambdaTestHelpers.LONG_STRING.length(); i++) {
-            pseudoRandom[i] = (double) LambdaTestHelpers.LONG_STRING.charAt(i);
-        }
-    }
-
-    static final Object[][] arrays = {
-            {"empty", to0},
-            {"0..1", to1},
-            {"0..10", to10},
-            {"0..100", to100},
-            {"0..1000", to1000},
-            {"100x[1]", ones},
-            {"2x[0..100]", twice},
-            {"reverse 0..100", reversed},
-            {"pseudorandom", pseudoRandom}
-    };
-
-    static {
-        {
-            List<Object[]> list = new ArrayList<>();
-            for (Object[] data : arrays) {
-                final Object name = data[0];
-                final double[] doubles = (double[]) data[1];
-
-                list.add(new Object[]{"array:" + name,
-                        TestData.Factory.ofArray("array:" + name, doubles)});
-
-                SpinedBuffer.OfDouble isl = new SpinedBuffer.OfDouble();
-                for (double i : doubles) {
-                    isl.accept(i);
-                }
-                list.add(new Object[]{"SpinedList:" + name,
-                        TestData.Factory.ofSpinedBuffer("SpinedList:" + name, isl)});
-            }
-            testData = list.toArray(new Object[0][]);
-        }
-
-        {
-            List<Object[]> spliterators = new ArrayList<>();
-            for (Object[] data : arrays) {
-                final Object name = data[0];
-                final double[] doubles = (double[]) data[1];
-
-                SpinedBuffer.OfDouble isl = new SpinedBuffer.OfDouble();
-                for (double i : doubles) {
-                    isl.accept(i);
-                }
-
-                spliterators.add(splitDescr("Arrays.s(array):" + name,
-                                            () -> Arrays.spliterator(doubles)));
-                spliterators.add(splitDescr("Arrays.s(array,o,l):" + name,
-                                            () -> Arrays.spliterator(doubles, 0, doubles.length / 2)));
-
-                spliterators.add(splitDescr("SpinedBuffer.s():" + name,
-                                            () -> isl.spliterator()));
-
-                spliterators.add(splitDescr("Primitives.s(SpinedBuffer.iterator(), size):" + name,
-                                            () -> Spliterators.spliterator(isl.iterator(), doubles.length, 0)));
-                spliterators.add(splitDescr("Primitives.s(SpinedBuffer.iterator()):" + name,
-                                            () -> Spliterators.spliteratorUnknownSize(isl.iterator(), 0)));
-                // Need more!
-            }
-            spliteratorTestData = spliterators.toArray(new Object[0][]);
-        }
-
-    }
-
-    static <T> Object[] splitDescr(String description, Supplier<Spliterator.OfDouble> s) {
-        return new Object[] { description, s };
-    }
-
-    // Return an array of ( String name, DoubleStreamTestData )
-    @DataProvider(name = "DoubleStreamTestData")
-    public static Object[][] makeDoubleStreamTestData() {
-        return testData;
-    }
-
-    // returns an array of (String name, Supplier<PrimitiveSpliterator<Double>>)
-    @DataProvider(name = "DoubleSpliterator")
-    public static Object[][] spliteratorProvider() {
-        return spliteratorTestData;
-    }
-}
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/DoubleStreamTestScenario.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,232 +0,0 @@
-/*
- * 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package java.util.stream;
-
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.PrimitiveIterator;
-import java.util.Set;
-import java.util.Spliterator;
-import java.util.function.Consumer;
-import java.util.function.DoubleConsumer;
-import java.util.function.Function;
-
-/**
- * Test scenarios for double streams.
- *
- * Each scenario is provided with a data source, a function that maps a fresh
- * stream (as provided by the data source) to a new stream, and a sink to
- * receive results.  Each scenario describes a different way of computing the
- * stream contents.  The test driver will ensure that all scenarios produce
- * the same output (modulo allowable differences in ordering).
- */
-@SuppressWarnings({"rawtypes", "unchecked"})
-public enum DoubleStreamTestScenario implements OpTestCase.BaseStreamTestScenario {
-
-    STREAM_FOR_EACH(false) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
-            DoubleStream s = m.apply(source);
-            if (s.isParallel()) {
-                s = s.sequential();
-            }
-            s.forEach(b);
-        }
-    },
-
-    STREAM_TO_ARRAY(false) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
-            for (double t : m.apply(source).toArray()) {
-                b.accept(t);
-            }
-        }
-    },
-
-    STREAM_ITERATOR(false) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
-            for (PrimitiveIterator.OfDouble seqIter = m.apply(source).iterator(); seqIter.hasNext(); )
-                b.accept(seqIter.nextDouble());
-        }
-    },
-
-    // Wrap as stream, and spliterate then iterate in pull mode
-    STREAM_SPLITERATOR(false) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
-            for (Spliterator.OfDouble spl = m.apply(source).spliterator(); spl.tryAdvance(b); ) {
-            }
-        }
-    },
-
-    // Wrap as stream, spliterate, then split a few times mixing advances with forEach
-    STREAM_SPLITERATOR_WITH_MIXED_TRAVERSE_AND_SPLIT(false) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
-            SpliteratorTestHelper.mixedTraverseAndSplit(b, m.apply(source).spliterator());
-        }
-    },
-
-    // Wrap as stream, and spliterate then iterate in pull mode
-    STREAM_SPLITERATOR_FOREACH(false) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
-            m.apply(source).spliterator().forEachRemaining(b);
-        }
-    },
-
-    PAR_STREAM_SEQUENTIAL_FOR_EACH(true) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
-            m.apply(source).sequential().forEach(b);
-        }
-    },
-
-    // Wrap as parallel stream + forEachOrdered
-    PAR_STREAM_FOR_EACH_ORDERED(true) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
-            // @@@ Want to explicitly select ordered equalator
-            m.apply(source).forEachOrdered(b);
-        }
-    },
-
-    // Wrap as stream, and spliterate then iterate sequentially
-    PAR_STREAM_SPLITERATOR(true) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
-            for (Spliterator.OfDouble spl = m.apply(source).spliterator(); spl.tryAdvance(b); ) {
-            }
-        }
-    },
-
-    // Wrap as stream, and spliterate then iterate sequentially
-    PAR_STREAM_SPLITERATOR_FOREACH(true) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
-            m.apply(source).spliterator().forEachRemaining(b);
-        }
-    },
-
-    PAR_STREAM_TO_ARRAY(true) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
-            for (double t : m.apply(source).toArray())
-                b.accept(t);
-        }
-    },
-
-    // Wrap as parallel stream, get the spliterator, wrap as a stream + toArray
-    PAR_STREAM_SPLITERATOR_STREAM_TO_ARRAY(true) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
-            DoubleStream s = m.apply(source);
-            Spliterator.OfDouble sp = s.spliterator();
-            DoubleStream ss = StreamSupport.doubleStream(() -> sp,
-                                                         StreamOpFlag.toCharacteristics(OpTestCase.getStreamFlags(s))
-                                                         | (sp.getExactSizeIfKnown() < 0 ? 0 : Spliterator.SIZED), true);
-            for (double t : ss.toArray())
-                b.accept(t);
-        }
-    },
-
-    PAR_STREAM_TO_ARRAY_CLEAR_SIZED(true) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
-            S_IN pipe1 = (S_IN) OpTestCase.chain(source,
-                                                 new FlagDeclaringOp(StreamOpFlag.NOT_SIZED, data.getShape()));
-            DoubleStream pipe2 = m.apply(pipe1);
-
-            for (double t : pipe2.toArray())
-                b.accept(t);
-        }
-    },
-
-    // Wrap as parallel stream + forEach synchronizing
-    PAR_STREAM_FOR_EACH(true, false) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
-            m.apply(source).forEach(e -> {
-                synchronized (data) {
-                    b.accept(e);
-                }
-            });
-        }
-    },
-
-    // Wrap as parallel stream + forEach synchronizing and clear SIZED flag
-    PAR_STREAM_FOR_EACH_CLEAR_SIZED(true, false) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m) {
-            S_IN pipe1 = (S_IN) OpTestCase.chain(source,
-                                                 new FlagDeclaringOp(StreamOpFlag.NOT_SIZED, data.getShape()));
-            m.apply(pipe1).forEach(e -> {
-                synchronized (data) {
-                    b.accept(e);
-                }
-            });
-        }
-    },
-    ;
-
-    // The set of scenarios that clean the SIZED flag
-    public static final Set<DoubleStreamTestScenario> CLEAR_SIZED_SCENARIOS = Collections.unmodifiableSet(
-            EnumSet.of(PAR_STREAM_TO_ARRAY_CLEAR_SIZED, PAR_STREAM_FOR_EACH_CLEAR_SIZED));
-
-    private boolean isParallel;
-
-    private final boolean isOrdered;
-
-    DoubleStreamTestScenario(boolean isParallel) {
-        this(isParallel, true);
-    }
-
-    DoubleStreamTestScenario(boolean isParallel, boolean isOrdered) {
-        this.isParallel = isParallel;
-        this.isOrdered = isOrdered;
-    }
-
-    public StreamShape getShape() {
-        return StreamShape.DOUBLE_VALUE;
-    }
-
-    public boolean isParallel() {
-        return isParallel;
-    }
-
-    public boolean isOrdered() {
-        return isOrdered;
-    }
-
-    public <T, U, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>>
-    void run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, S_OUT> m) {
-        try (S_IN source = getStream(data)) {
-            run(data, source, (DoubleConsumer) b, (Function<S_IN, DoubleStream>) m);
-        }
-    }
-
-    abstract <T, S_IN extends BaseStream<T, S_IN>>
-    void run(TestData<T, S_IN> data, S_IN source, DoubleConsumer b, Function<S_IN, DoubleStream> m);
-
-}
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/FlagDeclaringOp.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +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 java.util.stream;
-
-/**
- * An operation that injects or clears flags but otherwise performs no operation on elements.
- */
-@SuppressWarnings({"rawtypes", "unchecked"})
-public class FlagDeclaringOp<T> implements StatelessTestOp<T, T> {
-    private final int flags;
-    private final StreamShape shape;
-
-    public FlagDeclaringOp(int flags) {
-        this(flags, StreamShape.REFERENCE);
-    }
-
-    public FlagDeclaringOp(int flags, StreamShape shape) {
-        this.flags = flags;
-        this.shape = shape;
-    }
-
-    @Override
-    public StreamShape outputShape() {
-        return shape;
-    }
-
-    @Override
-    public StreamShape inputShape() {
-        return shape;
-    }
-
-    @Override
-    public int opGetFlags() {
-        return flags;
-    }
-
-    @Override
-    public Sink<T> opWrapSink(int flags, boolean parallel, Sink sink) {
-        return sink;
-    }
-}
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/IntStreamTestDataProvider.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,158 +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 java.util.stream;
-
-import org.testng.annotations.DataProvider;
-
-import java.util.*;
-import java.util.Spliterators;
-import java.util.function.Supplier;
-
-/** TestNG DataProvider for int-valued streams */
-public class IntStreamTestDataProvider {
-    private static final int[] to0 = new int[0];
-    private static final int[] to1 = new int[1];
-    private static final int[] to10 = new int[10];
-    private static final int[] to100 = new int[100];
-    private static final int[] to1000 = new int[1000];
-    private static final int[] reversed = new int[100];
-    private static final int[] ones = new int[100];
-    private static final int[] twice = new int[200];
-    private static final int[] pseudoRandom;
-
-    private static final Object[][] testData;
-    private static final Object[][] spliteratorTestData;
-
-    static {
-        int[][] arrays = {to0, to1, to10, to100, to1000};
-        for (int[] arr : arrays) {
-            for (int i = 0; i < arr.length; i++) {
-                arr[i] = i;
-            }
-        }
-        for (int i = 0; i < reversed.length; i++) {
-            reversed[i] = reversed.length - i;
-        }
-        for (int i = 0; i < ones.length; i++) {
-            ones[i] = 1;
-        }
-        System.arraycopy(to100, 0, twice, 0, to100.length);
-        System.arraycopy(to100, 0, twice, to100.length, to100.length);
-        pseudoRandom = new int[LambdaTestHelpers.LONG_STRING.length()];
-        for (int i = 0; i < LambdaTestHelpers.LONG_STRING.length(); i++) {
-            pseudoRandom[i] = (int) LambdaTestHelpers.LONG_STRING.charAt(i);
-        }
-    }
-
-    static final Object[][] arrays = {
-            {"empty", to0},
-            {"0..1", to1},
-            {"0..10", to10},
-            {"0..100", to100},
-            {"0..1000", to1000},
-            {"100x[1]", ones},
-            {"2x[0..100]", twice},
-            {"reverse 0..100", reversed},
-            {"pseudorandom", pseudoRandom}
-    };
-
-    static {
-        {
-            List<Object[]> list = new ArrayList<>();
-            for (Object[] data : arrays) {
-                final Object name = data[0];
-                final int[] ints = (int[]) data[1];
-
-                list.add(new Object[]{"array:" +
-                                      name, TestData.Factory.ofArray("array:" + name, ints)});
-
-                SpinedBuffer.OfInt isl = new SpinedBuffer.OfInt();
-                for (int i : ints) {
-                    isl.accept(i);
-                }
-                list.add(new Object[]{"SpinedList:" + name,
-                         TestData.Factory.ofSpinedBuffer("SpinedList:" + name, isl)});
-
-                list.add(streamDataDescr("IntStream.intRange(0,l): " + ints.length,
-                                         () -> IntStream.range(0, ints.length)));
-                list.add(streamDataDescr("IntStream.rangeClosed(0,l): " + ints.length,
-                                         () -> IntStream.rangeClosed(0, ints.length)));
-            }
-            testData = list.toArray(new Object[0][]);
-        }
-
-        {
-            List<Object[]> spliterators = new ArrayList<>();
-            for (Object[] data : arrays) {
-                final Object name = data[0];
-                final int[] ints = (int[]) data[1];
-
-                SpinedBuffer.OfInt isl = new SpinedBuffer.OfInt();
-                for (int i : ints) {
-                    isl.accept(i);
-                }
-
-                spliterators.add(splitDescr("Arrays.s(array):" + name,
-                                            () -> Arrays.spliterator(ints)));
-                spliterators.add(splitDescr("Arrays.s(array,o,l):" + name,
-                                            () -> Arrays.spliterator(ints, 0, ints.length / 2)));
-
-                spliterators.add(splitDescr("SpinedBuffer.s():" + name,
-                                            () -> isl.spliterator()));
-
-                spliterators.add(splitDescr("Primitives.s(SpinedBuffer.iterator(), size):" + name,
-                                            () -> Spliterators.spliterator(isl.iterator(), ints.length, 0)));
-                spliterators.add(splitDescr("Primitives.s(SpinedBuffer.iterator()):" + name,
-                                            () -> Spliterators.spliteratorUnknownSize(isl.iterator(), 0)));
-
-                spliterators.add(splitDescr("IntStream.intRange(0,l):" + name,
-                                            () -> IntStream.range(0, ints.length).spliterator()));
-                spliterators.add(splitDescr("IntStream.intRangeClosed(0,l):" + name,
-                                            () -> IntStream.rangeClosed(0, ints.length).spliterator()));
-                // Need more!
-            }
-            spliteratorTestData = spliterators.toArray(new Object[0][]);
-        }
-
-    }
-
-    static <T> Object[] streamDataDescr(String description, Supplier<IntStream> s) {
-        return new Object[] { description, TestData.Factory.ofIntSupplier(description, s) };
-    }
-
-    static <T> Object[] splitDescr(String description, Supplier<Spliterator.OfInt> s) {
-        return new Object[] { description, s };
-    }
-
-    // Return an array of ( String name, IntStreamTestData )
-    @DataProvider(name = "IntStreamTestData")
-    public static Object[][] makeIntStreamTestData() {
-        return testData;
-    }
-
-    // returns an array of (String name, Supplier<PrimitiveSpliterator<Integer>>)
-    @DataProvider(name = "IntSpliterator")
-    public static Object[][] spliteratorProvider() {
-        return spliteratorTestData;
-    }
-}
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/IntStreamTestScenario.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,233 +0,0 @@
-/*
- * 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 java.util.stream;
-
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.PrimitiveIterator;
-import java.util.Set;
-import java.util.Spliterator;
-import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.function.IntConsumer;
-
-/**
- * Test scenarios for int streams.
- *
- * Each scenario is provided with a data source, a function that maps a fresh
- * stream (as provided by the data source) to a new stream, and a sink to
- * receive results.  Each scenario describes a different way of computing the
- * stream contents.  The test driver will ensure that all scenarios produce
- * the same output (modulo allowable differences in ordering).
- */
-@SuppressWarnings({"rawtypes", "unchecked"})
-public enum IntStreamTestScenario implements OpTestCase.BaseStreamTestScenario {
-
-    STREAM_FOR_EACH(false) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
-            IntStream s = m.apply(source);
-            if (s.isParallel()) {
-                s = s.sequential();
-            }
-            s.forEach(b);
-        }
-    },
-
-    STREAM_TO_ARRAY(false) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
-            for (int t : m.apply(source).toArray()) {
-                b.accept(t);
-            }
-        }
-    },
-
-    STREAM_ITERATOR(false) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
-            for (PrimitiveIterator.OfInt seqIter = m.apply(source).iterator(); seqIter.hasNext(); )
-                b.accept(seqIter.nextInt());
-        }
-    },
-
-    // Wrap as stream, and spliterate then iterate in pull mode
-    STREAM_SPLITERATOR(false) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
-            for (Spliterator.OfInt spl = m.apply(source).spliterator(); spl.tryAdvance(b); ) {
-            }
-        }
-    },
-
-    // Wrap as stream, spliterate, then split a few times mixing advances with forEach
-    STREAM_SPLITERATOR_WITH_MIXED_TRAVERSE_AND_SPLIT(false) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
-            SpliteratorTestHelper.mixedTraverseAndSplit(b, m.apply(source).spliterator());
-        }
-    },
-
-    // Wrap as stream, and spliterate then iterate in pull mode
-    STREAM_SPLITERATOR_FOREACH(false) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
-            m.apply(source).spliterator().forEachRemaining(b);
-        }
-    },
-
-    PAR_STREAM_SEQUENTIAL_FOR_EACH(true) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
-            m.apply(source).sequential().forEach(b);
-        }
-    },
-
-    // Wrap as parallel stream + forEachOrdered
-    PAR_STREAM_FOR_EACH_ORDERED(true) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
-            // @@@ Want to explicitly select ordered equalator
-            m.apply(source).forEachOrdered(b);
-        }
-    },
-
-    // Wrap as stream, and spliterate then iterate sequentially
-    PAR_STREAM_SPLITERATOR(true) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
-            for (Spliterator.OfInt spl = m.apply(source).spliterator(); spl.tryAdvance(b); ) {
-            }
-        }
-    },
-
-    // Wrap as stream, and spliterate then iterate sequentially
-    PAR_STREAM_SPLITERATOR_FOREACH(true) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
-            m.apply(source).spliterator().forEachRemaining(b);
-        }
-    },
-
-    PAR_STREAM_TO_ARRAY(true) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
-            for (int t : m.apply(source).toArray())
-                b.accept(t);
-        }
-    },
-
-    // Wrap as parallel stream, get the spliterator, wrap as a stream + toArray
-    PAR_STREAM_SPLITERATOR_STREAM_TO_ARRAY(true) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
-            IntStream s = m.apply(source);
-            Spliterator.OfInt sp = s.spliterator();
-            IntStream ss = StreamSupport.intStream(() -> sp,
-                                                   StreamOpFlag.toCharacteristics(OpTestCase.getStreamFlags(s))
-                                                   | (sp.getExactSizeIfKnown() < 0 ? 0 : Spliterator.SIZED),
-                                                   true);
-            for (int t : ss.toArray())
-                b.accept(t);
-        }
-    },
-
-    PAR_STREAM_TO_ARRAY_CLEAR_SIZED(true) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
-            S_IN pipe1 = (S_IN) OpTestCase.chain(source,
-                                                 new FlagDeclaringOp(StreamOpFlag.NOT_SIZED, data.getShape()));
-            IntStream pipe2 = m.apply(pipe1);
-
-            for (int t : pipe2.toArray())
-                b.accept(t);
-        }
-    },
-
-    // Wrap as parallel stream + forEach synchronizing
-    PAR_STREAM_FOR_EACH(true, false) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
-            m.apply(source).forEach(e -> {
-                synchronized (data) {
-                    b.accept(e);
-                }
-            });
-        }
-    },
-
-    // Wrap as parallel stream + forEach synchronizing and clear SIZED flag
-    PAR_STREAM_FOR_EACH_CLEAR_SIZED(true, false) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m) {
-            S_IN pipe1 = (S_IN) OpTestCase.chain(source,
-                                                 new FlagDeclaringOp(StreamOpFlag.NOT_SIZED, data.getShape()));
-            m.apply(pipe1).forEach(e -> {
-                synchronized (data) {
-                    b.accept(e);
-                }
-            });
-        }
-    },
-    ;
-
-    // The set of scenarios that clean the SIZED flag
-    public static final Set<IntStreamTestScenario> CLEAR_SIZED_SCENARIOS = Collections.unmodifiableSet(
-            EnumSet.of(PAR_STREAM_TO_ARRAY_CLEAR_SIZED, PAR_STREAM_FOR_EACH_CLEAR_SIZED));
-
-    private final boolean isParallel;
-
-    private final boolean isOrdered;
-
-    IntStreamTestScenario(boolean isParallel) {
-        this(isParallel, true);
-    }
-
-    IntStreamTestScenario(boolean isParallel, boolean isOrdered) {
-        this.isParallel = isParallel;
-        this.isOrdered = isOrdered;
-    }
-
-    public StreamShape getShape() {
-        return StreamShape.INT_VALUE;
-    }
-
-    public boolean isParallel() {
-        return isParallel;
-    }
-
-    public boolean isOrdered() {
-        return isOrdered;
-    }
-
-    public <T, U, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>>
-    void run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, S_OUT> m) {
-        try (S_IN source = getStream(data)) {
-            run(data, source, (IntConsumer) b, (Function<S_IN, IntStream>) m);
-        }
-    }
-
-    abstract <T, S_IN extends BaseStream<T, S_IN>>
-    void run(TestData<T, S_IN> data, S_IN source, IntConsumer b, Function<S_IN, IntStream> m);
-
-}
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/IntermediateTestOp.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +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 java.util.stream;
-
-/**
- * A base type for test operations
- */
-interface IntermediateTestOp<E_IN, E_OUT> {
-
-    @SuppressWarnings({"rawtypes", "unchecked"})
-    public static<T> AbstractPipeline chain(AbstractPipeline upstream,
-                                            IntermediateTestOp<?, T> op) {
-        if (op instanceof StatelessTestOp)
-            return StatelessTestOp.chain(upstream, (StatelessTestOp) op);
-
-        if (op instanceof StatefulTestOp)
-            return StatefulTestOp.chain(upstream, (StatefulTestOp) op);
-
-        throw new IllegalStateException("Unknown test op type: " + op.getClass().getName());
-    }
-}
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/LambdaTestHelpers.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,462 +0,0 @@
-/*
- * Copyright (c) 1997, 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 java.util.stream;
-
-import java.util.*;
-import java.util.function.BiConsumer;
-import java.util.function.BiPredicate;
-import java.util.function.BinaryOperator;
-import java.util.function.Consumer;
-import java.util.function.DoubleBinaryOperator;
-import java.util.function.DoubleConsumer;
-import java.util.function.DoublePredicate;
-import java.util.function.Function;
-import java.util.function.IntBinaryOperator;
-import java.util.function.IntConsumer;
-import java.util.function.IntFunction;
-import java.util.function.IntPredicate;
-import java.util.function.IntUnaryOperator;
-import java.util.function.LongBinaryOperator;
-import java.util.function.LongConsumer;
-import java.util.function.LongPredicate;
-import java.util.function.Predicate;
-import java.util.function.Supplier;
-import java.util.function.ToDoubleFunction;
-import java.util.function.ToIntFunction;
-import java.util.function.ToLongFunction;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-/**
- * LambdaTestHelpers -- assertion methods and useful objects for lambda test cases
- */
-public class LambdaTestHelpers {
-    public static final String LONG_STRING = "When in the Course of human events it becomes necessary for one people to dissolve the political bands which have connected them with another and to assume among the powers of the earth, the separate and equal station to which the Laws of Nature and of Nature's God entitle them, a decent respect to the opinions of mankind requires that they should declare the causes which impel them to the separation.";
-
-    @SuppressWarnings("rawtypes")
-    public static final Consumer bEmpty = x -> {  };
-    @SuppressWarnings("rawtypes")
-    public static final IntConsumer bIntEmpty = x -> {  };
-    @SuppressWarnings("rawtypes")
-    public static final BiConsumer bBiEmpty = (x,y) -> { };
-    @SuppressWarnings("rawtypes")
-    public static final Consumer bHashCode = x -> { Objects.hashCode(x); };
-    @SuppressWarnings("rawtypes")
-    public static final BiConsumer bBiHashCode = (x,y) -> { Objects.hash(x, y); };
-    public static final Function<Integer, Integer> mZero = x -> 0;
-    public static final Function<Integer, Integer> mId = x -> x;
-    public static final Function<Integer, Integer> mDoubler = x -> x * 2;
-    public static final Function<Integer, Stream<Integer>> mfId = e -> Collections.singletonList(e).stream();
-    public static final Function<Integer, Stream<Integer>> mfNull = e -> Collections.<Integer>emptyList().stream();
-    public static final Function<Integer, Stream<Integer>> mfLt = e -> {
-        List<Integer> l = new ArrayList<>();
-        for (int i=0; i<e; i++)
-            l.add(i);
-        return l.stream();
-    };
-    public static final ToIntFunction<Integer> imDoubler = x -> x * 2;
-    public static final ToLongFunction<Long> lmDoubler = x -> x * 2;
-    public static final ToDoubleFunction<Double> dmDoubler = x -> x * 2;
-    public static final Predicate<Integer> pFalse = x -> false;
-    public static final Predicate<Integer> pTrue = x -> true;
-    public static final Predicate<Integer> pEven = x -> 0 == x % 2;
-    public static final Predicate<Integer> pOdd = x -> 1 == x % 2;
-    public static final IntPredicate ipFalse = x -> false;
-    public static final IntPredicate ipTrue = x -> true;
-    public static final IntPredicate ipEven = x -> 0 == x % 2;
-    public static final IntPredicate ipOdd = x -> 1 == x % 2;
-    public static final LongPredicate lpFalse = x -> false;
-    public static final LongPredicate lpTrue = x -> true;
-    public static final LongPredicate lpEven = x -> 0 == x % 2;
-    public static final LongPredicate lpOdd = x -> 1 == x % 2;
-    public static final DoublePredicate dpFalse = x -> false;
-    public static final DoublePredicate dpTrue = x -> true;
-    public static final DoublePredicate dpEven = x -> 0 == ((long) x) % 2;
-    public static final DoublePredicate dpOdd = x -> 1 == ((long) x) % 2;
-    public static final BinaryOperator<Integer> rPlus = (x, y) -> x+y;
-    public static final BinaryOperator<Integer> rMax = (x, y) -> Math.max(x, y);
-    public static final BinaryOperator<Integer> rMin = (x, y) -> Math.min(x,y);
-    public static final IntBinaryOperator irPlus = (x, y) -> x+y;
-    public static final IntBinaryOperator irMax = (x, y) -> Math.max(x, y);
-    public static final IntBinaryOperator irMin = (x, y) -> Math.min(x,y);
-    public static final IntUnaryOperator irDoubler = x -> x * 2;
-    public static final LongBinaryOperator lrPlus = (x, y) -> x+y;
-    public static final DoubleBinaryOperator drPlus = (x, y) -> x+y;
-    public static final Comparator<Integer> cInteger = (a, b) -> Integer.compare(a, b);
-    public static final BiPredicate<?, ?> bipFalse = (x, y) -> false;
-    public static final BiPredicate<?, ?> bipTrue = (x, y) -> true;
-    public static final BiPredicate<Integer, Integer> bipBothEven = (x, y) -> 0 == (x % 2 + y % 2);
-    public static final BiPredicate<Integer, Integer> bipBothOdd = (x, y) -> 2 == (x % 2 + y % 2);
-    public static final BiPredicate<?, ?> bipSameString = (x, y) -> String.valueOf(x).equals(String.valueOf(y));
-
-    public static final IntFunction<Integer[]> integerArrayGenerator = s -> new Integer[s];
-
-    public static final IntFunction<Object[]> objectArrayGenerator = s -> new Object[s];
-
-    public static final Function<String, Stream<Character>> flattenChars = string -> {
-        List<Character> l = new ArrayList<>();
-        for (int i=0; i<string.length(); i++)
-            l.add(string.charAt(i));
-        return l.stream();
-    };
-
-    public static final Function<String, IntStream> flattenInt
-            = string -> IntStream.range(0, string.length()).map(string::charAt);
-
-    public static <T, R> Function<T, R> forPredicate(Predicate<? super T> predicate, R forTrue, R forFalse) {
-        Objects.requireNonNull(predicate);
-
-        return t -> predicate.test(t) ? forTrue : forFalse;
-    }
-
-    public static <T> Function<T, T> identity() {
-        return t -> t;
-    }
-
-    public static<V, T, R> Function<V, R> compose(Function<? super T, ? extends R> after, Function<? super V, ? extends T> before) {
-        Objects.requireNonNull(before);
-        return (V v) -> after.apply(before.apply(v));
-    }
-
-    public static List<Integer> empty() {
-        ArrayList<Integer> list = new ArrayList<>();
-        list.add(null);
-        return list;
-    }
-
-    public static List<Integer> countTo(int n) {
-        return range(1, n);
-    }
-
-    public static List<Integer> range(int l, int u) {
-        ArrayList<Integer> list = new ArrayList<>(u - l + 1);
-        for (int i=l; i<=u; i++) {
-            list.add(i);
-        }
-        return list;
-    }
-
-    public static List<Integer> repeat(int value, int n) {
-        ArrayList<Integer> list = new ArrayList<>(n);
-        for (int i=1; i<=n; i++) {
-            list.add(value);
-        }
-        return list;
-    }
-
-    public static List<Double> asDoubles(List<Integer> integers) {
-        ArrayList<Double> list = new ArrayList<>();
-        for (Integer i : integers) {
-            list.add((double) i);
-        }
-        return list;
-    }
-
-    public static List<Long> asLongs(List<Integer> integers) {
-        ArrayList<Long> list = new ArrayList<>();
-        for (Integer i : integers) {
-            list.add((long) i);
-        }
-        return list;
-    }
-
-    public static void assertCountSum(Stream<? super Integer> it, int count, int sum) {
-        assertCountSum(it.iterator(), count, sum);
-    }
-
-    public static void assertCountSum(Iterable<? super Integer> it, int count, int sum) {
-        assertCountSum(it.iterator(), count, sum);
-    }
-
-    public static void assertCountSum(Iterator<? super Integer> it, int count, int sum) {
-        int c = 0;
-        int s = 0;
-        while (it.hasNext()) {
-            int i = (Integer) it.next();
-            c++;
-            s += i;
-        }
-
-        assertEquals(c, count);
-        assertEquals(s, sum);
-    }
-
-    public static void assertConcat(Iterator<Character> it, String result) {
-        StringBuilder sb = new StringBuilder();
-        while (it.hasNext()) {
-            sb.append(it.next());
-        }
-
-        assertEquals(result, sb.toString());
-    }
-
-    public static<T extends Comparable<? super T>> void assertSorted(Iterator<T> i) {
-        i = toBoxedList(i).iterator();
-
-        if (!i.hasNext())
-            return;
-        T last = i.next();
-        while (i.hasNext()) {
-            T t = i.next();
-            assertTrue(last.compareTo(t) <= 0);
-            assertTrue(t.compareTo(last) >= 0);
-            last = t;
-        }
-    }
-
-    public static<T> void assertSorted(Iterator<T> i, Comparator<? super T> comp) {
-        if (i instanceof PrimitiveIterator.OfInt
-                || i instanceof PrimitiveIterator.OfDouble
-                || i instanceof PrimitiveIterator.OfLong) {
-            i = toBoxedList(i).iterator();
-        }
-
-        if (!i.hasNext())
-            return;
-        T last = i.next();
-        while (i.hasNext()) {
-            T t = i.next();
-            assertTrue(comp.compare(last, t) <= 0);
-            assertTrue(comp.compare(t, last) >= 0);
-            last = t;
-        }
-    }
-
-    public static<T extends Comparable<? super T>> void assertSorted(Iterable<T> iter) {
-        assertSorted(iter.iterator());
-    }
-
-    public static<T> void assertSorted(Iterable<T> iter, Comparator<? super T> comp) {
-        assertSorted(iter.iterator(), comp);
-    }
-
-    public static <T> void assertUnique(Iterable<T> iter) {
-        assertUnique(iter.iterator());
-    }
-
-    public static<T> void assertUnique(Iterator<T> iter) {
-        if (!iter.hasNext()) {
-            return;
-        }
-
-        if (iter instanceof PrimitiveIterator.OfInt
-            || iter instanceof PrimitiveIterator.OfDouble
-            || iter instanceof PrimitiveIterator.OfLong) {
-            iter = toBoxedList(iter).iterator();
-        }
-
-        Set<T> uniq = new HashSet<>();
-        while(iter.hasNext()) {
-            T each = iter.next();
-            assertTrue(!uniq.contains(each), "Not unique");
-            uniq.add(each);
-        }
-    }
-
-    public static<T> void assertContents(Iterable<T> actual, Iterable<T> expected) {
-        if (actual instanceof Collection && expected instanceof Collection) {
-            assertEquals(actual, expected);
-        } else {
-            assertContents(actual.iterator(), expected.iterator());
-        }
-    }
-
-    public static<T> void assertContents(Iterator<T> actual, Iterator<T> expected) {
-        assertEquals(toBoxedList(actual), toBoxedList(expected));
-    }
-
-    @SafeVarargs
-    @SuppressWarnings("varargs")
-    public static<T> void assertContents(Iterator<T> actual, T... expected) {
-        assertContents(actual, Arrays.asList(expected).iterator());
-    }
-
-    /**
-     * The all consuming consumer (rampant capitalist) that can accepting a reference or any primitive value.
-     */
-    private static interface OmnivorousConsumer<T>
-            extends Consumer<T>, IntConsumer, LongConsumer, DoubleConsumer { }
-
-    @SuppressWarnings({"rawtypes", "unchecked"})
-    public static<T> Consumer<T> toBoxingConsumer(Consumer<? super T> c) {
-        return (Consumer<T>) new OmnivorousConsumer() {
-            @Override
-            public void accept(Object t) {
-                c.accept((T) t);
-            }
-
-            @Override
-            public void accept(int t) {
-                accept((Object) t);
-            }
-
-            @Override
-            public void accept(long t) {
-                accept((Object) t);
-            }
-
-            @Override
-            public void accept(double t) {
-                accept((Object) t);
-            }
-        };
-    }
-
-    /**
-     * Convert an iterator to a list using forEach with an implementation of
-     * {@link java.util.stream.LambdaTestHelpers.OmnivorousConsumer}.
-     *
-     * This ensures equality comparisons for test results do not trip
-     * the boxing trip-wires.
-     */
-    private static<T> List<T> toBoxedList(Iterator<T> it) {
-        List<T> l = new ArrayList<>();
-        it.forEachRemaining(toBoxingConsumer(l::add));
-        return l;
-    }
-
-    /**
-     * Convert a spliterator to a list using forEach with an implementation of
-     * {@link java.util.stream.LambdaTestHelpers.OmnivorousConsumer}.
-     *
-     * This ensures equality comparisons for test results do not trip
-     * the boxing trip-wires.
-     */
-    public static<T> List<T> toBoxedList(Spliterator<T> sp) {
-        List<T> l = new ArrayList<>();
-        sp.forEachRemaining(toBoxingConsumer(l::add));
-        return l;
-    }
-
-    /**
-     * Convert an iterator to a multi-set, represented as a Map, using forEach with an implementation of
-     * {@link java.util.stream.LambdaTestHelpers.OmnivorousConsumer}.
-     *
-     * This ensures equality comparisons for test results do not trip
-     * the boxing trip-wires.
-     */
-    @SuppressWarnings("unchecked")
-    private static<T> Map<T, Integer> toBoxedMultiset(Iterator<T> it) {
-        Map<Object, Integer> result = new HashMap<>();
-
-        it.forEachRemaining(toBoxingConsumer(o -> {
-                if (result.containsKey(o))
-                    result.put(o, result.get(o) + 1);
-                else
-                    result.put(o, 1);
-            }));
-
-        return (Map<T, Integer>) result;
-    }
-
-    @SuppressWarnings("unchecked")
-    public static<T> Map<T, Integer> toBoxedMultiset(Spliterator<T> it) {
-        Map<Object, Integer> result = new HashMap<>();
-
-        it.forEachRemaining(toBoxingConsumer(o -> {
-                if (result.containsKey(o))
-                    result.put(o, result.get(o) + 1);
-                else
-                    result.put(o, 1);
-            }));
-
-        return (Map<T, Integer>) result;
-    }
-
-    @SuppressWarnings("unchecked")
-    public static void assertContentsEqual(Object a, Object b) {
-        if (a instanceof Iterable && b instanceof Iterable)
-            assertContents((Iterable) a, (Iterable) b);
-        else
-            assertEquals(a, b);
-    }
-
-    public static<T> void assertContentsUnordered(Iterable<T> actual, Iterable<T> expected) {
-        assertContentsUnordered(actual.iterator(), expected.iterator());
-    }
-
-    public static<T> void assertContentsUnordered(Iterator<T> actual, Iterator<T> expected) {
-        assertEquals(toBoxedMultiset(actual), toBoxedMultiset(expected));
-    }
-
-    public static void launderAssertion(Runnable r, Supplier<String> additionalInfo) {
-        try {
-            r.run();
-        }
-        catch (AssertionError ae) {
-            AssertionError cloned = new AssertionError(ae.getMessage() + String.format("%n%s", additionalInfo.get()));
-            cloned.setStackTrace(ae.getStackTrace());
-            if (ae.getCause() != null)
-                cloned.initCause(ae.getCause());
-            throw cloned;
-        }
-    }
-
-    public static <T, S extends BaseStream<T, S>>
-    List<Function<S, S>> permuteStreamFunctions(List<Function<S, S>> opFunctions) {
-        List<List<Function<S, S>>> opFunctionPermutations = perm(opFunctions);
-
-        List<Function<S, S>> appliedFunctions = new ArrayList<>();
-        for (List<Function<S, S>> fs : opFunctionPermutations) {
-            Function<S, S> applied = s -> {
-                for (Function<S, S> f : fs) {
-                    s = f.apply(s);
-                }
-                return s;
-            };
-            appliedFunctions.add(applied);
-        }
-
-        return appliedFunctions;
-    }
-
-    private static <T> List<T> sub(List<T> l, int index) {
-        List<T> subL = new ArrayList<>(l);
-        subL.remove(index);
-        return subL;
-    }
-
-    public static <T> List<List<T>> perm(List<T> l) {
-        List<List<T>> result = new ArrayList<>();
-        for (int i = 0; i < l.size(); i++) {
-            for (List<T> perm : perm(sub(l, i))) {
-                perm.add(0, l.get(i));
-                result.add(perm);
-            }
-        }
-        result.add(new ArrayList<T>());
-
-        return result;
-    }
-
-    public static String flagsToString(int flags) {
-        StringJoiner sj = new StringJoiner(", ", "StreamOpFlag[", "]");
-        if (StreamOpFlag.DISTINCT.isKnown(flags)) sj.add("IS_DISTINCT");
-        if (StreamOpFlag.ORDERED.isKnown(flags)) sj.add("IS_ORDERED");
-        if (StreamOpFlag.SIZED.isKnown(flags)) sj.add("IS_SIZED");
-        if (StreamOpFlag.SORTED.isKnown(flags)) sj.add("IS_SORTED");
-        if (StreamOpFlag.SHORT_CIRCUIT.isKnown(flags)) sj.add("IS_SHORT_CIRCUIT");
-        return sj.toString();
-    }
-}
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/LambdaTestMode.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 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 java.util.stream;
-
-/**
- * Runtime modes of test execution.
- */
-public enum LambdaTestMode {
-    /**
-     * Execution mode with no particular runtime constraints.
-     */
-    NORMAL,
-
-    /**
-     * Execution mode where tests are executed for testing lambda serialization
-     * and deserialization.
-     *
-     * <p>This mode may be queried by tests or data supplied by data
-     * providers, which cannot otherwise be assigned to the test group
-     * <em>serialization-hostile</em>, to not execute or declare
-     * serialization-hostile code or data.
-     *
-     * <p>This mode is enabled if the boolean system property
-     * {@code org.openjdk.java.util.stream.sand.mode} is declared with a
-     * {@code true} value.
-     */
-    SERIALIZATION;
-
-    /**
-     * {@code true} if tests are executed in the mode for testing lambda
-     * Serialization ANd Deserialization (SAND).
-     */
-    private static final boolean IS_LAMBDA_SERIALIZATION_MODE =
-            Boolean.getBoolean("org.openjdk.java.util.stream.sand.mode");
-
-    /**
-     *
-     * @return the mode of test execution.
-     */
-    public static LambdaTestMode getMode() {
-        return IS_LAMBDA_SERIALIZATION_MODE ? SERIALIZATION : NORMAL;
-    }
-
-    /**
-     *
-     * @return {@code true} if normal test mode.
-     */
-    public static boolean isNormalMode() {
-        return getMode() == NORMAL;
-    }
-}
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/LoggingTestCase.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 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 java.util.stream;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.testng.Assert;
-import org.testng.ITestResult;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-/**
- * LoggingTestCase
- *
- */
-@Test
-public class LoggingTestCase extends Assert {
-    private Map<String, Object> context = new HashMap<>();
-
-    @BeforeMethod
-    public void before() {
-        context.clear();
-    }
-
-    @AfterMethod
-    public void after(ITestResult result) {
-        if (!result.isSuccess()) {
-            List<Object> list = new ArrayList<>();
-            Collections.addAll(list, result.getParameters());
-            list.add(context.toString());
-            result.setParameters(list.toArray(new Object[list.size()]));
-        }
-    }
-
-    protected void setContext(String key, Object value) {
-        context.put(key, value);
-    }
-
-    protected void clearContext(String key) {
-        context.remove(key);
-    }
-}
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/LongStreamTestDataProvider.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,158 +0,0 @@
-/*
- * Copyright (c) 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 java.util.stream;
-
-import org.testng.annotations.DataProvider;
-
-import java.util.*;
-import java.util.Spliterators;
-import java.util.function.Supplier;
-
-/** TestNG DataProvider for long-valued streams */
-public class LongStreamTestDataProvider {
-    private static final long[] to0 = new long[0];
-    private static final long[] to1 = new long[1];
-    private static final long[] to10 = new long[10];
-    private static final long[] to100 = new long[100];
-    private static final long[] to1000 = new long[1000];
-    private static final long[] reversed = new long[100];
-    private static final long[] ones = new long[100];
-    private static final long[] twice = new long[200];
-    private static final long[] pseudoRandom;
-
-    private static final Object[][] testData;
-    private static final Object[][] spliteratorTestData;
-
-    static {
-        long[][] arrays = {to0, to1, to10, to100, to1000};
-        for (long[] arr : arrays) {
-            for (int i = 0; i < arr.length; i++) {
-                arr[i] = i;
-            }
-        }
-        for (int i = 0; i < reversed.length; i++) {
-            reversed[i] = reversed.length - i;
-        }
-        for (int i = 0; i < ones.length; i++) {
-            ones[i] = 1;
-        }
-        System.arraycopy(to100, 0, twice, 0, to100.length);
-        System.arraycopy(to100, 0, twice, to100.length, to100.length);
-        pseudoRandom = new long[LambdaTestHelpers.LONG_STRING.length()];
-        for (int i = 0; i < LambdaTestHelpers.LONG_STRING.length(); i++) {
-            pseudoRandom[i] = (long) LambdaTestHelpers.LONG_STRING.charAt(i);
-        }
-    }
-
-    static final Object[][] arrays = {
-            {"empty", to0},
-            {"0..1", to1},
-            {"0..10", to10},
-            {"0..100", to100},
-            {"0..1000", to1000},
-            {"100x[1]", ones},
-            {"2x[0..100]", twice},
-            {"reverse 0..100", reversed},
-            {"pseudorandom", pseudoRandom}
-    };
-
-    static {
-        {
-            List<Object[]> list = new ArrayList<>();
-            for (Object[] data : arrays) {
-                final Object name = data[0];
-                final long[] longs = (long[]) data[1];
-
-                list.add(new Object[]{"array:" + name,
-                        TestData.Factory.ofArray("array:" + name, longs)});
-
-                SpinedBuffer.OfLong isl = new SpinedBuffer.OfLong();
-                for (long i : longs) {
-                    isl.accept(i);
-                }
-                list.add(new Object[]{"SpinedList:" + name,
-                        TestData.Factory.ofSpinedBuffer("SpinedList:" + name, isl)});
-
-                list.add(streamDataDescr("LongStream.longRange(0,l): " + longs.length,
-                                         () -> LongStream.range(0, longs.length)));
-                list.add(streamDataDescr("LongStream.longRangeClosed(0,l): " + longs.length,
-                                         () -> LongStream.rangeClosed(0, longs.length)));
-            }
-            testData = list.toArray(new Object[0][]);
-        }
-
-        {
-            List<Object[]> spliterators = new ArrayList<>();
-            for (Object[] data : arrays) {
-                final Object name = data[0];
-                final long[] longs = (long[]) data[1];
-
-                SpinedBuffer.OfLong isl = new SpinedBuffer.OfLong();
-                for (long i : longs) {
-                    isl.accept(i);
-                }
-
-                spliterators.add(splitDescr("Arrays.s(array):" + name,
-                                            () -> Arrays.spliterator(longs)));
-                spliterators.add(splitDescr("Arrays.s(array,o,l):" + name,
-                                            () -> Arrays.spliterator(longs, 0, longs.length / 2)));
-
-                spliterators.add(splitDescr("SpinedBuffer.s():" + name,
-                                            () -> isl.spliterator()));
-
-                spliterators.add(splitDescr("Primitives.s(SpinedBuffer.iterator(), size):" + name,
-                                            () -> Spliterators.spliterator(isl.iterator(), longs.length, 0)));
-                spliterators.add(splitDescr("Primitives.s(SpinedBuffer.iterator()):" + name,
-                                            () -> Spliterators.spliteratorUnknownSize(isl.iterator(), 0)));
-
-                spliterators.add(splitDescr("LongStream.longRange(0,l):" + name,
-                                            () -> LongStream.range(0, longs.length).spliterator()));
-                spliterators.add(splitDescr("LongStream.longRangeClosed(0,l):" + name,
-                                            () -> LongStream.rangeClosed(0, longs.length).spliterator()));
-                // Need more!
-            }
-            spliteratorTestData = spliterators.toArray(new Object[0][]);
-        }
-
-    }
-
-    static <T> Object[] streamDataDescr(String description, Supplier<LongStream> s) {
-        return new Object[] { description, TestData.Factory.ofLongSupplier(description, s) };
-    }
-
-    static <T> Object[] splitDescr(String description, Supplier<Spliterator.OfLong> s) {
-        return new Object[] { description, s };
-    }
-
-    // Return an array of ( String name, LongStreamTestData )
-    @DataProvider(name = "LongStreamTestData")
-    public static Object[][] makeLongStreamTestData() {
-        return testData;
-    }
-
-    // returns an array of (String name, Supplier<PrimitiveSpliterator<Long>>)
-    @DataProvider(name = "LongSpliterator")
-    public static Object[][] spliteratorProvider() {
-        return spliteratorTestData;
-    }
-}
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/LongStreamTestScenario.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,232 +0,0 @@
-/*
- * 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package java.util.stream;
-
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.PrimitiveIterator;
-import java.util.Set;
-import java.util.Spliterator;
-import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.function.LongConsumer;
-
-/**
- * Test scenarios for long streams.
- *
- * Each scenario is provided with a data source, a function that maps a fresh
- * stream (as provided by the data source) to a new stream, and a sink to
- * receive results.  Each scenario describes a different way of computing the
- * stream contents.  The test driver will ensure that all scenarios produce
- * the same output (modulo allowable differences in ordering).
- */
-@SuppressWarnings({"rawtypes", "unchecked"})
-public enum LongStreamTestScenario implements OpTestCase.BaseStreamTestScenario {
-
-    STREAM_FOR_EACH(false) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
-            LongStream s = m.apply(source);
-            if (s.isParallel()) {
-                s = s.sequential();
-            }
-            s.forEach(b);
-        }
-    },
-
-    STREAM_TO_ARRAY(false) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
-            for (long t : m.apply(source).toArray()) {
-                b.accept(t);
-            }
-        }
-    },
-
-    STREAM_ITERATOR(false) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
-            for (PrimitiveIterator.OfLong seqIter = m.apply(source).iterator(); seqIter.hasNext(); )
-                b.accept(seqIter.nextLong());
-        }
-    },
-
-    // Wrap as stream, and spliterate then iterate in pull mode
-    STREAM_SPLITERATOR(false) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
-            for (Spliterator.OfLong spl = m.apply(source).spliterator(); spl.tryAdvance(b); ) {
-            }
-        }
-    },
-
-    // Wrap as stream, spliterate, then split a few times mixing advances with forEach
-    STREAM_SPLITERATOR_WITH_MIXED_TRAVERSE_AND_SPLIT(false) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
-            SpliteratorTestHelper.mixedTraverseAndSplit(b, m.apply(source).spliterator());
-        }
-    },
-
-    // Wrap as stream, and spliterate then iterate in pull mode
-    STREAM_SPLITERATOR_FOREACH(false) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
-            m.apply(source).spliterator().forEachRemaining(b);
-        }
-    },
-
-    PAR_STREAM_SEQUENTIAL_FOR_EACH(true) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
-            m.apply(source).sequential().forEach(b);
-        }
-    },
-
-    // Wrap as parallel stream + forEachOrdered
-    PAR_STREAM_FOR_EACH_ORDERED(true) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
-            // @@@ Want to explicitly select ordered equalator
-            m.apply(source).forEachOrdered(b);
-        }
-    },
-
-    // Wrap as stream, and spliterate then iterate sequentially
-    PAR_STREAM_SPLITERATOR(true) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
-            for (Spliterator.OfLong spl = m.apply(source).spliterator(); spl.tryAdvance(b); ) {
-            }
-        }
-    },
-
-    // Wrap as stream, and spliterate then iterate sequentially
-    PAR_STREAM_SPLITERATOR_FOREACH(true) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
-            m.apply(source).spliterator().forEachRemaining(b);
-        }
-    },
-
-    PAR_STREAM_TO_ARRAY(true) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
-            for (long t : m.apply(source).toArray())
-                b.accept(t);
-        }
-    },
-
-    // Wrap as parallel stream, get the spliterator, wrap as a stream + toArray
-    PAR_STREAM_SPLITERATOR_STREAM_TO_ARRAY(true) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
-            LongStream s = m.apply(source);
-            Spliterator.OfLong sp = s.spliterator();
-            LongStream ss = StreamSupport.longStream(() -> sp,
-                                                     StreamOpFlag.toCharacteristics(OpTestCase.getStreamFlags(s))
-                                                     | (sp.getExactSizeIfKnown() < 0 ? 0 : Spliterator.SIZED), true);
-            for (long t : ss.toArray())
-                b.accept(t);
-        }
-    },
-
-    PAR_STREAM_TO_ARRAY_CLEAR_SIZED(true) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
-            S_IN pipe1 = (S_IN) OpTestCase.chain(source,
-                                                 new FlagDeclaringOp(StreamOpFlag.NOT_SIZED, data.getShape()));
-            LongStream pipe2 = m.apply(pipe1);
-
-            for (long t : pipe2.toArray())
-                b.accept(t);
-        }
-    },
-
-    // Wrap as parallel stream + forEach synchronizing
-    PAR_STREAM_FOR_EACH(true, false) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
-            m.apply(source).forEach(e -> {
-                synchronized (data) {
-                    b.accept(e);
-                }
-            });
-        }
-    },
-
-    // Wrap as parallel stream + forEach synchronizing and clear SIZED flag
-    PAR_STREAM_FOR_EACH_CLEAR_SIZED(true, false) {
-        <T, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m) {
-            S_IN pipe1 = (S_IN) OpTestCase.chain(source,
-                                                 new FlagDeclaringOp(StreamOpFlag.NOT_SIZED, data.getShape()));
-            m.apply(pipe1).forEach(e -> {
-                synchronized (data) {
-                    b.accept(e);
-                }
-            });
-        }
-    },
-    ;
-
-    // The set of scenarios that clean the SIZED flag
-    public static final Set<LongStreamTestScenario> CLEAR_SIZED_SCENARIOS = Collections.unmodifiableSet(
-            EnumSet.of(PAR_STREAM_TO_ARRAY_CLEAR_SIZED, PAR_STREAM_FOR_EACH_CLEAR_SIZED));
-
-    private boolean isParallel;
-
-    private final boolean isOrdered;
-
-    LongStreamTestScenario(boolean isParallel) {
-        this(isParallel, true);
-    }
-
-    LongStreamTestScenario(boolean isParallel, boolean isOrdered) {
-        this.isParallel = isParallel;
-        this.isOrdered = isOrdered;
-    }
-
-    public StreamShape getShape() {
-        return StreamShape.LONG_VALUE;
-    }
-
-    public boolean isParallel() {
-        return isParallel;
-    }
-
-    public boolean isOrdered() {
-        return isOrdered;
-    }
-
-    public <T, U, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>>
-    void run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, S_OUT> m) {
-        try (S_IN source = getStream(data)) {
-            run(data, source, (LongConsumer) b, (Function<S_IN, LongStream>) m);
-        }
-    }
-
-    abstract <T, S_IN extends BaseStream<T, S_IN>>
-    void run(TestData<T, S_IN> data, S_IN source, LongConsumer b, Function<S_IN, LongStream> m);
-
-}
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/OpTestCase.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,682 +0,0 @@
-/*
- * 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 java.util.stream;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumMap;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.Spliterator;
-import java.util.function.BiConsumer;
-import java.util.function.Consumer;
-import java.util.function.Function;
-
-import org.testng.annotations.Test;
-
-/**
- * Base class for streams test cases.  Provides 'exercise' methods for taking
- * lambdas that construct and modify streams, and evaluates them in different
- * ways and asserts that they produce equivalent results.
- */
-@Test
-public abstract class OpTestCase extends LoggingTestCase {
-
-    private final Map<StreamShape, Set<? extends BaseStreamTestScenario>> testScenarios;
-
-    protected OpTestCase() {
-        testScenarios = new EnumMap<>(StreamShape.class);
-        testScenarios.put(StreamShape.REFERENCE, Collections.unmodifiableSet(EnumSet.allOf(StreamTestScenario.class)));
-        testScenarios.put(StreamShape.INT_VALUE, Collections.unmodifiableSet(EnumSet.allOf(IntStreamTestScenario.class)));
-        testScenarios.put(StreamShape.LONG_VALUE, Collections.unmodifiableSet(EnumSet.allOf(LongStreamTestScenario.class)));
-        testScenarios.put(StreamShape.DOUBLE_VALUE, Collections.unmodifiableSet(EnumSet.allOf(DoubleStreamTestScenario.class)));
-    }
-
-    @SuppressWarnings("rawtypes")
-    public static int getStreamFlags(BaseStream s) {
-        return ((AbstractPipeline) s).getStreamFlags();
-    }
-
-    /**
-     * An asserter for results produced when exercising of stream or terminal
-     * tests.
-     *
-     * @param <R> the type of result to assert on
-     */
-    public interface ResultAsserter<R> {
-        /**
-         * Assert a result produced when exercising of stream or terminal
-         * test.
-         *
-         * @param actual the actual result
-         * @param expected the expected result
-         * @param isOrdered true if the pipeline is ordered
-         * @param isParallel true if the pipeline is parallel
-         */
-        void assertResult(R actual, R expected, boolean isOrdered, boolean isParallel);
-    }
-
-    // Exercise stream operations
-
-    public interface BaseStreamTestScenario {
-        StreamShape getShape();
-
-        boolean isParallel();
-
-        boolean isOrdered();
-
-        default <T, S_IN extends BaseStream<T, S_IN>>
-        S_IN getStream(TestData<T, S_IN> data) {
-            return isParallel()
-                   ? data.parallelStream()
-                   : data.stream();
-        }
-
-        <T, U, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>>
-        void run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, S_OUT> m);
-    }
-
-    protected <T, U, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>>
-    Collection<U> exerciseOps(TestData<T, S_IN> data, Function<S_IN, S_OUT> m) {
-        return withData(data).stream(m).exercise();
-    }
-
-    // Run multiple versions of exercise(), returning the result of the first, and asserting that others return the same result
-    // If the first version is s -> s.foo(), can be used with s -> s.mapToInt(i -> i).foo().mapToObj(i -> i) to test all shape variants
-    @SafeVarargs
-    protected final<T, U, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>>
-    Collection<U> exerciseOpsMulti(TestData<T, S_IN> data,
-                                   Function<S_IN, S_OUT>... ms) {
-        Collection<U> result = null;
-        for (Function<S_IN, S_OUT> m : ms) {
-            if (result == null)
-                result = withData(data).stream(m).exercise();
-            else {
-                Collection<U> r2 = withData(data).stream(m).exercise();
-                assertEquals(result, r2);
-            }
-        }
-        return result;
-    }
-
-    // Run multiple versions of exercise() for an Integer stream, returning the result of the first, and asserting that others return the same result
-    // Automates the conversion between Stream<Integer> and {Int,Long,Double}Stream and back, so client sites look like you are passing the same
-    // lambda four times, but in fact they are four different lambdas since they are transforming four different kinds of streams
-    protected final
-    Collection<Integer> exerciseOpsInt(TestData.OfRef<Integer> data,
-                                       Function<Stream<Integer>, Stream<Integer>> mRef,
-                                       Function<IntStream, IntStream> mInt,
-                                       Function<LongStream, LongStream> mLong,
-                                       Function<DoubleStream, DoubleStream> mDouble) {
-        @SuppressWarnings({ "rawtypes", "unchecked" })
-        Function<Stream<Integer>, Stream<Integer>>[] ms = new Function[4];
-        ms[0] = mRef;
-        ms[1] = s -> mInt.apply(s.mapToInt(e -> e)).mapToObj(e -> e);
-        ms[2] = s -> mLong.apply(s.mapToLong(e -> e)).mapToObj(e -> (int) e);
-        ms[3] = s -> mDouble.apply(s.mapToDouble(e -> e)).mapToObj(e -> (int) e);
-        return exerciseOpsMulti(data, ms);
-    }
-
-    // Run multiple versions of exercise() with multiple terminal operations for all kinds of stream, , and asserting against the expected result
-    // If the first version is s -> s.foo(), can be used with s -> s.mapToInt(i -> i).foo().mapToObj(i -> i) to test all shape variants
-    protected final<T, U, R, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>>
-    void exerciseTerminalOpsMulti(TestData<T, S_IN> data,
-                                  R expected,
-                                  Map<String, Function<S_IN, S_OUT>> streams,
-                                  Map<String, Function<S_OUT, R>> terminals) {
-        for (Map.Entry<String, Function<S_IN, S_OUT>> se : streams.entrySet()) {
-            setContext("Intermediate stream", se.getKey());
-            for (Map.Entry<String, Function<S_OUT, R>> te : terminals.entrySet()) {
-                setContext("Terminal stream", te.getKey());
-                withData(data)
-                        .terminal(se.getValue(), te.getValue())
-                        .expectedResult(expected)
-                        .exercise();
-
-            }
-        }
-    }
-
-    // Run multiple versions of exercise() with multiple terminal operation for all kinds of stream, and asserting against the expected result
-    // Automates the conversion between Stream<Integer> and {Int,Long,Double}Stream and back, so client sites look like you are passing the same
-    // lambda four times, but in fact they are four different lambdas since they are transforming four different kinds of streams
-    protected final
-    void exerciseTerminalOpsInt(TestData<Integer, Stream<Integer>> data,
-                                Collection<Integer> expected,
-                                String desc,
-                                Function<Stream<Integer>, Stream<Integer>> mRef,
-                                Function<IntStream, IntStream> mInt,
-                                Function<LongStream, LongStream> mLong,
-                                Function<DoubleStream, DoubleStream> mDouble,
-                                Map<String, Function<Stream<Integer>, Collection<Integer>>> terminals) {
-
-        Map<String, Function<Stream<Integer>, Stream<Integer>>> m = new HashMap<>();
-        m.put("Ref " + desc, mRef);
-        m.put("Int " + desc, s -> mInt.apply(s.mapToInt(e -> e)).mapToObj(e -> e));
-        m.put("Long " + desc, s -> mLong.apply(s.mapToLong(e -> e)).mapToObj(e -> (int) e));
-        m.put("Double " + desc, s -> mDouble.apply(s.mapToDouble(e -> e)).mapToObj(e -> (int) e));
-
-        exerciseTerminalOpsMulti(data, expected, m, terminals);
-    }
-
-
-    protected <T, U, S_OUT extends BaseStream<U, S_OUT>>
-    Collection<U> exerciseOps(Collection<T> data, Function<Stream<T>, S_OUT> m) {
-        TestData.OfRef<T> data1 = TestData.Factory.ofCollection("Collection of type " + data.getClass().getName(), data);
-        return withData(data1).stream(m).exercise();
-    }
-
-    protected <T, U, S_OUT extends BaseStream<U, S_OUT>, I extends Iterable<U>>
-    Collection<U> exerciseOps(Collection<T> data, Function<Stream<T>, S_OUT> m, I expected) {
-        TestData.OfRef<T> data1 = TestData.Factory.ofCollection("Collection of type " + data.getClass().getName(), data);
-        return withData(data1).stream(m).expectedResult(expected).exercise();
-    }
-
-    @SuppressWarnings("unchecked")
-    protected <U, S_OUT extends BaseStream<U, S_OUT>>
-    Collection<U> exerciseOps(int[] data, Function<IntStream, S_OUT> m) {
-        return withData(TestData.Factory.ofArray("int array", data)).stream(m).exercise();
-    }
-
-    protected Collection<Integer> exerciseOps(int[] data, Function<IntStream, IntStream> m, int[] expected) {
-        TestData.OfInt data1 = TestData.Factory.ofArray("int array", data);
-        return withData(data1).stream(m).expectedResult(expected).exercise();
-    }
-
-    protected <T, S_IN extends BaseStream<T, S_IN>> DataStreamBuilder<T, S_IN> withData(TestData<T, S_IN> data) {
-        Objects.requireNonNull(data);
-        return new DataStreamBuilder<>(data);
-    }
-
-    @SuppressWarnings({"rawtypes", "unchecked"})
-    public class DataStreamBuilder<T, S_IN extends BaseStream<T, S_IN>> {
-        final TestData<T, S_IN> data;
-
-        private DataStreamBuilder(TestData<T, S_IN> data) {
-            this.data = Objects.requireNonNull(data);
-        }
-
-        public <U, S_OUT extends BaseStream<U, S_OUT>>
-        ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> ops(IntermediateTestOp... ops) {
-            return new ExerciseDataStreamBuilder<>(data, (S_IN s) -> (S_OUT) chain(s, ops));
-        }
-
-        public <U, S_OUT extends BaseStream<U, S_OUT>> ExerciseDataStreamBuilder<T, U, S_IN, S_OUT>
-        stream(Function<S_IN, S_OUT> m) {
-            return new ExerciseDataStreamBuilder<>(data, m);
-        }
-
-        public <U, S_OUT extends BaseStream<U, S_OUT>> ExerciseDataStreamBuilder<T, U, S_IN, S_OUT>
-        stream(Function<S_IN, S_OUT> m, IntermediateTestOp<U, U> additionalOp) {
-            return new ExerciseDataStreamBuilder<>(data, s -> (S_OUT) chain(m.apply(s), additionalOp));
-        }
-
-        public <R> ExerciseDataTerminalBuilder<T, T, R, S_IN, S_IN>
-        terminal(Function<S_IN, R> terminalF) {
-            return new ExerciseDataTerminalBuilder<>(data, s -> s, terminalF);
-        }
-
-        public <U, R, S_OUT extends BaseStream<U, S_OUT>> ExerciseDataTerminalBuilder<T, U, R, S_IN, S_OUT>
-        terminal(Function<S_IN, S_OUT> streamF, Function<S_OUT, R> terminalF) {
-            return new ExerciseDataTerminalBuilder<>(data, streamF, terminalF);
-        }
-    }
-
-    @SuppressWarnings({"rawtypes", "unchecked"})
-    public class ExerciseDataStreamBuilder<T, U, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>> {
-        final TestData<T, S_IN> data;
-        final Function<S_IN, S_OUT> m;
-        final StreamShape shape;
-
-        Set<BaseStreamTestScenario> testSet = new HashSet<>();
-
-        Collection<U> refResult;
-
-        Consumer<TestData<T, S_IN>> before = LambdaTestHelpers.bEmpty;
-
-        Consumer<TestData<T, S_IN>> after = LambdaTestHelpers.bEmpty;
-
-        ResultAsserter<Iterable<U>> resultAsserter = (act, exp, ord, par) -> {
-            if (par & !ord) {
-                LambdaTestHelpers.assertContentsUnordered(act, exp);
-            }
-            else {
-                LambdaTestHelpers.assertContentsEqual(act, exp);
-            }
-        };
-
-        private ExerciseDataStreamBuilder(TestData<T, S_IN> data, Function<S_IN, S_OUT> m) {
-            this.data = data;
-
-            this.m = Objects.requireNonNull(m);
-
-            this.shape = ((AbstractPipeline<?, U, ?>) m.apply(data.stream())).getOutputShape();
-
-            // Have to initiate from the output shape of the last stream
-            // This means the stream mapper is required first rather than last
-            testSet.addAll(testScenarios.get(shape));
-        }
-
-        //
-
-        public <I extends Iterable<U>> ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> expectedResult(I expectedResult) {
-            List<U> l = new ArrayList<>();
-            expectedResult.forEach(l::add);
-            refResult = l;
-            return this;
-        }
-
-        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> expectedResult(int[] expectedResult) {
-            List l = new ArrayList();
-            for (int anExpectedResult : expectedResult) {
-                l.add(anExpectedResult);
-            }
-            refResult = l;
-            return this;
-        }
-
-        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> expectedResult(long[] expectedResult) {
-            List l = new ArrayList();
-            for (long anExpectedResult : expectedResult) {
-                l.add(anExpectedResult);
-            }
-            refResult = l;
-            return this;
-        }
-
-        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> expectedResult(double[] expectedResult) {
-            List l = new ArrayList();
-            for (double anExpectedResult : expectedResult) {
-                l.add(anExpectedResult);
-            }
-            refResult = l;
-            return this;
-        }
-
-        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> before(Consumer<TestData<T, S_IN>> before) {
-            this.before = Objects.requireNonNull(before);
-            return this;
-        }
-
-        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> after(Consumer<TestData<T, S_IN>> after) {
-            this.after = Objects.requireNonNull(after);
-            return this;
-        }
-
-        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> without(BaseStreamTestScenario... tests) {
-            return without(Arrays.asList(tests));
-        }
-
-        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> without(Collection<? extends BaseStreamTestScenario> tests) {
-            for (BaseStreamTestScenario ts : tests) {
-                if (ts.getShape() == shape) {
-                    testSet.remove(ts);
-                }
-            }
-
-            if (testSet.isEmpty()) {
-                throw new IllegalStateException("Test scenario set is empty");
-            }
-
-            return this;
-        }
-
-        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> with(BaseStreamTestScenario... tests) {
-            return with(Arrays.asList(tests));
-        }
-
-        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> with(Collection<? extends BaseStreamTestScenario> tests) {
-            testSet = new HashSet<>();
-
-            for (BaseStreamTestScenario ts : tests) {
-                if (ts.getShape() == shape) {
-                    testSet.add(ts);
-                }
-            }
-
-            if (testSet.isEmpty()) {
-                throw new IllegalStateException("Test scenario set is empty");
-            }
-
-            return this;
-        }
-
-        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> resultAsserter(ResultAsserter<Iterable<U>> resultAsserter) {
-            this.resultAsserter = resultAsserter;
-            return this;
-        }
-
-        // Build method
-
-        public Collection<U> exercise() {
-            final boolean isStreamOrdered;
-            if (refResult == null) {
-                // Induce the reference result
-                before.accept(data);
-                try (S_OUT sOut = m.apply(data.stream())) {
-                    isStreamOrdered = StreamOpFlag.ORDERED.isKnown(((AbstractPipeline) sOut).getStreamFlags());
-                    Node<U> refNodeResult = ((AbstractPipeline<?, U, ?>) sOut).evaluateToArrayNode(size -> (U[]) new Object[size]);
-                    refResult = LambdaTestHelpers.toBoxedList(refNodeResult.spliterator());
-                }
-                after.accept(data);
-            }
-            else {
-                try (S_OUT sOut = m.apply(data.stream())) {
-                    isStreamOrdered = StreamOpFlag.ORDERED.isKnown(((AbstractPipeline) sOut).getStreamFlags());
-                }
-            }
-
-            List<Error> errors = new ArrayList<>();
-            for (BaseStreamTestScenario test : testSet) {
-                try {
-                    before.accept(data);
-
-                    List<U> result = new ArrayList<>();
-                    test.run(data, LambdaTestHelpers.<U>toBoxingConsumer(result::add), m);
-
-                    Runnable asserter = () -> resultAsserter.assertResult(result, refResult, isStreamOrdered && test.isOrdered(), test.isParallel());
-
-                    if (refResult.size() > 1000) {
-                        LambdaTestHelpers.launderAssertion(
-                                asserter,
-                                () -> String.format("%n%s: [actual size=%d] != [expected size=%d]", test, result.size(), refResult.size()));
-                    }
-                    else {
-                        LambdaTestHelpers.launderAssertion(
-                                asserter,
-                                () -> String.format("%n%s: [actual] %s != [expected] %s", test, result, refResult));
-                    }
-
-                    after.accept(data);
-                } catch (Throwable t) {
-                    errors.add(new Error(String.format("%s: %s", test, t), t));
-                }
-            }
-
-            if (!errors.isEmpty()) {
-                StringBuilder sb = new StringBuilder();
-                int i = 1;
-                for (Error t : errors) {
-                    sb.append(i++).append(": ");
-                    if (t instanceof AssertionError) {
-                        sb.append(t).append("\n");
-                    }
-                    else {
-                        StringWriter sw = new StringWriter();
-                        PrintWriter pw = new PrintWriter(sw);
-
-                        t.getCause().printStackTrace(pw);
-                        pw.flush();
-                        sb.append(t).append("\n").append(sw);
-                    }
-                }
-                sb.append("--");
-
-                fail(String.format("%d failure(s) for test data: %s\n%s", i - 1, data.toString(), sb));
-            }
-
-            return refResult;
-        }
-    }
-
-    // Exercise terminal operations
-
-    interface BaseTerminalTestScenario<U, R, S_OUT extends BaseStream<U, S_OUT>> {
-        boolean requiresSingleStageSource();
-
-        boolean requiresParallelSource();
-
-        default R run(Function<S_OUT, R> terminalF, S_OUT source, StreamShape shape) {
-            return terminalF.apply(source);
-        }
-    }
-
-    @SuppressWarnings({"rawtypes", "unchecked"})
-    enum TerminalTestScenario implements BaseTerminalTestScenario {
-        SINGLE_SEQUENTIAL(true, false),
-
-        SINGLE_SEQUENTIAL_SHORT_CIRCUIT(true, false) {
-            @Override
-            public Object run(Function terminalF, BaseStream source, StreamShape shape) {
-                source = (BaseStream) chain(source, new ShortCircuitOp(shape));
-                return terminalF.apply(source);
-            }
-        },
-
-        SINGLE_PARALLEL(true, true),
-
-        ALL_SEQUENTIAL(false, false),
-
-        ALL_SEQUENTIAL_SHORT_CIRCUIT(false, false) {
-            @Override
-            public Object run(Function terminalF, BaseStream source, StreamShape shape) {
-                source = (BaseStream) chain(source, new ShortCircuitOp(shape));
-                return terminalF.apply(source);
-            }
-        },
-
-        ALL_PARALLEL(false, true),
-
-        ALL_PARALLEL_SEQUENTIAL(false, false) {
-            @Override
-            public Object run(Function terminalF, BaseStream source, StreamShape shape) {
-                return terminalF.apply(source.sequential());
-            }
-        },
-        ;
-
-        private final boolean requiresSingleStageSource;
-        private final boolean isParallel;
-
-        TerminalTestScenario(boolean requiresSingleStageSource, boolean isParallel) {
-            this.requiresSingleStageSource = requiresSingleStageSource;
-            this.isParallel = isParallel;
-        }
-
-        @Override
-        public boolean requiresSingleStageSource() {
-            return requiresSingleStageSource;
-        }
-
-        @Override
-        public boolean requiresParallelSource() {
-            return isParallel;
-        }
-
-    }
-
-    @SuppressWarnings({"rawtypes", "unchecked"})
-    public class ExerciseDataTerminalBuilder<T, U, R, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>> {
-        final TestData<T, S_IN> data;
-        final Function<S_IN, S_OUT> streamF;
-        final Function<S_OUT, R> terminalF;
-
-        R refResult;
-
-        ResultAsserter<R> resultAsserter = (act, exp, ord, par) -> LambdaTestHelpers.assertContentsEqual(act, exp);
-
-        private ExerciseDataTerminalBuilder(TestData<T, S_IN> data, Function<S_IN, S_OUT> streamF, Function<S_OUT, R> terminalF) {
-            this.data = data;
-            this.streamF = Objects.requireNonNull(streamF);
-            this.terminalF = Objects.requireNonNull(terminalF);
-        }
-
-        //
-
-        public ExerciseDataTerminalBuilder<T, U, R, S_IN, S_OUT> expectedResult(R expectedResult) {
-            this.refResult = expectedResult;
-            return this;
-        }
-
-        public ExerciseDataTerminalBuilder<T, U, R, S_IN, S_OUT> equalator(BiConsumer<R, R> equalityAsserter) {
-            resultAsserter = (act, exp, ord, par) -> equalityAsserter.accept(act, exp);
-            return this;
-        }
-
-        public ExerciseDataTerminalBuilder<T, U, R, S_IN, S_OUT> resultAsserter(ResultAsserter<R> resultAsserter) {
-            this.resultAsserter = resultAsserter;
-            return this;
-        }
-
-        // Build method
-
-        public R exercise() {
-            boolean isOrdered;
-            StreamShape shape;
-            Node<U> node;
-            try (S_OUT out = streamF.apply(data.stream()).sequential()) {
-                AbstractPipeline ap = (AbstractPipeline) out;
-                isOrdered = StreamOpFlag.ORDERED.isKnown(ap.getStreamFlags());
-                shape = ap.getOutputShape();
-                // Sequentially collect the output that will be input to the terminal op
-                node = ap.evaluateToArrayNode(size -> (U[]) new Object[size]);
-            }
-
-            EnumSet<TerminalTestScenario> tests = EnumSet.allOf(TerminalTestScenario.class);
-            if (refResult == null) {
-                // Induce the reference result
-                S_OUT source = (S_OUT) createPipeline(shape, node.spliterator(),
-                                                      StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SIZED,
-                                                      false);
-
-                refResult = (R) TerminalTestScenario.SINGLE_SEQUENTIAL.run(terminalF, source, shape);
-                tests.remove(TerminalTestScenario.SINGLE_SEQUENTIAL);
-            }
-
-            for (BaseTerminalTestScenario test : tests) {
-                S_OUT source;
-                if (test.requiresSingleStageSource()) {
-                    source = (S_OUT) createPipeline(shape, node.spliterator(),
-                                                    StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SIZED,
-                                                    test.requiresParallelSource());
-                }
-                else {
-                    source = streamF.apply(test.requiresParallelSource()
-                                           ? data.parallelStream() : data.stream());
-                }
-
-                R result;
-                try (source) {
-                    result = (R) test.run(terminalF, source, shape);
-                }
-                LambdaTestHelpers.launderAssertion(
-                        () -> resultAsserter.assertResult(result, refResult, isOrdered, test.requiresParallelSource()),
-                        () -> String.format("%s: %s != %s", test, refResult, result));
-            }
-
-            return refResult;
-        }
-
-        AbstractPipeline createPipeline(StreamShape shape, Spliterator s, int flags, boolean parallel) {
-            switch (shape) {
-                case REFERENCE:    return new ReferencePipeline.Head<>(s, flags, parallel);
-                case INT_VALUE:    return new IntPipeline.Head(s, flags, parallel);
-                case LONG_VALUE:   return new LongPipeline.Head(s, flags, parallel);
-                case DOUBLE_VALUE: return new DoublePipeline.Head(s, flags, parallel);
-                default: throw new IllegalStateException("Unknown shape: " + shape);
-            }
-        }
-    }
-
-    protected <T, R> R exerciseTerminalOps(Collection<T> data, Function<Stream<T>, R> m, R expected) {
-        TestData.OfRef<T> data1
-                = TestData.Factory.ofCollection("Collection of type " + data.getClass().getName(), data);
-        return withData(data1).terminal(m).expectedResult(expected).exercise();
-    }
-
-    protected <T, R, S_IN extends BaseStream<T, S_IN>> R
-    exerciseTerminalOps(TestData<T, S_IN> data,
-                        Function<S_IN, R> terminalF) {
-        return withData(data).terminal(terminalF).exercise();
-    }
-
-    protected <T, U, R, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>> R
-    exerciseTerminalOps(TestData<T, S_IN> data,
-                        Function<S_IN, S_OUT> streamF,
-                        Function<S_OUT, R> terminalF) {
-        return withData(data).terminal(streamF, terminalF).exercise();
-    }
-
-    //
-
-    @SuppressWarnings({"rawtypes", "unchecked"})
-    private static <T> AbstractPipeline<?, T, ?> chain(AbstractPipeline upstream, IntermediateTestOp<?, T> op) {
-        return (AbstractPipeline<?, T, ?>) IntermediateTestOp.chain(upstream, op);
-    }
-
-    @SuppressWarnings({"rawtypes", "unchecked"})
-    private static AbstractPipeline<?, ?, ?> chain(AbstractPipeline pipe, IntermediateTestOp... ops) {
-        for (IntermediateTestOp op : ops)
-            pipe = chain(pipe, op);
-        return pipe;
-    }
-
-    @SuppressWarnings("rawtypes")
-    private static <T> AbstractPipeline<?, T, ?> chain(BaseStream pipe, IntermediateTestOp<?, T> op) {
-        return chain((AbstractPipeline) pipe, op);
-    }
-
-    @SuppressWarnings("rawtypes")
-    public static AbstractPipeline<?, ?, ?> chain(BaseStream pipe, IntermediateTestOp... ops) {
-        return chain((AbstractPipeline) pipe, ops);
-    }
-
-    // Test data
-
-    static class ShortCircuitOp<T> implements StatelessTestOp<T,T> {
-        private final StreamShape shape;
-
-        ShortCircuitOp(StreamShape shape) {
-            this.shape = shape;
-        }
-
-        @Override
-        public Sink<T> opWrapSink(int flags, boolean parallel, Sink<T> sink) {
-            return sink;
-        }
-
-        @Override
-        public int opGetFlags() {
-            return StreamOpFlag.IS_SHORT_CIRCUIT;
-        }
-
-        @Override
-        public StreamShape outputShape() {
-            return shape;
-        }
-
-        @Override
-        public StreamShape inputShape() {
-            return shape;
-        }
-    }
-}
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/SpliteratorTestHelper.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,715 +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 java.util.stream;
-
-import org.testng.annotations.Test;
-
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Spliterator;
-import java.util.function.*;
-
-import static org.testng.Assert.*;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.fail;
-
-/**
- * Assertion methods for spliterators, to be called from other tests
- */
-public class SpliteratorTestHelper {
-
-    public interface ContentAsserter<T> {
-        void assertContents(Collection<T> actual, Collection<T> expected, boolean isOrdered);
-    }
-
-    private static ContentAsserter<Object> DEFAULT_CONTENT_ASSERTER
-            = SpliteratorTestHelper::assertContents;
-
-    @SuppressWarnings("unchecked")
-    private static <T> ContentAsserter<T> defaultContentAsserter() {
-        return (ContentAsserter<T>) DEFAULT_CONTENT_ASSERTER;
-    }
-
-    public static void testSpliterator(Supplier<Spliterator<Integer>> supplier) {
-        testSpliterator(supplier, defaultContentAsserter());
-    }
-
-    public static void testSpliterator(Supplier<Spliterator<Integer>> supplier,
-                                       ContentAsserter<Integer> asserter) {
-        testSpliterator(supplier, (Consumer<Integer> b) -> b, asserter);
-    }
-
-    public static void testIntSpliterator(Supplier<Spliterator.OfInt> supplier) {
-        testIntSpliterator(supplier, defaultContentAsserter());
-    }
-
-    public static void testIntSpliterator(Supplier<Spliterator.OfInt> supplier,
-                                          ContentAsserter<Integer> asserter) {
-        class BoxingAdapter implements Consumer<Integer>, IntConsumer {
-            private final Consumer<Integer> b;
-
-            BoxingAdapter(Consumer<Integer> b) {
-                this.b = b;
-            }
-
-            @Override
-            public void accept(Integer value) {
-                throw new IllegalStateException();
-            }
-
-            @Override
-            public void accept(int value) {
-                b.accept(value);
-            }
-        }
-
-        testSpliterator(supplier, BoxingAdapter::new, asserter);
-    }
-
-    public static void testLongSpliterator(Supplier<Spliterator.OfLong> supplier) {
-        testLongSpliterator(supplier, defaultContentAsserter());
-    }
-
-    public static void testLongSpliterator(Supplier<Spliterator.OfLong> supplier,
-                                           ContentAsserter<Long> asserter) {
-        class BoxingAdapter implements Consumer<Long>, LongConsumer {
-            private final Consumer<Long> b;
-
-            BoxingAdapter(Consumer<Long> b) {
-                this.b = b;
-            }
-
-            @Override
-            public void accept(Long value) {
-                throw new IllegalStateException();
-            }
-
-            @Override
-            public void accept(long value) {
-                b.accept(value);
-            }
-        }
-
-        testSpliterator(supplier, BoxingAdapter::new, asserter);
-    }
-
-    public static void testDoubleSpliterator(Supplier<Spliterator.OfDouble> supplier) {
-        testDoubleSpliterator(supplier, defaultContentAsserter());
-    }
-
-    public static void testDoubleSpliterator(Supplier<Spliterator.OfDouble> supplier,
-                                             ContentAsserter<Double> asserter) {
-        class BoxingAdapter implements Consumer<Double>, DoubleConsumer {
-            private final Consumer<Double> b;
-
-            BoxingAdapter(Consumer<Double> b) {
-                this.b = b;
-            }
-
-            @Override
-            public void accept(Double value) {
-                throw new IllegalStateException();
-            }
-
-            @Override
-            public void accept(double value) {
-                b.accept(value);
-            }
-        }
-
-        testSpliterator(supplier, BoxingAdapter::new, asserter);
-    }
-
-    static <T, S extends Spliterator<T>> void testSpliterator(Supplier<S> supplier,
-                                                              UnaryOperator<Consumer<T>> boxingAdapter,
-                                                              ContentAsserter<T> asserter) {
-        ArrayList<T> fromForEach = new ArrayList<>();
-        Spliterator<T> spliterator = supplier.get();
-        Consumer<T> addToFromForEach = boxingAdapter.apply(fromForEach::add);
-        spliterator.forEachRemaining(addToFromForEach);
-
-        Collection<T> exp = Collections.unmodifiableList(fromForEach);
-
-        testNullPointerException(supplier);
-        testForEach(exp, supplier, boxingAdapter, asserter);
-        testTryAdvance(exp, supplier, boxingAdapter, asserter);
-        testMixedTryAdvanceForEach(exp, supplier, boxingAdapter, asserter);
-        testMixedTraverseAndSplit(exp, supplier, boxingAdapter, asserter);
-        testSplitAfterFullTraversal(supplier, boxingAdapter);
-        testSplitOnce(exp, supplier, boxingAdapter, asserter);
-        testSplitSixDeep(exp, supplier, boxingAdapter, asserter);
-        testSplitUntilNull(exp, supplier, boxingAdapter, asserter);
-    }
-
-    //
-
-    private static <T, S extends Spliterator<T>> void testNullPointerException(Supplier<S> s) {
-        S sp = s.get();
-        // Have to check instances and use casts to avoid tripwire messages and
-        // directly test the primitive methods
-        if (sp instanceof Spliterator.OfInt) {
-            Spliterator.OfInt psp = (Spliterator.OfInt) sp;
-            executeAndCatch(NullPointerException.class, () -> psp.forEachRemaining((IntConsumer) null));
-            executeAndCatch(NullPointerException.class, () -> psp.tryAdvance((IntConsumer) null));
-        }
-        else if (sp instanceof Spliterator.OfLong) {
-            Spliterator.OfLong psp = (Spliterator.OfLong) sp;
-            executeAndCatch(NullPointerException.class, () -> psp.forEachRemaining((LongConsumer) null));
-            executeAndCatch(NullPointerException.class, () -> psp.tryAdvance((LongConsumer) null));
-        }
-        else if (sp instanceof Spliterator.OfDouble) {
-            Spliterator.OfDouble psp = (Spliterator.OfDouble) sp;
-            executeAndCatch(NullPointerException.class, () -> psp.forEachRemaining((DoubleConsumer) null));
-            executeAndCatch(NullPointerException.class, () -> psp.tryAdvance((DoubleConsumer) null));
-        }
-        else {
-            executeAndCatch(NullPointerException.class, () -> sp.forEachRemaining(null));
-            executeAndCatch(NullPointerException.class, () -> sp.tryAdvance(null));
-        }
-    }
-
-    private static <T, S extends Spliterator<T>> void testForEach(
-            Collection<T> exp,
-            Supplier<S> supplier,
-            UnaryOperator<Consumer<T>> boxingAdapter,
-            ContentAsserter<T> asserter) {
-        S spliterator = supplier.get();
-        long sizeIfKnown = spliterator.getExactSizeIfKnown();
-        boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
-
-        ArrayList<T> fromForEach = new ArrayList<>();
-        spliterator = supplier.get();
-        Consumer<T> addToFromForEach = boxingAdapter.apply(fromForEach::add);
-        spliterator.forEachRemaining(addToFromForEach);
-
-        // Assert that forEach now produces no elements
-        spliterator.forEachRemaining(boxingAdapter.apply(
-                e -> fail("Spliterator.forEach produced an element after spliterator exhausted: " + e)));
-        // Assert that tryAdvance now produce no elements
-        spliterator.tryAdvance(boxingAdapter.apply(
-                e -> fail("Spliterator.tryAdvance produced an element after spliterator exhausted: " + e)));
-
-        // assert that size, tryAdvance, and forEach are consistent
-        if (sizeIfKnown >= 0) {
-            assertEquals(sizeIfKnown, exp.size());
-        }
-        assertEquals(fromForEach.size(), exp.size());
-
-        asserter.assertContents(fromForEach, exp, isOrdered);
-    }
-
-    private static <T, S extends Spliterator<T>> void testTryAdvance(
-            Collection<T> exp,
-            Supplier<S> supplier,
-            UnaryOperator<Consumer<T>> boxingAdapter,
-            ContentAsserter<T> asserter) {
-        S spliterator = supplier.get();
-        long sizeIfKnown = spliterator.getExactSizeIfKnown();
-        boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
-
-        spliterator = supplier.get();
-        ArrayList<T> fromTryAdvance = new ArrayList<>();
-        Consumer<T> addToFromTryAdvance = boxingAdapter.apply(fromTryAdvance::add);
-        while (spliterator.tryAdvance(addToFromTryAdvance)) { }
-
-        // Assert that forEach now produces no elements
-        spliterator.forEachRemaining(boxingAdapter.apply(
-                e -> fail("Spliterator.forEach produced an element after spliterator exhausted: " + e)));
-        // Assert that tryAdvance now produce no elements
-        spliterator.tryAdvance(boxingAdapter.apply(
-                e -> fail("Spliterator.tryAdvance produced an element after spliterator exhausted: " + e)));
-
-        // assert that size, tryAdvance, and forEach are consistent
-        if (sizeIfKnown >= 0) {
-            assertEquals(sizeIfKnown, exp.size());
-        }
-        assertEquals(fromTryAdvance.size(), exp.size());
-
-        asserter.assertContents(fromTryAdvance, exp, isOrdered);
-    }
-
-    private static <T, S extends Spliterator<T>> void testMixedTryAdvanceForEach(
-            Collection<T> exp,
-            Supplier<S> supplier,
-            UnaryOperator<Consumer<T>> boxingAdapter,
-            ContentAsserter<T> asserter) {
-        S spliterator = supplier.get();
-        long sizeIfKnown = spliterator.getExactSizeIfKnown();
-        boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
-
-        // tryAdvance first few elements, then forEach rest
-        ArrayList<T> dest = new ArrayList<>();
-        spliterator = supplier.get();
-        Consumer<T> addToDest = boxingAdapter.apply(dest::add);
-        for (int i = 0; i < 10 && spliterator.tryAdvance(addToDest); i++) { }
-        spliterator.forEachRemaining(addToDest);
-
-        // Assert that forEach now produces no elements
-        spliterator.forEachRemaining(boxingAdapter.apply(
-                e -> fail("Spliterator.forEach produced an element after spliterator exhausted: " + e)));
-        // Assert that tryAdvance now produce no elements
-        spliterator.tryAdvance(boxingAdapter.apply(
-                e -> fail("Spliterator.tryAdvance produced an element after spliterator exhausted: " + e)));
-
-        if (sizeIfKnown >= 0) {
-            assertEquals(sizeIfKnown, dest.size());
-        }
-        assertEquals(dest.size(), exp.size());
-
-        asserter.assertContents(dest, exp, isOrdered);
-    }
-
-    private static <T, S extends Spliterator<T>> void testMixedTraverseAndSplit(
-            Collection<T> exp,
-            Supplier<S> supplier,
-            UnaryOperator<Consumer<T>> boxingAdapter,
-            ContentAsserter<T> asserter) {
-        S spliterator = supplier.get();
-        long sizeIfKnown = spliterator.getExactSizeIfKnown();
-        boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
-
-        // tryAdvance first few elements, then forEach rest
-        ArrayList<T> dest = new ArrayList<>();
-        spliterator = supplier.get();
-        Consumer<T> b = boxingAdapter.apply(dest::add);
-
-        Spliterator<T> spl1, spl2, spl3;
-        spliterator.tryAdvance(b);
-        spl2 = spliterator.trySplit();
-        if (spl2 != null) {
-            spl2.tryAdvance(b);
-            spl1 = spl2.trySplit();
-            if (spl1 != null) {
-                spl1.tryAdvance(b);
-                spl1.forEachRemaining(b);
-            }
-            spl2.tryAdvance(b);
-            spl2.forEachRemaining(b);
-        }
-        spliterator.tryAdvance(b);
-        spl3 = spliterator.trySplit();
-        if (spl3 != null) {
-            spl3.tryAdvance(b);
-            spl3.forEachRemaining(b);
-        }
-        spliterator.tryAdvance(b);
-        spliterator.forEachRemaining(b);
-
-        if (sizeIfKnown >= 0) {
-            assertEquals(sizeIfKnown, dest.size());
-        }
-        assertEquals(dest.size(), exp.size());
-
-        asserter.assertContents(dest, exp, isOrdered);
-    }
-
-    private static <T, S extends Spliterator<T>> void testSplitAfterFullTraversal(
-            Supplier<S> supplier,
-            UnaryOperator<Consumer<T>> boxingAdapter) {
-        // Full traversal using tryAdvance
-        Spliterator<T> spliterator = supplier.get();
-        while (spliterator.tryAdvance(boxingAdapter.apply(e -> { }))) { }
-        Spliterator<T> split = spliterator.trySplit();
-        assertNull(split);
-
-        // Full traversal using forEach
-        spliterator = supplier.get();
-        spliterator.forEachRemaining(boxingAdapter.apply(e -> { }));
-        split = spliterator.trySplit();
-        assertNull(split);
-
-        // Full traversal using tryAdvance then forEach
-        spliterator = supplier.get();
-        spliterator.tryAdvance(boxingAdapter.apply(e -> { }));
-        spliterator.forEachRemaining(boxingAdapter.apply(e -> { }));
-        split = spliterator.trySplit();
-        assertNull(split);
-    }
-
-    private static <T, S extends Spliterator<T>> void testSplitOnce(
-            Collection<T> exp,
-            Supplier<S> supplier,
-            UnaryOperator<Consumer<T>> boxingAdapter,
-            ContentAsserter<T> asserter) {
-        S spliterator = supplier.get();
-        long sizeIfKnown = spliterator.getExactSizeIfKnown();
-        boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
-
-        ArrayList<T> fromSplit = new ArrayList<>();
-        Spliterator<T> s1 = supplier.get();
-        Spliterator<T> s2 = s1.trySplit();
-        long s1Size = s1.getExactSizeIfKnown();
-        long s2Size = (s2 != null) ? s2.getExactSizeIfKnown() : 0;
-        Consumer<T> addToFromSplit = boxingAdapter.apply(fromSplit::add);
-        if (s2 != null)
-            s2.forEachRemaining(addToFromSplit);
-        s1.forEachRemaining(addToFromSplit);
-
-        if (sizeIfKnown >= 0) {
-            assertEquals(sizeIfKnown, fromSplit.size());
-            if (s1Size >= 0 && s2Size >= 0)
-                assertEquals(sizeIfKnown, s1Size + s2Size);
-        }
-
-        asserter.assertContents(fromSplit, exp, isOrdered);
-    }
-
-    private static <T, S extends Spliterator<T>> void testSplitSixDeep(
-            Collection<T> exp,
-            Supplier<S> supplier,
-            UnaryOperator<Consumer<T>> boxingAdapter,
-            ContentAsserter<T> asserter) {
-        S spliterator = supplier.get();
-        boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
-
-        for (int depth=0; depth < 6; depth++) {
-            List<T> dest = new ArrayList<>();
-            spliterator = supplier.get();
-
-            assertSpliterator(spliterator);
-
-            // verify splitting with forEach
-            splitSixDeepVisitor(depth, 0, dest, spliterator, boxingAdapter, spliterator.characteristics(), false);
-            asserter.assertContents(dest, exp, isOrdered);
-
-            // verify splitting with tryAdvance
-            dest.clear();
-            spliterator = supplier.get();
-            splitSixDeepVisitor(depth, 0, dest, spliterator, boxingAdapter, spliterator.characteristics(), true);
-            asserter.assertContents(dest, exp, isOrdered);
-        }
-    }
-
-    private static <T, S extends Spliterator<T>>
-    void splitSixDeepVisitor(int depth, int curLevel,
-                             List<T> dest, S spliterator, UnaryOperator<Consumer<T>> boxingAdapter,
-                             int rootCharacteristics, boolean useTryAdvance) {
-        if (curLevel < depth) {
-            long beforeSize = spliterator.getExactSizeIfKnown();
-            Spliterator<T> split = spliterator.trySplit();
-            if (split != null) {
-                assertSpliterator(split, rootCharacteristics);
-                assertSpliterator(spliterator, rootCharacteristics);
-
-                if ((rootCharacteristics & Spliterator.SUBSIZED) != 0 &&
-                    (rootCharacteristics & Spliterator.SIZED) != 0) {
-                    assertEquals(beforeSize, split.estimateSize() + spliterator.estimateSize());
-                }
-                splitSixDeepVisitor(depth, curLevel + 1, dest, split, boxingAdapter, rootCharacteristics, useTryAdvance);
-            }
-            splitSixDeepVisitor(depth, curLevel + 1, dest, spliterator, boxingAdapter, rootCharacteristics, useTryAdvance);
-        }
-        else {
-            long sizeIfKnown = spliterator.getExactSizeIfKnown();
-            if (useTryAdvance) {
-                Consumer<T> addToDest = boxingAdapter.apply(dest::add);
-                int count = 0;
-                while (spliterator.tryAdvance(addToDest)) {
-                    ++count;
-                }
-
-                if (sizeIfKnown >= 0)
-                    assertEquals(sizeIfKnown, count);
-
-                // Assert that forEach now produces no elements
-                spliterator.forEachRemaining(boxingAdapter.apply(
-                        e -> fail("Spliterator.forEach produced an element after spliterator exhausted: " + e)));
-
-                Spliterator<T> split = spliterator.trySplit();
-                assertNull(split);
-            }
-            else {
-                List<T> leafDest = new ArrayList<>();
-                Consumer<T> addToLeafDest = boxingAdapter.apply(leafDest::add);
-                spliterator.forEachRemaining(addToLeafDest);
-
-                if (sizeIfKnown >= 0)
-                    assertEquals(sizeIfKnown, leafDest.size());
-
-                // Assert that forEach now produces no elements
-                spliterator.tryAdvance(boxingAdapter.apply(
-                        e -> fail("Spliterator.tryAdvance produced an element after spliterator exhausted: " + e)));
-
-                Spliterator<T> split = spliterator.trySplit();
-                assertNull(split);
-
-                dest.addAll(leafDest);
-            }
-        }
-    }
-
-    private static <T, S extends Spliterator<T>> void testSplitUntilNull(
-            Collection<T> exp,
-            Supplier<S> supplier,
-            UnaryOperator<Consumer<T>> boxingAdapter,
-            ContentAsserter<T> asserter) {
-        Spliterator<T> s = supplier.get();
-        boolean isOrdered = s.hasCharacteristics(Spliterator.ORDERED);
-        assertSpliterator(s);
-
-        List<T> splits = new ArrayList<>();
-        Consumer<T> c = boxingAdapter.apply(splits::add);
-
-        testSplitUntilNull(new SplitNode<T>(c, s));
-        asserter.assertContents(splits, exp, isOrdered);
-    }
-
-    private static class SplitNode<T> {
-        // Constant for every node
-        final Consumer<T> c;
-        final int rootCharacteristics;
-
-        final Spliterator<T> s;
-
-        SplitNode(Consumer<T> c, Spliterator<T> s) {
-            this(c, s.characteristics(), s);
-        }
-
-        private SplitNode(Consumer<T> c, int rootCharacteristics, Spliterator<T> s) {
-            this.c = c;
-            this.rootCharacteristics = rootCharacteristics;
-            this.s = s;
-        }
-
-        SplitNode<T> fromSplit(Spliterator<T> split) {
-            return new SplitNode<>(c, rootCharacteristics, split);
-        }
-    }
-
-    /**
-     * Set the maximum stack capacity to 0.25MB. This should be more than enough to detect a bad spliterator
-     * while not unduly disrupting test infrastructure given the test data sizes that are used are small.
-     * Note that j.u.c.ForkJoinPool sets the max queue size to 64M (1 << 26).
-     */
-    private static final int MAXIMUM_STACK_CAPACITY = 1 << 18; // 0.25MB
-
-    private static <T> void testSplitUntilNull(SplitNode<T> e) {
-        // Use an explicit stack to avoid a StackOverflowException when testing a Spliterator
-        // that when repeatedly split produces a right-balanced (and maybe degenerate) tree, or
-        // for a spliterator that is badly behaved.
-        Deque<SplitNode<T>> stack = new ArrayDeque<>();
-        stack.push(e);
-
-        int iteration = 0;
-        while (!stack.isEmpty()) {
-            assertTrue(iteration++ < MAXIMUM_STACK_CAPACITY, "Exceeded maximum stack modification count of 1 << 18");
-
-            e = stack.pop();
-            Spliterator<T> parentAndRightSplit = e.s;
-
-            long parentEstimateSize = parentAndRightSplit.estimateSize();
-            assertTrue(parentEstimateSize >= 0,
-                       String.format("Split size estimate %d < 0", parentEstimateSize));
-
-            long parentSize = parentAndRightSplit.getExactSizeIfKnown();
-            Spliterator<T> leftSplit = parentAndRightSplit.trySplit();
-            if (leftSplit == null) {
-                parentAndRightSplit.forEachRemaining(e.c);
-                continue;
-            }
-
-            assertSpliterator(leftSplit, e.rootCharacteristics);
-            assertSpliterator(parentAndRightSplit, e.rootCharacteristics);
-
-            if (parentEstimateSize != Long.MAX_VALUE && leftSplit.estimateSize() > 0
-                && parentAndRightSplit.estimateSize() > 0) {
-                assertTrue(leftSplit.estimateSize() < parentEstimateSize,
-                           String.format("Left split size estimate %d >= parent split size estimate %d",
-                                         leftSplit.estimateSize(), parentEstimateSize));
-                assertTrue(parentAndRightSplit.estimateSize() < parentEstimateSize,
-                           String.format("Right split size estimate %d >= parent split size estimate %d",
-                                         leftSplit.estimateSize(), parentEstimateSize));
-            }
-            else {
-                assertTrue(leftSplit.estimateSize() <= parentEstimateSize,
-                           String.format("Left split size estimate %d > parent split size estimate %d",
-                                         leftSplit.estimateSize(), parentEstimateSize));
-                assertTrue(parentAndRightSplit.estimateSize() <= parentEstimateSize,
-                           String.format("Right split size estimate %d > parent split size estimate %d",
-                                         leftSplit.estimateSize(), parentEstimateSize));
-            }
-
-            long leftSize = leftSplit.getExactSizeIfKnown();
-            long rightSize = parentAndRightSplit.getExactSizeIfKnown();
-            if (parentSize >= 0 && leftSize >= 0 && rightSize >= 0)
-                assertEquals(parentSize, leftSize + rightSize,
-                             String.format("exact left split size %d + exact right split size %d != parent exact split size %d",
-                                           leftSize, rightSize, parentSize));
-
-            // Add right side to stack first so left side is popped off first
-            stack.push(e.fromSplit(parentAndRightSplit));
-            stack.push(e.fromSplit(leftSplit));
-        }
-    }
-
-    private static void assertSpliterator(Spliterator<?> s, int rootCharacteristics) {
-        if ((rootCharacteristics & Spliterator.SUBSIZED) != 0) {
-            assertTrue(s.hasCharacteristics(Spliterator.SUBSIZED),
-                       "Child split is not SUBSIZED when root split is SUBSIZED");
-        }
-        assertSpliterator(s);
-    }
-
-    private static void assertSpliterator(Spliterator<?> s) {
-        if (s.hasCharacteristics(Spliterator.SUBSIZED)) {
-            assertTrue(s.hasCharacteristics(Spliterator.SIZED));
-        }
-        if (s.hasCharacteristics(Spliterator.SIZED)) {
-            assertTrue(s.estimateSize() != Long.MAX_VALUE);
-            assertTrue(s.getExactSizeIfKnown() >= 0);
-        }
-        try {
-            s.getComparator();
-            assertTrue(s.hasCharacteristics(Spliterator.SORTED));
-        } catch (IllegalStateException e) {
-            assertFalse(s.hasCharacteristics(Spliterator.SORTED));
-        }
-    }
-
-    private static<T> void assertContents(Collection<T> actual, Collection<T> expected, boolean isOrdered) {
-        if (isOrdered) {
-            assertEquals(actual, expected);
-        }
-        else {
-            LambdaTestHelpers.assertContentsUnordered(actual, expected);
-        }
-    }
-
-    private static void executeAndCatch(Class<? extends Exception> expected, Runnable r) {
-        Exception caught = null;
-        try {
-            r.run();
-        }
-        catch (Exception e) {
-            caught = e;
-        }
-
-        assertNotNull(caught,
-                      String.format("No Exception was thrown, expected an Exception of %s to be thrown",
-                                    expected.getName()));
-        assertTrue(expected.isInstance(caught),
-                   String.format("Exception thrown %s not an instance of %s",
-                                 caught.getClass().getName(), expected.getName()));
-    }
-
-    static<U> void mixedTraverseAndSplit(Consumer<U> b, Spliterator<U> splTop) {
-        Spliterator<U> spl1, spl2, spl3;
-        splTop.tryAdvance(b);
-        spl2 = splTop.trySplit();
-        if (spl2 != null) {
-            spl2.tryAdvance(b);
-            spl1 = spl2.trySplit();
-            if (spl1 != null) {
-                spl1.tryAdvance(b);
-                spl1.forEachRemaining(b);
-            }
-            spl2.tryAdvance(b);
-            spl2.forEachRemaining(b);
-        }
-        splTop.tryAdvance(b);
-        spl3 = splTop.trySplit();
-        if (spl3 != null) {
-            spl3.tryAdvance(b);
-            spl3.forEachRemaining(b);
-        }
-        splTop.tryAdvance(b);
-        splTop.forEachRemaining(b);
-    }
-
-    static void mixedTraverseAndSplit(IntConsumer b, Spliterator.OfInt splTop) {
-        Spliterator.OfInt spl1, spl2, spl3;
-        splTop.tryAdvance(b);
-        spl2 = splTop.trySplit();
-        if (spl2 != null) {
-            spl2.tryAdvance(b);
-            spl1 = spl2.trySplit();
-            if (spl1 != null) {
-                spl1.tryAdvance(b);
-                spl1.forEachRemaining(b);
-            }
-            spl2.tryAdvance(b);
-            spl2.forEachRemaining(b);
-        }
-        splTop.tryAdvance(b);
-        spl3 = splTop.trySplit();
-        if (spl3 != null) {
-            spl3.tryAdvance(b);
-            spl3.forEachRemaining(b);
-        }
-        splTop.tryAdvance(b);
-        splTop.forEachRemaining(b);
-    }
-    static void mixedTraverseAndSplit(LongConsumer b, Spliterator.OfLong splTop) {
-        Spliterator.OfLong spl1, spl2, spl3;
-        splTop.tryAdvance(b);
-        spl2 = splTop.trySplit();
-        if (spl2 != null) {
-            spl2.tryAdvance(b);
-            spl1 = spl2.trySplit();
-            if (spl1 != null) {
-                spl1.tryAdvance(b);
-                spl1.forEachRemaining(b);
-            }
-            spl2.tryAdvance(b);
-            spl2.forEachRemaining(b);
-        }
-        splTop.tryAdvance(b);
-        spl3 = splTop.trySplit();
-        if (spl3 != null) {
-            spl3.tryAdvance(b);
-            spl3.forEachRemaining(b);
-        }
-        splTop.tryAdvance(b);
-        splTop.forEachRemaining(b);
-    }
-
-    static void mixedTraverseAndSplit(DoubleConsumer b, Spliterator.OfDouble splTop) {
-        Spliterator.OfDouble spl1, spl2, spl3;
-        splTop.tryAdvance(b);
-        spl2 = splTop.trySplit();
-        if (spl2 != null) {
-            spl2.tryAdvance(b);
-            spl1 = spl2.trySplit();
-            if (spl1 != null) {
-                spl1.tryAdvance(b);
-                spl1.forEachRemaining(b);
-            }
-            spl2.tryAdvance(b);
-            spl2.forEachRemaining(b);
-        }
-        splTop.tryAdvance(b);
-        spl3 = splTop.trySplit();
-        if (spl3 != null) {
-            spl3.tryAdvance(b);
-            spl3.forEachRemaining(b);
-        }
-        splTop.tryAdvance(b);
-        splTop.forEachRemaining(b);
-    }
-}
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/StatefulTestOp.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,138 +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 java.util.stream;
-
-import java.util.Spliterator;
-import java.util.function.IntFunction;
-
-/**
- * The base type for a stateful test operation.
- */
-interface StatefulTestOp<E> extends IntermediateTestOp<E, E> {
-
-    @SuppressWarnings({"rawtypes", "unchecked"})
-    public static<T> AbstractPipeline chain(AbstractPipeline upstream,
-                                            StatefulTestOp op) {
-        switch (op.outputShape()) {
-            case REFERENCE:
-                return new ReferencePipeline.StatefulOp<Object, T>(upstream, op.inputShape(), op.opGetFlags()) {
-                    @Override
-                    Sink opWrapSink(int flags, Sink sink) {
-                        return op.opWrapSink(flags, isParallel(), sink);
-                    }
-
-                    @Override
-                    <P_IN> Spliterator<T> opEvaluateParallelLazy(PipelineHelper<T> helper,
-                                                                 Spliterator<P_IN> spliterator) {
-                        return op.opEvaluateParallelLazy(helper, spliterator);
-                    }
-
-                    @Override
-                    <P_IN> Node<T> opEvaluateParallel(PipelineHelper<T> helper,
-                                                      Spliterator<P_IN> spliterator,
-                                                      IntFunction<T[]> generator) {
-                        return op.opEvaluateParallel(helper, spliterator, generator);
-                    }
-                };
-            case INT_VALUE:
-                return new IntPipeline.StatefulOp<Object>(upstream, op.inputShape(), op.opGetFlags()) {
-                    @Override
-                    Sink opWrapSink(int flags, Sink sink) {
-                        return op.opWrapSink(flags, isParallel(), sink);
-                    }
-
-                    @Override
-                    <P_IN> Spliterator<Integer> opEvaluateParallelLazy(PipelineHelper<Integer> helper,
-                                                                 Spliterator<P_IN> spliterator) {
-                        return op.opEvaluateParallelLazy(helper, spliterator);
-                    }
-
-                    @Override
-                    <P_IN> Node<Integer> opEvaluateParallel(PipelineHelper<Integer> helper,
-                                                            Spliterator<P_IN> spliterator,
-                                                            IntFunction<Integer[]> generator) {
-                        return (Node<Integer>) op.opEvaluateParallel(helper, spliterator, generator);
-                    }
-                };
-            case LONG_VALUE:
-                return new LongPipeline.StatefulOp<Object>(upstream, op.inputShape(), op.opGetFlags()) {
-                    @Override
-                    Sink opWrapSink(int flags, Sink sink) {
-                        return op.opWrapSink(flags, isParallel(), sink);
-                    }
-
-                    @Override
-                    <P_IN> Spliterator<Long> opEvaluateParallelLazy(PipelineHelper<Long> helper,
-                                                                 Spliterator<P_IN> spliterator) {
-                        return op.opEvaluateParallelLazy(helper, spliterator);
-                    }
-
-                    @Override
-                    <P_IN> Node<Long> opEvaluateParallel(PipelineHelper<Long> helper,
-                                                         Spliterator<P_IN> spliterator,
-                                                         IntFunction<Long[]> generator) {
-                        return (Node<Long>) op.opEvaluateParallel(helper, spliterator, generator);
-                    }
-                };
-            case DOUBLE_VALUE:
-                return new DoublePipeline.StatefulOp<Object>(upstream, op.inputShape(), op.opGetFlags()) {
-                    @Override
-                    Sink opWrapSink(int flags, Sink sink) {
-                        return op.opWrapSink(flags, isParallel(), sink);
-                    }
-
-                    @Override
-                    <P_IN> Spliterator<Double> opEvaluateParallelLazy(PipelineHelper<Double> helper,
-                                                                    Spliterator<P_IN> spliterator) {
-                        return op.opEvaluateParallelLazy(helper, spliterator);
-                    }
-
-                    @Override
-                    <P_IN> Node<Double> opEvaluateParallel(PipelineHelper<Double> helper,
-                                                           Spliterator<P_IN> spliterator,
-                                                           IntFunction<Double[]> generator) {
-                        return (Node<Double>) op.opEvaluateParallel(helper, spliterator, generator);
-                    }
-                };
-            default: throw new IllegalStateException(op.outputShape().toString());
-        }
-    }
-
-    default StreamShape inputShape() { return StreamShape.REFERENCE; }
-
-    default StreamShape outputShape() { return StreamShape.REFERENCE; }
-
-    default int opGetFlags() { return 0; }
-
-    Sink<E> opWrapSink(int flags, boolean parallel, Sink<E> sink);
-
-    @SuppressWarnings("unchecked")
-    default <P_IN> Spliterator<E> opEvaluateParallelLazy(PipelineHelper<E> helper,
-                                                         Spliterator<P_IN> spliterator) {
-        return opEvaluateParallel(helper, spliterator, i -> (E[]) new Object[i]).spliterator();
-    }
-
-    <P_IN> Node<E> opEvaluateParallel(PipelineHelper<E> helper,
-                                      Spliterator<P_IN> spliterator,
-                                      IntFunction<E[]> generator);
-}
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/StatelessTestOp.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 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 java.util.stream;
-
-/**
- * The base type of a stateless test operation
- */
-interface StatelessTestOp<E_IN, E_OUT> extends IntermediateTestOp<E_IN, E_OUT> {
-
-    @SuppressWarnings({"rawtypes", "unchecked"})
-    public static<T> AbstractPipeline chain(AbstractPipeline upstream,
-                                            StatelessTestOp<?, T> op) {
-        int flags = op.opGetFlags();
-        switch (op.outputShape()) {
-            case REFERENCE:
-                return new ReferencePipeline.StatelessOp<Object, T>(upstream, op.inputShape(), flags) {
-                    public Sink opWrapSink(int flags, Sink<T> sink) {
-                        return op.opWrapSink(flags, isParallel(), sink);
-                    }
-                };
-            case INT_VALUE:
-                return new IntPipeline.StatelessOp<Object>(upstream, op.inputShape(), flags) {
-                    public Sink opWrapSink(int flags, Sink sink) {
-                        return op.opWrapSink(flags, isParallel(), sink);
-                    }
-                };
-            case LONG_VALUE:
-                return new LongPipeline.StatelessOp<Object>(upstream, op.inputShape(), flags) {
-                    @Override
-                    Sink opWrapSink(int flags, Sink sink) {
-                        return op.opWrapSink(flags, isParallel(), sink);
-                    }
-                };
-            case DOUBLE_VALUE:
-                return new DoublePipeline.StatelessOp<Object>(upstream, op.inputShape(), flags) {
-                    @Override
-                    Sink opWrapSink(int flags, Sink sink) {
-                        return op.opWrapSink(flags, isParallel(), sink);
-                    }
-                };
-            default: throw new IllegalStateException(op.outputShape().toString());
-        }
-    }
-
-    default StreamShape inputShape() { return StreamShape.REFERENCE; }
-
-    default StreamShape outputShape() { return StreamShape.REFERENCE; }
-
-    default int opGetFlags() { return 0; }
-
-    Sink<E_IN> opWrapSink(int flags, boolean parallel, Sink<E_OUT> sink);
-}
-
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/StreamOpFlagTestHelper.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +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 java.util.stream;
-
-import java.util.EnumSet;
-
-public class StreamOpFlagTestHelper {
-
-    /** EnumSet containing stream flags */
-    private static final EnumSet<StreamOpFlag> allStreamFlags;
-
-    static {
-        allStreamFlags = EnumSet.allOf(StreamOpFlag.class);
-        for (StreamOpFlag f : EnumSet.allOf(StreamOpFlag.class))
-            if (!f.isStreamFlag())
-                allStreamFlags.remove(f);
-    }
-
-
-    static EnumSet<StreamOpFlag> allStreamFlags() {
-        // EnumSet is mutable
-        return allStreamFlags.clone();
-    }
-
-    public static boolean isStreamOrdered(Stream<?> s) {
-        return StreamOpFlag.ORDERED.isKnown(OpTestCase.getStreamFlags(s));
-    }
-}
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/StreamTestDataProvider.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,205 +0,0 @@
-/*
- * 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 java.util.stream;
-
-import org.testng.annotations.DataProvider;
-
-import java.util.*;
-import java.util.Spliterators;
-import java.util.function.Supplier;
-
-/**
- * StreamTestDataProvider
- *
- * @author Brian Goetz
- */
-/** TestNG DataProvider for ref-valued streams */
-public class StreamTestDataProvider {
-    private static final Integer[] to0 = new Integer[0];
-    private static final Integer[] to1 = new Integer[1];
-    private static final Integer[] to10 = new Integer[10];
-    private static final Integer[] to100 = new Integer[100];
-    private static final Integer[] to1000 = new Integer[1000];
-    private static final Integer[] reversed = new Integer[100];
-    private static final Integer[] ones = new Integer[100];
-    private static final Integer[] twice = new Integer[200];
-    private static final Integer[] pseudoRandom;
-
-    private static final Object[][] testData;
-    private static final Object[][] withNullTestData;
-    private static final Object[][] spliteratorTestData;
-
-    static {
-        Integer[][] arrays = {to0, to1, to10, to100, to1000};
-        for (Integer[] arr : arrays) {
-            for (int i = 0; i < arr.length; i++) {
-                arr[i] = i;
-            }
-        }
-        for (int i = 0; i < reversed.length; i++) {
-            reversed[i] = reversed.length - i;
-        }
-        for (int i = 0; i < ones.length; i++) {
-            ones[i] = 1;
-        }
-        System.arraycopy(to100, 0, twice, 0, to100.length);
-        System.arraycopy(to100, 0, twice, to100.length, to100.length);
-        pseudoRandom = new Integer[LambdaTestHelpers.LONG_STRING.length()];
-        for (int i = 0; i < LambdaTestHelpers.LONG_STRING.length(); i++) {
-            pseudoRandom[i] = (int) LambdaTestHelpers.LONG_STRING.charAt(i);
-        }
-    }
-
-    static final Object[][] arrays = {
-            {"empty", to0},
-            {"0..1", to1},
-            {"0..10", to10},
-            {"0..100", to100},
-            {"0..1000", to1000},
-            {"100x[1]", ones},
-            {"2x[0..100]", twice},
-            {"reverse 0..100", reversed},
-            {"pseudorandom", pseudoRandom}
-    };
-
-    static {
-        {
-            List<Object[]> list = new ArrayList<>();
-            for (Object[] data : arrays) {
-                final Object name = data[0];
-                final Integer[] ints = (Integer[])data[1];
-                final List<Integer> intsAsList = Arrays.asList(ints);
-
-                list.add(arrayDataDescr("array:" + name, ints));
-                list.add(collectionDataDescr("ArrayList.asList:" + name, intsAsList));
-                list.add(collectionDataDescr("ArrayList:" + name, new ArrayList<>(intsAsList)));
-                list.add(streamDataDescr("DelegatingStream(ArrayList):" + name,
-                                         () -> new ArrayList<>(intsAsList).stream()));
-                List<Integer> aList = new ArrayList<>(intsAsList);
-                if (LambdaTestMode.isNormalMode()) {
-                    // Only include sub-lists for normal test execution mode
-                    // This data is serialization-hostile since the state of the
-                    // deserialized sub-list will be out of sync with the
-                    // enclosing list.
-                    list.add(collectionDataDescr("ArrayList.Sublist:" + name,
-                                                 (ints.length) <= 1 ? aList.subList(0, 0) : aList.subList(1, ints.length / 2)));
-                }
-                list.add(collectionDataDescr("LinkedList:" + name, new LinkedList<>(intsAsList)));
-                list.add(collectionDataDescr("HashSet:" + name, new HashSet<>(intsAsList)));
-                list.add(collectionDataDescr("LinkedHashSet:" + name, new LinkedHashSet<>(intsAsList)));
-                list.add(collectionDataDescr("TreeSet:" + name, new TreeSet<>(intsAsList)));
-                SpinedBuffer<Integer> spinedBuffer = new SpinedBuffer<>();
-                intsAsList.forEach(spinedBuffer);
-                list.add(sbDataDescr("SpinedBuffer:" + name, spinedBuffer));
-
-                // @@@ Add more
-            }
-            testData = list.toArray(new Object[0][]);
-        }
-
-        // Simple combination of numbers and null values, probably excessive but may catch
-        // errors for initialization/termination/sequence
-        // @@@ This is separate from the other data for now until nulls are consistently supported by
-        // all operations
-        {
-            List<Object[]> list = new ArrayList<>();
-            int size = 5;
-            for (int i = 0; i < (1 << size) - 2; i++) {
-                Integer[] content = new Integer[size];
-                for (int e = 0; e < size; e++) {
-                    content[e] = (i & (1 << e)) > 0 ? e + 1 : null;
-                }
-
-                // ORDERED
-                list.add(arrayDataDescr("array:" + i, content));
-                // not ORDERED, DISTINCT
-                list.add(collectionDataDescr("HashSet:" + i, new HashSet<>(Arrays.asList(content))));
-            }
-
-            withNullTestData = list.toArray(new Object[0][]);
-        }
-
-        {
-            List<Object[]> spliterators = new ArrayList<>();
-            for (Object[] data : arrays) {
-                final Object name = data[0];
-                final Integer[] ints = (Integer[])data[1];
-
-                spliterators.add(splitDescr("Arrays.s(array):" + name,
-                                            () -> Arrays.spliterator(ints)));
-                spliterators.add(splitDescr("arrays.s(array,o,l):" + name,
-                                            () -> Arrays.spliterator(ints, 0, ints.length/2)));
-                spliterators.add(splitDescr("SpinedBuffer.s():" + name,
-                                            () -> {
-                                                SpinedBuffer<Integer> sb = new SpinedBuffer<>();
-                                                for (Integer i : ints)
-                                                    sb.accept(i);
-                                                return sb.spliterator();
-                                            }));
-                spliterators.add(splitDescr("Iterators.s(Arrays.s(array).iterator(), size):" + name,
-                                            () -> Spliterators.spliterator(Arrays.asList(ints).iterator(), ints.length, 0)));
-                spliterators.add(splitDescr("Iterators.s(Arrays.s(array).iterator()):" + name,
-                                            () -> Spliterators.spliteratorUnknownSize(Arrays.asList(ints).iterator(), 0)));
-                // @@@ Add map and collection spliterators when spliterator() is exposed on Collection or Iterable
-            }
-            spliteratorTestData = spliterators.toArray(new Object[0][]);
-        }
-    }
-
-    static <T> Object[] arrayDataDescr(String description, T[] data) {
-        return new Object[] { description, TestData.Factory.ofArray(description, data)};
-    }
-
-    static <T> Object[] streamDataDescr(String description, Supplier<Stream<T>> supplier) {
-        return new Object[] { description, TestData.Factory.ofSupplier(description, supplier)};
-    }
-
-    static <T> Object[] collectionDataDescr(String description, Collection<T> data) {
-        return new Object[] { description, TestData.Factory.ofCollection(description, data)};
-    }
-
-    static <T> Object[] sbDataDescr(String description, SpinedBuffer<T> data) {
-        return new Object[] { description, TestData.Factory.ofSpinedBuffer(description, data)};
-    }
-
-    static <T> Object[] splitDescr(String description, Supplier<Spliterator<T>> ss) {
-        return new Object[] { description, ss };
-    }
-
-    // Return an array of ( String name, StreamTestData<Integer> )
-    @DataProvider(name = "StreamTestData<Integer>")
-    public static Object[][] makeStreamTestData() {
-        return testData;
-    }
-
-    @DataProvider(name = "withNull:StreamTestData<Integer>")
-    public static Object[][] makeStreamWithNullTestData() {
-        return withNullTestData;
-    }
-
-    // returns an array of (String name, Supplier<Spliterator<Integer>>)
-    @DataProvider(name = "Spliterator<Integer>")
-    public static Object[][] spliteratorProvider() {
-        return spliteratorTestData;
-    }
-}
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/StreamTestScenario.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,278 +0,0 @@
-/*
- * 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 java.util.stream;
-
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.Spliterator;
-import java.util.function.Consumer;
-import java.util.function.Function;
-
-/**
- * Test scenarios for reference streams.
- *
- * Each scenario is provided with a data source, a function that maps a fresh
- * stream (as provided by the data source) to a new stream, and a sink to
- * receive results.  Each scenario describes a different way of computing the
- * stream contents.  The test driver will ensure that all scenarios produce
- * the same output (modulo allowable differences in ordering).
- */
-@SuppressWarnings({"rawtypes", "unchecked"})
-public enum StreamTestScenario implements OpTestCase.BaseStreamTestScenario {
-
-    STREAM_FOR_EACH(false) {
-        <T, U, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
-            Stream<U> s = m.apply(source);
-            if (s.isParallel()) {
-                s = s.sequential();
-            }
-            s.forEach(b);
-        }
-    },
-
-    // Collec to list
-    STREAM_COLLECT(false) {
-        <T, U, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
-            for (U t : m.apply(source).collect(Collectors.toList())) {
-                b.accept(t);
-            }
-        }
-    },
-
-    // To array
-    STREAM_TO_ARRAY(false) {
-        <T, U, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
-            for (Object t : m.apply(source).toArray()) {
-                b.accept((U) t);
-            }
-        }
-    },
-
-    // Wrap as stream, and iterate in pull mode
-    STREAM_ITERATOR(false) {
-        <T, U, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
-            for (Iterator<U> seqIter = m.apply(source).iterator(); seqIter.hasNext(); )
-                b.accept(seqIter.next());
-        }
-    },
-
-    // Wrap as stream, and spliterate then iterate in pull mode
-    STREAM_SPLITERATOR(false) {
-        <T, U, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
-            for (Spliterator<U> spl = m.apply(source).spliterator(); spl.tryAdvance(b); ) {
-            }
-        }
-    },
-
-    // Wrap as stream, spliterate, then split a few times mixing advances with forEach
-    STREAM_SPLITERATOR_WITH_MIXED_TRAVERSE_AND_SPLIT(false) {
-        <T, U, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
-            SpliteratorTestHelper.mixedTraverseAndSplit(b, m.apply(source).spliterator());
-        }
-    },
-
-    // Wrap as stream, and spliterate then iterate in pull mode
-    STREAM_SPLITERATOR_FOREACH(false) {
-        <T, U, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
-            m.apply(source).spliterator().forEachRemaining(b);
-        }
-    },
-
-    // Wrap as parallel stream + sequential
-    PAR_STREAM_SEQUENTIAL_FOR_EACH(true) {
-        <T, U, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
-            m.apply(source).sequential().forEach(b);
-        }
-    },
-
-    // Wrap as parallel stream + forEachOrdered
-    PAR_STREAM_FOR_EACH_ORDERED(true) {
-        <T, U, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
-            // @@@ Want to explicitly select ordered equalator
-            m.apply(source).forEachOrdered(b);
-        }
-    },
-
-    // Wrap as stream, and spliterate then iterate sequentially
-    PAR_STREAM_SPLITERATOR(true) {
-        <T, U, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
-            for (Spliterator<U> spl = m.apply(source).spliterator(); spl.tryAdvance(b); ) {
-            }
-        }
-    },
-
-    // Wrap as stream, and spliterate then iterate sequentially
-    PAR_STREAM_SPLITERATOR_FOREACH(true) {
-        <T, U, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
-            m.apply(source).spliterator().forEachRemaining(b);
-        }
-    },
-
-    // Wrap as parallel stream + toArray
-    PAR_STREAM_TO_ARRAY(true) {
-        <T, U, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
-            for (Object t : m.apply(source).toArray())
-                b.accept((U) t);
-        }
-    },
-
-    // Wrap as parallel stream, get the spliterator, wrap as a stream + toArray
-    PAR_STREAM_SPLITERATOR_STREAM_TO_ARRAY(true) {
-        <T, U, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
-            Stream<U> s = m.apply(source);
-            Spliterator<U> sp = s.spliterator();
-            Stream<U> ss = StreamSupport.stream(() -> sp,
-                                                StreamOpFlag.toCharacteristics(OpTestCase.getStreamFlags(s))
-                                                | (sp.getExactSizeIfKnown() < 0 ? 0 : Spliterator.SIZED), true);
-            for (Object t : ss.toArray())
-                b.accept((U) t);
-        }
-    },
-
-    // Wrap as parallel stream + toArray and clear SIZED flag
-    PAR_STREAM_TO_ARRAY_CLEAR_SIZED(true) {
-        <T, U, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
-            S_IN pipe1 = (S_IN) OpTestCase.chain(source,
-                                                 new FlagDeclaringOp(StreamOpFlag.NOT_SIZED, data.getShape()));
-            Stream<U> pipe2 = m.apply(pipe1);
-
-            for (Object t : pipe2.toArray())
-                b.accept((U) t);
-        }
-    },
-
-    // Wrap as parallel + collect to list
-    PAR_STREAM_COLLECT_TO_LIST(true) {
-        <T, U, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
-            for (U u : m.apply(source).collect(Collectors.toList()))
-                b.accept(u);
-        }
-    },
-
-    // Wrap sequential as parallel, + collect to list
-    STREAM_TO_PAR_STREAM_COLLECT_TO_LIST(true) {
-        public <T, S_IN extends BaseStream<T, S_IN>>
-        S_IN getStream(TestData<T, S_IN> data) {
-            return data.stream().parallel();
-        }
-
-        <T, U, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
-            for (U u : m.apply(source).collect(Collectors.toList()))
-                b.accept(u);
-        }
-    },
-
-    // Wrap parallel as sequential,, + collect
-    PAR_STREAM_TO_STREAM_COLLECT_TO_LIST(true) {
-        <T, U, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
-            for (U u : m.apply(source).collect(Collectors.toList()))
-                b.accept(u);
-        }
-    },
-
-    // Wrap as parallel stream + forEach synchronizing
-    PAR_STREAM_FOR_EACH(true, false) {
-        <T, U, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
-            m.apply(source).forEach(e -> {
-                synchronized (data) {
-                    b.accept(e);
-                }
-            });
-        }
-    },
-
-    // Wrap as parallel stream + forEach synchronizing and clear SIZED flag
-    PAR_STREAM_FOR_EACH_CLEAR_SIZED(true, false) {
-        <T, U, S_IN extends BaseStream<T, S_IN>>
-        void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m) {
-            S_IN pipe1 = (S_IN) OpTestCase.chain(source,
-                                                 new FlagDeclaringOp(StreamOpFlag.NOT_SIZED, data.getShape()));
-            m.apply(pipe1).forEach(e -> {
-                synchronized (data) {
-                    b.accept(e);
-                }
-            });
-        }
-    },
-    ;
-
-    // The set of scenarios that clean the SIZED flag
-    public static final Set<StreamTestScenario> CLEAR_SIZED_SCENARIOS = Collections.unmodifiableSet(
-            EnumSet.of(PAR_STREAM_TO_ARRAY_CLEAR_SIZED, PAR_STREAM_FOR_EACH_CLEAR_SIZED));
-
-    private final boolean isParallel;
-
-    private final boolean isOrdered;
-
-    StreamTestScenario(boolean isParallel) {
-        this(isParallel, true);
-    }
-
-    StreamTestScenario(boolean isParallel, boolean isOrdered) {
-        this.isParallel = isParallel;
-        this.isOrdered = isOrdered;
-    }
-
-    public StreamShape getShape() {
-        return StreamShape.REFERENCE;
-    }
-
-    public boolean isParallel() {
-        return isParallel;
-    }
-
-    public boolean isOrdered() {
-        return isOrdered;
-    }
-
-    public <T, U, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>>
-    void run(TestData<T, S_IN> data, Consumer<U> b, Function<S_IN, S_OUT> m) {
-        try (S_IN source = getStream(data)) {
-            run(data, source, b, (Function<S_IN, Stream<U>>) m);
-        }
-    }
-
-    abstract <T, U, S_IN extends BaseStream<T, S_IN>>
-    void run(TestData<T, S_IN> data, S_IN source, Consumer<U> b, Function<S_IN, Stream<U>> m);
-
-}
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/TestData.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,355 +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 java.util.stream;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.PrimitiveIterator;
-import java.util.Spliterator;
-import java.util.Spliterators;
-import java.util.function.DoubleConsumer;
-import java.util.function.Function;
-import java.util.function.IntConsumer;
-import java.util.function.LongConsumer;
-import java.util.function.Supplier;
-import java.util.function.ToIntFunction;
-
-/** Describes a test data set for use in stream tests */
-public interface TestData<T, S extends BaseStream<T, S>>
-        extends Iterable<T> {
-
-    default int size() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    default Iterator<T> iterator() {
-        return Spliterators.iterator(spliterator());
-    }
-
-    Spliterator<T> spliterator();
-
-    default boolean isOrdered() {
-        return spliterator().hasCharacteristics(Spliterator.ORDERED);
-    }
-
-    StreamShape getShape();
-
-    default <A extends Collection<? super T>> A into(A target) {
-        spliterator().forEachRemaining(target::add);
-        return target;
-    }
-
-    S stream();
-
-    S parallelStream();
-
-    public interface OfRef<T> extends TestData<T, Stream<T>> { }
-
-    public interface OfInt extends TestData<Integer, IntStream> { }
-
-    public interface OfLong extends TestData<Long, LongStream> { }
-
-    public interface OfDouble extends TestData<Double, DoubleStream> { }
-
-    // @@@ Temporary garbage class to avoid triggering bugs with lambdas in static methods in interfaces
-    public static class Factory {
-        public static <T> OfRef<T> ofArray(String name, T[] array) {
-            return new AbstractTestData.RefTestData<>(name, array, Arrays::stream, a -> Arrays.stream(a).parallel(),
-                                                      Arrays::spliterator, a -> a.length);
-        }
-
-        public static <T> OfRef<T> ofCollection(String name, Collection<T> collection) {
-            return new AbstractTestData.RefTestData<>(name, collection, Collection::stream, Collection::parallelStream,
-                                                      Collection::spliterator, Collection::size);
-        }
-
-        public static <T> OfRef<T> ofSpinedBuffer(String name, SpinedBuffer<T> buffer) {
-            return new AbstractTestData.RefTestData<>(name, buffer,
-                                                      b -> StreamSupport.stream(b.spliterator(), false),
-                                                      b -> StreamSupport.stream(b.spliterator(), true),
-                                                      SpinedBuffer::spliterator,
-                                                      b -> (int) b.count());
-        }
-
-        public static <T> OfRef<T> ofSupplier(String name, Supplier<Stream<T>> supplier) {
-            return new AbstractTestData.RefTestData<>(name, supplier,
-                                                      Supplier::get,
-                                                      s -> s.get().parallel(),
-                                                      s -> s.get().spliterator(),
-                                                      s -> (int) s.get().spliterator().getExactSizeIfKnown());
-        }
-
-        public static <T> OfRef<T> ofRefNode(String name, Node<T> node) {
-            return new AbstractTestData.RefTestData<>(name, node,
-                                                      n -> StreamSupport.stream(n::spliterator, Spliterator.SIZED | Spliterator.ORDERED, false),
-                                                      n -> StreamSupport.stream(n::spliterator, Spliterator.SIZED | Spliterator.ORDERED, true),
-                                                      Node::spliterator,
-                                                      n -> (int) n.count());
-        }
-
-        // int factories
-        public static <T> OfInt ofArray(String name, int[] array) {
-            return new AbstractTestData.IntTestData<>(name, array, Arrays::stream, a -> Arrays.stream(a).parallel(),
-                                                      Arrays::spliterator, a -> a.length);
-        }
-
-        public static OfInt ofSpinedBuffer(String name, SpinedBuffer.OfInt buffer) {
-            return new AbstractTestData.IntTestData<>(name, buffer,
-                                                      b -> StreamSupport.intStream(b.spliterator(), false),
-                                                      b -> StreamSupport.intStream(b.spliterator(), true),
-                                                      SpinedBuffer.OfInt::spliterator,
-                                                      b -> (int) b.count());
-        }
-
-        public static OfInt ofIntSupplier(String name, Supplier<IntStream> supplier) {
-            return new AbstractTestData.IntTestData<>(name, supplier,
-                                                      Supplier::get,
-                                                      s -> s.get().parallel(),
-                                                      s -> s.get().spliterator(),
-                                                      s -> (int) s.get().spliterator().getExactSizeIfKnown());
-        }
-
-        public static OfInt ofNode(String name, Node.OfInt node) {
-            int characteristics = Spliterator.SIZED | Spliterator.ORDERED;
-            return new AbstractTestData.IntTestData<>(name, node,
-                                                      n -> StreamSupport.intStream(n::spliterator, characteristics, false),
-                                                      n -> StreamSupport.intStream(n::spliterator, characteristics, true),
-                                                      Node.OfInt::spliterator,
-                                                      n -> (int) n.count());
-        }
-
-        // long factories
-        public static <T> OfLong ofArray(String name, long[] array) {
-            return new AbstractTestData.LongTestData<>(name, array, Arrays::stream, a -> Arrays.stream(a).parallel(),
-                                                       Arrays::spliterator, a -> a.length);
-        }
-
-        public static OfLong ofSpinedBuffer(String name, SpinedBuffer.OfLong buffer) {
-            return new AbstractTestData.LongTestData<>(name, buffer,
-                                                      b -> StreamSupport.longStream(b.spliterator(), false),
-                                                      b -> StreamSupport.longStream(b.spliterator(), true),
-                                                      SpinedBuffer.OfLong::spliterator,
-                                                      b -> (int) b.count());
-        }
-
-        public static OfLong ofLongSupplier(String name, Supplier<LongStream> supplier) {
-            return new AbstractTestData.LongTestData<>(name, supplier,
-                                                      Supplier::get,
-                                                      s -> s.get().parallel(),
-                                                      s -> s.get().spliterator(),
-                                                      s -> (int) s.get().spliterator().getExactSizeIfKnown());
-        }
-
-        public static OfLong ofNode(String name, Node.OfLong node) {
-            int characteristics = Spliterator.SIZED | Spliterator.ORDERED;
-            return new AbstractTestData.LongTestData<>(name, node,
-                                                      n -> StreamSupport.longStream(n::spliterator, characteristics, false),
-                                                      n -> StreamSupport.longStream(n::spliterator, characteristics, true),
-                                                      Node.OfLong::spliterator,
-                                                      n -> (int) n.count());
-        }
-
-        // double factories
-        public static <T> OfDouble ofArray(String name, double[] array) {
-            return new AbstractTestData.DoubleTestData<>(name, array, Arrays::stream, a -> Arrays.stream(a).parallel(),
-                                                         Arrays::spliterator, a -> a.length);
-        }
-
-        public static OfDouble ofSpinedBuffer(String name, SpinedBuffer.OfDouble buffer) {
-            return new AbstractTestData.DoubleTestData<>(name, buffer,
-                                                         b -> StreamSupport.doubleStream(b.spliterator(), false),
-                                                         b -> StreamSupport.doubleStream(b.spliterator(), true),
-                                                         SpinedBuffer.OfDouble::spliterator,
-                                                         b -> (int) b.count());
-        }
-
-        public static OfDouble ofDoubleSupplier(String name, Supplier<DoubleStream> supplier) {
-            return new AbstractTestData.DoubleTestData<>(name, supplier,
-                                                         Supplier::get,
-                                                         s -> s.get().parallel(),
-                                                         s -> s.get().spliterator(),
-                                                         s -> (int) s.get().spliterator().getExactSizeIfKnown());
-        }
-
-        public static OfDouble ofNode(String name, Node.OfDouble node) {
-            int characteristics = Spliterator.SIZED | Spliterator.ORDERED;
-            return new AbstractTestData.DoubleTestData<>(name, node,
-                                                         n -> StreamSupport.doubleStream(n::spliterator, characteristics, false),
-                                                         n -> StreamSupport.doubleStream(n::spliterator, characteristics, true),
-                                                         Node.OfDouble::spliterator,
-                                                         n -> (int) n.count());
-        }
-    }
-
-
-    abstract class AbstractTestData<T, S extends BaseStream<T, S>,
-            T_STATE,
-                                    T_SPLITR extends Spliterator<T>>
-            implements TestData<T, S> {
-        private final String name;
-        private final StreamShape shape;
-        protected final T_STATE state;
-        private final ToIntFunction<T_STATE> sizeFn;
-        private final Function<T_STATE, S> streamFn;
-        private final Function<T_STATE, S> parStreamFn;
-        private final Function<T_STATE, T_SPLITR> splitrFn;
-
-        AbstractTestData(String name,
-                         StreamShape shape,
-                         T_STATE state,
-                         Function<T_STATE, S> streamFn,
-                         Function<T_STATE, S> parStreamFn,
-                         Function<T_STATE, T_SPLITR> splitrFn,
-                         ToIntFunction<T_STATE> sizeFn) {
-            this.name = name;
-            this.shape = shape;
-            this.state = state;
-            this.streamFn = streamFn;
-            this.parStreamFn = parStreamFn;
-            this.splitrFn = splitrFn;
-            this.sizeFn = sizeFn;
-        }
-
-        @Override
-        public StreamShape getShape() {
-            return shape;
-        }
-
-        @Override
-        public String toString() {
-            return getClass().getSimpleName() + "[" + name + "]";
-        }
-
-        @Override
-        public int size() {
-            return sizeFn.applyAsInt(state);
-        }
-
-        @Override
-        public T_SPLITR spliterator() {
-            return splitrFn.apply(state);
-        }
-
-        @Override
-        public S stream() {
-            return streamFn.apply(state);
-        }
-
-        @Override
-        public S parallelStream() {
-            return parStreamFn.apply(state);
-        }
-
-        public static class RefTestData<T, I>
-                extends AbstractTestData<T, Stream<T>, I, Spliterator<T>>
-                implements TestData.OfRef<T> {
-
-            protected RefTestData(String name,
-                                  I state,
-                                  Function<I, Stream<T>> streamFn,
-                                  Function<I, Stream<T>> parStreamFn,
-                                  Function<I, Spliterator<T>> splitrFn,
-                                  ToIntFunction<I> sizeFn) {
-                super(name, StreamShape.REFERENCE, state, streamFn, parStreamFn, splitrFn, sizeFn);
-            }
-
-        }
-
-        static class IntTestData<I>
-                extends AbstractTestData<Integer, IntStream, I, Spliterator.OfInt>
-                implements TestData.OfInt {
-
-            protected IntTestData(String name,
-                                  I state,
-                                  Function<I, IntStream> streamFn,
-                                  Function<I, IntStream> parStreamFn,
-                                  Function<I, Spliterator.OfInt> splitrFn,
-                                  ToIntFunction<I> sizeFn) {
-                super(name, StreamShape.INT_VALUE, state, streamFn, parStreamFn, splitrFn, sizeFn);
-            }
-
-            @Override
-            public PrimitiveIterator.OfInt iterator() {
-                return Spliterators.iterator(spliterator());
-            }
-
-            @Override
-            public <A extends Collection<? super Integer>> A into(A target) {
-                spliterator().forEachRemaining((IntConsumer) target::add);
-                return target;
-            }
-        }
-
-        static class LongTestData<I>
-                extends AbstractTestData<Long, LongStream, I, Spliterator.OfLong>
-                implements TestData.OfLong {
-
-            protected LongTestData(String name,
-                                   I state,
-                                   Function<I, LongStream> streamFn,
-                                   Function<I, LongStream> parStreamFn,
-                                   Function<I, Spliterator.OfLong> splitrFn,
-                                   ToIntFunction<I> sizeFn) {
-                super(name, StreamShape.LONG_VALUE, state, streamFn, parStreamFn, splitrFn, sizeFn);
-            }
-
-            @Override
-            public PrimitiveIterator.OfLong iterator() {
-                return Spliterators.iterator(spliterator());
-            }
-
-            @Override
-            public <A extends Collection<? super Long>> A into(A target) {
-                spliterator().forEachRemaining((LongConsumer) target::add);
-                return target;
-            }
-        }
-
-        static class DoubleTestData<I>
-                extends AbstractTestData<Double, DoubleStream, I, Spliterator.OfDouble>
-                implements OfDouble {
-
-            protected DoubleTestData(String name,
-                                     I state,
-                                     Function<I, DoubleStream> streamFn,
-                                     Function<I, DoubleStream> parStreamFn,
-                                     Function<I, Spliterator.OfDouble> splitrFn,
-                                     ToIntFunction<I> sizeFn) {
-                super(name, StreamShape.DOUBLE_VALUE, state, streamFn, parStreamFn, splitrFn, sizeFn);
-            }
-
-            @Override
-            public PrimitiveIterator.OfDouble iterator() {
-                return Spliterators.iterator(spliterator());
-            }
-
-            @Override
-            public <A extends Collection<? super Double>> A into(A target) {
-                spliterator().forEachRemaining((DoubleConsumer) target::add);
-                return target;
-            }
-        }
-    }
-}
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/TestFlagExpectedOp.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,125 +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 java.util.stream;
-
-import org.testng.Assert;
-
-import java.util.EnumSet;
-
-class TestFlagExpectedOp<T> extends FlagDeclaringOp<T> {
-
-    static class Builder<T> {
-        final int flags;
-        StreamShape shape = StreamShape.REFERENCE;
-
-        EnumSet<StreamOpFlag> known = EnumSet.noneOf(StreamOpFlag.class);
-        EnumSet<StreamOpFlag> preserve = EnumSet.noneOf(StreamOpFlag.class);
-        EnumSet<StreamOpFlag> notKnown = EnumSet.noneOf(StreamOpFlag.class);
-
-        Builder(int flags) {
-            this.flags = flags;
-        }
-
-        Builder<T> known(EnumSet<StreamOpFlag> known) {
-            this.known = known;
-            return this;
-        }
-
-        Builder<T> preserve(EnumSet<StreamOpFlag> preserve) {
-            this.preserve = preserve;
-            return this;
-        }
-
-        Builder<T> notKnown(EnumSet<StreamOpFlag> notKnown) {
-            this.notKnown = notKnown;
-            return this;
-        }
-
-        Builder<T> shape(StreamShape shape) {
-            this.shape = shape;
-            return this;
-        }
-
-        TestFlagExpectedOp<T> build() {
-            return new TestFlagExpectedOp<>(flags, known, preserve, notKnown, shape);
-        }
-    }
-
-    final EnumSet<StreamOpFlag> known;
-    final EnumSet<StreamOpFlag> preserve;
-    final EnumSet<StreamOpFlag> notKnown;
-    final StreamShape shape;
-
-    TestFlagExpectedOp(int flags,
-                       EnumSet<StreamOpFlag> known,
-                       EnumSet<StreamOpFlag> preserve,
-                       EnumSet<StreamOpFlag> notKnown) {
-        this(flags, known, preserve, notKnown, StreamShape.REFERENCE);
-    }
-
-    TestFlagExpectedOp(int flags,
-                       EnumSet<StreamOpFlag> known,
-                       EnumSet<StreamOpFlag> preserve,
-                       EnumSet<StreamOpFlag> notKnown,
-                       StreamShape shape) {
-        super(flags);
-        this.known = known;
-        this.preserve = preserve;
-        this.notKnown = notKnown;
-        this.shape = shape;
-    }
-
-    @Override
-    public StreamShape outputShape() {
-        return shape;
-    }
-
-    @Override
-    public StreamShape inputShape() {
-        return shape;
-    }
-
-    @Override
-    @SuppressWarnings({"rawtypes", "unchecked"})
-    public Sink<T> opWrapSink(int flags, boolean parallel, Sink upstream) {
-        assertFlags(flags);
-        return upstream;
-    }
-
-    private void assertFlags(int flags) {
-        for (StreamOpFlag f : known) {
-            Assert.assertTrue(f.isKnown(flags),
-                              String.format("Flag %s is not known, but should be known.", f.toString()));
-        }
-
-        for (StreamOpFlag f : preserve) {
-            Assert.assertTrue(f.isPreserved(flags),
-                              String.format("Flag %s is not preserved, but should be preserved.", f.toString()));
-        }
-
-        for (StreamOpFlag f : notKnown) {
-            Assert.assertFalse(f.isKnown(flags),
-                               String.format("Flag %s is known, but should be not known.", f.toString()));
-        }
-    }
-}
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/ThowableHelper.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package java.util.stream;
-
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-
-public final class ThowableHelper {
-
-    public static void checkException(Class<? extends Exception> ce, Runnable r) {
-        Exception caught = null;
-        try {
-            r.run();
-        } catch (Exception e) {
-            caught = e;
-        }
-
-        assertNotNull(caught);
-        assertTrue(ce.isInstance(caught));
-    }
-
-    public static void checkNPE(Runnable r) {
-        checkException(NullPointerException.class, r);
-    }
-
-    public static void checkISE(Runnable r) {
-        checkException(IllegalStateException.class, r);
-    }
-}
--- a/jdk/test/java/util/stream/boottest/TEST.properties	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/java/util/stream/boottest/TEST.properties	Tue Nov 17 10:29:28 2015 -0800
@@ -1,5 +1,5 @@
 # This file identifies root(s) of the test-ng hierarchy.
 
-TestNG.dirs = .
-bootclasspath.dirs = .
-lib.dirs = /java/util/stream/bootlib
+TestNG.dirs = java.base
+bootclasspath.dirs = java.base
+lib.dirs = /java/util/stream/bootlib/java.base
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/boottest/java.base/java/util/stream/DoubleNodeTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 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 java.util.stream;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.PrimitiveIterator;
+import java.util.Spliterators;
+import java.util.function.Function;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+@Test
+public class DoubleNodeTest extends OpTestCase {
+
+    @DataProvider(name = "nodes")
+    public Object[][] createSizes() {
+        List<Object[]> params = new ArrayList<>();
+
+        for (int size : Arrays.asList(0, 1, 4, 15, 16, 17, 127, 128, 129, 1000)) {
+            double[] array = new double[size];
+            for (int i = 0; i < array.length; i++) {
+                array[i] = i;
+            }
+
+            List<Node<Double>> nodes = new ArrayList<>();
+
+            nodes.add(Nodes.node(array));
+            nodes.add(degenerateTree(Spliterators.iterator(Arrays.spliterator(array))));
+            nodes.add(tree(toList(array), l -> Nodes.node(toDoubleArray(l))));
+            nodes.add(fill(array, Nodes.doubleBuilder(array.length)));
+            nodes.add(fill(array, Nodes.doubleBuilder()));
+
+            for (Node<Double> node : nodes) {
+                params.add(new Object[]{array, node});
+            }
+
+        }
+
+        return params.toArray(new Object[0][]);
+    }
+
+    private static void assertEqualsListDoubleArray(List<Double> list, double[] array) {
+        assertEquals(list.size(), array.length);
+        for (int i = 0; i < array.length; i++)
+            assertEquals(array[i], list.get(i));
+    }
+
+    private List<Double> toList(double[] a) {
+        List<Double> l = new ArrayList<>();
+        for (double i : a) {
+            l.add(i);
+        }
+
+        return l;
+    }
+
+    private double[] toDoubleArray(List<Double> l) {
+        double[] a = new double[l.size()];
+
+        int i = 0;
+        for (Double e : l) {
+            a[i++] = e;
+        }
+        return a;
+    }
+
+    private Node.OfDouble fill(double[] array, Node.Builder.OfDouble nb) {
+        nb.begin(array.length);
+        for (double i : array)
+            nb.accept(i);
+        nb.end();
+        return nb.build();
+    }
+
+    private Node.OfDouble degenerateTree(PrimitiveIterator.OfDouble it) {
+        if (!it.hasNext()) {
+            return Nodes.node(new double[0]);
+        }
+
+        double i = it.nextDouble();
+        if (it.hasNext()) {
+            return new Nodes.ConcNode.OfDouble(Nodes.node(new double[] {i}), degenerateTree(it));
+        }
+        else {
+            return Nodes.node(new double[] {i});
+        }
+    }
+
+    private Node.OfDouble tree(List<Double> l, Function<List<Double>, Node.OfDouble> m) {
+        if (l.size() < 3) {
+            return m.apply(l);
+        }
+        else {
+            return new Nodes.ConcNode.OfDouble(
+                    tree(l.subList(0, l.size() / 2), m),
+                    tree(l.subList(l.size() / 2, l.size()), m));
+        }
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testAsArray(double[] array, Node.OfDouble n) {
+        assertEquals(n.asPrimitiveArray(), array);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testFlattenAsArray(double[] array, Node.OfDouble n) {
+        assertEquals(Nodes.flattenDouble(n).asPrimitiveArray(), array);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testCopyTo(double[] array, Node.OfDouble n) {
+        double[] copy = new double[(int) n.count()];
+        n.copyInto(copy, 0);
+
+        assertEquals(copy, array);
+    }
+
+    @Test(dataProvider = "nodes", groups = { "serialization-hostile" })
+    public void testForEach(double[] array, Node.OfDouble n) {
+        List<Double> l = new ArrayList<>((int) n.count());
+        n.forEach((double e) -> {
+            l.add(e);
+        });
+
+        assertEqualsListDoubleArray(l, array);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testStreams(double[] array, Node.OfDouble n) {
+        TestData.OfDouble data = TestData.Factory.ofNode("Node", n);
+
+        exerciseOps(data, s -> s);
+
+        exerciseTerminalOps(data, s -> s.toArray());
+    }
+
+    @Test(dataProvider = "nodes", groups={ "serialization-hostile" })
+    // throws SOE on serialization of DoubleConcNode[size=1000]
+    public void testSpliterator(double[] array, Node.OfDouble n) {
+        SpliteratorTestHelper.testDoubleSpliterator(n::spliterator);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testTruncate(double[] array, Node.OfDouble n) {
+        int[] nums = new int[] { 0, 1, array.length / 2, array.length - 1, array.length };
+        for (int start : nums)
+            for (int end : nums) {
+                if (start < 0 || end < 0 || end < start || end > array.length)
+                    continue;
+                Node.OfDouble slice = n.truncate(start, end, Double[]::new);
+                double[] asArray = slice.asPrimitiveArray();
+                for (int k = start; k < end; k++)
+                    assertEquals(array[k], asArray[k - start]);
+            }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/boottest/java.base/java/util/stream/FlagOpTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,283 @@
+/*
+ * 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 java.util.stream;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.function.Supplier;
+
+import static java.util.stream.LambdaTestHelpers.countTo;
+
+@Test
+public class FlagOpTest extends OpTestCase {
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testFlagsPassThrough(String name, TestData<Integer, Stream<Integer>> data) {
+
+        @SuppressWarnings({"unchecked", "rawtypes"})
+        TestFlagPassThroughOp<Integer>[] ops = new TestFlagPassThroughOp[3];
+        ops[0] = new TestFlagPassThroughOp<>();
+        ops[1] = new TestFlagPassThroughOp<>();
+        ops[2] = new TestFlagPassThroughOp<>();
+
+        ops[0].set(null, ops[1]);
+        ops[1].set(ops[0], ops[2]);
+        ops[2].set(ops[1], null);
+
+        withData(data).ops(ops).exercise();
+    }
+
+    static class TestFlagPassThroughOp<T> extends FlagDeclaringOp<T> {
+        TestFlagPassThroughOp<T> upstream;
+        TestFlagPassThroughOp<T> downstream;
+
+        TestFlagPassThroughOp() {
+            super(0);
+        }
+
+        void set(TestFlagPassThroughOp<T> upstream, TestFlagPassThroughOp<T> downstream)  {
+            this.upstream = upstream;
+            this.downstream = downstream;
+        }
+
+        int wrapFlags;
+
+        @Override
+        @SuppressWarnings({"unchecked", "rawtypes"})
+        public Sink<T> opWrapSink(int flags, boolean parallel, Sink sink) {
+            this.wrapFlags = flags;
+
+            if (downstream != null) {
+                assertTrue(flags == downstream.wrapFlags);
+            }
+
+            return sink;
+        }
+    }
+
+    public void testFlagsClearAllSet() {
+        int clearAllFlags = 0;
+        for (StreamOpFlag f : EnumSet.allOf(StreamOpFlag.class)) {
+            if (f.isStreamFlag()) {
+                clearAllFlags |= f.clear();
+            }
+        }
+
+        EnumSet<StreamOpFlag> known = EnumSet.noneOf(StreamOpFlag.class);
+        EnumSet<StreamOpFlag> notKnown = StreamOpFlagTestHelper.allStreamFlags();
+
+        List<FlagDeclaringOp<Integer>> ops = new ArrayList<>();
+        ops.add(new FlagDeclaringOp<>(clearAllFlags));
+        for (StreamOpFlag f : StreamOpFlagTestHelper.allStreamFlags()) {
+            if (f.canSet(StreamOpFlag.Type.OP)) {
+                ops.add(new TestFlagExpectedOp<>(f.set(),
+                                             known.clone(),
+                                             EnumSet.noneOf(StreamOpFlag.class),
+                                             notKnown.clone()));
+                known.add(f);
+                notKnown.remove(f);
+            }
+        }
+        ops.add(new TestFlagExpectedOp<>(0,
+                                         known.clone(),
+                                         EnumSet.noneOf(StreamOpFlag.class),
+                                         notKnown.clone()));
+
+        TestData<Integer, Stream<Integer>> data = TestData.Factory.ofArray("Array", countTo(10).toArray(new Integer[0]));
+        @SuppressWarnings("rawtypes")
+        FlagDeclaringOp[] opsArray = ops.toArray(new FlagDeclaringOp[ops.size()]);
+
+        withData(data).ops(opsArray).
+                without(StreamTestScenario.CLEAR_SIZED_SCENARIOS).
+                exercise();
+    }
+
+    public void testFlagsSetAllClear() {
+        EnumSet<StreamOpFlag> known = StreamOpFlagTestHelper.allStreamFlags();
+        int setAllFlags = 0;
+        for (StreamOpFlag f : EnumSet.allOf(StreamOpFlag.class)) {
+            if (f.isStreamFlag()) {
+                if (f.canSet(StreamOpFlag.Type.OP)) {
+                    setAllFlags |= f.set();
+                } else {
+                    known.remove(f);
+                }
+            }
+        }
+
+        EnumSet<StreamOpFlag> notKnown = EnumSet.noneOf(StreamOpFlag.class);
+
+        List<FlagDeclaringOp<Integer>> ops = new ArrayList<>();
+        ops.add(new FlagDeclaringOp<>(setAllFlags));
+        for (StreamOpFlag f : StreamOpFlagTestHelper.allStreamFlags()) {
+            ops.add(new TestFlagExpectedOp<>(f.clear(),
+                                             known.clone(),
+                                             EnumSet.noneOf(StreamOpFlag.class),
+                                             notKnown.clone()));
+            known.remove(f);
+            notKnown.add(f);
+        }
+        ops.add(new TestFlagExpectedOp<>(0,
+                                         known.clone(),
+                                         EnumSet.noneOf(StreamOpFlag.class),
+                                         notKnown.clone()));
+
+        TestData<Integer, Stream<Integer>> data = TestData.Factory.ofArray("Array", countTo(10).toArray(new Integer[0]));
+        @SuppressWarnings("rawtypes")
+        FlagDeclaringOp[] opsArray = ops.toArray(new FlagDeclaringOp[ops.size()]);
+
+
+        withData(data).ops(opsArray).
+                without(StreamTestScenario.CLEAR_SIZED_SCENARIOS).
+                exercise();
+    }
+
+    public void testFlagsParallelCollect() {
+        testFlagsSetSequence(CollectorOps::collector);
+    }
+
+    private void testFlagsSetSequence(Supplier<StatefulTestOp<Integer>> cf) {
+        EnumSet<StreamOpFlag> known = EnumSet.of(StreamOpFlag.ORDERED, StreamOpFlag.SIZED);
+        EnumSet<StreamOpFlag> preserve = EnumSet.of(StreamOpFlag.DISTINCT, StreamOpFlag.SORTED);
+
+        List<IntermediateTestOp<Integer, Integer>> ops = new ArrayList<>();
+        for (StreamOpFlag f : EnumSet.of(StreamOpFlag.DISTINCT, StreamOpFlag.SORTED)) {
+            ops.add(cf.get());
+            ops.add(new TestFlagExpectedOp<>(f.set(),
+                                             known.clone(),
+                                             preserve.clone(),
+                                             EnumSet.noneOf(StreamOpFlag.class)));
+            known.add(f);
+            preserve.remove(f);
+        }
+        ops.add(cf.get());
+        ops.add(new TestFlagExpectedOp<>(0,
+                                         known.clone(),
+                                         preserve.clone(),
+                                         EnumSet.noneOf(StreamOpFlag.class)));
+
+        TestData<Integer, Stream<Integer>> data = TestData.Factory.ofArray("Array", countTo(10).toArray(new Integer[0]));
+        @SuppressWarnings("rawtypes")
+        IntermediateTestOp[] opsArray = ops.toArray(new IntermediateTestOp[ops.size()]);
+
+        withData(data).ops(opsArray).
+                without(StreamTestScenario.CLEAR_SIZED_SCENARIOS).
+                exercise();
+    }
+
+
+    public void testFlagsClearParallelCollect() {
+        testFlagsClearSequence(CollectorOps::collector);
+    }
+
+    protected void testFlagsClearSequence(Supplier<StatefulTestOp<Integer>> cf) {
+        EnumSet<StreamOpFlag> known = EnumSet.of(StreamOpFlag.ORDERED, StreamOpFlag.SIZED);
+        EnumSet<StreamOpFlag> preserve = EnumSet.of(StreamOpFlag.DISTINCT, StreamOpFlag.SORTED);
+        EnumSet<StreamOpFlag> notKnown = EnumSet.noneOf(StreamOpFlag.class);
+
+        List<IntermediateTestOp<Integer, Integer>> ops = new ArrayList<>();
+        for (StreamOpFlag f : EnumSet.of(StreamOpFlag.ORDERED, StreamOpFlag.DISTINCT, StreamOpFlag.SORTED)) {
+            ops.add(cf.get());
+            ops.add(new TestFlagExpectedOp<>(f.clear(),
+                                             known.clone(),
+                                             preserve.clone(),
+                                             notKnown.clone()));
+            known.remove(f);
+            preserve.remove(f);
+            notKnown.add(f);
+        }
+        ops.add(cf.get());
+        ops.add(new TestFlagExpectedOp<>(0,
+                                         known.clone(),
+                                         preserve.clone(),
+                                         notKnown.clone()));
+
+        TestData<Integer, Stream<Integer>> data = TestData.Factory.ofArray("Array", countTo(10).toArray(new Integer[0]));
+        @SuppressWarnings("rawtypes")
+        IntermediateTestOp[] opsArray = ops.toArray(new IntermediateTestOp[ops.size()]);
+
+        withData(data).ops(opsArray).
+                without(StreamTestScenario.CLEAR_SIZED_SCENARIOS).
+                exercise();
+    }
+
+    public void testFlagsSizedOrderedParallelCollect() {
+        EnumSet<StreamOpFlag> parKnown = EnumSet.of(StreamOpFlag.SIZED);
+        EnumSet<StreamOpFlag> serKnown = parKnown.clone();
+
+        List<IntermediateTestOp<Integer, Integer>> ops = new ArrayList<>();
+        for (StreamOpFlag f : parKnown) {
+            ops.add(CollectorOps.collector());
+            ops.add(new ParSerTestFlagExpectedOp<>(f.clear(),
+                                             parKnown,
+                                             serKnown));
+            serKnown.remove(f);
+        }
+        ops.add(CollectorOps.collector());
+        ops.add(new ParSerTestFlagExpectedOp<>(0,
+                                         parKnown,
+                                         EnumSet.noneOf(StreamOpFlag.class)));
+
+        TestData<Integer, Stream<Integer>> data = TestData.Factory.ofArray("Array", countTo(10).toArray(new Integer[0]));
+        @SuppressWarnings("rawtypes")
+        IntermediateTestOp[] opsArray = ops.toArray(new IntermediateTestOp[ops.size()]);
+
+        withData(data).ops(opsArray).exercise();
+    }
+
+    static class ParSerTestFlagExpectedOp<T> extends FlagDeclaringOp<T> {
+        final EnumSet<StreamOpFlag> parKnown;
+        final EnumSet<StreamOpFlag> serKnown;
+
+        ParSerTestFlagExpectedOp(int flags, EnumSet<StreamOpFlag> known, EnumSet<StreamOpFlag> serKnown) {
+            super(flags);
+            this.parKnown = known;
+            this.serKnown = serKnown;
+        }
+
+        @Override
+        @SuppressWarnings({"unchecked", "rawtypes"})
+        public Sink<T> opWrapSink(int flags, boolean parallel, Sink upstream) {
+            assertFlags(flags, parallel);
+            return upstream;
+        }
+
+        protected void assertFlags(int flags, boolean parallel) {
+            if (parallel) {
+                for (StreamOpFlag f : parKnown) {
+                    Assert.assertTrue(f.isKnown(flags), String.format("Flag %s is not known, but should be known.", f.toString()));
+                }
+
+            } else {
+                for (StreamOpFlag f : serKnown) {
+                    Assert.assertTrue(f.isKnown(flags), String.format("Flag %s is not known, but should be known.", f.toString()));
+                }
+
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/boottest/java.base/java/util/stream/IntNodeTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,177 @@
+/*
+ * 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 java.util.stream;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.PrimitiveIterator;
+import java.util.Spliterators;
+import java.util.function.Function;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+@Test
+public class IntNodeTest extends OpTestCase {
+
+    @DataProvider(name = "nodes")
+    public Object[][] createSizes() {
+        List<Object[]> params = new ArrayList<>();
+
+        for (int size : Arrays.asList(0, 1, 4, 15, 16, 17, 127, 128, 129, 1000)) {
+            int[] array = new int[size];
+            for (int i = 0; i < array.length; i++) {
+                array[i] = i;
+            }
+
+            List<Node<Integer>> nodes = new ArrayList<>();
+
+            nodes.add(Nodes.node(array));
+            nodes.add(degenerateTree(Spliterators.iterator(Arrays.spliterator(array))));
+            nodes.add(tree(toList(array), l -> Nodes.node(toIntArray(l))));
+            nodes.add(fill(array, Nodes.intBuilder(array.length)));
+            nodes.add(fill(array, Nodes.intBuilder()));
+
+            for (Node<Integer> node : nodes) {
+                params.add(new Object[]{array, node});
+            }
+
+        }
+
+        return params.toArray(new Object[0][]);
+    }
+
+    private static void assertEqualsListIntArray(List<Integer> list, int[] array) {
+        assertEquals(list.size(), array.length);
+        for (int i = 0; i < array.length; i++)
+            assertEquals(array[i], (int) list.get(i));
+    }
+
+    private List<Integer> toList(int[] a) {
+        List<Integer> l = new ArrayList<>();
+        for (int i : a) {
+            l.add(i);
+        }
+
+        return l;
+    }
+
+    private int[] toIntArray(List<Integer> l) {
+        int[] a = new int[l.size()];
+
+        int i = 0;
+        for (Integer e : l) {
+            a[i++] = e;
+        }
+        return a;
+    }
+
+    private Node.OfInt fill(int[] array, Node.Builder.OfInt nb) {
+        nb.begin(array.length);
+        for (int i : array)
+            nb.accept(i);
+        nb.end();
+        return nb.build();
+    }
+
+    private Node.OfInt degenerateTree(PrimitiveIterator.OfInt it) {
+        if (!it.hasNext()) {
+            return Nodes.node(new int[0]);
+        }
+
+        int i = it.nextInt();
+        if (it.hasNext()) {
+            return new Nodes.ConcNode.OfInt(Nodes.node(new int[] {i}), degenerateTree(it));
+        }
+        else {
+            return Nodes.node(new int[] {i});
+        }
+    }
+
+    private Node.OfInt tree(List<Integer> l, Function<List<Integer>, Node.OfInt> m) {
+        if (l.size() < 3) {
+            return m.apply(l);
+        }
+        else {
+            return new Nodes.ConcNode.OfInt(
+                    tree(l.subList(0, l.size() / 2), m),
+                    tree(l.subList(l.size() / 2, l.size()), m));
+        }
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testAsArray(int[] array, Node.OfInt n) {
+        assertEquals(n.asPrimitiveArray(), array);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testFlattenAsArray(int[] array, Node.OfInt n) {
+        assertEquals(Nodes.flattenInt(n).asPrimitiveArray(), array);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testCopyTo(int[] array, Node.OfInt n) {
+        int[] copy = new int[(int) n.count()];
+        n.copyInto(copy, 0);
+
+        assertEquals(copy, array);
+    }
+
+    @Test(dataProvider = "nodes", groups = { "serialization-hostile" })
+    public void testForEach(int[] array, Node.OfInt n) {
+        List<Integer> l = new ArrayList<>((int) n.count());
+        n.forEach((int e) -> {
+            l.add(e);
+        });
+
+        assertEqualsListIntArray(l, array);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testStreams(int[] array, Node.OfInt n) {
+        TestData.OfInt data = TestData.Factory.ofNode("Node", n);
+
+        exerciseOps(data, s -> s);
+        exerciseTerminalOps(data, s -> s.toArray());
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testSpliterator(int[] array, Node.OfInt n) {
+        SpliteratorTestHelper.testIntSpliterator(n::spliterator);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testTruncate(int[] array, Node.OfInt n) {
+        int[] nums = new int[] { 0, 1, array.length / 2, array.length - 1, array.length };
+        for (int start : nums)
+            for (int end : nums) {
+                if (start < 0 || end < 0 || end < start || end > array.length)
+                    continue;
+                Node.OfInt slice = n.truncate(start, end, Integer[]::new);
+                int[] asArray = slice.asPrimitiveArray();
+                for (int k = start; k < end; k++)
+                    assertEquals(array[k], asArray[k - start]);
+            }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/boottest/java.base/java/util/stream/LongNodeTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 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 java.util.stream;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.PrimitiveIterator;
+import java.util.Spliterators;
+import java.util.function.Function;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+@Test
+public class LongNodeTest extends OpTestCase {
+
+    @DataProvider(name = "nodes")
+    public Object[][] createSizes() {
+        List<Object[]> params = new ArrayList<>();
+
+        for (int size : Arrays.asList(0, 1, 4, 15, 16, 17, 127, 128, 129, 1000)) {
+            long[] array = new long[size];
+            for (int i = 0; i < array.length; i++) {
+                array[i] = i;
+            }
+
+            List<Node<Long>> nodes = new ArrayList<>();
+
+            nodes.add(Nodes.node(array));
+            nodes.add(degenerateTree(Spliterators.iterator(Arrays.spliterator(array))));
+            nodes.add(tree(toList(array), l -> Nodes.node(toLongArray(l))));
+            nodes.add(fill(array, Nodes.longBuilder(array.length)));
+            nodes.add(fill(array, Nodes.longBuilder()));
+
+            for (Node<Long> node : nodes) {
+                params.add(new Object[]{array, node});
+            }
+
+        }
+
+        return params.toArray(new Object[0][]);
+    }
+
+    private static void assertEqualsListLongArray(List<Long> list, long[] array) {
+        assertEquals(list.size(), array.length);
+        for (int i = 0; i < array.length; i++)
+            assertEquals(array[i], (long) list.get(i));
+    }
+
+    private List<Long> toList(long[] a) {
+        List<Long> l = new ArrayList<>();
+        for (long i : a) {
+            l.add(i);
+        }
+
+        return l;
+    }
+
+    private long[] toLongArray(List<Long> l) {
+        long[] a = new long[l.size()];
+
+        int i = 0;
+        for (Long e : l) {
+            a[i++] = e;
+        }
+        return a;
+    }
+
+    private Node.OfLong fill(long[] array, Node.Builder.OfLong nb) {
+        nb.begin(array.length);
+        for (long i : array)
+            nb.accept(i);
+        nb.end();
+        return nb.build();
+    }
+
+    private Node.OfLong degenerateTree(PrimitiveIterator.OfLong it) {
+        if (!it.hasNext()) {
+            return Nodes.node(new long[0]);
+        }
+
+        long i = it.nextLong();
+        if (it.hasNext()) {
+            return new Nodes.ConcNode.OfLong(Nodes.node(new long[] {i}), degenerateTree(it));
+        }
+        else {
+            return Nodes.node(new long[] {i});
+        }
+    }
+
+    private Node.OfLong tree(List<Long> l, Function<List<Long>, Node.OfLong> m) {
+        if (l.size() < 3) {
+            return m.apply(l);
+        }
+        else {
+            return new Nodes.ConcNode.OfLong(
+                    tree(l.subList(0, l.size() / 2), m),
+                    tree(l.subList(l.size() / 2, l.size()), m));
+        }
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testAsArray(long[] array, Node.OfLong n) {
+        assertEquals(n.asPrimitiveArray(), array);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testFlattenAsArray(long[] array, Node.OfLong n) {
+        assertEquals(Nodes.flattenLong(n).asPrimitiveArray(), array);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testCopyTo(long[] array, Node.OfLong n) {
+        long[] copy = new long[(int) n.count()];
+        n.copyInto(copy, 0);
+
+        assertEquals(copy, array);
+    }
+
+    @Test(dataProvider = "nodes", groups = { "serialization-hostile" })
+    public void testForEach(long[] array, Node.OfLong n) {
+        List<Long> l = new ArrayList<>((int) n.count());
+        n.forEach((long e) -> {
+            l.add(e);
+        });
+
+        assertEqualsListLongArray(l, array);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testStreams(long[] array, Node.OfLong n) {
+        TestData.OfLong data = TestData.Factory.ofNode("Node", n);
+
+        exerciseOps(data, s -> s);
+
+        exerciseTerminalOps(data, s -> s.toArray());
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testSpliterator(long[] array, Node.OfLong n) {
+        SpliteratorTestHelper.testLongSpliterator(n::spliterator);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testTruncate(long[] array, Node.OfLong n) {
+        int[] nums = new int[] { 0, 1, array.length / 2, array.length - 1, array.length };
+        for (int start : nums)
+            for (int end : nums) {
+                if (start < 0 || end < 0 || end < start || end > array.length)
+                    continue;
+                Node.OfLong slice = n.truncate(start, end, Long[]::new);
+                long[] asArray = slice.asPrimitiveArray();
+                for (int k = start; k < end; k++)
+                    assertEquals(array[k], asArray[k - start]);
+            }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/boottest/java.base/java/util/stream/NodeBuilderTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,236 @@
+/*
+ * 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 java.util.stream;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.DoubleConsumer;
+import java.util.function.Function;
+import java.util.function.IntConsumer;
+import java.util.function.LongConsumer;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static java.util.stream.LambdaTestHelpers.assertContents;
+import static java.util.stream.LambdaTestHelpers.countTo;
+import static org.testng.Assert.assertEquals;
+
+@Test
+public class NodeBuilderTest {
+
+    List<Integer> sizes = Arrays.asList(0, 1, 4, 16, 256,
+                                        1023, 1024, 1025,
+                                        2047, 2048, 2049,
+                                        1024 * 32 - 1, 1024 * 32, 1024 * 32 + 1);
+
+    @DataProvider(name = "Node.Builder")
+    public Object[][] createNodeBuilders() {
+        List<List<Integer>> ls = new ArrayList<>();
+        for (int size : sizes) {
+            ls.add(countTo(size));
+        }
+
+        List<Function<Integer, Node.Builder<Integer>>> ms = Arrays.asList(
+                s -> Nodes.builder(),
+                s -> Nodes.builder(s, LambdaTestHelpers.integerArrayGenerator)
+        );
+
+        Object[][] params = new Object[ls.size() * ms.size()][];
+        int i = 0;
+        for (List<Integer> l : ls) {
+            for (Function<Integer, Node.Builder<Integer>> m : ms) {
+                params[i++] = new Object[]{l, m};
+            }
+        }
+
+        return params;
+    }
+
+    @Test(dataProvider = "Node.Builder", groups = { "serialization-hostile" })
+    public void testIteration(List<Integer> l, Function<Integer, Node.Builder<Integer>> m) {
+        Node.Builder<Integer> nb = m.apply(l.size());
+        nb.begin(l.size());
+        for (Integer i : l) {
+            nb.accept(i);
+        }
+        nb.end();
+
+        Node<Integer> n = nb.build();
+        assertEquals(n.count(), l.size());
+
+        {
+            List<Integer> _l = new ArrayList<>();
+            n.forEach(_l::add);
+
+            assertContents(_l, l);
+        }
+    }
+
+    // Node.Builder.OfInt
+
+    @DataProvider(name = "Node.Builder<Integer>")
+    public Object[][] createIntNodeBuilders() {
+        List<List<Integer>> ls = new ArrayList<>();
+        for (int size : sizes) {
+            ls.add(countTo(size));
+        }
+
+        List<Function<Integer, Node.Builder<Integer>>> ms = Arrays.asList(
+                s -> Nodes.intBuilder(),
+                s -> Nodes.intBuilder(s)
+        );
+
+        Object[][] params = new Object[ls.size() * ms.size()][];
+        int i = 0;
+        for (List<Integer> l : ls) {
+            for (Function<Integer, Node.Builder<Integer>> m : ms) {
+                params[i++] = new Object[]{l, m};
+            }
+        }
+
+        return params;
+    }
+
+    @Test(dataProvider = "Node.Builder<Integer>", groups = { "serialization-hostile" })
+    public void testIntIteration(List<Integer> l, Function<Integer, Node.Builder.OfInt> m) {
+        Node.Builder.OfInt nb = m.apply(l.size());
+        nb.begin(l.size());
+        for (Integer i : l) {
+            nb.accept((int) i);
+        }
+        nb.end();
+
+        Node.OfInt n = nb.build();
+        assertEquals(n.count(), l.size());
+
+        {
+            List<Integer> _l = new ArrayList<>();
+            n.forEach((IntConsumer) _l::add);
+
+            assertContents(_l, l);
+        }
+
+    }
+
+    // Node.Builder.OfLong
+
+    @DataProvider(name = "Node.Builder<Long>")
+    public Object[][] createLongNodeBuilders() {
+        List<List<Long>> ls = new ArrayList<>();
+        for (int size : sizes) {
+            List<Long> l = new ArrayList<>();
+            for (long i = 0; i < size; i++) {
+                l.add(i);
+            }
+            ls.add(l);
+        }
+
+        List<Function<Integer, Node.Builder<Long>>> ms = Arrays.asList(
+                s -> Nodes.longBuilder(),
+                s -> Nodes.longBuilder(s)
+        );
+
+        Object[][] params = new Object[ls.size() * ms.size()][];
+        int i = 0;
+        for (List<Long> l : ls) {
+            for (Function<Integer, Node.Builder<Long>> m : ms) {
+                params[i++] = new Object[]{l, m};
+            }
+        }
+
+        return params;
+    }
+
+    @Test(dataProvider = "Node.Builder<Long>")
+    public void testLongIteration(List<Long> l, Function<Integer, Node.Builder.OfLong> m) {
+        Node.Builder.OfLong nb = m.apply(l.size());
+        nb.begin(l.size());
+        for (Long i : l) {
+            nb.accept((long) i);
+        }
+        nb.end();
+
+        Node.OfLong n = nb.build();
+        assertEquals(n.count(), l.size());
+
+        {
+            List<Long> _l = new ArrayList<>();
+            n.forEach((LongConsumer) _l::add);
+
+            assertContents(_l, l);
+        }
+
+    }
+
+    // Node.Builder.OfDouble
+
+    @DataProvider(name = "Node.Builder<Double>")
+    public Object[][] createDoubleNodeBuilders() {
+        List<List<Double>> ls = new ArrayList<>();
+        for (int size : sizes) {
+            List<Double> l = new ArrayList<>();
+            for (long i = 0; i < size; i++) {
+                l.add((double) i);
+            }
+            ls.add(l);
+        }
+
+        List<Function<Integer, Node.Builder<Double>>> ms = Arrays.asList(
+                s -> Nodes.doubleBuilder(),
+                s -> Nodes.doubleBuilder(s)
+        );
+
+        Object[][] params = new Object[ls.size() * ms.size()][];
+        int i = 0;
+        for (List<Double> l : ls) {
+            for (Function<Integer, Node.Builder<Double>> m : ms) {
+                params[i++] = new Object[]{l, m};
+            }
+        }
+
+        return params;
+    }
+
+    @Test(dataProvider = "Node.Builder<Double>")
+    public void testDoubleIteration(List<Double> l, Function<Integer, Node.Builder.OfDouble> m) {
+        Node.Builder.OfDouble nb = m.apply(l.size());
+        nb.begin(l.size());
+        for (Double i : l) {
+            nb.accept((double) i);
+        }
+        nb.end();
+
+        Node.OfDouble n = nb.build();
+        assertEquals(n.count(), l.size());
+
+        {
+            List<Double> _l = new ArrayList<>();
+            n.forEach((DoubleConsumer) _l::add);
+
+            assertContents(_l, l);
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/boottest/java.base/java/util/stream/NodeTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,154 @@
+/*
+ * 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 java.util.stream;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.function.Function;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+@Test
+public class NodeTest extends OpTestCase {
+
+    @DataProvider(name = "nodes")
+    public Object[][] createSizes() {
+        List<Object[]> params = new ArrayList<>();
+
+        for (int size : Arrays.asList(0, 1, 4, 15, 16, 17, 127, 128, 129, 1000)) {
+            Integer[] array = new Integer[size];
+            for (int i = 0; i < array.length; i++) {
+                array[i] = i;
+            }
+
+            List<Node<Integer>> nodes = new ArrayList<>();
+            nodes.add(Nodes.node(array));
+            nodes.add(Nodes.node(Arrays.asList(array)));
+            nodes.add(degenerateTree(Arrays.asList(array).iterator()));
+            nodes.add(tree(Arrays.asList(array), l -> Nodes.node(l.toArray(new Integer[l.size()]))));
+            nodes.add(tree(Arrays.asList(array), l -> Nodes.node(l)));
+            nodes.add(fill(array, Nodes.builder(array.length, LambdaTestHelpers.integerArrayGenerator)));
+            nodes.add(fill(array, Nodes.builder()));
+
+            for (int i = 0; i < nodes.size(); i++) {
+                params.add(new Object[]{array, nodes.get(i)});
+            }
+
+        }
+
+        return params.toArray(new Object[0][]);
+    }
+
+    Node<Integer> fill(Integer[] array, Node.Builder<Integer> nb) {
+        nb.begin(array.length);
+        for (Integer i : array) {
+            nb.accept(i);
+        }
+        nb.end();
+        return nb.build();
+    }
+
+    Node<Integer> degenerateTree(Iterator<Integer> it) {
+        if (!it.hasNext()) {
+            return Nodes.node(Collections.emptyList());
+        }
+
+        Integer i = it.next();
+        if (it.hasNext()) {
+            return new Nodes.ConcNode<Integer>(Nodes.node(new Integer[] {i}), degenerateTree(it));
+        }
+        else {
+            return Nodes.node(new Integer[]{i});
+        }
+    }
+
+    Node<Integer> tree(List<Integer> l, Function<List<Integer>, Node<Integer>> m) {
+        if (l.size() < 3) {
+            return m.apply(l);
+        }
+        else {
+            return new Nodes.ConcNode<>(
+                    tree(l.subList(0, l.size() / 2), m),
+                    tree(l.subList(l.size() / 2, l.size()), m ));
+        }
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testAsArray(Integer[] array, Node<Integer> n) {
+        assertEquals(n.asArray(LambdaTestHelpers.integerArrayGenerator), array);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testFlattenAsArray(Integer[] array, Node<Integer> n) {
+        assertEquals(Nodes.flatten(n, LambdaTestHelpers.integerArrayGenerator)
+                          .asArray(LambdaTestHelpers.integerArrayGenerator), array);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testCopyTo(Integer[] array, Node<Integer> n) {
+        Integer[] copy = new Integer[(int) n.count()];
+        n.copyInto(copy, 0);
+
+        assertEquals(copy, array);
+    }
+
+    @Test(dataProvider = "nodes", groups = { "serialization-hostile" })
+    public void testForEach(Integer[] array, Node<Integer> n) {
+        List<Integer> l = new ArrayList<>((int) n.count());
+        n.forEach(e -> l.add(e));
+
+        assertEquals(l.toArray(), array);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testStreams(Integer[] array, Node<Integer> n) {
+        TestData<Integer, Stream<Integer>> data = TestData.Factory.ofRefNode("Node", n);
+
+        exerciseOps(data, s -> s);
+
+        exerciseTerminalOps(data, s -> s.toArray());
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testSpliterator(Integer[] array, Node<Integer> n) {
+        SpliteratorTestHelper.testSpliterator(n::spliterator);
+    }
+
+    @Test(dataProvider = "nodes")
+    public void testTruncate(Integer[] array, Node<Integer> n) {
+        int[] nums = new int[] { 0, 1, array.length / 2, array.length - 1, array.length };
+        for (int start : nums)
+            for (int end : nums) {
+                if (start < 0 || end < 0 || end < start || end > array.length)
+                    continue;
+                Node<Integer> slice = n.truncate(start, end, Integer[]::new);
+                Integer[] asArray = slice.asArray(Integer[]::new);
+                for (int k = start; k < end; k++)
+                    assertEquals(array[k], asArray[k - start]);
+            }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/boottest/java.base/java/util/stream/SliceSpliteratorTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 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 java.util.stream;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Spliterator;
+
+import static java.util.stream.Collectors.toList;
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @bug 8012987
+ */
+@Test
+public class SliceSpliteratorTest extends LoggingTestCase {
+
+    static class UnorderedContentAsserter<T> implements SpliteratorTestHelper.ContentAsserter<T> {
+        Collection<T> source;
+
+        UnorderedContentAsserter(Collection<T> source) {
+            this.source = source;
+        }
+
+        @Override
+        public void assertContents(Collection<T> actual, Collection<T> expected, boolean isOrdered) {
+            if (isOrdered) {
+                assertEquals(actual, expected);
+            }
+            else {
+                assertEquals(actual.size(), expected.size());
+                assertTrue(source.containsAll(actual));
+            }
+        }
+    }
+
+    interface SliceTester {
+        void test(int size, int skip, int limit);
+    }
+
+    @DataProvider(name = "sliceSpliteratorDataProvider")
+    public static Object[][] sliceSpliteratorDataProvider() {
+        List<Object[]> data = new ArrayList<>();
+
+        // SIZED/SUBSIZED slice spliterator
+
+        {
+            SliceTester r = (size, skip, limit) -> {
+                final Collection<Integer> source =  IntStream.range(0, size).boxed().collect(toList());
+
+                SpliteratorTestHelper.testSpliterator(() -> {
+                    Spliterator<Integer> s = Arrays.spliterator(source.stream().toArray(Integer[]::new));
+
+                    return new StreamSpliterators.SliceSpliterator.OfRef<>(s, skip, limit);
+                });
+            };
+            data.add(new Object[]{"StreamSpliterators.SliceSpliterator.OfRef", r});
+        }
+
+        {
+            SliceTester r = (size, skip, limit) -> {
+                final Collection<Integer> source =  IntStream.range(0, size).boxed().collect(toList());
+
+                SpliteratorTestHelper.testIntSpliterator(() -> {
+                    Spliterator.OfInt s = Arrays.spliterator(source.stream().mapToInt(i->i).toArray());
+
+                    return new StreamSpliterators.SliceSpliterator.OfInt(s, skip, limit);
+                });
+            };
+            data.add(new Object[]{"StreamSpliterators.SliceSpliterator.OfInt", r});
+        }
+
+        {
+            SliceTester r = (size, skip, limit) -> {
+                final Collection<Long> source =  LongStream.range(0, size).boxed().collect(toList());
+
+                SpliteratorTestHelper.testLongSpliterator(() -> {
+                    Spliterator.OfLong s = Arrays.spliterator(source.stream().mapToLong(i->i).toArray());
+
+                    return new StreamSpliterators.SliceSpliterator.OfLong(s, skip, limit);
+                });
+            };
+            data.add(new Object[]{"StreamSpliterators.SliceSpliterator.OfLong", r});
+        }
+
+        {
+            SliceTester r = (size, skip, limit) -> {
+                final Collection<Double> source =  LongStream.range(0, size).asDoubleStream().boxed().collect(toList());
+
+                SpliteratorTestHelper.testDoubleSpliterator(() -> {
+                    Spliterator.OfDouble s = Arrays.spliterator(source.stream().mapToDouble(i->i).toArray());
+
+                    return new StreamSpliterators.SliceSpliterator.OfDouble(s, skip, limit);
+                });
+            };
+            data.add(new Object[]{"StreamSpliterators.SliceSpliterator.OfLong", r});
+        }
+
+
+        // Unordered slice spliterator
+
+        {
+            SliceTester r = (size, skip, limit) -> {
+                final Collection<Integer> source =  IntStream.range(0, size).boxed().collect(toList());
+                final UnorderedContentAsserter<Integer> uca = new UnorderedContentAsserter<>(source);
+
+                SpliteratorTestHelper.testSpliterator(() -> {
+                    Spliterator<Integer> s = Arrays.spliterator(source.stream().toArray(Integer[]::new));
+
+                    return new StreamSpliterators.UnorderedSliceSpliterator.OfRef<>(s, skip, limit);
+                }, uca);
+            };
+            data.add(new Object[]{"StreamSpliterators.UnorderedSliceSpliterator.OfRef", r});
+        }
+
+        {
+            SliceTester r = (size, skip, limit) -> {
+                final Collection<Integer> source =  IntStream.range(0, size).boxed().collect(toList());
+                final UnorderedContentAsserter<Integer> uca = new UnorderedContentAsserter<>(source);
+
+                SpliteratorTestHelper.testIntSpliterator(() -> {
+                    Spliterator.OfInt s = Arrays.spliterator(source.stream().mapToInt(i->i).toArray());
+
+                    return new StreamSpliterators.UnorderedSliceSpliterator.OfInt(s, skip, limit);
+                }, uca);
+            };
+            data.add(new Object[]{"StreamSpliterators.UnorderedSliceSpliterator.OfInt", r});
+        }
+
+        {
+            SliceTester r = (size, skip, limit) -> {
+                final Collection<Long> source =  LongStream.range(0, size).boxed().collect(toList());
+                final UnorderedContentAsserter<Long> uca = new UnorderedContentAsserter<>(source);
+
+                SpliteratorTestHelper.testLongSpliterator(() -> {
+                    Spliterator.OfLong s = Arrays.spliterator(source.stream().mapToLong(i->i).toArray());
+
+                    return new StreamSpliterators.UnorderedSliceSpliterator.OfLong(s, skip, limit);
+                }, uca);
+            };
+            data.add(new Object[]{"StreamSpliterators.UnorderedSliceSpliterator.OfLong", r});
+        }
+
+        {
+            SliceTester r = (size, skip, limit) -> {
+                final Collection<Double> source =  LongStream.range(0, size).asDoubleStream().boxed().collect(toList());
+                final UnorderedContentAsserter<Double> uca = new UnorderedContentAsserter<>(source);
+
+                SpliteratorTestHelper.testDoubleSpliterator(() -> {
+                    Spliterator.OfDouble s = Arrays.spliterator(LongStream.range(0, SIZE).asDoubleStream().toArray());
+
+                    return new StreamSpliterators.UnorderedSliceSpliterator.OfDouble(s, skip, limit);
+                }, uca);
+            };
+            data.add(new Object[]{"StreamSpliterators.UnorderedSliceSpliterator.OfLong", r});
+        }
+
+        return data.toArray(new Object[0][]);
+    }
+
+    static final int SIZE = 256;
+
+    static final int STEP = 32;
+
+    @Test(dataProvider = "sliceSpliteratorDataProvider")
+    public void testSliceSpliterator(String description, SliceTester r) {
+        setContext("size", SIZE);
+        for (int skip = 0; skip < SIZE; skip += STEP) {
+            setContext("skip", skip);
+            for (int limit = 0; limit < SIZE; limit += STEP) {
+                setContext("limit", skip);
+                r.test(SIZE, skip, limit);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/boottest/java.base/java/util/stream/SpinedBufferTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,370 @@
+/*
+ * 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 java.util.stream;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.*;
+import java.util.function.DoubleConsumer;
+import java.util.function.IntConsumer;
+import java.util.function.LongConsumer;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+
+@Test
+public class SpinedBufferTest {
+
+    // Create sizes around the boundary of spines
+    static List<Integer> sizes;
+    static {
+        try {
+            sizes = IntStream.range(0, 15)
+                             .map(i -> 1 << i)
+                             .flatMap(i -> Arrays.stream(new int[] { i-2, i-1, i, i+1, i+2 }))
+                             .filter(i -> i >= 0)
+                             .boxed()
+                             .distinct()
+                             .collect(Collectors.toList());
+        }
+        catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private static final int TEST_SIZE = 5000;
+
+    // SpinedBuffer
+
+    @DataProvider(name = "SpinedBuffer")
+    public Object[][] createSpinedBuffer() {
+        List<Object[]> params = new ArrayList<>();
+
+        for (int size : sizes) {
+            int[] array = IntStream.range(0, size).toArray();
+
+            SpinedBuffer<Integer> sb = new SpinedBuffer<>();
+            Arrays.stream(array).boxed().forEach(sb);
+            params.add(new Object[]{array, sb});
+
+            sb = new SpinedBuffer<>(size / 2);
+            Arrays.stream(array).boxed().forEach(sb);
+            params.add(new Object[]{array, sb});
+
+            sb = new SpinedBuffer<>(size);
+            Arrays.stream(array).boxed().forEach(sb);
+            params.add(new Object[]{array, sb});
+
+            sb = new SpinedBuffer<>(size * 2);
+            Arrays.stream(array).boxed().forEach(sb);
+            params.add(new Object[]{array, sb});
+        }
+
+        return params.toArray(new Object[0][]);
+    }
+
+    @Test(dataProvider = "SpinedBuffer")
+    public void testSpliterator(int[] array, SpinedBuffer<Integer> sb) {
+        assertEquals(sb.count(), array.length);
+        assertEquals(sb.count(), sb.spliterator().getExactSizeIfKnown());
+
+        SpliteratorTestHelper.testSpliterator(sb::spliterator);
+    }
+
+    @Test(dataProvider = "SpinedBuffer", groups = { "serialization-hostile" })
+    public void testLastSplit(int[] array, SpinedBuffer<Integer> sb) {
+        Spliterator<Integer> spliterator = sb.spliterator();
+        Spliterator<Integer> split = spliterator.trySplit();
+        long splitSizes = (split == null) ? 0 : split.getExactSizeIfKnown();
+        long lastSplitSize = spliterator.getExactSizeIfKnown();
+        splitSizes += lastSplitSize;
+
+        assertEquals(splitSizes, array.length);
+
+        List<Integer> contentOfLastSplit = new ArrayList<>();
+        spliterator.forEachRemaining(contentOfLastSplit::add);
+
+        assertEquals(contentOfLastSplit.size(), lastSplitSize);
+
+        List<Integer> end = Arrays.stream(array)
+                .boxed()
+                .skip(array.length - lastSplitSize)
+                .collect(Collectors.toList());
+        assertEquals(contentOfLastSplit, end);
+    }
+
+    @Test(groups = { "serialization-hostile" })
+    public void testSpinedBuffer() {
+        List<Integer> list1 = new ArrayList<>();
+        List<Integer> list2 = new ArrayList<>();
+        SpinedBuffer<Integer> sb = new SpinedBuffer<>();
+        for (int i = 0; i < TEST_SIZE; i++) {
+            list1.add(i);
+            sb.accept(i);
+        }
+        Iterator<Integer> it = sb.iterator();
+        for (int i = 0; i < TEST_SIZE; i++)
+            list2.add(it.next());
+        assertFalse(it.hasNext());
+        assertEquals(list1, list2);
+
+        for (int i = 0; i < TEST_SIZE; i++)
+            assertEquals(sb.get(i), (Integer) i, Integer.toString(i));
+
+        list2.clear();
+        sb.forEach(list2::add);
+        assertEquals(list1, list2);
+        Integer[] array = sb.asArray(LambdaTestHelpers.integerArrayGenerator);
+        list2.clear();
+        for (Integer i : array)
+            list2.add(i);
+        assertEquals(list1, list2);
+    }
+
+    // IntSpinedBuffer
+
+    @DataProvider(name = "IntSpinedBuffer")
+    public Object[][] createIntSpinedBuffer() {
+        List<Object[]> params = new ArrayList<>();
+
+        for (int size : sizes) {
+            int[] array = IntStream.range(0, size).toArray();
+            SpinedBuffer.OfInt sb = new SpinedBuffer.OfInt();
+            Arrays.stream(array).forEach(sb);
+
+            params.add(new Object[]{array, sb});
+        }
+
+        return params.toArray(new Object[0][]);
+    }
+
+    @Test(dataProvider = "IntSpinedBuffer")
+    public void testIntSpliterator(int[] array, SpinedBuffer.OfInt sb) {
+        assertEquals(sb.count(), array.length);
+        assertEquals(sb.count(), sb.spliterator().getExactSizeIfKnown());
+
+        SpliteratorTestHelper.testIntSpliterator(sb::spliterator);
+    }
+
+    @Test(dataProvider = "IntSpinedBuffer", groups = { "serialization-hostile" })
+    public void testIntLastSplit(int[] array, SpinedBuffer.OfInt sb) {
+        Spliterator.OfInt spliterator = sb.spliterator();
+        Spliterator.OfInt split = spliterator.trySplit();
+        long splitSizes = (split == null) ? 0 : split.getExactSizeIfKnown();
+        long lastSplitSize = spliterator.getExactSizeIfKnown();
+        splitSizes += lastSplitSize;
+
+        assertEquals(splitSizes, array.length);
+
+        List<Integer> contentOfLastSplit = new ArrayList<>();
+        spliterator.forEachRemaining((IntConsumer) contentOfLastSplit::add);
+
+        assertEquals(contentOfLastSplit.size(), lastSplitSize);
+
+        List<Integer> end = Arrays.stream(array)
+                .boxed()
+                .skip(array.length - lastSplitSize)
+                .collect(Collectors.toList());
+        assertEquals(contentOfLastSplit, end);
+    }
+
+    @Test(groups = { "serialization-hostile" })
+    public void testIntSpinedBuffer() {
+        List<Integer> list1 = new ArrayList<>();
+        List<Integer> list2 = new ArrayList<>();
+        SpinedBuffer.OfInt sb = new SpinedBuffer.OfInt();
+        for (int i = 0; i < TEST_SIZE; i++) {
+            list1.add(i);
+            sb.accept(i);
+        }
+        PrimitiveIterator.OfInt it = sb.iterator();
+        for (int i = 0; i < TEST_SIZE; i++)
+            list2.add(it.nextInt());
+        assertFalse(it.hasNext());
+        assertEquals(list1, list2);
+
+        for (int i = 0; i < TEST_SIZE; i++)
+            assertEquals(sb.get(i), i, Integer.toString(i));
+
+        list2.clear();
+        sb.forEach((int i) -> list2.add(i));
+        assertEquals(list1, list2);
+        int[] array = sb.asPrimitiveArray();
+        list2.clear();
+        for (int i : array)
+            list2.add(i);
+        assertEquals(list1, list2);
+    }
+
+    // LongSpinedBuffer
+
+    @DataProvider(name = "LongSpinedBuffer")
+    public Object[][] createLongSpinedBuffer() {
+        List<Object[]> params = new ArrayList<>();
+
+        for (int size : sizes) {
+            long[] array = LongStream.range(0, size).toArray();
+            SpinedBuffer.OfLong sb = new SpinedBuffer.OfLong();
+            Arrays.stream(array).forEach(sb);
+
+            params.add(new Object[]{array, sb});
+        }
+
+        return params.toArray(new Object[0][]);
+    }
+
+    @Test(dataProvider = "LongSpinedBuffer")
+    public void testLongSpliterator(long[] array, SpinedBuffer.OfLong sb) {
+        assertEquals(sb.count(), array.length);
+        assertEquals(sb.count(), sb.spliterator().getExactSizeIfKnown());
+
+        SpliteratorTestHelper.testLongSpliterator(sb::spliterator);
+    }
+
+    @Test(dataProvider = "LongSpinedBuffer", groups = { "serialization-hostile" })
+    public void testLongLastSplit(long[] array, SpinedBuffer.OfLong sb) {
+        Spliterator.OfLong spliterator = sb.spliterator();
+        Spliterator.OfLong split = spliterator.trySplit();
+        long splitSizes = (split == null) ? 0 : split.getExactSizeIfKnown();
+        long lastSplitSize = spliterator.getExactSizeIfKnown();
+        splitSizes += lastSplitSize;
+
+        assertEquals(splitSizes, array.length);
+
+        List<Long> contentOfLastSplit = new ArrayList<>();
+        spliterator.forEachRemaining((LongConsumer) contentOfLastSplit::add);
+
+        assertEquals(contentOfLastSplit.size(), lastSplitSize);
+
+        List<Long> end = Arrays.stream(array)
+                .boxed()
+                .skip(array.length - lastSplitSize)
+                .collect(Collectors.toList());
+        assertEquals(contentOfLastSplit, end);
+    }
+
+    @Test(groups = { "serialization-hostile" })
+    public void testLongSpinedBuffer() {
+        List<Long> list1 = new ArrayList<>();
+        List<Long> list2 = new ArrayList<>();
+        SpinedBuffer.OfLong sb = new SpinedBuffer.OfLong();
+        for (long i = 0; i < TEST_SIZE; i++) {
+            list1.add(i);
+            sb.accept(i);
+        }
+        PrimitiveIterator.OfLong it = sb.iterator();
+        for (int i = 0; i < TEST_SIZE; i++)
+            list2.add(it.nextLong());
+        assertFalse(it.hasNext());
+        assertEquals(list1, list2);
+
+        for (int i = 0; i < TEST_SIZE; i++)
+            assertEquals(sb.get(i), i, Long.toString(i));
+
+        list2.clear();
+        sb.forEach((long i) -> list2.add(i));
+        assertEquals(list1, list2);
+        long[] array = sb.asPrimitiveArray();
+        list2.clear();
+        for (long i : array)
+            list2.add(i);
+        assertEquals(list1, list2);
+    }
+
+    // DoubleSpinedBuffer
+
+    @DataProvider(name = "DoubleSpinedBuffer")
+    public Object[][] createDoubleSpinedBuffer() {
+        List<Object[]> params = new ArrayList<>();
+
+        for (int size : sizes) {
+            // @@@ replace with double range when implemented
+            double[] array = LongStream.range(0, size).asDoubleStream().toArray();
+            SpinedBuffer.OfDouble sb = new SpinedBuffer.OfDouble();
+            Arrays.stream(array).forEach(sb);
+
+            params.add(new Object[]{array, sb});
+        }
+
+        return params.toArray(new Object[0][]);
+    }
+
+    @Test(dataProvider = "DoubleSpinedBuffer")
+    public void testDoubleSpliterator(double[] array, SpinedBuffer.OfDouble sb) {
+        assertEquals(sb.count(), array.length);
+        assertEquals(sb.count(), sb.spliterator().getExactSizeIfKnown());
+
+        SpliteratorTestHelper.testDoubleSpliterator(sb::spliterator);
+    }
+
+    @Test(dataProvider = "DoubleSpinedBuffer", groups = { "serialization-hostile" })
+    public void testLongLastSplit(double[] array, SpinedBuffer.OfDouble sb) {
+        Spliterator.OfDouble spliterator = sb.spliterator();
+        Spliterator.OfDouble split = spliterator.trySplit();
+        long splitSizes = (split == null) ? 0 : split.getExactSizeIfKnown();
+        long lastSplitSize = spliterator.getExactSizeIfKnown();
+        splitSizes += lastSplitSize;
+
+        assertEquals(splitSizes, array.length);
+
+        List<Double> contentOfLastSplit = new ArrayList<>();
+        spliterator.forEachRemaining((DoubleConsumer) contentOfLastSplit::add);
+
+        assertEquals(contentOfLastSplit.size(), lastSplitSize);
+
+        List<Double> end = Arrays.stream(array)
+                .boxed()
+                .skip(array.length - lastSplitSize)
+                .collect(Collectors.toList());
+        assertEquals(contentOfLastSplit, end);
+    }
+
+    @Test(groups = { "serialization-hostile" })
+    public void testDoubleSpinedBuffer() {
+        List<Double> list1 = new ArrayList<>();
+        List<Double> list2 = new ArrayList<>();
+        SpinedBuffer.OfDouble sb = new SpinedBuffer.OfDouble();
+        for (long i = 0; i < TEST_SIZE; i++) {
+            list1.add((double) i);
+            sb.accept((double) i);
+        }
+        PrimitiveIterator.OfDouble it = sb.iterator();
+        for (int i = 0; i < TEST_SIZE; i++)
+            list2.add(it.nextDouble());
+        assertFalse(it.hasNext());
+        assertEquals(list1, list2);
+
+        for (int i = 0; i < TEST_SIZE; i++)
+            assertEquals(sb.get(i), (double) i, Double.toString(i));
+
+        list2.clear();
+        sb.forEach((double i) -> list2.add(i));
+        assertEquals(list1, list2);
+        double[] array = sb.asPrimitiveArray();
+        list2.clear();
+        for (double i : array)
+            list2.add(i);
+        assertEquals(list1, list2);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/boottest/java.base/java/util/stream/StreamFlagsTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,96 @@
+/*
+ * 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 java.util.stream;
+
+import org.testng.annotations.Test;
+
+import java.util.*;
+import java.util.stream.Stream;
+import java.util.stream.StreamOpFlag;
+import java.util.stream.Streams;
+
+import static java.util.stream.StreamOpFlag.*;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * StreamFlagsTest
+ *
+ * @author Brian Goetz
+ */
+@Test
+public class StreamFlagsTest {
+    Stream<String> arrayList = new ArrayList<String>().stream();
+    Stream<String> linkedList = new LinkedList<String>().stream();
+    Stream<String> hashSet = new HashSet<String>().stream();
+    Stream<String> treeSet = new TreeSet<String>().stream();
+    Stream<String> linkedHashSet = new LinkedHashSet<String>().stream();
+    Stream<String> repeat = Stream.generate(() -> "");
+
+    Stream<?>[] streams = { arrayList, linkedList, hashSet, treeSet, linkedHashSet, repeat };
+
+    private void assertFlags(int value, EnumSet<StreamOpFlag> setFlags, EnumSet<StreamOpFlag> clearFlags) {
+        for (StreamOpFlag flag : setFlags)
+            assertTrue(flag.isKnown(value));
+        for (StreamOpFlag flag : clearFlags)
+            assertTrue(!flag.isKnown(value));
+    }
+
+    public void testBaseStreams() {
+        Stream<String> arrayList = new ArrayList<String>().stream();
+        Stream<String> linkedList = new LinkedList<String>().stream();
+        Stream<String> hashSet = new HashSet<String>().stream();
+        Stream<String> treeSet = new TreeSet<String>().stream();
+        Stream<String> linkedHashSet = new LinkedHashSet<String>().stream();
+        Stream<String> repeat = Stream.generate(() -> "");
+
+        assertFlags(OpTestCase.getStreamFlags(arrayList),
+                    EnumSet.of(ORDERED, SIZED),
+                    EnumSet.of(DISTINCT, SORTED, SHORT_CIRCUIT));
+        assertFlags(OpTestCase.getStreamFlags(linkedList),
+                    EnumSet.of(ORDERED, SIZED),
+                    EnumSet.of(DISTINCT, SORTED, SHORT_CIRCUIT));
+        assertFlags(OpTestCase.getStreamFlags(hashSet),
+                    EnumSet.of(SIZED, DISTINCT),
+                    EnumSet.of(ORDERED, SORTED, SHORT_CIRCUIT));
+        assertFlags(OpTestCase.getStreamFlags(treeSet),
+                    EnumSet.of(ORDERED, SIZED, DISTINCT, SORTED),
+                    EnumSet.of(SHORT_CIRCUIT));
+        assertFlags(OpTestCase.getStreamFlags(linkedHashSet),
+                    EnumSet.of(ORDERED, DISTINCT, SIZED),
+                    EnumSet.of(SORTED, SHORT_CIRCUIT));
+        assertFlags(OpTestCase.getStreamFlags(repeat),
+                    EnumSet.noneOf(StreamOpFlag.class),
+                    EnumSet.of(DISTINCT, SORTED, SHORT_CIRCUIT));
+    }
+
+    public void testFilter() {
+        for (Stream<?> s : streams) {
+            int baseFlags = OpTestCase.getStreamFlags(s);
+            int filteredFlags = OpTestCase.getStreamFlags(s.filter((Object e) -> true));
+            int expectedFlags = baseFlags & ~SIZED.set();
+
+            assertEquals(filteredFlags, expectedFlags);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/boottest/java.base/java/util/stream/StreamOpFlagsTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,381 @@
+/*
+ * 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 java.util.stream;
+
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Spliterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.ToDoubleFunction;
+import java.util.function.ToIntFunction;
+import java.util.function.ToLongFunction;
+
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.StreamOpFlag.*;
+import static org.testng.Assert.*;
+import static org.testng.Assert.assertEquals;
+
+@Test
+public class StreamOpFlagsTest {
+
+    public void testNullCombine() {
+        int sourceFlags = StreamOpFlag.IS_SIZED;
+
+        assertEquals(sourceFlags, toStreamFlags(combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE)));
+    }
+
+    public void testInitialOpFlagsFromSourceFlags() {
+        List<StreamOpFlag> flags = new ArrayList<>(StreamOpFlagTestHelper.allStreamFlags());
+        for (int i = 0; i < (1 << flags.size()); i++)  {
+            int sourceFlags = 0;
+            for (int f = 0; f < flags.size(); f++) {
+                if ((i & (1 << f)) != 0)  {
+                    sourceFlags |= flags.get(f).set();
+                }
+            }
+
+            int opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
+            assertEquals(opsFlags, (~(sourceFlags << 1)) & StreamOpFlag.INITIAL_OPS_VALUE);
+        }
+    }
+
+    public void testSameCombine() {
+        for (StreamOpFlag f : StreamOpFlagTestHelper.allStreamFlags()) {
+            int sourceFlags = f.set();
+            int opsFlags;
+
+            opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
+            opsFlags = combineOpFlags(f.set(), opsFlags);
+            assertEquals(sourceFlags, toStreamFlags(opsFlags));
+        }
+    }
+
+    public void testOpClear() {
+        for (StreamOpFlag f : StreamOpFlagTestHelper.allStreamFlags()) {
+            // Clear when source not set
+            int sourceFlags = 0;
+            int opsFlags;
+
+            opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
+            opsFlags = combineOpFlags(f.clear(), opsFlags);
+            assertEquals(sourceFlags, toStreamFlags(opsFlags));
+
+            // Clear when source set
+            sourceFlags = f.set();
+
+            opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
+            opsFlags = combineOpFlags(f.clear(), opsFlags);
+            assertEquals(0, toStreamFlags(opsFlags));
+        }
+    }
+
+    public void testOpInject() {
+        for (StreamOpFlag f : StreamOpFlagTestHelper.allStreamFlags()) {
+            // Set when source not set
+            int sourceFlags = 0;
+            int opsFlags;
+
+            opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
+            opsFlags = combineOpFlags(f.set(), opsFlags);
+            assertEquals(f.set(), toStreamFlags(opsFlags));
+
+            // Set when source set
+            sourceFlags = f.set();
+
+            opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
+            opsFlags = combineOpFlags(f.set(), opsFlags);
+            assertEquals(sourceFlags, toStreamFlags(opsFlags));
+        }
+    }
+
+    public void testPairSet() {
+        List<Integer> sourceFlagsList
+                = StreamOpFlagTestHelper.allStreamFlags().stream().map(StreamOpFlag::set).collect(toList());
+        sourceFlagsList.add(0, 0);
+
+        for (int sourceFlags : sourceFlagsList) {
+            for (StreamOpFlag f1 : StreamOpFlagTestHelper.allStreamFlags()) {
+                for (StreamOpFlag f2 : StreamOpFlagTestHelper.allStreamFlags()) {
+                    int opsFlags;
+
+                    opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
+                    opsFlags = combineOpFlags(f1.set(), opsFlags);
+                    opsFlags = combineOpFlags(f2.set(), opsFlags);
+                    assertEquals(sourceFlags | f1.set() | f2.set(), toStreamFlags(opsFlags));
+                }
+            }
+        }
+    }
+
+    public void testPairSetAndClear() {
+        List<Integer> sourceFlagsList
+                = StreamOpFlagTestHelper.allStreamFlags().stream().map(StreamOpFlag::set).collect(toList());
+        sourceFlagsList.add(0, 0);
+
+        for (int sourceFlags : sourceFlagsList) {
+            for (StreamOpFlag f1 : StreamOpFlagTestHelper.allStreamFlags())  {
+                for (StreamOpFlag f2 : StreamOpFlagTestHelper.allStreamFlags()) {
+                    int opsFlags;
+
+                    opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
+                    opsFlags = combineOpFlags(f1.set(), opsFlags);
+                    opsFlags = combineOpFlags(f2.clear(), opsFlags);
+                    if (f1 == f2)
+                        assertEquals((f2.set() == sourceFlags) ? 0 : sourceFlags, toStreamFlags(opsFlags));
+                    else
+                        assertEquals((f2.set() == sourceFlags) ? f1.set() : sourceFlags | f1.set(), toStreamFlags(opsFlags));
+                }
+            }
+        }
+    }
+
+    public void testShortCircuit() {
+        int opsFlags = combineOpFlags(0, StreamOpFlag.INITIAL_OPS_VALUE);
+        assertFalse(StreamOpFlag.SHORT_CIRCUIT.isKnown(opsFlags));
+
+        opsFlags = combineOpFlags(StreamOpFlag.IS_SHORT_CIRCUIT, opsFlags);
+        assertTrue(StreamOpFlag.SHORT_CIRCUIT.isKnown(opsFlags));
+
+        opsFlags = combineOpFlags(0, opsFlags);
+        assertTrue(StreamOpFlag.SHORT_CIRCUIT.isKnown(opsFlags));
+    }
+
+    public void testApplySourceFlags() {
+        int sourceFlags = StreamOpFlag.IS_SIZED | StreamOpFlag.IS_DISTINCT;
+
+        List<Integer> ops = Arrays.asList(StreamOpFlag.NOT_SIZED, StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SORTED);
+
+        int opsFlags = StreamOpFlag.combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
+        for (int opFlags : ops) {
+            opsFlags = combineOpFlags(opFlags, opsFlags);
+        }
+        assertFalse(StreamOpFlag.SIZED.isKnown(opsFlags));
+        assertTrue(StreamOpFlag.SIZED.isCleared(opsFlags));
+        assertFalse(StreamOpFlag.SIZED.isPreserved(opsFlags));
+        assertTrue(StreamOpFlag.DISTINCT.isKnown(opsFlags));
+        assertFalse(StreamOpFlag.DISTINCT.isCleared(opsFlags));
+        assertFalse(StreamOpFlag.DISTINCT.isPreserved(opsFlags));
+        assertTrue(StreamOpFlag.SORTED.isKnown(opsFlags));
+        assertFalse(StreamOpFlag.SORTED.isCleared(opsFlags));
+        assertFalse(StreamOpFlag.SORTED.isPreserved(opsFlags));
+        assertTrue(StreamOpFlag.ORDERED.isKnown(opsFlags));
+        assertFalse(StreamOpFlag.ORDERED.isCleared(opsFlags));
+        assertFalse(StreamOpFlag.ORDERED.isPreserved(opsFlags));
+
+        int streamFlags = toStreamFlags(opsFlags);
+        assertFalse(StreamOpFlag.SIZED.isKnown(streamFlags));
+        assertTrue(StreamOpFlag.DISTINCT.isKnown(streamFlags));
+        assertTrue(StreamOpFlag.SORTED.isKnown(streamFlags));
+        assertTrue(StreamOpFlag.ORDERED.isKnown(streamFlags));
+    }
+
+    public void testSpliteratorMask() {
+        assertSpliteratorMask(StreamOpFlag.DISTINCT.set(), StreamOpFlag.IS_DISTINCT);
+        assertSpliteratorMask(StreamOpFlag.DISTINCT.clear(), 0);
+
+        assertSpliteratorMask(StreamOpFlag.SORTED.set(), StreamOpFlag.IS_SORTED);
+        assertSpliteratorMask(StreamOpFlag.SORTED.clear(), 0);
+
+        assertSpliteratorMask(StreamOpFlag.ORDERED.set(), StreamOpFlag.IS_ORDERED);
+        assertSpliteratorMask(StreamOpFlag.ORDERED.clear(), 0);
+
+        assertSpliteratorMask(StreamOpFlag.SIZED.set(), StreamOpFlag.IS_SIZED);
+        assertSpliteratorMask(StreamOpFlag.SIZED.clear(), 0);
+
+        assertSpliteratorMask(StreamOpFlag.SHORT_CIRCUIT.set(), 0);
+        assertSpliteratorMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
+    }
+
+    private void assertSpliteratorMask(int actual, int expected) {
+        assertEquals(actual & StreamOpFlag.SPLITERATOR_CHARACTERISTICS_MASK, expected);
+    }
+
+    public void testStreamMask() {
+        assertStreamMask(StreamOpFlag.DISTINCT.set(), StreamOpFlag.IS_DISTINCT);
+        assertStreamMask(StreamOpFlag.DISTINCT.clear(), 0);
+
+        assertStreamMask(StreamOpFlag.SORTED.set(), StreamOpFlag.IS_SORTED);
+        assertStreamMask(StreamOpFlag.SORTED.clear(), 0);
+
+        assertStreamMask(StreamOpFlag.ORDERED.set(), StreamOpFlag.IS_ORDERED);
+        assertStreamMask(StreamOpFlag.ORDERED.clear(), 0);
+
+        assertStreamMask(StreamOpFlag.SIZED.set(), StreamOpFlag.IS_SIZED);
+        assertStreamMask(StreamOpFlag.SIZED.clear(), 0);
+
+        assertStreamMask(StreamOpFlag.SHORT_CIRCUIT.set(), 0);
+        assertStreamMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
+    }
+
+    private void assertStreamMask(int actual, int expected) {
+        assertEquals(actual & StreamOpFlag.STREAM_MASK, expected);
+    }
+
+    public void testOpMask() {
+        assertOpMask(StreamOpFlag.DISTINCT.set(), StreamOpFlag.IS_DISTINCT);
+        assertOpMask(StreamOpFlag.DISTINCT.clear(), StreamOpFlag.NOT_DISTINCT);
+
+        assertOpMask(StreamOpFlag.SORTED.set(), StreamOpFlag.IS_SORTED);
+        assertOpMask(StreamOpFlag.SORTED.clear(), StreamOpFlag.NOT_SORTED);
+
+        assertOpMask(StreamOpFlag.ORDERED.set(), StreamOpFlag.IS_ORDERED);
+        assertOpMask(StreamOpFlag.ORDERED.clear(), StreamOpFlag.NOT_ORDERED);
+
+        assertOpMask(StreamOpFlag.SIZED.set(), 0);
+        assertOpMask(StreamOpFlag.SIZED.clear(), StreamOpFlag.NOT_SIZED);
+
+        assertOpMask(StreamOpFlag.SHORT_CIRCUIT.set(), StreamOpFlag.IS_SHORT_CIRCUIT);
+        assertOpMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
+    }
+
+    private void assertOpMask(int actual, int expected) {
+        assertEquals(actual & StreamOpFlag.OP_MASK, expected);
+    }
+
+    public void testTerminalOpMask() {
+        assertTerminalOpMask(StreamOpFlag.DISTINCT.set(), 0);
+        assertTerminalOpMask(StreamOpFlag.DISTINCT.clear(), 0);
+
+        assertTerminalOpMask(StreamOpFlag.SORTED.set(), 0);
+        assertTerminalOpMask(StreamOpFlag.SORTED.clear(), 0);
+
+        assertTerminalOpMask(StreamOpFlag.ORDERED.set(), 0);
+        assertTerminalOpMask(StreamOpFlag.ORDERED.clear(), StreamOpFlag.NOT_ORDERED);
+
+        assertTerminalOpMask(StreamOpFlag.SIZED.set(), 0);
+        assertTerminalOpMask(StreamOpFlag.SIZED.clear(), 0);
+
+        assertTerminalOpMask(StreamOpFlag.SHORT_CIRCUIT.set(), StreamOpFlag.IS_SHORT_CIRCUIT);
+        assertTerminalOpMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
+    }
+
+    private void assertTerminalOpMask(int actual, int expected) {
+        assertEquals(actual & StreamOpFlag.TERMINAL_OP_MASK, expected);
+    }
+
+    public void testUpstreamTerminalOpMask() {
+        assertUpstreamTerminalOpMask(StreamOpFlag.DISTINCT.set(), 0);
+        assertUpstreamTerminalOpMask(StreamOpFlag.DISTINCT.clear(), 0);
+
+        assertUpstreamTerminalOpMask(StreamOpFlag.SORTED.set(), 0);
+        assertUpstreamTerminalOpMask(StreamOpFlag.SORTED.clear(), 0);
+
+        assertUpstreamTerminalOpMask(StreamOpFlag.ORDERED.set(), 0);
+        assertUpstreamTerminalOpMask(StreamOpFlag.ORDERED.clear(), StreamOpFlag.NOT_ORDERED);
+
+        assertUpstreamTerminalOpMask(StreamOpFlag.SIZED.set(), 0);
+        assertUpstreamTerminalOpMask(StreamOpFlag.SIZED.clear(), 0);
+
+        assertUpstreamTerminalOpMask(StreamOpFlag.SHORT_CIRCUIT.set(), 0);
+        assertUpstreamTerminalOpMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
+    }
+
+    private void assertUpstreamTerminalOpMask(int actual, int expected) {
+        assertEquals(actual & StreamOpFlag.UPSTREAM_TERMINAL_OP_MASK, expected);
+    }
+
+    public void testSpliteratorCharacteristics() {
+        assertEquals(Spliterator.DISTINCT, StreamOpFlag.IS_DISTINCT);
+        assertEquals(Spliterator.SORTED, StreamOpFlag.IS_SORTED);
+        assertEquals(Spliterator.ORDERED, StreamOpFlag.IS_ORDERED);
+        assertEquals(Spliterator.SIZED, StreamOpFlag.IS_SIZED);
+
+        List<Integer> others = Arrays.asList(Spliterator.NONNULL, Spliterator.IMMUTABLE,
+                                             Spliterator.CONCURRENT, Spliterator.SUBSIZED);
+        for (int c : others) {
+            assertNotEquals(c, StreamOpFlag.IS_SHORT_CIRCUIT);
+        }
+    }
+
+    public void testSpliteratorCharacteristicsMask() {
+        assertSpliteratorCharacteristicsMask(StreamOpFlag.DISTINCT.set(), StreamOpFlag.IS_DISTINCT);
+        assertSpliteratorCharacteristicsMask(StreamOpFlag.DISTINCT.clear(), 0);
+
+        assertSpliteratorCharacteristicsMask(StreamOpFlag.SORTED.set(), StreamOpFlag.IS_SORTED);
+        assertSpliteratorCharacteristicsMask(StreamOpFlag.SORTED.clear(), 0);
+
+        assertSpliteratorCharacteristicsMask(StreamOpFlag.ORDERED.set(), StreamOpFlag.IS_ORDERED);
+        assertSpliteratorCharacteristicsMask(StreamOpFlag.ORDERED.clear(), 0);
+
+        assertSpliteratorCharacteristicsMask(StreamOpFlag.SIZED.set(), StreamOpFlag.IS_SIZED);
+        assertSpliteratorCharacteristicsMask(StreamOpFlag.SIZED.clear(), 0);
+
+        assertSpliteratorCharacteristicsMask(StreamOpFlag.SHORT_CIRCUIT.set(), 0);
+        assertSpliteratorCharacteristicsMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
+    }
+
+    private void assertSpliteratorCharacteristicsMask(int actual, int expected) {
+        assertEquals(StreamOpFlag.fromCharacteristics(actual), expected);
+    }
+
+    public void testSpliteratorSorted() {
+        class SortedEmptySpliterator implements Spliterator<Object> {
+            final Comparator<Object> c;
+
+            SortedEmptySpliterator(Comparator<Object> c) {
+                this.c = c;
+            }
+
+            @Override
+            public Spliterator<Object> trySplit() {
+                return null;
+            }
+
+            @Override
+            public boolean tryAdvance(Consumer<? super Object> action) {
+                return false;
+            }
+
+            @Override
+            public long estimateSize() {
+                return Long.MAX_VALUE;
+            }
+
+            @Override
+            public int characteristics() {
+                return Spliterator.SORTED;
+            }
+
+            @Override
+            public Comparator<? super Object> getComparator() {
+                return c;
+            }
+        };
+
+        {
+            int flags = StreamOpFlag.fromCharacteristics(new SortedEmptySpliterator(null));
+            assertEquals(flags, StreamOpFlag.IS_SORTED);
+        }
+
+        {
+            int flags = StreamOpFlag.fromCharacteristics(new SortedEmptySpliterator((a, b) -> 0));
+            assertEquals(flags, 0);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/boottest/java.base/java/util/stream/StreamReuseTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,441 @@
+/*
+ * 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 java.util.stream;
+
+import org.testng.annotations.Test;
+
+import java.util.function.Function;
+
+import static org.testng.Assert.fail;
+
+/**
+ * StreamReuseTest
+ *
+ * @author Brian Goetz
+ */
+@Test
+public class StreamReuseTest {
+
+    private <T, U, E, S extends BaseStream<E, S>, D extends TestData<E, S>> void assertSecondFails(
+            D data,
+            Function<S, T> first,
+            Function<S, U> second,
+            Class<? extends Throwable> exception,
+            String text) {
+        S stream = data.stream();
+        T fr = first.apply(stream);
+        try {
+            U sr = second.apply(stream);
+            fail(text + " (seq)");
+        }
+        catch (Throwable e) {
+            if (exception.isAssignableFrom(e.getClass())) {
+                // Expected
+            }
+            else if (e instanceof Error)
+                throw (Error) e;
+            else if (e instanceof RuntimeException)
+                throw (RuntimeException) e;
+            else
+                throw new AssertionError("Unexpected exception " + e.getClass(), e);
+        }
+
+        stream = data.parallelStream();
+        fr = first.apply(stream);
+        try {
+            U sr = second.apply(stream);
+            fail(text + " (par)");
+        }
+        catch (Throwable e) {
+            if (exception.isAssignableFrom(e.getClass())) {
+                // Expected
+            }
+            else if (e instanceof Error)
+                throw (Error) e;
+            else if (e instanceof RuntimeException)
+                throw (RuntimeException) e;
+            else
+                throw new AssertionError("Unexpected exception " + e.getClass(), e);
+        }
+    }
+
+    // Stream
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testTwoStreams(String name, TestData<Integer, Stream<Integer>> data) {
+        assertSecondFails(data,
+                          (Stream<Integer> s) -> s.map(i -> i), (Stream<Integer> s) -> s.map(i -> i),
+                          IllegalStateException.class,
+                          "Stream map / map succeeded erroneously");
+        assertSecondFails(data,
+                          Stream::distinct, (Stream<Integer> s) -> s.map(i -> i),
+                          IllegalStateException.class,
+                          "Stream distinct / map succeeded erroneously");
+        assertSecondFails(data,
+                          (Stream<Integer> s) -> s.map(i -> i), Stream::distinct,
+                          IllegalStateException.class,
+                          "Stream map / distinct succeeded erroneously");
+        assertSecondFails(data,
+                          Stream::distinct, Stream::distinct,
+                          IllegalStateException.class,
+                          "Stream distinct / distinct succeeded erroneously");
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testTwoTerminals(String name, TestData<Integer, Stream<Integer>> data) {
+        assertSecondFails(data,
+                          Stream::findFirst, Stream::findFirst,
+                          IllegalStateException.class,
+                          "Stream findFirst / findFirst succeeded erroneously");
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testTerminalStream(String name, TestData<Integer, Stream<Integer>> data) {
+        assertSecondFails(data,
+                          Stream::findFirst, (Stream<Integer> s) -> s.map(i -> i),
+                          IllegalStateException.class,
+                          "Stream findFirst / map succeeded erroneously");
+        assertSecondFails(data,
+                          (Stream<Integer> s) -> s.map(i -> i), Stream::findFirst,
+                          IllegalStateException.class,
+                          "Stream map / findFirst succeeded erroneously");
+        assertSecondFails(data,
+                          Stream::findFirst, Stream::distinct,
+                          IllegalStateException.class,
+                          "Stream findFirst / distinct succeeded erroneously");
+        assertSecondFails(data,
+                          Stream::distinct, Stream::findFirst,
+                          IllegalStateException.class,
+                          "Stream distinct / findFirst succeeded erroneously");
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testTwoIterators(String name, TestData<Integer, Stream<Integer>> data) {
+        assertSecondFails(data,
+                          Stream::iterator, Stream::iterator,
+                          IllegalStateException.class,
+                          "Stream iterator / iterator succeeded erroneously");
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testTerminalIterator(String name, TestData<Integer, Stream<Integer>> data) {
+        assertSecondFails(data,
+                          Stream::iterator, Stream::findFirst,
+                          IllegalStateException.class,
+                          "Stream iterator / findFirst succeeded erroneously");
+        assertSecondFails(data,
+                          Stream::findFirst, Stream::iterator,
+                          IllegalStateException.class,
+                          "Stream findFirst / iterator succeeded erroneously");
+    }
+
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    public void testStreamIterator(String name, TestData<Integer, Stream<Integer>> data) {
+        assertSecondFails(data,
+                          Stream::iterator, (Stream<Integer> s) -> s.map(i -> i),
+                          IllegalStateException.class,
+                          "Stream iterator / map succeeded erroneously");
+        assertSecondFails(data,
+                          (Stream<Integer> s) -> s.map(i -> i), Stream::iterator,
+                          IllegalStateException.class,
+                          "Stream map / iterator succeeded erroneously");
+        assertSecondFails(data,
+                          Stream::iterator, Stream::distinct,
+                          IllegalStateException.class,
+                          "Stream iterator / distinct succeeded erroneously");
+        assertSecondFails(data,
+                          Stream::distinct, Stream::iterator,
+                          IllegalStateException.class,
+                          "Stream distinct / iterator succeeded erroneously");
+    }
+
+    // IntStream
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testTwoStreams(String name, TestData.OfInt data) {
+        assertSecondFails(data,
+                          (IntStream s) -> s.mapToObj(i -> i), (IntStream s) -> s.mapToObj(i -> i),
+                          IllegalStateException.class,
+                          "IntStream map / map succeeded erroneously");
+        assertSecondFails(data,
+                          IntStream::distinct, (IntStream s) -> s.mapToObj(i -> i),
+                          IllegalStateException.class,
+                          "IntStream distinct / map succeeded erroneously");
+        assertSecondFails(data,
+                          (IntStream s) -> s.mapToObj(i -> i), IntStream::distinct,
+                          IllegalStateException.class,
+                          "IntStream map / distinct succeeded erroneously");
+        assertSecondFails(data,
+                          IntStream::distinct, IntStream::distinct,
+                          IllegalStateException.class,
+                          "IntStream distinct / distinct succeeded erroneously");
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testTwoTerminals(String name, TestData.OfInt data) {
+        assertSecondFails(data,
+                          IntStream::sum, IntStream::sum,
+                          IllegalStateException.class,
+                          "IntStream sum / sum succeeded erroneously");
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testTerminalStream(String name, TestData.OfInt data) {
+        assertSecondFails(data,
+                          IntStream::sum, (IntStream s) -> s.mapToObj(i -> i),
+                          IllegalStateException.class,
+                          "IntStream sum / map succeeded erroneously");
+        assertSecondFails(data,
+                          (IntStream s) -> s.mapToObj(i -> i), IntStream::sum,
+                          IllegalStateException.class,
+                          "IntStream map / sum succeeded erroneously");
+        assertSecondFails(data,
+                          IntStream::sum, IntStream::distinct,
+                          IllegalStateException.class,
+                          "IntStream sum / distinct succeeded erroneously");
+        assertSecondFails(data,
+                          IntStream::distinct, IntStream::sum,
+                          IllegalStateException.class,
+                          "IntStream distinct / sum succeeded erroneously");
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testTwoIterators(String name, TestData.OfInt data) {
+        assertSecondFails(data,
+                          IntStream::iterator, IntStream::iterator,
+                          IllegalStateException.class,
+                          "IntStream iterator / iterator succeeded erroneously");
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testTerminalIterator(String name, TestData.OfInt data) {
+        assertSecondFails(data,
+                          IntStream::iterator, IntStream::sum,
+                          IllegalStateException.class,
+                          "IntStream iterator / sum succeeded erroneously");
+        assertSecondFails(data,
+                          IntStream::sum, IntStream::iterator,
+                          IllegalStateException.class,
+                          "Stream sum / iterator succeeded erroneously");
+    }
+
+    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
+    public void testStreamIterator(String name, TestData.OfInt data) {
+        assertSecondFails(data,
+                          IntStream::iterator, (IntStream s) -> s.mapToObj(i -> i),
+                          IllegalStateException.class,
+                          "IntStream iterator / map succeeded erroneously");
+        assertSecondFails(data,
+                          (IntStream s) -> s.mapToObj(i -> i), IntStream::iterator,
+                          IllegalStateException.class,
+                          "IntStream map / iterator succeeded erroneously");
+        assertSecondFails(data,
+                          IntStream::iterator, IntStream::distinct,
+                          IllegalStateException.class,
+                          "IntStream iterator / distinct succeeded erroneously");
+        assertSecondFails(data,
+                          IntStream::distinct, IntStream::iterator,
+                          IllegalStateException.class,
+                          "IntStream distinct / iterator succeeded erroneously");
+    }
+
+    // LongStream
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testTwoStreams(String name, TestData.OfLong data) {
+        assertSecondFails(data,
+                          (LongStream s) -> s.mapToObj(i -> i), (LongStream s) -> s.mapToObj(i -> i),
+                          IllegalStateException.class,
+                          "LongStream map / map succeeded erroneously");
+        assertSecondFails(data,
+                          LongStream::distinct, (LongStream s) -> s.mapToObj(i -> i),
+                          IllegalStateException.class,
+                          "LongStream distinct / map succeeded erroneously");
+        assertSecondFails(data,
+                          (LongStream s) -> s.mapToObj(i -> i), LongStream::distinct,
+                          IllegalStateException.class,
+                          "LongStream map / distinct succeeded erroneously");
+        assertSecondFails(data,
+                          LongStream::distinct, LongStream::distinct,
+                          IllegalStateException.class,
+                          "LongStream distinct / distinct succeeded erroneously");
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testTwoTerminals(String name, TestData.OfLong data) {
+        assertSecondFails(data,
+                          LongStream::sum, LongStream::sum,
+                          IllegalStateException.class,
+                          "LongStream sum / sum succeeded erroneously");
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testTerminalStream(String name, TestData.OfLong data) {
+        assertSecondFails(data,
+                          LongStream::sum, (LongStream s) -> s.mapToObj(i -> i),
+                          IllegalStateException.class,
+                          "LongStream sum / map succeeded erroneously");
+        assertSecondFails(data,
+                          (LongStream s) -> s.mapToObj(i -> i), LongStream::sum,
+                          IllegalStateException.class,
+                          "LongStream map / sum succeeded erroneously");
+        assertSecondFails(data,
+                          LongStream::sum, LongStream::distinct,
+                          IllegalStateException.class,
+                          "LongStream sum / distinct succeeded erroneously");
+        assertSecondFails(data,
+                          LongStream::distinct, LongStream::sum,
+                          IllegalStateException.class,
+                          "LongStream distinct / sum succeeded erroneously");
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testTwoIterators(String name, TestData.OfLong data) {
+        assertSecondFails(data,
+                          LongStream::iterator, LongStream::iterator,
+                          IllegalStateException.class,
+                          "LongStream iterator / iterator succeeded erroneously");
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testTerminalIterator(String name, TestData.OfLong data) {
+        assertSecondFails(data,
+                          LongStream::iterator, LongStream::sum,
+                          IllegalStateException.class,
+                          "LongStream iterator / sum succeeded erroneously");
+        assertSecondFails(data,
+                          LongStream::sum, LongStream::iterator,
+                          IllegalStateException.class,
+                          "Stream sum / iterator succeeded erroneously");
+    }
+
+    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
+    public void testStreamIterator(String name, TestData.OfLong data) {
+        assertSecondFails(data,
+                          LongStream::iterator, (LongStream s) -> s.mapToObj(i -> i),
+                          IllegalStateException.class,
+                          "LongStream iterator / map succeeded erroneously");
+        assertSecondFails(data,
+                          (LongStream s) -> s.mapToObj(i -> i), LongStream::iterator,
+                          IllegalStateException.class,
+                          "LongStream map / iterator succeeded erroneously");
+        assertSecondFails(data,
+                          LongStream::iterator, LongStream::distinct,
+                          IllegalStateException.class,
+                          "LongStream iterator / distinct succeeded erroneously");
+        assertSecondFails(data,
+                          LongStream::distinct, LongStream::iterator,
+                          IllegalStateException.class,
+                          "LongStream distinct / iterator succeeded erroneously");
+    }
+
+    // DoubleStream
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testTwoStreams(String name, TestData.OfDouble data) {
+        assertSecondFails(data,
+                          (DoubleStream s) -> s.mapToObj(i -> i), (DoubleStream s) -> s.mapToObj(i -> i),
+                          IllegalStateException.class,
+                          "DoubleStream map / map succeeded erroneously");
+        assertSecondFails(data,
+                          DoubleStream::distinct, (DoubleStream s) -> s.mapToObj(i -> i),
+                          IllegalStateException.class,
+                          "DoubleStream distinct / map succeeded erroneously");
+        assertSecondFails(data,
+                          (DoubleStream s) -> s.mapToObj(i -> i), DoubleStream::distinct,
+                          IllegalStateException.class,
+                          "DoubleStream map / distinct succeeded erroneously");
+        assertSecondFails(data,
+                          DoubleStream::distinct, DoubleStream::distinct,
+                          IllegalStateException.class,
+                          "DoubleStream distinct / distinct succeeded erroneously");
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testTwoTerminals(String name, TestData.OfDouble data) {
+        assertSecondFails(data,
+                          DoubleStream::sum, DoubleStream::sum,
+                          IllegalStateException.class,
+                          "DoubleStream sum / sum succeeded erroneously");
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testTerminalStream(String name, TestData.OfDouble data) {
+        assertSecondFails(data,
+                          DoubleStream::sum, (DoubleStream s) -> s.mapToObj(i -> i),
+                          IllegalStateException.class,
+                          "DoubleStream sum / map succeeded erroneously");
+        assertSecondFails(data,
+                          (DoubleStream s) -> s.mapToObj(i -> i), DoubleStream::sum,
+                          IllegalStateException.class,
+                          "DoubleStream map / sum succeeded erroneously");
+        assertSecondFails(data,
+                          DoubleStream::sum, DoubleStream::distinct,
+                          IllegalStateException.class,
+                          "DoubleStream sum / distinct succeeded erroneously");
+        assertSecondFails(data,
+                          DoubleStream::distinct, DoubleStream::sum,
+                          IllegalStateException.class,
+                          "DoubleStream distinct / sum succeeded erroneously");
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testTwoIterators(String name, TestData.OfDouble data) {
+        assertSecondFails(data,
+                          DoubleStream::iterator, DoubleStream::iterator,
+                          IllegalStateException.class,
+                          "DoubleStream iterator / iterator succeeded erroneously");
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testTerminalIterator(String name, TestData.OfDouble data) {
+        assertSecondFails(data,
+                          DoubleStream::iterator, DoubleStream::sum,
+                          IllegalStateException.class,
+                          "DoubleStream iterator / sum succeeded erroneously");
+        assertSecondFails(data,
+                          DoubleStream::sum, DoubleStream::iterator,
+                          IllegalStateException.class,
+                          "Stream sum / iterator succeeded erroneously");
+    }
+
+    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
+    public void testStreamIterator(String name, TestData.OfDouble data) {
+        assertSecondFails(data,
+                          DoubleStream::iterator, (DoubleStream s) -> s.mapToObj(i -> i),
+                          IllegalStateException.class,
+                          "DoubleStream iterator / map succeeded erroneously");
+        assertSecondFails(data,
+                          (DoubleStream s) -> s.mapToObj(i -> i), DoubleStream::iterator,
+                          IllegalStateException.class,
+                          "DoubleStream map / iterator succeeded erroneously");
+        assertSecondFails(data,
+                          DoubleStream::iterator, DoubleStream::distinct,
+                          IllegalStateException.class,
+                          "DoubleStream iterator / distinct succeeded erroneously");
+        assertSecondFails(data,
+                          DoubleStream::distinct, DoubleStream::iterator,
+                          IllegalStateException.class,
+                          "DoubleStream distinct / iterator succeeded erroneously");
+    }
+}
--- a/jdk/test/java/util/stream/boottest/java/util/stream/DoubleNodeTest.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,179 +0,0 @@
-/*
- * Copyright (c) 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 java.util.stream;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.PrimitiveIterator;
-import java.util.Spliterators;
-import java.util.function.Function;
-
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-@Test
-public class DoubleNodeTest extends OpTestCase {
-
-    @DataProvider(name = "nodes")
-    public Object[][] createSizes() {
-        List<Object[]> params = new ArrayList<>();
-
-        for (int size : Arrays.asList(0, 1, 4, 15, 16, 17, 127, 128, 129, 1000)) {
-            double[] array = new double[size];
-            for (int i = 0; i < array.length; i++) {
-                array[i] = i;
-            }
-
-            List<Node<Double>> nodes = new ArrayList<>();
-
-            nodes.add(Nodes.node(array));
-            nodes.add(degenerateTree(Spliterators.iterator(Arrays.spliterator(array))));
-            nodes.add(tree(toList(array), l -> Nodes.node(toDoubleArray(l))));
-            nodes.add(fill(array, Nodes.doubleBuilder(array.length)));
-            nodes.add(fill(array, Nodes.doubleBuilder()));
-
-            for (Node<Double> node : nodes) {
-                params.add(new Object[]{array, node});
-            }
-
-        }
-
-        return params.toArray(new Object[0][]);
-    }
-
-    private static void assertEqualsListDoubleArray(List<Double> list, double[] array) {
-        assertEquals(list.size(), array.length);
-        for (int i = 0; i < array.length; i++)
-            assertEquals(array[i], list.get(i));
-    }
-
-    private List<Double> toList(double[] a) {
-        List<Double> l = new ArrayList<>();
-        for (double i : a) {
-            l.add(i);
-        }
-
-        return l;
-    }
-
-    private double[] toDoubleArray(List<Double> l) {
-        double[] a = new double[l.size()];
-
-        int i = 0;
-        for (Double e : l) {
-            a[i++] = e;
-        }
-        return a;
-    }
-
-    private Node.OfDouble fill(double[] array, Node.Builder.OfDouble nb) {
-        nb.begin(array.length);
-        for (double i : array)
-            nb.accept(i);
-        nb.end();
-        return nb.build();
-    }
-
-    private Node.OfDouble degenerateTree(PrimitiveIterator.OfDouble it) {
-        if (!it.hasNext()) {
-            return Nodes.node(new double[0]);
-        }
-
-        double i = it.nextDouble();
-        if (it.hasNext()) {
-            return new Nodes.ConcNode.OfDouble(Nodes.node(new double[] {i}), degenerateTree(it));
-        }
-        else {
-            return Nodes.node(new double[] {i});
-        }
-    }
-
-    private Node.OfDouble tree(List<Double> l, Function<List<Double>, Node.OfDouble> m) {
-        if (l.size() < 3) {
-            return m.apply(l);
-        }
-        else {
-            return new Nodes.ConcNode.OfDouble(
-                    tree(l.subList(0, l.size() / 2), m),
-                    tree(l.subList(l.size() / 2, l.size()), m));
-        }
-    }
-
-    @Test(dataProvider = "nodes")
-    public void testAsArray(double[] array, Node.OfDouble n) {
-        assertEquals(n.asPrimitiveArray(), array);
-    }
-
-    @Test(dataProvider = "nodes")
-    public void testFlattenAsArray(double[] array, Node.OfDouble n) {
-        assertEquals(Nodes.flattenDouble(n).asPrimitiveArray(), array);
-    }
-
-    @Test(dataProvider = "nodes")
-    public void testCopyTo(double[] array, Node.OfDouble n) {
-        double[] copy = new double[(int) n.count()];
-        n.copyInto(copy, 0);
-
-        assertEquals(copy, array);
-    }
-
-    @Test(dataProvider = "nodes", groups = { "serialization-hostile" })
-    public void testForEach(double[] array, Node.OfDouble n) {
-        List<Double> l = new ArrayList<>((int) n.count());
-        n.forEach((double e) -> {
-            l.add(e);
-        });
-
-        assertEqualsListDoubleArray(l, array);
-    }
-
-    @Test(dataProvider = "nodes")
-    public void testStreams(double[] array, Node.OfDouble n) {
-        TestData.OfDouble data = TestData.Factory.ofNode("Node", n);
-
-        exerciseOps(data, s -> s);
-
-        exerciseTerminalOps(data, s -> s.toArray());
-    }
-
-    @Test(dataProvider = "nodes", groups={ "serialization-hostile" })
-    // throws SOE on serialization of DoubleConcNode[size=1000]
-    public void testSpliterator(double[] array, Node.OfDouble n) {
-        SpliteratorTestHelper.testDoubleSpliterator(n::spliterator);
-    }
-
-    @Test(dataProvider = "nodes")
-    public void testTruncate(double[] array, Node.OfDouble n) {
-        int[] nums = new int[] { 0, 1, array.length / 2, array.length - 1, array.length };
-        for (int start : nums)
-            for (int end : nums) {
-                if (start < 0 || end < 0 || end < start || end > array.length)
-                    continue;
-                Node.OfDouble slice = n.truncate(start, end, Double[]::new);
-                double[] asArray = slice.asPrimitiveArray();
-                for (int k = start; k < end; k++)
-                    assertEquals(array[k], asArray[k - start]);
-            }
-    }
-}
--- a/jdk/test/java/util/stream/boottest/java/util/stream/FlagOpTest.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,283 +0,0 @@
-/*
- * 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 java.util.stream;
-
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import java.util.ArrayList;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.function.Supplier;
-
-import static java.util.stream.LambdaTestHelpers.countTo;
-
-@Test
-public class FlagOpTest extends OpTestCase {
-
-    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
-    public void testFlagsPassThrough(String name, TestData<Integer, Stream<Integer>> data) {
-
-        @SuppressWarnings({"unchecked", "rawtypes"})
-        TestFlagPassThroughOp<Integer>[] ops = new TestFlagPassThroughOp[3];
-        ops[0] = new TestFlagPassThroughOp<>();
-        ops[1] = new TestFlagPassThroughOp<>();
-        ops[2] = new TestFlagPassThroughOp<>();
-
-        ops[0].set(null, ops[1]);
-        ops[1].set(ops[0], ops[2]);
-        ops[2].set(ops[1], null);
-
-        withData(data).ops(ops).exercise();
-    }
-
-    static class TestFlagPassThroughOp<T> extends FlagDeclaringOp<T> {
-        TestFlagPassThroughOp<T> upstream;
-        TestFlagPassThroughOp<T> downstream;
-
-        TestFlagPassThroughOp() {
-            super(0);
-        }
-
-        void set(TestFlagPassThroughOp<T> upstream, TestFlagPassThroughOp<T> downstream)  {
-            this.upstream = upstream;
-            this.downstream = downstream;
-        }
-
-        int wrapFlags;
-
-        @Override
-        @SuppressWarnings({"unchecked", "rawtypes"})
-        public Sink<T> opWrapSink(int flags, boolean parallel, Sink sink) {
-            this.wrapFlags = flags;
-
-            if (downstream != null) {
-                assertTrue(flags == downstream.wrapFlags);
-            }
-
-            return sink;
-        }
-    }
-
-    public void testFlagsClearAllSet() {
-        int clearAllFlags = 0;
-        for (StreamOpFlag f : EnumSet.allOf(StreamOpFlag.class)) {
-            if (f.isStreamFlag()) {
-                clearAllFlags |= f.clear();
-            }
-        }
-
-        EnumSet<StreamOpFlag> known = EnumSet.noneOf(StreamOpFlag.class);
-        EnumSet<StreamOpFlag> notKnown = StreamOpFlagTestHelper.allStreamFlags();
-
-        List<FlagDeclaringOp<Integer>> ops = new ArrayList<>();
-        ops.add(new FlagDeclaringOp<>(clearAllFlags));
-        for (StreamOpFlag f : StreamOpFlagTestHelper.allStreamFlags()) {
-            if (f.canSet(StreamOpFlag.Type.OP)) {
-                ops.add(new TestFlagExpectedOp<>(f.set(),
-                                             known.clone(),
-                                             EnumSet.noneOf(StreamOpFlag.class),
-                                             notKnown.clone()));
-                known.add(f);
-                notKnown.remove(f);
-            }
-        }
-        ops.add(new TestFlagExpectedOp<>(0,
-                                         known.clone(),
-                                         EnumSet.noneOf(StreamOpFlag.class),
-                                         notKnown.clone()));
-
-        TestData<Integer, Stream<Integer>> data = TestData.Factory.ofArray("Array", countTo(10).toArray(new Integer[0]));
-        @SuppressWarnings("rawtypes")
-        FlagDeclaringOp[] opsArray = ops.toArray(new FlagDeclaringOp[ops.size()]);
-
-        withData(data).ops(opsArray).
-                without(StreamTestScenario.CLEAR_SIZED_SCENARIOS).
-                exercise();
-    }
-
-    public void testFlagsSetAllClear() {
-        EnumSet<StreamOpFlag> known = StreamOpFlagTestHelper.allStreamFlags();
-        int setAllFlags = 0;
-        for (StreamOpFlag f : EnumSet.allOf(StreamOpFlag.class)) {
-            if (f.isStreamFlag()) {
-                if (f.canSet(StreamOpFlag.Type.OP)) {
-                    setAllFlags |= f.set();
-                } else {
-                    known.remove(f);
-                }
-            }
-        }
-
-        EnumSet<StreamOpFlag> notKnown = EnumSet.noneOf(StreamOpFlag.class);
-
-        List<FlagDeclaringOp<Integer>> ops = new ArrayList<>();
-        ops.add(new FlagDeclaringOp<>(setAllFlags));
-        for (StreamOpFlag f : StreamOpFlagTestHelper.allStreamFlags()) {
-            ops.add(new TestFlagExpectedOp<>(f.clear(),
-                                             known.clone(),
-                                             EnumSet.noneOf(StreamOpFlag.class),
-                                             notKnown.clone()));
-            known.remove(f);
-            notKnown.add(f);
-        }
-        ops.add(new TestFlagExpectedOp<>(0,
-                                         known.clone(),
-                                         EnumSet.noneOf(StreamOpFlag.class),
-                                         notKnown.clone()));
-
-        TestData<Integer, Stream<Integer>> data = TestData.Factory.ofArray("Array", countTo(10).toArray(new Integer[0]));
-        @SuppressWarnings("rawtypes")
-        FlagDeclaringOp[] opsArray = ops.toArray(new FlagDeclaringOp[ops.size()]);
-
-
-        withData(data).ops(opsArray).
-                without(StreamTestScenario.CLEAR_SIZED_SCENARIOS).
-                exercise();
-    }
-
-    public void testFlagsParallelCollect() {
-        testFlagsSetSequence(CollectorOps::collector);
-    }
-
-    private void testFlagsSetSequence(Supplier<StatefulTestOp<Integer>> cf) {
-        EnumSet<StreamOpFlag> known = EnumSet.of(StreamOpFlag.ORDERED, StreamOpFlag.SIZED);
-        EnumSet<StreamOpFlag> preserve = EnumSet.of(StreamOpFlag.DISTINCT, StreamOpFlag.SORTED);
-
-        List<IntermediateTestOp<Integer, Integer>> ops = new ArrayList<>();
-        for (StreamOpFlag f : EnumSet.of(StreamOpFlag.DISTINCT, StreamOpFlag.SORTED)) {
-            ops.add(cf.get());
-            ops.add(new TestFlagExpectedOp<>(f.set(),
-                                             known.clone(),
-                                             preserve.clone(),
-                                             EnumSet.noneOf(StreamOpFlag.class)));
-            known.add(f);
-            preserve.remove(f);
-        }
-        ops.add(cf.get());
-        ops.add(new TestFlagExpectedOp<>(0,
-                                         known.clone(),
-                                         preserve.clone(),
-                                         EnumSet.noneOf(StreamOpFlag.class)));
-
-        TestData<Integer, Stream<Integer>> data = TestData.Factory.ofArray("Array", countTo(10).toArray(new Integer[0]));
-        @SuppressWarnings("rawtypes")
-        IntermediateTestOp[] opsArray = ops.toArray(new IntermediateTestOp[ops.size()]);
-
-        withData(data).ops(opsArray).
-                without(StreamTestScenario.CLEAR_SIZED_SCENARIOS).
-                exercise();
-    }
-
-
-    public void testFlagsClearParallelCollect() {
-        testFlagsClearSequence(CollectorOps::collector);
-    }
-
-    protected void testFlagsClearSequence(Supplier<StatefulTestOp<Integer>> cf) {
-        EnumSet<StreamOpFlag> known = EnumSet.of(StreamOpFlag.ORDERED, StreamOpFlag.SIZED);
-        EnumSet<StreamOpFlag> preserve = EnumSet.of(StreamOpFlag.DISTINCT, StreamOpFlag.SORTED);
-        EnumSet<StreamOpFlag> notKnown = EnumSet.noneOf(StreamOpFlag.class);
-
-        List<IntermediateTestOp<Integer, Integer>> ops = new ArrayList<>();
-        for (StreamOpFlag f : EnumSet.of(StreamOpFlag.ORDERED, StreamOpFlag.DISTINCT, StreamOpFlag.SORTED)) {
-            ops.add(cf.get());
-            ops.add(new TestFlagExpectedOp<>(f.clear(),
-                                             known.clone(),
-                                             preserve.clone(),
-                                             notKnown.clone()));
-            known.remove(f);
-            preserve.remove(f);
-            notKnown.add(f);
-        }
-        ops.add(cf.get());
-        ops.add(new TestFlagExpectedOp<>(0,
-                                         known.clone(),
-                                         preserve.clone(),
-                                         notKnown.clone()));
-
-        TestData<Integer, Stream<Integer>> data = TestData.Factory.ofArray("Array", countTo(10).toArray(new Integer[0]));
-        @SuppressWarnings("rawtypes")
-        IntermediateTestOp[] opsArray = ops.toArray(new IntermediateTestOp[ops.size()]);
-
-        withData(data).ops(opsArray).
-                without(StreamTestScenario.CLEAR_SIZED_SCENARIOS).
-                exercise();
-    }
-
-    public void testFlagsSizedOrderedParallelCollect() {
-        EnumSet<StreamOpFlag> parKnown = EnumSet.of(StreamOpFlag.SIZED);
-        EnumSet<StreamOpFlag> serKnown = parKnown.clone();
-
-        List<IntermediateTestOp<Integer, Integer>> ops = new ArrayList<>();
-        for (StreamOpFlag f : parKnown) {
-            ops.add(CollectorOps.collector());
-            ops.add(new ParSerTestFlagExpectedOp<>(f.clear(),
-                                             parKnown,
-                                             serKnown));
-            serKnown.remove(f);
-        }
-        ops.add(CollectorOps.collector());
-        ops.add(new ParSerTestFlagExpectedOp<>(0,
-                                         parKnown,
-                                         EnumSet.noneOf(StreamOpFlag.class)));
-
-        TestData<Integer, Stream<Integer>> data = TestData.Factory.ofArray("Array", countTo(10).toArray(new Integer[0]));
-        @SuppressWarnings("rawtypes")
-        IntermediateTestOp[] opsArray = ops.toArray(new IntermediateTestOp[ops.size()]);
-
-        withData(data).ops(opsArray).exercise();
-    }
-
-    static class ParSerTestFlagExpectedOp<T> extends FlagDeclaringOp<T> {
-        final EnumSet<StreamOpFlag> parKnown;
-        final EnumSet<StreamOpFlag> serKnown;
-
-        ParSerTestFlagExpectedOp(int flags, EnumSet<StreamOpFlag> known, EnumSet<StreamOpFlag> serKnown) {
-            super(flags);
-            this.parKnown = known;
-            this.serKnown = serKnown;
-        }
-
-        @Override
-        @SuppressWarnings({"unchecked", "rawtypes"})
-        public Sink<T> opWrapSink(int flags, boolean parallel, Sink upstream) {
-            assertFlags(flags, parallel);
-            return upstream;
-        }
-
-        protected void assertFlags(int flags, boolean parallel) {
-            if (parallel) {
-                for (StreamOpFlag f : parKnown) {
-                    Assert.assertTrue(f.isKnown(flags), String.format("Flag %s is not known, but should be known.", f.toString()));
-                }
-
-            } else {
-                for (StreamOpFlag f : serKnown) {
-                    Assert.assertTrue(f.isKnown(flags), String.format("Flag %s is not known, but should be known.", f.toString()));
-                }
-
-            }
-        }
-    }
-}
--- a/jdk/test/java/util/stream/boottest/java/util/stream/IntNodeTest.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,177 +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 java.util.stream;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.PrimitiveIterator;
-import java.util.Spliterators;
-import java.util.function.Function;
-
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-@Test
-public class IntNodeTest extends OpTestCase {
-
-    @DataProvider(name = "nodes")
-    public Object[][] createSizes() {
-        List<Object[]> params = new ArrayList<>();
-
-        for (int size : Arrays.asList(0, 1, 4, 15, 16, 17, 127, 128, 129, 1000)) {
-            int[] array = new int[size];
-            for (int i = 0; i < array.length; i++) {
-                array[i] = i;
-            }
-
-            List<Node<Integer>> nodes = new ArrayList<>();
-
-            nodes.add(Nodes.node(array));
-            nodes.add(degenerateTree(Spliterators.iterator(Arrays.spliterator(array))));
-            nodes.add(tree(toList(array), l -> Nodes.node(toIntArray(l))));
-            nodes.add(fill(array, Nodes.intBuilder(array.length)));
-            nodes.add(fill(array, Nodes.intBuilder()));
-
-            for (Node<Integer> node : nodes) {
-                params.add(new Object[]{array, node});
-            }
-
-        }
-
-        return params.toArray(new Object[0][]);
-    }
-
-    private static void assertEqualsListIntArray(List<Integer> list, int[] array) {
-        assertEquals(list.size(), array.length);
-        for (int i = 0; i < array.length; i++)
-            assertEquals(array[i], (int) list.get(i));
-    }
-
-    private List<Integer> toList(int[] a) {
-        List<Integer> l = new ArrayList<>();
-        for (int i : a) {
-            l.add(i);
-        }
-
-        return l;
-    }
-
-    private int[] toIntArray(List<Integer> l) {
-        int[] a = new int[l.size()];
-
-        int i = 0;
-        for (Integer e : l) {
-            a[i++] = e;
-        }
-        return a;
-    }
-
-    private Node.OfInt fill(int[] array, Node.Builder.OfInt nb) {
-        nb.begin(array.length);
-        for (int i : array)
-            nb.accept(i);
-        nb.end();
-        return nb.build();
-    }
-
-    private Node.OfInt degenerateTree(PrimitiveIterator.OfInt it) {
-        if (!it.hasNext()) {
-            return Nodes.node(new int[0]);
-        }
-
-        int i = it.nextInt();
-        if (it.hasNext()) {
-            return new Nodes.ConcNode.OfInt(Nodes.node(new int[] {i}), degenerateTree(it));
-        }
-        else {
-            return Nodes.node(new int[] {i});
-        }
-    }
-
-    private Node.OfInt tree(List<Integer> l, Function<List<Integer>, Node.OfInt> m) {
-        if (l.size() < 3) {
-            return m.apply(l);
-        }
-        else {
-            return new Nodes.ConcNode.OfInt(
-                    tree(l.subList(0, l.size() / 2), m),
-                    tree(l.subList(l.size() / 2, l.size()), m));
-        }
-    }
-
-    @Test(dataProvider = "nodes")
-    public void testAsArray(int[] array, Node.OfInt n) {
-        assertEquals(n.asPrimitiveArray(), array);
-    }
-
-    @Test(dataProvider = "nodes")
-    public void testFlattenAsArray(int[] array, Node.OfInt n) {
-        assertEquals(Nodes.flattenInt(n).asPrimitiveArray(), array);
-    }
-
-    @Test(dataProvider = "nodes")
-    public void testCopyTo(int[] array, Node.OfInt n) {
-        int[] copy = new int[(int) n.count()];
-        n.copyInto(copy, 0);
-
-        assertEquals(copy, array);
-    }
-
-    @Test(dataProvider = "nodes", groups = { "serialization-hostile" })
-    public void testForEach(int[] array, Node.OfInt n) {
-        List<Integer> l = new ArrayList<>((int) n.count());
-        n.forEach((int e) -> {
-            l.add(e);
-        });
-
-        assertEqualsListIntArray(l, array);
-    }
-
-    @Test(dataProvider = "nodes")
-    public void testStreams(int[] array, Node.OfInt n) {
-        TestData.OfInt data = TestData.Factory.ofNode("Node", n);
-
-        exerciseOps(data, s -> s);
-        exerciseTerminalOps(data, s -> s.toArray());
-    }
-
-    @Test(dataProvider = "nodes")
-    public void testSpliterator(int[] array, Node.OfInt n) {
-        SpliteratorTestHelper.testIntSpliterator(n::spliterator);
-    }
-
-    @Test(dataProvider = "nodes")
-    public void testTruncate(int[] array, Node.OfInt n) {
-        int[] nums = new int[] { 0, 1, array.length / 2, array.length - 1, array.length };
-        for (int start : nums)
-            for (int end : nums) {
-                if (start < 0 || end < 0 || end < start || end > array.length)
-                    continue;
-                Node.OfInt slice = n.truncate(start, end, Integer[]::new);
-                int[] asArray = slice.asPrimitiveArray();
-                for (int k = start; k < end; k++)
-                    assertEquals(array[k], asArray[k - start]);
-            }
-    }
-}
--- a/jdk/test/java/util/stream/boottest/java/util/stream/LongNodeTest.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,178 +0,0 @@
-/*
- * Copyright (c) 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 java.util.stream;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.PrimitiveIterator;
-import java.util.Spliterators;
-import java.util.function.Function;
-
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-@Test
-public class LongNodeTest extends OpTestCase {
-
-    @DataProvider(name = "nodes")
-    public Object[][] createSizes() {
-        List<Object[]> params = new ArrayList<>();
-
-        for (int size : Arrays.asList(0, 1, 4, 15, 16, 17, 127, 128, 129, 1000)) {
-            long[] array = new long[size];
-            for (int i = 0; i < array.length; i++) {
-                array[i] = i;
-            }
-
-            List<Node<Long>> nodes = new ArrayList<>();
-
-            nodes.add(Nodes.node(array));
-            nodes.add(degenerateTree(Spliterators.iterator(Arrays.spliterator(array))));
-            nodes.add(tree(toList(array), l -> Nodes.node(toLongArray(l))));
-            nodes.add(fill(array, Nodes.longBuilder(array.length)));
-            nodes.add(fill(array, Nodes.longBuilder()));
-
-            for (Node<Long> node : nodes) {
-                params.add(new Object[]{array, node});
-            }
-
-        }
-
-        return params.toArray(new Object[0][]);
-    }
-
-    private static void assertEqualsListLongArray(List<Long> list, long[] array) {
-        assertEquals(list.size(), array.length);
-        for (int i = 0; i < array.length; i++)
-            assertEquals(array[i], (long) list.get(i));
-    }
-
-    private List<Long> toList(long[] a) {
-        List<Long> l = new ArrayList<>();
-        for (long i : a) {
-            l.add(i);
-        }
-
-        return l;
-    }
-
-    private long[] toLongArray(List<Long> l) {
-        long[] a = new long[l.size()];
-
-        int i = 0;
-        for (Long e : l) {
-            a[i++] = e;
-        }
-        return a;
-    }
-
-    private Node.OfLong fill(long[] array, Node.Builder.OfLong nb) {
-        nb.begin(array.length);
-        for (long i : array)
-            nb.accept(i);
-        nb.end();
-        return nb.build();
-    }
-
-    private Node.OfLong degenerateTree(PrimitiveIterator.OfLong it) {
-        if (!it.hasNext()) {
-            return Nodes.node(new long[0]);
-        }
-
-        long i = it.nextLong();
-        if (it.hasNext()) {
-            return new Nodes.ConcNode.OfLong(Nodes.node(new long[] {i}), degenerateTree(it));
-        }
-        else {
-            return Nodes.node(new long[] {i});
-        }
-    }
-
-    private Node.OfLong tree(List<Long> l, Function<List<Long>, Node.OfLong> m) {
-        if (l.size() < 3) {
-            return m.apply(l);
-        }
-        else {
-            return new Nodes.ConcNode.OfLong(
-                    tree(l.subList(0, l.size() / 2), m),
-                    tree(l.subList(l.size() / 2, l.size()), m));
-        }
-    }
-
-    @Test(dataProvider = "nodes")
-    public void testAsArray(long[] array, Node.OfLong n) {
-        assertEquals(n.asPrimitiveArray(), array);
-    }
-
-    @Test(dataProvider = "nodes")
-    public void testFlattenAsArray(long[] array, Node.OfLong n) {
-        assertEquals(Nodes.flattenLong(n).asPrimitiveArray(), array);
-    }
-
-    @Test(dataProvider = "nodes")
-    public void testCopyTo(long[] array, Node.OfLong n) {
-        long[] copy = new long[(int) n.count()];
-        n.copyInto(copy, 0);
-
-        assertEquals(copy, array);
-    }
-
-    @Test(dataProvider = "nodes", groups = { "serialization-hostile" })
-    public void testForEach(long[] array, Node.OfLong n) {
-        List<Long> l = new ArrayList<>((int) n.count());
-        n.forEach((long e) -> {
-            l.add(e);
-        });
-
-        assertEqualsListLongArray(l, array);
-    }
-
-    @Test(dataProvider = "nodes")
-    public void testStreams(long[] array, Node.OfLong n) {
-        TestData.OfLong data = TestData.Factory.ofNode("Node", n);
-
-        exerciseOps(data, s -> s);
-
-        exerciseTerminalOps(data, s -> s.toArray());
-    }
-
-    @Test(dataProvider = "nodes")
-    public void testSpliterator(long[] array, Node.OfLong n) {
-        SpliteratorTestHelper.testLongSpliterator(n::spliterator);
-    }
-
-    @Test(dataProvider = "nodes")
-    public void testTruncate(long[] array, Node.OfLong n) {
-        int[] nums = new int[] { 0, 1, array.length / 2, array.length - 1, array.length };
-        for (int start : nums)
-            for (int end : nums) {
-                if (start < 0 || end < 0 || end < start || end > array.length)
-                    continue;
-                Node.OfLong slice = n.truncate(start, end, Long[]::new);
-                long[] asArray = slice.asPrimitiveArray();
-                for (int k = start; k < end; k++)
-                    assertEquals(array[k], asArray[k - start]);
-            }
-    }
-}
--- a/jdk/test/java/util/stream/boottest/java/util/stream/NodeBuilderTest.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,236 +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 java.util.stream;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.function.DoubleConsumer;
-import java.util.function.Function;
-import java.util.function.IntConsumer;
-import java.util.function.LongConsumer;
-
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-import static java.util.stream.LambdaTestHelpers.assertContents;
-import static java.util.stream.LambdaTestHelpers.countTo;
-import static org.testng.Assert.assertEquals;
-
-@Test
-public class NodeBuilderTest {
-
-    List<Integer> sizes = Arrays.asList(0, 1, 4, 16, 256,
-                                        1023, 1024, 1025,
-                                        2047, 2048, 2049,
-                                        1024 * 32 - 1, 1024 * 32, 1024 * 32 + 1);
-
-    @DataProvider(name = "Node.Builder")
-    public Object[][] createNodeBuilders() {
-        List<List<Integer>> ls = new ArrayList<>();
-        for (int size : sizes) {
-            ls.add(countTo(size));
-        }
-
-        List<Function<Integer, Node.Builder<Integer>>> ms = Arrays.asList(
-                s -> Nodes.builder(),
-                s -> Nodes.builder(s, LambdaTestHelpers.integerArrayGenerator)
-        );
-
-        Object[][] params = new Object[ls.size() * ms.size()][];
-        int i = 0;
-        for (List<Integer> l : ls) {
-            for (Function<Integer, Node.Builder<Integer>> m : ms) {
-                params[i++] = new Object[]{l, m};
-            }
-        }
-
-        return params;
-    }
-
-    @Test(dataProvider = "Node.Builder", groups = { "serialization-hostile" })
-    public void testIteration(List<Integer> l, Function<Integer, Node.Builder<Integer>> m) {
-        Node.Builder<Integer> nb = m.apply(l.size());
-        nb.begin(l.size());
-        for (Integer i : l) {
-            nb.accept(i);
-        }
-        nb.end();
-
-        Node<Integer> n = nb.build();
-        assertEquals(n.count(), l.size());
-
-        {
-            List<Integer> _l = new ArrayList<>();
-            n.forEach(_l::add);
-
-            assertContents(_l, l);
-        }
-    }
-
-    // Node.Builder.OfInt
-
-    @DataProvider(name = "Node.Builder<Integer>")
-    public Object[][] createIntNodeBuilders() {
-        List<List<Integer>> ls = new ArrayList<>();
-        for (int size : sizes) {
-            ls.add(countTo(size));
-        }
-
-        List<Function<Integer, Node.Builder<Integer>>> ms = Arrays.asList(
-                s -> Nodes.intBuilder(),
-                s -> Nodes.intBuilder(s)
-        );
-
-        Object[][] params = new Object[ls.size() * ms.size()][];
-        int i = 0;
-        for (List<Integer> l : ls) {
-            for (Function<Integer, Node.Builder<Integer>> m : ms) {
-                params[i++] = new Object[]{l, m};
-            }
-        }
-
-        return params;
-    }
-
-    @Test(dataProvider = "Node.Builder<Integer>", groups = { "serialization-hostile" })
-    public void testIntIteration(List<Integer> l, Function<Integer, Node.Builder.OfInt> m) {
-        Node.Builder.OfInt nb = m.apply(l.size());
-        nb.begin(l.size());
-        for (Integer i : l) {
-            nb.accept((int) i);
-        }
-        nb.end();
-
-        Node.OfInt n = nb.build();
-        assertEquals(n.count(), l.size());
-
-        {
-            List<Integer> _l = new ArrayList<>();
-            n.forEach((IntConsumer) _l::add);
-
-            assertContents(_l, l);
-        }
-
-    }
-
-    // Node.Builder.OfLong
-
-    @DataProvider(name = "Node.Builder<Long>")
-    public Object[][] createLongNodeBuilders() {
-        List<List<Long>> ls = new ArrayList<>();
-        for (int size : sizes) {
-            List<Long> l = new ArrayList<>();
-            for (long i = 0; i < size; i++) {
-                l.add(i);
-            }
-            ls.add(l);
-        }
-
-        List<Function<Integer, Node.Builder<Long>>> ms = Arrays.asList(
-                s -> Nodes.longBuilder(),
-                s -> Nodes.longBuilder(s)
-        );
-
-        Object[][] params = new Object[ls.size() * ms.size()][];
-        int i = 0;
-        for (List<Long> l : ls) {
-            for (Function<Integer, Node.Builder<Long>> m : ms) {
-                params[i++] = new Object[]{l, m};
-            }
-        }
-
-        return params;
-    }
-
-    @Test(dataProvider = "Node.Builder<Long>")
-    public void testLongIteration(List<Long> l, Function<Integer, Node.Builder.OfLong> m) {
-        Node.Builder.OfLong nb = m.apply(l.size());
-        nb.begin(l.size());
-        for (Long i : l) {
-            nb.accept((long) i);
-        }
-        nb.end();
-
-        Node.OfLong n = nb.build();
-        assertEquals(n.count(), l.size());
-
-        {
-            List<Long> _l = new ArrayList<>();
-            n.forEach((LongConsumer) _l::add);
-
-            assertContents(_l, l);
-        }
-
-    }
-
-    // Node.Builder.OfDouble
-
-    @DataProvider(name = "Node.Builder<Double>")
-    public Object[][] createDoubleNodeBuilders() {
-        List<List<Double>> ls = new ArrayList<>();
-        for (int size : sizes) {
-            List<Double> l = new ArrayList<>();
-            for (long i = 0; i < size; i++) {
-                l.add((double) i);
-            }
-            ls.add(l);
-        }
-
-        List<Function<Integer, Node.Builder<Double>>> ms = Arrays.asList(
-                s -> Nodes.doubleBuilder(),
-                s -> Nodes.doubleBuilder(s)
-        );
-
-        Object[][] params = new Object[ls.size() * ms.size()][];
-        int i = 0;
-        for (List<Double> l : ls) {
-            for (Function<Integer, Node.Builder<Double>> m : ms) {
-                params[i++] = new Object[]{l, m};
-            }
-        }
-
-        return params;
-    }
-
-    @Test(dataProvider = "Node.Builder<Double>")
-    public void testDoubleIteration(List<Double> l, Function<Integer, Node.Builder.OfDouble> m) {
-        Node.Builder.OfDouble nb = m.apply(l.size());
-        nb.begin(l.size());
-        for (Double i : l) {
-            nb.accept((double) i);
-        }
-        nb.end();
-
-        Node.OfDouble n = nb.build();
-        assertEquals(n.count(), l.size());
-
-        {
-            List<Double> _l = new ArrayList<>();
-            n.forEach((DoubleConsumer) _l::add);
-
-            assertContents(_l, l);
-        }
-
-    }
-}
--- a/jdk/test/java/util/stream/boottest/java/util/stream/NodeTest.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,154 +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 java.util.stream;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.function.Function;
-
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-@Test
-public class NodeTest extends OpTestCase {
-
-    @DataProvider(name = "nodes")
-    public Object[][] createSizes() {
-        List<Object[]> params = new ArrayList<>();
-
-        for (int size : Arrays.asList(0, 1, 4, 15, 16, 17, 127, 128, 129, 1000)) {
-            Integer[] array = new Integer[size];
-            for (int i = 0; i < array.length; i++) {
-                array[i] = i;
-            }
-
-            List<Node<Integer>> nodes = new ArrayList<>();
-            nodes.add(Nodes.node(array));
-            nodes.add(Nodes.node(Arrays.asList(array)));
-            nodes.add(degenerateTree(Arrays.asList(array).iterator()));
-            nodes.add(tree(Arrays.asList(array), l -> Nodes.node(l.toArray(new Integer[l.size()]))));
-            nodes.add(tree(Arrays.asList(array), l -> Nodes.node(l)));
-            nodes.add(fill(array, Nodes.builder(array.length, LambdaTestHelpers.integerArrayGenerator)));
-            nodes.add(fill(array, Nodes.builder()));
-
-            for (int i = 0; i < nodes.size(); i++) {
-                params.add(new Object[]{array, nodes.get(i)});
-            }
-
-        }
-
-        return params.toArray(new Object[0][]);
-    }
-
-    Node<Integer> fill(Integer[] array, Node.Builder<Integer> nb) {
-        nb.begin(array.length);
-        for (Integer i : array) {
-            nb.accept(i);
-        }
-        nb.end();
-        return nb.build();
-    }
-
-    Node<Integer> degenerateTree(Iterator<Integer> it) {
-        if (!it.hasNext()) {
-            return Nodes.node(Collections.emptyList());
-        }
-
-        Integer i = it.next();
-        if (it.hasNext()) {
-            return new Nodes.ConcNode<Integer>(Nodes.node(new Integer[] {i}), degenerateTree(it));
-        }
-        else {
-            return Nodes.node(new Integer[]{i});
-        }
-    }
-
-    Node<Integer> tree(List<Integer> l, Function<List<Integer>, Node<Integer>> m) {
-        if (l.size() < 3) {
-            return m.apply(l);
-        }
-        else {
-            return new Nodes.ConcNode<>(
-                    tree(l.subList(0, l.size() / 2), m),
-                    tree(l.subList(l.size() / 2, l.size()), m ));
-        }
-    }
-
-    @Test(dataProvider = "nodes")
-    public void testAsArray(Integer[] array, Node<Integer> n) {
-        assertEquals(n.asArray(LambdaTestHelpers.integerArrayGenerator), array);
-    }
-
-    @Test(dataProvider = "nodes")
-    public void testFlattenAsArray(Integer[] array, Node<Integer> n) {
-        assertEquals(Nodes.flatten(n, LambdaTestHelpers.integerArrayGenerator)
-                          .asArray(LambdaTestHelpers.integerArrayGenerator), array);
-    }
-
-    @Test(dataProvider = "nodes")
-    public void testCopyTo(Integer[] array, Node<Integer> n) {
-        Integer[] copy = new Integer[(int) n.count()];
-        n.copyInto(copy, 0);
-
-        assertEquals(copy, array);
-    }
-
-    @Test(dataProvider = "nodes", groups = { "serialization-hostile" })
-    public void testForEach(Integer[] array, Node<Integer> n) {
-        List<Integer> l = new ArrayList<>((int) n.count());
-        n.forEach(e -> l.add(e));
-
-        assertEquals(l.toArray(), array);
-    }
-
-    @Test(dataProvider = "nodes")
-    public void testStreams(Integer[] array, Node<Integer> n) {
-        TestData<Integer, Stream<Integer>> data = TestData.Factory.ofRefNode("Node", n);
-
-        exerciseOps(data, s -> s);
-
-        exerciseTerminalOps(data, s -> s.toArray());
-    }
-
-    @Test(dataProvider = "nodes")
-    public void testSpliterator(Integer[] array, Node<Integer> n) {
-        SpliteratorTestHelper.testSpliterator(n::spliterator);
-    }
-
-    @Test(dataProvider = "nodes")
-    public void testTruncate(Integer[] array, Node<Integer> n) {
-        int[] nums = new int[] { 0, 1, array.length / 2, array.length - 1, array.length };
-        for (int start : nums)
-            for (int end : nums) {
-                if (start < 0 || end < 0 || end < start || end > array.length)
-                    continue;
-                Node<Integer> slice = n.truncate(start, end, Integer[]::new);
-                Integer[] asArray = slice.asArray(Integer[]::new);
-                for (int k = start; k < end; k++)
-                    assertEquals(array[k], asArray[k - start]);
-            }
-    }
-}
--- a/jdk/test/java/util/stream/boottest/java/util/stream/SliceSpliteratorTest.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,201 +0,0 @@
-/*
- * Copyright (c) 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 java.util.stream;
-
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Spliterator;
-
-import static java.util.stream.Collectors.toList;
-import static org.testng.Assert.assertEquals;
-
-/**
- * @bug 8012987
- */
-@Test
-public class SliceSpliteratorTest extends LoggingTestCase {
-
-    static class UnorderedContentAsserter<T> implements SpliteratorTestHelper.ContentAsserter<T> {
-        Collection<T> source;
-
-        UnorderedContentAsserter(Collection<T> source) {
-            this.source = source;
-        }
-
-        @Override
-        public void assertContents(Collection<T> actual, Collection<T> expected, boolean isOrdered) {
-            if (isOrdered) {
-                assertEquals(actual, expected);
-            }
-            else {
-                assertEquals(actual.size(), expected.size());
-                assertTrue(source.containsAll(actual));
-            }
-        }
-    }
-
-    interface SliceTester {
-        void test(int size, int skip, int limit);
-    }
-
-    @DataProvider(name = "sliceSpliteratorDataProvider")
-    public static Object[][] sliceSpliteratorDataProvider() {
-        List<Object[]> data = new ArrayList<>();
-
-        // SIZED/SUBSIZED slice spliterator
-
-        {
-            SliceTester r = (size, skip, limit) -> {
-                final Collection<Integer> source =  IntStream.range(0, size).boxed().collect(toList());
-
-                SpliteratorTestHelper.testSpliterator(() -> {
-                    Spliterator<Integer> s = Arrays.spliterator(source.stream().toArray(Integer[]::new));
-
-                    return new StreamSpliterators.SliceSpliterator.OfRef<>(s, skip, limit);
-                });
-            };
-            data.add(new Object[]{"StreamSpliterators.SliceSpliterator.OfRef", r});
-        }
-
-        {
-            SliceTester r = (size, skip, limit) -> {
-                final Collection<Integer> source =  IntStream.range(0, size).boxed().collect(toList());
-
-                SpliteratorTestHelper.testIntSpliterator(() -> {
-                    Spliterator.OfInt s = Arrays.spliterator(source.stream().mapToInt(i->i).toArray());
-
-                    return new StreamSpliterators.SliceSpliterator.OfInt(s, skip, limit);
-                });
-            };
-            data.add(new Object[]{"StreamSpliterators.SliceSpliterator.OfInt", r});
-        }
-
-        {
-            SliceTester r = (size, skip, limit) -> {
-                final Collection<Long> source =  LongStream.range(0, size).boxed().collect(toList());
-
-                SpliteratorTestHelper.testLongSpliterator(() -> {
-                    Spliterator.OfLong s = Arrays.spliterator(source.stream().mapToLong(i->i).toArray());
-
-                    return new StreamSpliterators.SliceSpliterator.OfLong(s, skip, limit);
-                });
-            };
-            data.add(new Object[]{"StreamSpliterators.SliceSpliterator.OfLong", r});
-        }
-
-        {
-            SliceTester r = (size, skip, limit) -> {
-                final Collection<Double> source =  LongStream.range(0, size).asDoubleStream().boxed().collect(toList());
-
-                SpliteratorTestHelper.testDoubleSpliterator(() -> {
-                    Spliterator.OfDouble s = Arrays.spliterator(source.stream().mapToDouble(i->i).toArray());
-
-                    return new StreamSpliterators.SliceSpliterator.OfDouble(s, skip, limit);
-                });
-            };
-            data.add(new Object[]{"StreamSpliterators.SliceSpliterator.OfLong", r});
-        }
-
-
-        // Unordered slice spliterator
-
-        {
-            SliceTester r = (size, skip, limit) -> {
-                final Collection<Integer> source =  IntStream.range(0, size).boxed().collect(toList());
-                final UnorderedContentAsserter<Integer> uca = new UnorderedContentAsserter<>(source);
-
-                SpliteratorTestHelper.testSpliterator(() -> {
-                    Spliterator<Integer> s = Arrays.spliterator(source.stream().toArray(Integer[]::new));
-
-                    return new StreamSpliterators.UnorderedSliceSpliterator.OfRef<>(s, skip, limit);
-                }, uca);
-            };
-            data.add(new Object[]{"StreamSpliterators.UnorderedSliceSpliterator.OfRef", r});
-        }
-
-        {
-            SliceTester r = (size, skip, limit) -> {
-                final Collection<Integer> source =  IntStream.range(0, size).boxed().collect(toList());
-                final UnorderedContentAsserter<Integer> uca = new UnorderedContentAsserter<>(source);
-
-                SpliteratorTestHelper.testIntSpliterator(() -> {
-                    Spliterator.OfInt s = Arrays.spliterator(source.stream().mapToInt(i->i).toArray());
-
-                    return new StreamSpliterators.UnorderedSliceSpliterator.OfInt(s, skip, limit);
-                }, uca);
-            };
-            data.add(new Object[]{"StreamSpliterators.UnorderedSliceSpliterator.OfInt", r});
-        }
-
-        {
-            SliceTester r = (size, skip, limit) -> {
-                final Collection<Long> source =  LongStream.range(0, size).boxed().collect(toList());
-                final UnorderedContentAsserter<Long> uca = new UnorderedContentAsserter<>(source);
-
-                SpliteratorTestHelper.testLongSpliterator(() -> {
-                    Spliterator.OfLong s = Arrays.spliterator(source.stream().mapToLong(i->i).toArray());
-
-                    return new StreamSpliterators.UnorderedSliceSpliterator.OfLong(s, skip, limit);
-                }, uca);
-            };
-            data.add(new Object[]{"StreamSpliterators.UnorderedSliceSpliterator.OfLong", r});
-        }
-
-        {
-            SliceTester r = (size, skip, limit) -> {
-                final Collection<Double> source =  LongStream.range(0, size).asDoubleStream().boxed().collect(toList());
-                final UnorderedContentAsserter<Double> uca = new UnorderedContentAsserter<>(source);
-
-                SpliteratorTestHelper.testDoubleSpliterator(() -> {
-                    Spliterator.OfDouble s = Arrays.spliterator(LongStream.range(0, SIZE).asDoubleStream().toArray());
-
-                    return new StreamSpliterators.UnorderedSliceSpliterator.OfDouble(s, skip, limit);
-                }, uca);
-            };
-            data.add(new Object[]{"StreamSpliterators.UnorderedSliceSpliterator.OfLong", r});
-        }
-
-        return data.toArray(new Object[0][]);
-    }
-
-    static final int SIZE = 256;
-
-    static final int STEP = 32;
-
-    @Test(dataProvider = "sliceSpliteratorDataProvider")
-    public void testSliceSpliterator(String description, SliceTester r) {
-        setContext("size", SIZE);
-        for (int skip = 0; skip < SIZE; skip += STEP) {
-            setContext("skip", skip);
-            for (int limit = 0; limit < SIZE; limit += STEP) {
-                setContext("limit", skip);
-                r.test(SIZE, skip, limit);
-            }
-        }
-    }
-}
--- a/jdk/test/java/util/stream/boottest/java/util/stream/SpinedBufferTest.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,370 +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 java.util.stream;
-
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-import java.util.*;
-import java.util.function.DoubleConsumer;
-import java.util.function.IntConsumer;
-import java.util.function.LongConsumer;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-
-@Test
-public class SpinedBufferTest {
-
-    // Create sizes around the boundary of spines
-    static List<Integer> sizes;
-    static {
-        try {
-            sizes = IntStream.range(0, 15)
-                             .map(i -> 1 << i)
-                             .flatMap(i -> Arrays.stream(new int[] { i-2, i-1, i, i+1, i+2 }))
-                             .filter(i -> i >= 0)
-                             .boxed()
-                             .distinct()
-                             .collect(Collectors.toList());
-        }
-        catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    private static final int TEST_SIZE = 5000;
-
-    // SpinedBuffer
-
-    @DataProvider(name = "SpinedBuffer")
-    public Object[][] createSpinedBuffer() {
-        List<Object[]> params = new ArrayList<>();
-
-        for (int size : sizes) {
-            int[] array = IntStream.range(0, size).toArray();
-
-            SpinedBuffer<Integer> sb = new SpinedBuffer<>();
-            Arrays.stream(array).boxed().forEach(sb);
-            params.add(new Object[]{array, sb});
-
-            sb = new SpinedBuffer<>(size / 2);
-            Arrays.stream(array).boxed().forEach(sb);
-            params.add(new Object[]{array, sb});
-
-            sb = new SpinedBuffer<>(size);
-            Arrays.stream(array).boxed().forEach(sb);
-            params.add(new Object[]{array, sb});
-
-            sb = new SpinedBuffer<>(size * 2);
-            Arrays.stream(array).boxed().forEach(sb);
-            params.add(new Object[]{array, sb});
-        }
-
-        return params.toArray(new Object[0][]);
-    }
-
-    @Test(dataProvider = "SpinedBuffer")
-    public void testSpliterator(int[] array, SpinedBuffer<Integer> sb) {
-        assertEquals(sb.count(), array.length);
-        assertEquals(sb.count(), sb.spliterator().getExactSizeIfKnown());
-
-        SpliteratorTestHelper.testSpliterator(sb::spliterator);
-    }
-
-    @Test(dataProvider = "SpinedBuffer", groups = { "serialization-hostile" })
-    public void testLastSplit(int[] array, SpinedBuffer<Integer> sb) {
-        Spliterator<Integer> spliterator = sb.spliterator();
-        Spliterator<Integer> split = spliterator.trySplit();
-        long splitSizes = (split == null) ? 0 : split.getExactSizeIfKnown();
-        long lastSplitSize = spliterator.getExactSizeIfKnown();
-        splitSizes += lastSplitSize;
-
-        assertEquals(splitSizes, array.length);
-
-        List<Integer> contentOfLastSplit = new ArrayList<>();
-        spliterator.forEachRemaining(contentOfLastSplit::add);
-
-        assertEquals(contentOfLastSplit.size(), lastSplitSize);
-
-        List<Integer> end = Arrays.stream(array)
-                .boxed()
-                .skip(array.length - lastSplitSize)
-                .collect(Collectors.toList());
-        assertEquals(contentOfLastSplit, end);
-    }
-
-    @Test(groups = { "serialization-hostile" })
-    public void testSpinedBuffer() {
-        List<Integer> list1 = new ArrayList<>();
-        List<Integer> list2 = new ArrayList<>();
-        SpinedBuffer<Integer> sb = new SpinedBuffer<>();
-        for (int i = 0; i < TEST_SIZE; i++) {
-            list1.add(i);
-            sb.accept(i);
-        }
-        Iterator<Integer> it = sb.iterator();
-        for (int i = 0; i < TEST_SIZE; i++)
-            list2.add(it.next());
-        assertFalse(it.hasNext());
-        assertEquals(list1, list2);
-
-        for (int i = 0; i < TEST_SIZE; i++)
-            assertEquals(sb.get(i), (Integer) i, Integer.toString(i));
-
-        list2.clear();
-        sb.forEach(list2::add);
-        assertEquals(list1, list2);
-        Integer[] array = sb.asArray(LambdaTestHelpers.integerArrayGenerator);
-        list2.clear();
-        for (Integer i : array)
-            list2.add(i);
-        assertEquals(list1, list2);
-    }
-
-    // IntSpinedBuffer
-
-    @DataProvider(name = "IntSpinedBuffer")
-    public Object[][] createIntSpinedBuffer() {
-        List<Object[]> params = new ArrayList<>();
-
-        for (int size : sizes) {
-            int[] array = IntStream.range(0, size).toArray();
-            SpinedBuffer.OfInt sb = new SpinedBuffer.OfInt();
-            Arrays.stream(array).forEach(sb);
-
-            params.add(new Object[]{array, sb});
-        }
-
-        return params.toArray(new Object[0][]);
-    }
-
-    @Test(dataProvider = "IntSpinedBuffer")
-    public void testIntSpliterator(int[] array, SpinedBuffer.OfInt sb) {
-        assertEquals(sb.count(), array.length);
-        assertEquals(sb.count(), sb.spliterator().getExactSizeIfKnown());
-
-        SpliteratorTestHelper.testIntSpliterator(sb::spliterator);
-    }
-
-    @Test(dataProvider = "IntSpinedBuffer", groups = { "serialization-hostile" })
-    public void testIntLastSplit(int[] array, SpinedBuffer.OfInt sb) {
-        Spliterator.OfInt spliterator = sb.spliterator();
-        Spliterator.OfInt split = spliterator.trySplit();
-        long splitSizes = (split == null) ? 0 : split.getExactSizeIfKnown();
-        long lastSplitSize = spliterator.getExactSizeIfKnown();
-        splitSizes += lastSplitSize;
-
-        assertEquals(splitSizes, array.length);
-
-        List<Integer> contentOfLastSplit = new ArrayList<>();
-        spliterator.forEachRemaining((IntConsumer) contentOfLastSplit::add);
-
-        assertEquals(contentOfLastSplit.size(), lastSplitSize);
-
-        List<Integer> end = Arrays.stream(array)
-                .boxed()
-                .skip(array.length - lastSplitSize)
-                .collect(Collectors.toList());
-        assertEquals(contentOfLastSplit, end);
-    }
-
-    @Test(groups = { "serialization-hostile" })
-    public void testIntSpinedBuffer() {
-        List<Integer> list1 = new ArrayList<>();
-        List<Integer> list2 = new ArrayList<>();
-        SpinedBuffer.OfInt sb = new SpinedBuffer.OfInt();
-        for (int i = 0; i < TEST_SIZE; i++) {
-            list1.add(i);
-            sb.accept(i);
-        }
-        PrimitiveIterator.OfInt it = sb.iterator();
-        for (int i = 0; i < TEST_SIZE; i++)
-            list2.add(it.nextInt());
-        assertFalse(it.hasNext());
-        assertEquals(list1, list2);
-
-        for (int i = 0; i < TEST_SIZE; i++)
-            assertEquals(sb.get(i), i, Integer.toString(i));
-
-        list2.clear();
-        sb.forEach((int i) -> list2.add(i));
-        assertEquals(list1, list2);
-        int[] array = sb.asPrimitiveArray();
-        list2.clear();
-        for (int i : array)
-            list2.add(i);
-        assertEquals(list1, list2);
-    }
-
-    // LongSpinedBuffer
-
-    @DataProvider(name = "LongSpinedBuffer")
-    public Object[][] createLongSpinedBuffer() {
-        List<Object[]> params = new ArrayList<>();
-
-        for (int size : sizes) {
-            long[] array = LongStream.range(0, size).toArray();
-            SpinedBuffer.OfLong sb = new SpinedBuffer.OfLong();
-            Arrays.stream(array).forEach(sb);
-
-            params.add(new Object[]{array, sb});
-        }
-
-        return params.toArray(new Object[0][]);
-    }
-
-    @Test(dataProvider = "LongSpinedBuffer")
-    public void testLongSpliterator(long[] array, SpinedBuffer.OfLong sb) {
-        assertEquals(sb.count(), array.length);
-        assertEquals(sb.count(), sb.spliterator().getExactSizeIfKnown());
-
-        SpliteratorTestHelper.testLongSpliterator(sb::spliterator);
-    }
-
-    @Test(dataProvider = "LongSpinedBuffer", groups = { "serialization-hostile" })
-    public void testLongLastSplit(long[] array, SpinedBuffer.OfLong sb) {
-        Spliterator.OfLong spliterator = sb.spliterator();
-        Spliterator.OfLong split = spliterator.trySplit();
-        long splitSizes = (split == null) ? 0 : split.getExactSizeIfKnown();
-        long lastSplitSize = spliterator.getExactSizeIfKnown();
-        splitSizes += lastSplitSize;
-
-        assertEquals(splitSizes, array.length);
-
-        List<Long> contentOfLastSplit = new ArrayList<>();
-        spliterator.forEachRemaining((LongConsumer) contentOfLastSplit::add);
-
-        assertEquals(contentOfLastSplit.size(), lastSplitSize);
-
-        List<Long> end = Arrays.stream(array)
-                .boxed()
-                .skip(array.length - lastSplitSize)
-                .collect(Collectors.toList());
-        assertEquals(contentOfLastSplit, end);
-    }
-
-    @Test(groups = { "serialization-hostile" })
-    public void testLongSpinedBuffer() {
-        List<Long> list1 = new ArrayList<>();
-        List<Long> list2 = new ArrayList<>();
-        SpinedBuffer.OfLong sb = new SpinedBuffer.OfLong();
-        for (long i = 0; i < TEST_SIZE; i++) {
-            list1.add(i);
-            sb.accept(i);
-        }
-        PrimitiveIterator.OfLong it = sb.iterator();
-        for (int i = 0; i < TEST_SIZE; i++)
-            list2.add(it.nextLong());
-        assertFalse(it.hasNext());
-        assertEquals(list1, list2);
-
-        for (int i = 0; i < TEST_SIZE; i++)
-            assertEquals(sb.get(i), i, Long.toString(i));
-
-        list2.clear();
-        sb.forEach((long i) -> list2.add(i));
-        assertEquals(list1, list2);
-        long[] array = sb.asPrimitiveArray();
-        list2.clear();
-        for (long i : array)
-            list2.add(i);
-        assertEquals(list1, list2);
-    }
-
-    // DoubleSpinedBuffer
-
-    @DataProvider(name = "DoubleSpinedBuffer")
-    public Object[][] createDoubleSpinedBuffer() {
-        List<Object[]> params = new ArrayList<>();
-
-        for (int size : sizes) {
-            // @@@ replace with double range when implemented
-            double[] array = LongStream.range(0, size).asDoubleStream().toArray();
-            SpinedBuffer.OfDouble sb = new SpinedBuffer.OfDouble();
-            Arrays.stream(array).forEach(sb);
-
-            params.add(new Object[]{array, sb});
-        }
-
-        return params.toArray(new Object[0][]);
-    }
-
-    @Test(dataProvider = "DoubleSpinedBuffer")
-    public void testDoubleSpliterator(double[] array, SpinedBuffer.OfDouble sb) {
-        assertEquals(sb.count(), array.length);
-        assertEquals(sb.count(), sb.spliterator().getExactSizeIfKnown());
-
-        SpliteratorTestHelper.testDoubleSpliterator(sb::spliterator);
-    }
-
-    @Test(dataProvider = "DoubleSpinedBuffer", groups = { "serialization-hostile" })
-    public void testLongLastSplit(double[] array, SpinedBuffer.OfDouble sb) {
-        Spliterator.OfDouble spliterator = sb.spliterator();
-        Spliterator.OfDouble split = spliterator.trySplit();
-        long splitSizes = (split == null) ? 0 : split.getExactSizeIfKnown();
-        long lastSplitSize = spliterator.getExactSizeIfKnown();
-        splitSizes += lastSplitSize;
-
-        assertEquals(splitSizes, array.length);
-
-        List<Double> contentOfLastSplit = new ArrayList<>();
-        spliterator.forEachRemaining((DoubleConsumer) contentOfLastSplit::add);
-
-        assertEquals(contentOfLastSplit.size(), lastSplitSize);
-
-        List<Double> end = Arrays.stream(array)
-                .boxed()
-                .skip(array.length - lastSplitSize)
-                .collect(Collectors.toList());
-        assertEquals(contentOfLastSplit, end);
-    }
-
-    @Test(groups = { "serialization-hostile" })
-    public void testDoubleSpinedBuffer() {
-        List<Double> list1 = new ArrayList<>();
-        List<Double> list2 = new ArrayList<>();
-        SpinedBuffer.OfDouble sb = new SpinedBuffer.OfDouble();
-        for (long i = 0; i < TEST_SIZE; i++) {
-            list1.add((double) i);
-            sb.accept((double) i);
-        }
-        PrimitiveIterator.OfDouble it = sb.iterator();
-        for (int i = 0; i < TEST_SIZE; i++)
-            list2.add(it.nextDouble());
-        assertFalse(it.hasNext());
-        assertEquals(list1, list2);
-
-        for (int i = 0; i < TEST_SIZE; i++)
-            assertEquals(sb.get(i), (double) i, Double.toString(i));
-
-        list2.clear();
-        sb.forEach((double i) -> list2.add(i));
-        assertEquals(list1, list2);
-        double[] array = sb.asPrimitiveArray();
-        list2.clear();
-        for (double i : array)
-            list2.add(i);
-        assertEquals(list1, list2);
-    }
-}
--- a/jdk/test/java/util/stream/boottest/java/util/stream/StreamFlagsTest.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +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 java.util.stream;
-
-import org.testng.annotations.Test;
-
-import java.util.*;
-import java.util.stream.Stream;
-import java.util.stream.StreamOpFlag;
-import java.util.stream.Streams;
-
-import static java.util.stream.StreamOpFlag.*;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-/**
- * StreamFlagsTest
- *
- * @author Brian Goetz
- */
-@Test
-public class StreamFlagsTest {
-    Stream<String> arrayList = new ArrayList<String>().stream();
-    Stream<String> linkedList = new LinkedList<String>().stream();
-    Stream<String> hashSet = new HashSet<String>().stream();
-    Stream<String> treeSet = new TreeSet<String>().stream();
-    Stream<String> linkedHashSet = new LinkedHashSet<String>().stream();
-    Stream<String> repeat = Stream.generate(() -> "");
-
-    Stream<?>[] streams = { arrayList, linkedList, hashSet, treeSet, linkedHashSet, repeat };
-
-    private void assertFlags(int value, EnumSet<StreamOpFlag> setFlags, EnumSet<StreamOpFlag> clearFlags) {
-        for (StreamOpFlag flag : setFlags)
-            assertTrue(flag.isKnown(value));
-        for (StreamOpFlag flag : clearFlags)
-            assertTrue(!flag.isKnown(value));
-    }
-
-    public void testBaseStreams() {
-        Stream<String> arrayList = new ArrayList<String>().stream();
-        Stream<String> linkedList = new LinkedList<String>().stream();
-        Stream<String> hashSet = new HashSet<String>().stream();
-        Stream<String> treeSet = new TreeSet<String>().stream();
-        Stream<String> linkedHashSet = new LinkedHashSet<String>().stream();
-        Stream<String> repeat = Stream.generate(() -> "");
-
-        assertFlags(OpTestCase.getStreamFlags(arrayList),
-                    EnumSet.of(ORDERED, SIZED),
-                    EnumSet.of(DISTINCT, SORTED, SHORT_CIRCUIT));
-        assertFlags(OpTestCase.getStreamFlags(linkedList),
-                    EnumSet.of(ORDERED, SIZED),
-                    EnumSet.of(DISTINCT, SORTED, SHORT_CIRCUIT));
-        assertFlags(OpTestCase.getStreamFlags(hashSet),
-                    EnumSet.of(SIZED, DISTINCT),
-                    EnumSet.of(ORDERED, SORTED, SHORT_CIRCUIT));
-        assertFlags(OpTestCase.getStreamFlags(treeSet),
-                    EnumSet.of(ORDERED, SIZED, DISTINCT, SORTED),
-                    EnumSet.of(SHORT_CIRCUIT));
-        assertFlags(OpTestCase.getStreamFlags(linkedHashSet),
-                    EnumSet.of(ORDERED, DISTINCT, SIZED),
-                    EnumSet.of(SORTED, SHORT_CIRCUIT));
-        assertFlags(OpTestCase.getStreamFlags(repeat),
-                    EnumSet.noneOf(StreamOpFlag.class),
-                    EnumSet.of(DISTINCT, SORTED, SHORT_CIRCUIT));
-    }
-
-    public void testFilter() {
-        for (Stream<?> s : streams) {
-            int baseFlags = OpTestCase.getStreamFlags(s);
-            int filteredFlags = OpTestCase.getStreamFlags(s.filter((Object e) -> true));
-            int expectedFlags = baseFlags & ~SIZED.set();
-
-            assertEquals(filteredFlags, expectedFlags);
-        }
-    }
-}
--- a/jdk/test/java/util/stream/boottest/java/util/stream/StreamOpFlagsTest.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,381 +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 java.util.stream;
-
-import org.testng.annotations.Test;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Spliterator;
-import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.function.ToDoubleFunction;
-import java.util.function.ToIntFunction;
-import java.util.function.ToLongFunction;
-
-import static java.util.stream.Collectors.toList;
-import static java.util.stream.StreamOpFlag.*;
-import static org.testng.Assert.*;
-import static org.testng.Assert.assertEquals;
-
-@Test
-public class StreamOpFlagsTest {
-
-    public void testNullCombine() {
-        int sourceFlags = StreamOpFlag.IS_SIZED;
-
-        assertEquals(sourceFlags, toStreamFlags(combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE)));
-    }
-
-    public void testInitialOpFlagsFromSourceFlags() {
-        List<StreamOpFlag> flags = new ArrayList<>(StreamOpFlagTestHelper.allStreamFlags());
-        for (int i = 0; i < (1 << flags.size()); i++)  {
-            int sourceFlags = 0;
-            for (int f = 0; f < flags.size(); f++) {
-                if ((i & (1 << f)) != 0)  {
-                    sourceFlags |= flags.get(f).set();
-                }
-            }
-
-            int opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
-            assertEquals(opsFlags, (~(sourceFlags << 1)) & StreamOpFlag.INITIAL_OPS_VALUE);
-        }
-    }
-
-    public void testSameCombine() {
-        for (StreamOpFlag f : StreamOpFlagTestHelper.allStreamFlags()) {
-            int sourceFlags = f.set();
-            int opsFlags;
-
-            opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
-            opsFlags = combineOpFlags(f.set(), opsFlags);
-            assertEquals(sourceFlags, toStreamFlags(opsFlags));
-        }
-    }
-
-    public void testOpClear() {
-        for (StreamOpFlag f : StreamOpFlagTestHelper.allStreamFlags()) {
-            // Clear when source not set
-            int sourceFlags = 0;
-            int opsFlags;
-
-            opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
-            opsFlags = combineOpFlags(f.clear(), opsFlags);
-            assertEquals(sourceFlags, toStreamFlags(opsFlags));
-
-            // Clear when source set
-            sourceFlags = f.set();
-
-            opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
-            opsFlags = combineOpFlags(f.clear(), opsFlags);
-            assertEquals(0, toStreamFlags(opsFlags));
-        }
-    }
-
-    public void testOpInject() {
-        for (StreamOpFlag f : StreamOpFlagTestHelper.allStreamFlags()) {
-            // Set when source not set
-            int sourceFlags = 0;
-            int opsFlags;
-
-            opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
-            opsFlags = combineOpFlags(f.set(), opsFlags);
-            assertEquals(f.set(), toStreamFlags(opsFlags));
-
-            // Set when source set
-            sourceFlags = f.set();
-
-            opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
-            opsFlags = combineOpFlags(f.set(), opsFlags);
-            assertEquals(sourceFlags, toStreamFlags(opsFlags));
-        }
-    }
-
-    public void testPairSet() {
-        List<Integer> sourceFlagsList
-                = StreamOpFlagTestHelper.allStreamFlags().stream().map(StreamOpFlag::set).collect(toList());
-        sourceFlagsList.add(0, 0);
-
-        for (int sourceFlags : sourceFlagsList) {
-            for (StreamOpFlag f1 : StreamOpFlagTestHelper.allStreamFlags()) {
-                for (StreamOpFlag f2 : StreamOpFlagTestHelper.allStreamFlags()) {
-                    int opsFlags;
-
-                    opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
-                    opsFlags = combineOpFlags(f1.set(), opsFlags);
-                    opsFlags = combineOpFlags(f2.set(), opsFlags);
-                    assertEquals(sourceFlags | f1.set() | f2.set(), toStreamFlags(opsFlags));
-                }
-            }
-        }
-    }
-
-    public void testPairSetAndClear() {
-        List<Integer> sourceFlagsList
-                = StreamOpFlagTestHelper.allStreamFlags().stream().map(StreamOpFlag::set).collect(toList());
-        sourceFlagsList.add(0, 0);
-
-        for (int sourceFlags : sourceFlagsList) {
-            for (StreamOpFlag f1 : StreamOpFlagTestHelper.allStreamFlags())  {
-                for (StreamOpFlag f2 : StreamOpFlagTestHelper.allStreamFlags()) {
-                    int opsFlags;
-
-                    opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
-                    opsFlags = combineOpFlags(f1.set(), opsFlags);
-                    opsFlags = combineOpFlags(f2.clear(), opsFlags);
-                    if (f1 == f2)
-                        assertEquals((f2.set() == sourceFlags) ? 0 : sourceFlags, toStreamFlags(opsFlags));
-                    else
-                        assertEquals((f2.set() == sourceFlags) ? f1.set() : sourceFlags | f1.set(), toStreamFlags(opsFlags));
-                }
-            }
-        }
-    }
-
-    public void testShortCircuit() {
-        int opsFlags = combineOpFlags(0, StreamOpFlag.INITIAL_OPS_VALUE);
-        assertFalse(StreamOpFlag.SHORT_CIRCUIT.isKnown(opsFlags));
-
-        opsFlags = combineOpFlags(StreamOpFlag.IS_SHORT_CIRCUIT, opsFlags);
-        assertTrue(StreamOpFlag.SHORT_CIRCUIT.isKnown(opsFlags));
-
-        opsFlags = combineOpFlags(0, opsFlags);
-        assertTrue(StreamOpFlag.SHORT_CIRCUIT.isKnown(opsFlags));
-    }
-
-    public void testApplySourceFlags() {
-        int sourceFlags = StreamOpFlag.IS_SIZED | StreamOpFlag.IS_DISTINCT;
-
-        List<Integer> ops = Arrays.asList(StreamOpFlag.NOT_SIZED, StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SORTED);
-
-        int opsFlags = StreamOpFlag.combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
-        for (int opFlags : ops) {
-            opsFlags = combineOpFlags(opFlags, opsFlags);
-        }
-        assertFalse(StreamOpFlag.SIZED.isKnown(opsFlags));
-        assertTrue(StreamOpFlag.SIZED.isCleared(opsFlags));
-        assertFalse(StreamOpFlag.SIZED.isPreserved(opsFlags));
-        assertTrue(StreamOpFlag.DISTINCT.isKnown(opsFlags));
-        assertFalse(StreamOpFlag.DISTINCT.isCleared(opsFlags));
-        assertFalse(StreamOpFlag.DISTINCT.isPreserved(opsFlags));
-        assertTrue(StreamOpFlag.SORTED.isKnown(opsFlags));
-        assertFalse(StreamOpFlag.SORTED.isCleared(opsFlags));
-        assertFalse(StreamOpFlag.SORTED.isPreserved(opsFlags));
-        assertTrue(StreamOpFlag.ORDERED.isKnown(opsFlags));
-        assertFalse(StreamOpFlag.ORDERED.isCleared(opsFlags));
-        assertFalse(StreamOpFlag.ORDERED.isPreserved(opsFlags));
-
-        int streamFlags = toStreamFlags(opsFlags);
-        assertFalse(StreamOpFlag.SIZED.isKnown(streamFlags));
-        assertTrue(StreamOpFlag.DISTINCT.isKnown(streamFlags));
-        assertTrue(StreamOpFlag.SORTED.isKnown(streamFlags));
-        assertTrue(StreamOpFlag.ORDERED.isKnown(streamFlags));
-    }
-
-    public void testSpliteratorMask() {
-        assertSpliteratorMask(StreamOpFlag.DISTINCT.set(), StreamOpFlag.IS_DISTINCT);
-        assertSpliteratorMask(StreamOpFlag.DISTINCT.clear(), 0);
-
-        assertSpliteratorMask(StreamOpFlag.SORTED.set(), StreamOpFlag.IS_SORTED);
-        assertSpliteratorMask(StreamOpFlag.SORTED.clear(), 0);
-
-        assertSpliteratorMask(StreamOpFlag.ORDERED.set(), StreamOpFlag.IS_ORDERED);
-        assertSpliteratorMask(StreamOpFlag.ORDERED.clear(), 0);
-
-        assertSpliteratorMask(StreamOpFlag.SIZED.set(), StreamOpFlag.IS_SIZED);
-        assertSpliteratorMask(StreamOpFlag.SIZED.clear(), 0);
-
-        assertSpliteratorMask(StreamOpFlag.SHORT_CIRCUIT.set(), 0);
-        assertSpliteratorMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
-    }
-
-    private void assertSpliteratorMask(int actual, int expected) {
-        assertEquals(actual & StreamOpFlag.SPLITERATOR_CHARACTERISTICS_MASK, expected);
-    }
-
-    public void testStreamMask() {
-        assertStreamMask(StreamOpFlag.DISTINCT.set(), StreamOpFlag.IS_DISTINCT);
-        assertStreamMask(StreamOpFlag.DISTINCT.clear(), 0);
-
-        assertStreamMask(StreamOpFlag.SORTED.set(), StreamOpFlag.IS_SORTED);
-        assertStreamMask(StreamOpFlag.SORTED.clear(), 0);
-
-        assertStreamMask(StreamOpFlag.ORDERED.set(), StreamOpFlag.IS_ORDERED);
-        assertStreamMask(StreamOpFlag.ORDERED.clear(), 0);
-
-        assertStreamMask(StreamOpFlag.SIZED.set(), StreamOpFlag.IS_SIZED);
-        assertStreamMask(StreamOpFlag.SIZED.clear(), 0);
-
-        assertStreamMask(StreamOpFlag.SHORT_CIRCUIT.set(), 0);
-        assertStreamMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
-    }
-
-    private void assertStreamMask(int actual, int expected) {
-        assertEquals(actual & StreamOpFlag.STREAM_MASK, expected);
-    }
-
-    public void testOpMask() {
-        assertOpMask(StreamOpFlag.DISTINCT.set(), StreamOpFlag.IS_DISTINCT);
-        assertOpMask(StreamOpFlag.DISTINCT.clear(), StreamOpFlag.NOT_DISTINCT);
-
-        assertOpMask(StreamOpFlag.SORTED.set(), StreamOpFlag.IS_SORTED);
-        assertOpMask(StreamOpFlag.SORTED.clear(), StreamOpFlag.NOT_SORTED);
-
-        assertOpMask(StreamOpFlag.ORDERED.set(), StreamOpFlag.IS_ORDERED);
-        assertOpMask(StreamOpFlag.ORDERED.clear(), StreamOpFlag.NOT_ORDERED);
-
-        assertOpMask(StreamOpFlag.SIZED.set(), 0);
-        assertOpMask(StreamOpFlag.SIZED.clear(), StreamOpFlag.NOT_SIZED);
-
-        assertOpMask(StreamOpFlag.SHORT_CIRCUIT.set(), StreamOpFlag.IS_SHORT_CIRCUIT);
-        assertOpMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
-    }
-
-    private void assertOpMask(int actual, int expected) {
-        assertEquals(actual & StreamOpFlag.OP_MASK, expected);
-    }
-
-    public void testTerminalOpMask() {
-        assertTerminalOpMask(StreamOpFlag.DISTINCT.set(), 0);
-        assertTerminalOpMask(StreamOpFlag.DISTINCT.clear(), 0);
-
-        assertTerminalOpMask(StreamOpFlag.SORTED.set(), 0);
-        assertTerminalOpMask(StreamOpFlag.SORTED.clear(), 0);
-
-        assertTerminalOpMask(StreamOpFlag.ORDERED.set(), 0);
-        assertTerminalOpMask(StreamOpFlag.ORDERED.clear(), StreamOpFlag.NOT_ORDERED);
-
-        assertTerminalOpMask(StreamOpFlag.SIZED.set(), 0);
-        assertTerminalOpMask(StreamOpFlag.SIZED.clear(), 0);
-
-        assertTerminalOpMask(StreamOpFlag.SHORT_CIRCUIT.set(), StreamOpFlag.IS_SHORT_CIRCUIT);
-        assertTerminalOpMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
-    }
-
-    private void assertTerminalOpMask(int actual, int expected) {
-        assertEquals(actual & StreamOpFlag.TERMINAL_OP_MASK, expected);
-    }
-
-    public void testUpstreamTerminalOpMask() {
-        assertUpstreamTerminalOpMask(StreamOpFlag.DISTINCT.set(), 0);
-        assertUpstreamTerminalOpMask(StreamOpFlag.DISTINCT.clear(), 0);
-
-        assertUpstreamTerminalOpMask(StreamOpFlag.SORTED.set(), 0);
-        assertUpstreamTerminalOpMask(StreamOpFlag.SORTED.clear(), 0);
-
-        assertUpstreamTerminalOpMask(StreamOpFlag.ORDERED.set(), 0);
-        assertUpstreamTerminalOpMask(StreamOpFlag.ORDERED.clear(), StreamOpFlag.NOT_ORDERED);
-
-        assertUpstreamTerminalOpMask(StreamOpFlag.SIZED.set(), 0);
-        assertUpstreamTerminalOpMask(StreamOpFlag.SIZED.clear(), 0);
-
-        assertUpstreamTerminalOpMask(StreamOpFlag.SHORT_CIRCUIT.set(), 0);
-        assertUpstreamTerminalOpMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
-    }
-
-    private void assertUpstreamTerminalOpMask(int actual, int expected) {
-        assertEquals(actual & StreamOpFlag.UPSTREAM_TERMINAL_OP_MASK, expected);
-    }
-
-    public void testSpliteratorCharacteristics() {
-        assertEquals(Spliterator.DISTINCT, StreamOpFlag.IS_DISTINCT);
-        assertEquals(Spliterator.SORTED, StreamOpFlag.IS_SORTED);
-        assertEquals(Spliterator.ORDERED, StreamOpFlag.IS_ORDERED);
-        assertEquals(Spliterator.SIZED, StreamOpFlag.IS_SIZED);
-
-        List<Integer> others = Arrays.asList(Spliterator.NONNULL, Spliterator.IMMUTABLE,
-                                             Spliterator.CONCURRENT, Spliterator.SUBSIZED);
-        for (int c : others) {
-            assertNotEquals(c, StreamOpFlag.IS_SHORT_CIRCUIT);
-        }
-    }
-
-    public void testSpliteratorCharacteristicsMask() {
-        assertSpliteratorCharacteristicsMask(StreamOpFlag.DISTINCT.set(), StreamOpFlag.IS_DISTINCT);
-        assertSpliteratorCharacteristicsMask(StreamOpFlag.DISTINCT.clear(), 0);
-
-        assertSpliteratorCharacteristicsMask(StreamOpFlag.SORTED.set(), StreamOpFlag.IS_SORTED);
-        assertSpliteratorCharacteristicsMask(StreamOpFlag.SORTED.clear(), 0);
-
-        assertSpliteratorCharacteristicsMask(StreamOpFlag.ORDERED.set(), StreamOpFlag.IS_ORDERED);
-        assertSpliteratorCharacteristicsMask(StreamOpFlag.ORDERED.clear(), 0);
-
-        assertSpliteratorCharacteristicsMask(StreamOpFlag.SIZED.set(), StreamOpFlag.IS_SIZED);
-        assertSpliteratorCharacteristicsMask(StreamOpFlag.SIZED.clear(), 0);
-
-        assertSpliteratorCharacteristicsMask(StreamOpFlag.SHORT_CIRCUIT.set(), 0);
-        assertSpliteratorCharacteristicsMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
-    }
-
-    private void assertSpliteratorCharacteristicsMask(int actual, int expected) {
-        assertEquals(StreamOpFlag.fromCharacteristics(actual), expected);
-    }
-
-    public void testSpliteratorSorted() {
-        class SortedEmptySpliterator implements Spliterator<Object> {
-            final Comparator<Object> c;
-
-            SortedEmptySpliterator(Comparator<Object> c) {
-                this.c = c;
-            }
-
-            @Override
-            public Spliterator<Object> trySplit() {
-                return null;
-            }
-
-            @Override
-            public boolean tryAdvance(Consumer<? super Object> action) {
-                return false;
-            }
-
-            @Override
-            public long estimateSize() {
-                return Long.MAX_VALUE;
-            }
-
-            @Override
-            public int characteristics() {
-                return Spliterator.SORTED;
-            }
-
-            @Override
-            public Comparator<? super Object> getComparator() {
-                return c;
-            }
-        };
-
-        {
-            int flags = StreamOpFlag.fromCharacteristics(new SortedEmptySpliterator(null));
-            assertEquals(flags, StreamOpFlag.IS_SORTED);
-        }
-
-        {
-            int flags = StreamOpFlag.fromCharacteristics(new SortedEmptySpliterator((a, b) -> 0));
-            assertEquals(flags, 0);
-        }
-    }
-}
--- a/jdk/test/java/util/stream/boottest/java/util/stream/StreamReuseTest.java	Tue Nov 10 13:46:45 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,441 +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 java.util.stream;
-
-import org.testng.annotations.Test;
-
-import java.util.function.Function;
-
-import static org.testng.Assert.fail;
-
-/**
- * StreamReuseTest
- *
- * @author Brian Goetz
- */
-@Test
-public class StreamReuseTest {
-
-    private <T, U, E, S extends BaseStream<E, S>, D extends TestData<E, S>> void assertSecondFails(
-            D data,
-            Function<S, T> first,
-            Function<S, U> second,
-            Class<? extends Throwable> exception,
-            String text) {
-        S stream = data.stream();
-        T fr = first.apply(stream);
-        try {
-            U sr = second.apply(stream);
-            fail(text + " (seq)");
-        }
-        catch (Throwable e) {
-            if (exception.isAssignableFrom(e.getClass())) {
-                // Expected
-            }
-            else if (e instanceof Error)
-                throw (Error) e;
-            else if (e instanceof RuntimeException)
-                throw (RuntimeException) e;
-            else
-                throw new AssertionError("Unexpected exception " + e.getClass(), e);
-        }
-
-        stream = data.parallelStream();
-        fr = first.apply(stream);
-        try {
-            U sr = second.apply(stream);
-            fail(text + " (par)");
-        }
-        catch (Throwable e) {
-            if (exception.isAssignableFrom(e.getClass())) {
-                // Expected
-            }
-            else if (e instanceof Error)
-                throw (Error) e;
-            else if (e instanceof RuntimeException)
-                throw (RuntimeException) e;
-            else
-                throw new AssertionError("Unexpected exception " + e.getClass(), e);
-        }
-    }
-
-    // Stream
-
-    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
-    public void testTwoStreams(String name, TestData<Integer, Stream<Integer>> data) {
-        assertSecondFails(data,
-                          (Stream<Integer> s) -> s.map(i -> i), (Stream<Integer> s) -> s.map(i -> i),
-                          IllegalStateException.class,
-                          "Stream map / map succeeded erroneously");
-        assertSecondFails(data,
-                          Stream::distinct, (Stream<Integer> s) -> s.map(i -> i),
-                          IllegalStateException.class,
-                          "Stream distinct / map succeeded erroneously");
-        assertSecondFails(data,
-                          (Stream<Integer> s) -> s.map(i -> i), Stream::distinct,
-                          IllegalStateException.class,
-                          "Stream map / distinct succeeded erroneously");
-        assertSecondFails(data,
-                          Stream::distinct, Stream::distinct,
-                          IllegalStateException.class,
-                          "Stream distinct / distinct succeeded erroneously");
-    }
-
-    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
-    public void testTwoTerminals(String name, TestData<Integer, Stream<Integer>> data) {
-        assertSecondFails(data,
-                          Stream::findFirst, Stream::findFirst,
-                          IllegalStateException.class,
-                          "Stream findFirst / findFirst succeeded erroneously");
-    }
-
-    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
-    public void testTerminalStream(String name, TestData<Integer, Stream<Integer>> data) {
-        assertSecondFails(data,
-                          Stream::findFirst, (Stream<Integer> s) -> s.map(i -> i),
-                          IllegalStateException.class,
-                          "Stream findFirst / map succeeded erroneously");
-        assertSecondFails(data,
-                          (Stream<Integer> s) -> s.map(i -> i), Stream::findFirst,
-                          IllegalStateException.class,
-                          "Stream map / findFirst succeeded erroneously");
-        assertSecondFails(data,
-                          Stream::findFirst, Stream::distinct,
-                          IllegalStateException.class,
-                          "Stream findFirst / distinct succeeded erroneously");
-        assertSecondFails(data,
-                          Stream::distinct, Stream::findFirst,
-                          IllegalStateException.class,
-                          "Stream distinct / findFirst succeeded erroneously");
-    }
-
-    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
-    public void testTwoIterators(String name, TestData<Integer, Stream<Integer>> data) {
-        assertSecondFails(data,
-                          Stream::iterator, Stream::iterator,
-                          IllegalStateException.class,
-                          "Stream iterator / iterator succeeded erroneously");
-    }
-
-    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
-    public void testTerminalIterator(String name, TestData<Integer, Stream<Integer>> data) {
-        assertSecondFails(data,
-                          Stream::iterator, Stream::findFirst,
-                          IllegalStateException.class,
-                          "Stream iterator / findFirst succeeded erroneously");
-        assertSecondFails(data,
-                          Stream::findFirst, Stream::iterator,
-                          IllegalStateException.class,
-                          "Stream findFirst / iterator succeeded erroneously");
-    }
-
-    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
-    public void testStreamIterator(String name, TestData<Integer, Stream<Integer>> data) {
-        assertSecondFails(data,
-                          Stream::iterator, (Stream<Integer> s) -> s.map(i -> i),
-                          IllegalStateException.class,
-                          "Stream iterator / map succeeded erroneously");
-        assertSecondFails(data,
-                          (Stream<Integer> s) -> s.map(i -> i), Stream::iterator,
-                          IllegalStateException.class,
-                          "Stream map / iterator succeeded erroneously");
-        assertSecondFails(data,
-                          Stream::iterator, Stream::distinct,
-                          IllegalStateException.class,
-                          "Stream iterator / distinct succeeded erroneously");
-        assertSecondFails(data,
-                          Stream::distinct, Stream::iterator,
-                          IllegalStateException.class,
-                          "Stream distinct / iterator succeeded erroneously");
-    }
-
-    // IntStream
-
-    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
-    public void testTwoStreams(String name, TestData.OfInt data) {
-        assertSecondFails(data,
-                          (IntStream s) -> s.mapToObj(i -> i), (IntStream s) -> s.mapToObj(i -> i),
-                          IllegalStateException.class,
-                          "IntStream map / map succeeded erroneously");
-        assertSecondFails(data,
-                          IntStream::distinct, (IntStream s) -> s.mapToObj(i -> i),
-                          IllegalStateException.class,
-                          "IntStream distinct / map succeeded erroneously");
-        assertSecondFails(data,
-                          (IntStream s) -> s.mapToObj(i -> i), IntStream::distinct,
-                          IllegalStateException.class,
-                          "IntStream map / distinct succeeded erroneously");
-        assertSecondFails(data,
-                          IntStream::distinct, IntStream::distinct,
-                          IllegalStateException.class,
-                          "IntStream distinct / distinct succeeded erroneously");
-    }
-
-    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
-    public void testTwoTerminals(String name, TestData.OfInt data) {
-        assertSecondFails(data,
-                          IntStream::sum, IntStream::sum,
-                          IllegalStateException.class,
-                          "IntStream sum / sum succeeded erroneously");
-    }
-
-    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
-    public void testTerminalStream(String name, TestData.OfInt data) {
-        assertSecondFails(data,
-                          IntStream::sum, (IntStream s) -> s.mapToObj(i -> i),
-                          IllegalStateException.class,
-                          "IntStream sum / map succeeded erroneously");
-        assertSecondFails(data,
-                          (IntStream s) -> s.mapToObj(i -> i), IntStream::sum,
-                          IllegalStateException.class,
-                          "IntStream map / sum succeeded erroneously");
-        assertSecondFails(data,
-                          IntStream::sum, IntStream::distinct,
-                          IllegalStateException.class,
-                          "IntStream sum / distinct succeeded erroneously");
-        assertSecondFails(data,
-                          IntStream::distinct, IntStream::sum,
-                          IllegalStateException.class,
-                          "IntStream distinct / sum succeeded erroneously");
-    }
-
-    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
-    public void testTwoIterators(String name, TestData.OfInt data) {
-        assertSecondFails(data,
-                          IntStream::iterator, IntStream::iterator,
-                          IllegalStateException.class,
-                          "IntStream iterator / iterator succeeded erroneously");
-    }
-
-    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
-    public void testTerminalIterator(String name, TestData.OfInt data) {
-        assertSecondFails(data,
-                          IntStream::iterator, IntStream::sum,
-                          IllegalStateException.class,
-                          "IntStream iterator / sum succeeded erroneously");
-        assertSecondFails(data,
-                          IntStream::sum, IntStream::iterator,
-                          IllegalStateException.class,
-                          "Stream sum / iterator succeeded erroneously");
-    }
-
-    @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
-    public void testStreamIterator(String name, TestData.OfInt data) {
-        assertSecondFails(data,
-                          IntStream::iterator, (IntStream s) -> s.mapToObj(i -> i),
-                          IllegalStateException.class,
-                          "IntStream iterator / map succeeded erroneously");
-        assertSecondFails(data,
-                          (IntStream s) -> s.mapToObj(i -> i), IntStream::iterator,
-                          IllegalStateException.class,
-                          "IntStream map / iterator succeeded erroneously");
-        assertSecondFails(data,
-                          IntStream::iterator, IntStream::distinct,
-                          IllegalStateException.class,
-                          "IntStream iterator / distinct succeeded erroneously");
-        assertSecondFails(data,
-                          IntStream::distinct, IntStream::iterator,
-                          IllegalStateException.class,
-                          "IntStream distinct / iterator succeeded erroneously");
-    }
-
-    // LongStream
-
-    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
-    public void testTwoStreams(String name, TestData.OfLong data) {
-        assertSecondFails(data,
-                          (LongStream s) -> s.mapToObj(i -> i), (LongStream s) -> s.mapToObj(i -> i),
-                          IllegalStateException.class,
-                          "LongStream map / map succeeded erroneously");
-        assertSecondFails(data,
-                          LongStream::distinct, (LongStream s) -> s.mapToObj(i -> i),
-                          IllegalStateException.class,
-                          "LongStream distinct / map succeeded erroneously");
-        assertSecondFails(data,
-                          (LongStream s) -> s.mapToObj(i -> i), LongStream::distinct,
-                          IllegalStateException.class,
-                          "LongStream map / distinct succeeded erroneously");
-        assertSecondFails(data,
-                          LongStream::distinct, LongStream::distinct,
-                          IllegalStateException.class,
-                          "LongStream distinct / distinct succeeded erroneously");
-    }
-
-    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
-    public void testTwoTerminals(String name, TestData.OfLong data) {
-        assertSecondFails(data,
-                          LongStream::sum, LongStream::sum,
-                          IllegalStateException.class,
-                          "LongStream sum / sum succeeded erroneously");
-    }
-
-    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
-    public void testTerminalStream(String name, TestData.OfLong data) {
-        assertSecondFails(data,
-                          LongStream::sum, (LongStream s) -> s.mapToObj(i -> i),
-                          IllegalStateException.class,
-                          "LongStream sum / map succeeded erroneously");
-        assertSecondFails(data,
-                          (LongStream s) -> s.mapToObj(i -> i), LongStream::sum,
-                          IllegalStateException.class,
-                          "LongStream map / sum succeeded erroneously");
-        assertSecondFails(data,
-                          LongStream::sum, LongStream::distinct,
-                          IllegalStateException.class,
-                          "LongStream sum / distinct succeeded erroneously");
-        assertSecondFails(data,
-                          LongStream::distinct, LongStream::sum,
-                          IllegalStateException.class,
-                          "LongStream distinct / sum succeeded erroneously");
-    }
-
-    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
-    public void testTwoIterators(String name, TestData.OfLong data) {
-        assertSecondFails(data,
-                          LongStream::iterator, LongStream::iterator,
-                          IllegalStateException.class,
-                          "LongStream iterator / iterator succeeded erroneously");
-    }
-
-    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
-    public void testTerminalIterator(String name, TestData.OfLong data) {
-        assertSecondFails(data,
-                          LongStream::iterator, LongStream::sum,
-                          IllegalStateException.class,
-                          "LongStream iterator / sum succeeded erroneously");
-        assertSecondFails(data,
-                          LongStream::sum, LongStream::iterator,
-                          IllegalStateException.class,
-                          "Stream sum / iterator succeeded erroneously");
-    }
-
-    @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
-    public void testStreamIterator(String name, TestData.OfLong data) {
-        assertSecondFails(data,
-                          LongStream::iterator, (LongStream s) -> s.mapToObj(i -> i),
-                          IllegalStateException.class,
-                          "LongStream iterator / map succeeded erroneously");
-        assertSecondFails(data,
-                          (LongStream s) -> s.mapToObj(i -> i), LongStream::iterator,
-                          IllegalStateException.class,
-                          "LongStream map / iterator succeeded erroneously");
-        assertSecondFails(data,
-                          LongStream::iterator, LongStream::distinct,
-                          IllegalStateException.class,
-                          "LongStream iterator / distinct succeeded erroneously");
-        assertSecondFails(data,
-                          LongStream::distinct, LongStream::iterator,
-                          IllegalStateException.class,
-                          "LongStream distinct / iterator succeeded erroneously");
-    }
-
-    // DoubleStream
-
-    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
-    public void testTwoStreams(String name, TestData.OfDouble data) {
-        assertSecondFails(data,
-                          (DoubleStream s) -> s.mapToObj(i -> i), (DoubleStream s) -> s.mapToObj(i -> i),
-                          IllegalStateException.class,
-                          "DoubleStream map / map succeeded erroneously");
-        assertSecondFails(data,
-                          DoubleStream::distinct, (DoubleStream s) -> s.mapToObj(i -> i),
-                          IllegalStateException.class,
-                          "DoubleStream distinct / map succeeded erroneously");
-        assertSecondFails(data,
-                          (DoubleStream s) -> s.mapToObj(i -> i), DoubleStream::distinct,
-                          IllegalStateException.class,
-                          "DoubleStream map / distinct succeeded erroneously");
-        assertSecondFails(data,
-                          DoubleStream::distinct, DoubleStream::distinct,
-                          IllegalStateException.class,
-                          "DoubleStream distinct / distinct succeeded erroneously");
-    }
-
-    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
-    public void testTwoTerminals(String name, TestData.OfDouble data) {
-        assertSecondFails(data,
-                          DoubleStream::sum, DoubleStream::sum,
-                          IllegalStateException.class,
-                          "DoubleStream sum / sum succeeded erroneously");
-    }
-
-    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
-    public void testTerminalStream(String name, TestData.OfDouble data) {
-        assertSecondFails(data,
-                          DoubleStream::sum, (DoubleStream s) -> s.mapToObj(i -> i),
-                          IllegalStateException.class,
-                          "DoubleStream sum / map succeeded erroneously");
-        assertSecondFails(data,
-                          (DoubleStream s) -> s.mapToObj(i -> i), DoubleStream::sum,
-                          IllegalStateException.class,
-                          "DoubleStream map / sum succeeded erroneously");
-        assertSecondFails(data,
-                          DoubleStream::sum, DoubleStream::distinct,
-                          IllegalStateException.class,
-                          "DoubleStream sum / distinct succeeded erroneously");
-        assertSecondFails(data,
-                          DoubleStream::distinct, DoubleStream::sum,
-                          IllegalStateException.class,
-                          "DoubleStream distinct / sum succeeded erroneously");
-    }
-
-    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
-    public void testTwoIterators(String name, TestData.OfDouble data) {
-        assertSecondFails(data,
-                          DoubleStream::iterator, DoubleStream::iterator,
-                          IllegalStateException.class,
-                          "DoubleStream iterator / iterator succeeded erroneously");
-    }
-
-    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
-    public void testTerminalIterator(String name, TestData.OfDouble data) {
-        assertSecondFails(data,
-                          DoubleStream::iterator, DoubleStream::sum,
-                          IllegalStateException.class,
-                          "DoubleStream iterator / sum succeeded erroneously");
-        assertSecondFails(data,
-                          DoubleStream::sum, DoubleStream::iterator,
-                          IllegalStateException.class,
-                          "Stream sum / iterator succeeded erroneously");
-    }
-
-    @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
-    public void testStreamIterator(String name, TestData.OfDouble data) {
-        assertSecondFails(data,
-                          DoubleStream::iterator, (DoubleStream s) -> s.mapToObj(i -> i),
-                          IllegalStateException.class,
-                          "DoubleStream iterator / map succeeded erroneously");
-        assertSecondFails(data,
-                          (DoubleStream s) -> s.mapToObj(i -> i), DoubleStream::iterator,
-                          IllegalStateException.class,
-                          "DoubleStream map / iterator succeeded erroneously");
-        assertSecondFails(data,
-                          DoubleStream::iterator, DoubleStream::distinct,
-                          IllegalStateException.class,
-                          "DoubleStream iterator / distinct succeeded erroneously");
-        assertSecondFails(data,
-                          DoubleStream::distinct, DoubleStream::iterator,
-                          IllegalStateException.class,
-                          "DoubleStream distinct / iterator succeeded erroneously");
-    }
-}
--- a/jdk/test/java/util/stream/test/TEST.properties	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/java/util/stream/test/TEST.properties	Tue Nov 17 10:29:28 2015 -0800
@@ -2,7 +2,7 @@
 
 TestNG.dirs = .
 
-lib.dirs = /java/util/stream/bootlib
+lib.dirs = /java/util/stream/bootlib/java.base
 
 # Tests that must run in othervm mode
 othervm.dirs= /java/util/stream
--- a/jdk/test/java/util/zip/TestLocalTime.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/java/util/zip/TestLocalTime.java	Tue Nov 17 10:29:28 2015 -0800
@@ -21,9 +21,10 @@
  * questions.
  */
 
-/**
+/*
  * @test
  * @bug 8075526
+ * @key intermittent
  * @summary Test timestamp via ZipEntry.get/setTimeLocal()
  */
 
--- a/jdk/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java	Tue Nov 17 10:29:28 2015 -0800
@@ -38,14 +38,14 @@
     private final OutputBuffer output;
     private final String stdout;
     private final String stderr;
-    private final int exitValue;
+    private final int exitValue;    // useless now. output contains exit value.
 
     /**
      * Create an OutputAnalyzer, a utility class for verifying output and exit
      * value from a Process.
      * <p>
      * OutputAnalyzer should never be instantiated directly -
-     * use {@linkplain ProcessTools#executeProcess(p)} instead
+     * use {@linkplain ProcessTools#executeProcess(ProcessBuilder)} instead
      *
      * @param process
      *            Process to analyze
@@ -93,13 +93,14 @@
      * @throws RuntimeException
      *             If the string was not found
      */
-    public void shouldContain(String expectedString) {
+    public OutputAnalyzer shouldContain(String expectedString) {
         if (!getStdout().contains(expectedString)
                 && !getStderr().contains(expectedString)) {
             reportDiagnosticSummary();
             throw new RuntimeException("'" + expectedString
                     + "' missing from stdout/stderr \n");
         }
+        return this;
     }
 
     /**
@@ -110,12 +111,13 @@
      * @throws RuntimeException
      *             If the string was not found
      */
-    public void stdoutShouldContain(String expectedString) {
+    public OutputAnalyzer stdoutShouldContain(String expectedString) {
         if (!getStdout().contains(expectedString)) {
             reportDiagnosticSummary();
             throw new RuntimeException("'" + expectedString
                     + "' missing from stdout \n");
         }
+        return this;
     }
 
     /**
@@ -126,24 +128,25 @@
      * @throws RuntimeException
      *             If the string was not found
      */
-    public void stderrShouldContain(String expectedString) {
+    public OutputAnalyzer stderrShouldContain(String expectedString) {
         if (!getStderr().contains(expectedString)) {
             reportDiagnosticSummary();
             throw new RuntimeException("'" + expectedString
                     + "' missing from stderr \n");
         }
+        return this;
     }
 
     /**
      * Verify that the stdout and stderr contents of output buffer does not
      * contain the string
      *
-     * @param expectedString
+     * @param notExpectedString
      *            String that the buffer should not contain
      * @throws RuntimeException
      *             If the string was found
      */
-    public void shouldNotContain(String notExpectedString) {
+    public OutputAnalyzer shouldNotContain(String notExpectedString) {
         if (getStdout().contains(notExpectedString)) {
             reportDiagnosticSummary();
             throw new RuntimeException("'" + notExpectedString
@@ -154,40 +157,43 @@
             throw new RuntimeException("'" + notExpectedString
                     + "' found in stderr \n");
         }
+        return this;
     }
 
     /**
      * Verify that the stdout contents of output buffer does not contain the
      * string
      *
-     * @param expectedString
+     * @param notExpectedString
      *            String that the buffer should not contain
      * @throws RuntimeException
      *             If the string was found
      */
-    public void stdoutShouldNotContain(String notExpectedString) {
+    public OutputAnalyzer stdoutShouldNotContain(String notExpectedString) {
         if (getStdout().contains(notExpectedString)) {
             reportDiagnosticSummary();
             throw new RuntimeException("'" + notExpectedString
                     + "' found in stdout \n");
         }
+        return this;
     }
 
     /**
      * Verify that the stderr contents of output buffer does not contain the
      * string
      *
-     * @param expectedString
+     * @param notExpectedString
      *            String that the buffer should not contain
      * @throws RuntimeException
      *             If the string was found
      */
-    public void stderrShouldNotContain(String notExpectedString) {
+    public OutputAnalyzer stderrShouldNotContain(String notExpectedString) {
         if (getStderr().contains(notExpectedString)) {
             reportDiagnosticSummary();
             throw new RuntimeException("'" + notExpectedString
                     + "' found in stderr \n");
         }
+        return this;
     }
 
     /**
@@ -198,7 +204,7 @@
      * @throws RuntimeException
      *             If the pattern was not found
      */
-    public void shouldMatch(String pattern) {
+    public OutputAnalyzer shouldMatch(String pattern) {
         Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE)
                 .matcher(getStdout());
         Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE)
@@ -208,6 +214,7 @@
             throw new RuntimeException("'" + pattern
                     + "' missing from stdout/stderr \n");
         }
+        return this;
     }
 
     /**
@@ -217,7 +224,7 @@
      * @throws RuntimeException
      *             If the pattern was not found
      */
-    public void stdoutShouldMatch(String pattern) {
+    public OutputAnalyzer stdoutShouldMatch(String pattern) {
         Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(
                 getStdout());
         if (!matcher.find()) {
@@ -225,6 +232,7 @@
             throw new RuntimeException("'" + pattern
                     + "' missing from stdout \n");
         }
+        return this;
     }
 
     /**
@@ -234,7 +242,7 @@
      * @throws RuntimeException
      *             If the pattern was not found
      */
-    public void stderrShouldMatch(String pattern) {
+    public OutputAnalyzer stderrShouldMatch(String pattern) {
         Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(
                 getStderr());
         if (!matcher.find()) {
@@ -242,6 +250,7 @@
             throw new RuntimeException("'" + pattern
                     + "' missing from stderr \n");
         }
+        return this;
     }
 
     /**
@@ -252,7 +261,7 @@
      * @throws RuntimeException
      *             If the pattern was found
      */
-    public void shouldNotMatch(String pattern) {
+    public OutputAnalyzer shouldNotMatch(String pattern) {
         Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(
                 getStdout());
         if (matcher.find()) {
@@ -266,6 +275,7 @@
             throw new RuntimeException("'" + pattern + "' found in stderr: '"
                     + matcher.group() + "' \n");
         }
+        return this;
     }
 
     /**
@@ -276,13 +286,14 @@
      * @throws RuntimeException
      *             If the pattern was found
      */
-    public void stdoutShouldNotMatch(String pattern) {
+    public OutputAnalyzer stdoutShouldNotMatch(String pattern) {
         Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(
                 getStdout());
         if (matcher.find()) {
             reportDiagnosticSummary();
             throw new RuntimeException("'" + pattern + "' found in stdout \n");
         }
+        return this;
     }
 
     /**
@@ -293,13 +304,14 @@
      * @throws RuntimeException
      *             If the pattern was found
      */
-    public void stderrShouldNotMatch(String pattern) {
+    public OutputAnalyzer stderrShouldNotMatch(String pattern) {
         Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(
                 getStderr());
         if (matcher.find()) {
             reportDiagnosticSummary();
             throw new RuntimeException("'" + pattern + "' found in stderr \n");
         }
+        return this;
     }
 
     /**
@@ -347,12 +359,13 @@
      *             If the exit value from the process did not match the expected
      *             value
      */
-    public void shouldHaveExitValue(int expectedExitValue) {
+    public OutputAnalyzer shouldHaveExitValue(int expectedExitValue) {
         if (getExitValue() != expectedExitValue) {
             reportDiagnosticSummary();
             throw new RuntimeException("Expected to get exit value of ["
                     + expectedExitValue + "]\n");
         }
+        return this;
     }
 
     /**
@@ -360,11 +373,12 @@
      * - standard input produced by the process under test - standard output -
      * exit code Note: the command line is printed by the ProcessTools
      */
-    private void reportDiagnosticSummary() {
+    private OutputAnalyzer reportDiagnosticSummary() {
         String msg = " stdout: [" + getStdout() + "];\n" + " stderr: [" + getStderr()
                 + "]\n" + " exitValue = " + getExitValue() + "\n";
 
         System.err.println(msg);
+        return this;
     }
 
     /**
--- a/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java	Tue Nov 17 10:29:28 2015 -0800
@@ -365,11 +365,31 @@
      * @return The {@linkplain OutputAnalyzer} instance wrapping the process.
      */
     public static OutputAnalyzer executeProcess(ProcessBuilder pb) throws Exception {
+        return executeProcess(pb, null);
+    }
+
+    /**
+     * Executes a process, pipe some text into its STDIN, waits for it
+     * to finish and returns the process output. The process will have exited
+     * before this method returns.
+     * @param pb The ProcessBuilder to execute.
+     * @param input The text to pipe into STDIN. Can be null.
+     * @return The {@linkplain OutputAnalyzer} instance wrapping the process.
+     */
+    public static OutputAnalyzer executeProcess(ProcessBuilder pb, String input)
+            throws Exception {
         OutputAnalyzer output = null;
         Process p = null;
         boolean failed = false;
         try {
             p = pb.start();
+            if (input != null) {
+                try (OutputStream os = p.getOutputStream();
+                        PrintStream ps = new PrintStream(os)) {
+                    ps.print(input);
+                    ps.flush();
+                }
+            }
             output = new OutputAnalyzer(p);
             p.waitFor();
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/SerializationUtils.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,51 @@
+/*
+ * 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 jdk.testlibrary;
+
+import java.io.*;
+
+/**
+ * Common library for various test serialization utility functions.
+ */
+public final class SerializationUtils {
+    /*
+     * Serialize an object into byte array.
+     */
+    public static byte[] serialize(Object obj) throws Exception {
+        try (ByteArrayOutputStream bs = new ByteArrayOutputStream();
+                ObjectOutputStream out = new ObjectOutputStream(bs);) {
+            out.writeObject(obj);
+            return bs.toByteArray();
+        }
+    }
+
+    /*
+     * Deserialize an object from byte array.
+     */
+    public static Object deserialize(byte[] ba) throws Exception {
+        try (ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(ba));) {
+            return in.readObject();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/invoke/util/WrapperTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,108 @@
+/*
+ * 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 test.sun.invoke.util;
+
+import sun.invoke.util.ValueConversions;
+import sun.invoke.util.Wrapper;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.MethodHandle;
+import java.io.Serializable;
+import java.util.Arrays;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/* @test
+ * @summary unit tests to assert Wrapper zero identities and conversion behave correctly
+ * @modules java.base/sun.invoke.util
+ * @compile -XDignore.symbol.file WrapperTest.java
+ * @run junit test.sun.invoke.util.WrapperTest
+ */
+public class WrapperTest {
+
+    @Test
+    public void testShortZeroConversion() throws Throwable {
+        MethodHandle h1 = MethodHandles.constant(Short.class, (short)42);
+        MethodHandle h2 = h1.asType(MethodType.methodType(void.class));  // drop 42
+        MethodHandle h3 = h2.asType(MethodType.methodType(short.class));  // add 0
+        MethodHandle h4 = h3.asType(MethodType.methodType(Object.class));  // box
+
+        Object x = h4.invokeExact();
+        assertEquals(x, (short)0);
+        assertTrue(x == Short.valueOf((short)0));
+        assertTrue(x == Wrapper.SHORT.zero());
+    }
+
+    @Test
+    public void testIntZeroConversion() throws Throwable {
+        MethodHandle h1 = MethodHandles.constant(Integer.class, 42);
+        MethodHandle h2 = h1.asType(MethodType.methodType(void.class));  // drop 42
+        MethodHandle h3 = h2.asType(MethodType.methodType(int.class));  // add 0
+        MethodHandle h4 = h3.asType(MethodType.methodType(Object.class));  // box
+
+        Object x = h4.invokeExact();
+        assertEquals(x, 0);
+        assertTrue(x == Integer.valueOf(0));
+        assertTrue(x == Wrapper.INT.zero());
+    }
+
+    @Test
+    public void testLongZeroConversion() throws Throwable {
+        MethodHandle h1 = MethodHandles.constant(Long.class, 42L);
+        MethodHandle h2 = h1.asType(MethodType.methodType(void.class));  // drop 42
+        MethodHandle h3 = h2.asType(MethodType.methodType(long.class));  // add 0
+        MethodHandle h4 = h3.asType(MethodType.methodType(Object.class));  // box
+
+        Object x = h4.invokeExact();
+        assertEquals(x, 0L);
+        assertTrue(x == Long.valueOf(0));
+        assertTrue(x == Wrapper.LONG.zero());
+    }
+
+    @Test
+    public void testByteZeroConversion() throws Throwable {
+        MethodHandle h1 = MethodHandles.constant(Byte.class, (byte)42);
+        MethodHandle h2 = h1.asType(MethodType.methodType(void.class));  // drop 42
+        MethodHandle h3 = h2.asType(MethodType.methodType(byte.class));  // add 0
+        MethodHandle h4 = h3.asType(MethodType.methodType(Object.class));  // box
+
+        Object x = h4.invokeExact();
+        assertEquals(x, (byte)0);
+        assertTrue(x == Byte.valueOf((byte)0));
+        assertTrue(x == Wrapper.BYTE.zero());
+    }
+
+    @Test
+    public void testCharacterZeroConversion() throws Throwable {
+        MethodHandle h1 = MethodHandles.constant(Character.class, (char)42);
+        MethodHandle h2 = h1.asType(MethodType.methodType(void.class));  // drop 42
+        MethodHandle h3 = h2.asType(MethodType.methodType(char.class));  // add 0
+        MethodHandle h4 = h3.asType(MethodType.methodType(Object.class));  // box
+
+        Object x = h4.invokeExact();
+        assertEquals(x, (char)0);
+        assertTrue(x == Character.valueOf((char)0));
+        assertTrue(x == Wrapper.CHAR.zero());
+    }
+}
--- a/jdk/test/sun/jvmstat/monitor/MonitoredVm/TestPollingInterval.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/sun/jvmstat/monitor/MonitoredVm/TestPollingInterval.java	Tue Nov 17 10:29:28 2015 -0800
@@ -42,7 +42,7 @@
  * @summary setInterval() for local MonitoredHost and local MonitoredVm
  * @modules jdk.jvmstat/sun.jvmstat.monitor
  * @library /lib/testlibrary
- * @library /../../test/lib/share/classes
+ * @library /test/lib/share/classes
  * @build jdk.testlibrary.*
  * @build jdk.test.lib.apps.*
  * @run main TestPollingInterval
--- a/jdk/test/sun/nio/cs/TestStringCoding.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/sun/nio/cs/TestStringCoding.java	Tue Nov 17 10:29:28 2015 -0800
@@ -22,7 +22,7 @@
  */
 
 /* @test
- * @bug 6636323 6636319 7040220 7096080 7183053 8080248
+ * @bug 6636323 6636319 7040220 7096080 7183053 8080248 8054307
  * @summary Test if StringCoding and NIO result have the same de/encoding result
  * @modules java.base/sun.nio.cs
  * @run main/othervm/timeout=2000 TestStringCoding
@@ -36,41 +36,61 @@
 public class TestStringCoding {
     public static void main(String[] args) throws Throwable {
 
+        // full bmp first
+        char[] bmp = new char[0x10000];
+        for (int i = 0; i < 0x10000; i++) {
+            bmp[i] = (char)i;
+        }
+        char[] latin = Arrays.copyOf(bmp, 0x100);
+        char[] ascii =  Arrays.copyOf(bmp, 0x80);
+
+        byte[] latinBA = new byte[0x100];
+        for (int i = 0; i < 0x100; i++) {
+            latinBA[i] = (byte)i;
+        }
+        byte[] asciiBA =  Arrays.copyOf(latinBA, 0x80);
+
         for (Boolean hasSM: new boolean[] { false, true }) {
-            if (hasSM)
+            if (hasSM) {
                 System.setSecurityManager(new PermissiveSecurityManger());
+            }
             for (Charset cs:  Charset.availableCharsets().values()) {
                 if ("ISO-2022-CN".equals(cs.name()) ||
                     "x-COMPOUND_TEXT".equals(cs.name()) ||
                     "x-JISAutoDetect".equals(cs.name()))
                     continue;
                 System.out.printf("Testing(sm=%b) " + cs.name() + "....", hasSM);
-                // full bmp first
-                char[] bmpCA = new char[0x10000];
-                for (int i = 0; i < 0x10000; i++) {
-                     bmpCA[i] = (char)i;
-                }
-                byte[] sbBA = new byte[0x100];
-                for (int i = 0; i < 0x100; i++) {
-                    sbBA[i] = (byte)i;
-                }
-                test(cs, bmpCA, sbBA);
+
+                testNewString(cs, testGetBytes(cs, new String(bmp)));
+                testNewString(cs, testGetBytes(cs, new String(latin)));
+                testNewString(cs, testGetBytes(cs, new String(ascii)));
+                testGetBytes(cs, testNewString(cs, latinBA));
+                testGetBytes(cs, testNewString(cs, asciiBA));
+
                 // "randomed" sizes
                 Random rnd = new Random();
                 for (int i = 0; i < 10; i++) {
-                    int clen = rnd.nextInt(0x10000);
-                    int blen = rnd.nextInt(0x100);
                     //System.out.printf("    blen=%d, clen=%d%n", blen, clen);
-                    test(cs, Arrays.copyOf(bmpCA, clen), Arrays.copyOf(sbBA, blen));
+                    char[] bmp0 = Arrays.copyOf(bmp, rnd.nextInt(0x10000));
+                    testNewString(cs, testGetBytes(cs, new String(bmp0)));
                     //add a pair of surrogates
-                    int pos = clen / 2;
-                    if ((pos + 1) < blen) {
-                        bmpCA[pos] = '\uD800';
-                        bmpCA[pos+1] = '\uDC00';
+                    int pos = bmp0.length / 2;
+                    if ((pos + 1) < bmp0.length) {
+                        bmp0[pos] = '\uD800';
+                        bmp0[pos+1] = '\uDC00';
                     }
-                    test(cs, Arrays.copyOf(bmpCA, clen), Arrays.copyOf(sbBA, blen));
+                    testNewString(cs, testGetBytes(cs, new String(bmp0)));
+
+                    char[] latin0 = Arrays.copyOf(latin, rnd.nextInt(0x100));
+                    char[] ascii0 = Arrays.copyOf(ascii, rnd.nextInt(0x80));
+                    byte[] latinBA0 = Arrays.copyOf(latinBA, rnd.nextInt(0x100));
+                    byte[] asciiBA0 = Arrays.copyOf(asciiBA, rnd.nextInt(0x80));
+                    testNewString(cs, testGetBytes(cs, new String(latin0)));
+                    testNewString(cs, testGetBytes(cs, new String(ascii0)));
+                    testGetBytes(cs, testNewString(cs, latinBA0));
+                    testGetBytes(cs, testNewString(cs, asciiBA0));
                 }
-
+                testSurrogates(cs);
                 testMixed(cs);
                 System.out.println("done!");
             }
@@ -109,8 +129,9 @@
 
         //getBytes(cs);
         bmpBA = bmpStr.getBytes(cs);
-        if (!Arrays.equals(bmpBA, baNIO))
+        if (!Arrays.equals(bmpBA, baNIO)) {
             throw new RuntimeException("getBytes(cs) failed  -> " + cs.name());
+        }
 
         //new String(csn);
         String strSC = new String(bmpBA, cs.name());
@@ -118,49 +139,61 @@
         if(!strNIO.equals(strSC)) {
             throw new RuntimeException("new String(csn) failed  -> " + cs.name());
         }
-
         //new String(cs);
         strSC = new String(bmpBA, cs);
-        if (!strNIO.equals(strSC))
+        if (!strNIO.equals(strSC)) {
             throw new RuntimeException("new String(cs) failed  -> " + cs.name());
-
+        }
     }
 
-    static void test(Charset cs, char[] bmpCA, byte[] sbBA) throws Throwable {
-        String bmpStr = new String(bmpCA);
-        CharsetDecoder dec = cs.newDecoder()
-            .onMalformedInput(CodingErrorAction.REPLACE)
-            .onUnmappableCharacter(CodingErrorAction.REPLACE);
+    static byte[] getBytes(CharsetEncoder enc, String str) throws Throwable {
+        ByteBuffer bf = enc.reset().encode(CharBuffer.wrap(str.toCharArray()));
+        byte[] ba = new byte[bf.limit()];
+        bf.get(ba, 0, ba.length);
+        return ba;
+    }
+
+    static byte[] testGetBytes(Charset cs, String str) throws Throwable {
         CharsetEncoder enc = cs.newEncoder()
             .onMalformedInput(CodingErrorAction.REPLACE)
             .onUnmappableCharacter(CodingErrorAction.REPLACE);
-
         //getBytes(csn);
-        byte[] baSC = bmpStr.getBytes(cs.name());
-        ByteBuffer bf = enc.reset().encode(CharBuffer.wrap(bmpCA));
-        byte[] baNIO = new byte[bf.limit()];
-        bf.get(baNIO, 0, baNIO.length);
-        if (!Arrays.equals(baSC, baNIO))
+        byte[] baSC = str.getBytes(cs.name());
+        byte[] baNIO = getBytes(enc, str);
+        if (!Arrays.equals(baSC, baNIO)) {
             throw new RuntimeException("getBytes(csn) failed  -> " + cs.name());
-
+        }
         //getBytes(cs);
-        baSC = bmpStr.getBytes(cs);
-        if (!Arrays.equals(baSC, baNIO))
+        baSC = str.getBytes(cs);
+        if (!Arrays.equals(baSC, baNIO)) {
             throw new RuntimeException("getBytes(cs) failed  -> " + cs.name());
+        }
+        return baSC;
+    }
 
+    static String testNewString(Charset cs, byte[] ba) throws Throwable {
+        CharsetDecoder dec = cs.newDecoder()
+            .onMalformedInput(CodingErrorAction.REPLACE)
+            .onUnmappableCharacter(CodingErrorAction.REPLACE);
         //new String(csn);
-        String strSC = new String(sbBA, cs.name());
-        String strNIO = dec.reset().decode(ByteBuffer.wrap(sbBA)).toString();
-
-        if(!strNIO.equals(strSC))
+        String strSC = new String(ba, cs.name());
+        String strNIO = dec.reset().decode(ByteBuffer.wrap(ba)).toString();
+        if(!strNIO.equals(strSC)) {
             throw new RuntimeException("new String(csn) failed  -> " + cs.name());
+        }
+        //new String(cs);
+        strSC = new String(ba, cs);
+        if (!strNIO.equals(strSC)) {
+            throw new RuntimeException("new String(cs)/bmp failed  -> " + cs.name());
+        }
+        return strSC;
+    }
 
-        //new String(cs);
-        strSC = new String(sbBA, cs);
-        if (!strNIO.equals(strSC))
-            throw new RuntimeException("new String(cs) failed  -> " + cs.name());
-
+    static void testSurrogates(Charset cs) throws Throwable {
         //encode unmappable surrogates
+        CharsetEncoder enc = cs.newEncoder()
+            .onMalformedInput(CodingErrorAction.REPLACE)
+            .onUnmappableCharacter(CodingErrorAction.REPLACE);
         if (enc instanceof sun.nio.cs.ArrayEncoder &&
             cs.contains(Charset.forName("ASCII"))) {
             if (cs.name().equals("UTF-8") ||     // utf8 handles surrogates
--- a/jdk/test/sun/nio/cs/TestStringCodingUTF8.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/sun/nio/cs/TestStringCodingUTF8.java	Tue Nov 17 10:29:28 2015 -0800
@@ -22,7 +22,7 @@
  */
 
 /* @test
-   @bug 7040220
+   @bug 7040220 8054307
    @summary Test if StringCoding and NIO result have the same de/encoding result for UTF-8
  * @run main/othervm/timeout=2000 TestStringCodingUTF8
  * @key randomness
@@ -50,6 +50,18 @@
         }
         test(cs, bmp, 0, bmp.length);
 
+        char[] ascii = new char[0x80];
+        for (int i = 0; i < 0x80; i++) {
+            ascii[i] = (char)i;
+        }
+        test(cs, ascii, 0, ascii.length);
+
+        char[] latin1 = new char[0x100];
+        for (int i = 0; i < 0x100; i++) {
+            latin1[i] = (char)i;
+        }
+        test(cs, latin1, 0, latin1.length);
+
         ArrayList<Integer> list = new ArrayList<>(0x20000);
         for (int i = 0; i < 0x20000; i++) {
             list.add(i, i);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/jca/PreferredProviderNegativeTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,130 @@
+/*
+ * 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 8076359 8133151
+ * @summary Test for jdk.security.provider.preferred security property
+ * @requires os.name == "SunOS"
+ * @run main/othervm  PreferredProviderNegativeTest preJCESet AES:OracleUcrypto false
+ * @run main/othervm  PreferredProviderNegativeTest preJCESet AES:SunNegative true
+ * @run main/othervm  PreferredProviderNegativeTest afterJCESet AES:SunJGSS
+ * @run main/othervm  PreferredProviderNegativeTest afterJCESet AES:SunECNegative
+ * @run main/othervm  PreferredProviderNegativeTest invalidAlg AESNegative:SunJCE
+ */
+
+import java.security.Security;
+import java.security.NoSuchAlgorithmException;
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
+
+public class PreferredProviderNegativeTest {
+
+    /*
+     * Test security property could be set by valid and invalid provider
+     * before JCE was loaded
+     */
+    public static void preJCESet(String value, boolean negativeProvider)
+            throws NoSuchAlgorithmException, NoSuchPaddingException {
+        Security.setProperty("jdk.security.provider.preferred", value);
+
+        if (!Security.getProperty("jdk.security.provider.preferred")
+                .equals(value)) {
+            throw new RuntimeException(
+                    "Test Failed:The property wasn't set");
+        }
+
+        String[] arrays = value.split(":");
+        Cipher cipher = Cipher.getInstance(arrays[0]);
+
+        if (negativeProvider) {
+            if (cipher.getProvider().getName().equals(arrays[1])) {
+                throw new RuntimeException(
+                        "Test Failed:The provider shouldn't be set");
+            }
+        } else {
+            if (!cipher.getProvider().getName().equals(arrays[1])) {
+                throw new RuntimeException(
+                        "Test Faild:The provider could be set "
+                                + "by valid provider ");
+            }
+        }
+        System.out.println("Test Pass");
+    }
+
+    /*
+     * Test that the setting of the security property after Cipher.getInstance()
+     * does not influence previously loaded instances
+     */
+    public static void afterJCESet(String value)
+            throws NoSuchAlgorithmException, NoSuchPaddingException {
+        String[] arrays = value.split(":");
+        Cipher cipher = Cipher.getInstance(arrays[0]);
+
+        Security.setProperty("jdk.security.provider.preferred", value);
+        if (!cipher.getProvider().getName().equals("SunJCE")) {
+            throw new RuntimeException(
+                    "Test Failed:The security property can't be updated after JCE load.");
+        }
+        System.out.println("Test Pass");
+    }
+
+    /* Test the security property with negative algorithm */
+    public static void invalidAlg(String value) throws NoSuchPaddingException {
+        String[] arrays = value.split(":");
+
+        try {
+            Security.setProperty("jdk.security.provider.preferred", value);
+            Cipher.getInstance(arrays[0]);
+        } catch (NoSuchAlgorithmException e) {
+            System.out.println("Test Pass:Got NoSuchAlgorithmException as expired");
+            return;
+        }
+        throw new RuntimeException(
+                "Test Failed:Expected NoSuchAlgorithmException was not thrown");
+    }
+
+    public static void main(String[] args)
+            throws NoSuchAlgorithmException, NoSuchPaddingException {
+        boolean negativeProvider;
+
+        if (args.length >= 2) {
+            switch (args[0]) {
+                case "preJCESet":
+                    negativeProvider = Boolean.valueOf(args[2]);
+                    PreferredProviderNegativeTest.preJCESet(args[1], negativeProvider);
+                    break;
+                case "afterJCESet":
+                    PreferredProviderNegativeTest.afterJCESet(args[1]);
+                    break;
+                case "invalidAlg":
+                    PreferredProviderNegativeTest.invalidAlg(args[1]);
+                    break;
+            }
+        } else {
+            throw new RuntimeException(
+                    "Test Failed:Please pass the correct args");
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/jca/PreferredProviderTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -0,0 +1,131 @@
+/*
+ * 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 8076359 8133151
+ * @summary Test the value for new jdk.security.provider.preferred security property
+ * @requires os.name == "SunOS"
+ */
+
+import java.security.KeyFactory;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.Security;
+import java.util.Arrays;
+import java.util.List;
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
+
+public class PreferredProviderTest {
+
+    private static final List<DataTuple> SPARC_DATA = Arrays.asList(
+            new DataTuple("SHA-256", "SUN"), new DataTuple("SHA-384", "SUN"),
+            new DataTuple("SHA-512", "SUN"));
+    private static final List<DataTuple> X86_DATA = Arrays
+            .asList(new DataTuple("RSA", "SunRsaSign"));
+
+    public void RunTest(String type)
+            throws NoSuchAlgorithmException, NoSuchPaddingException {
+        String preferredProvider = Security
+                .getProperty("jdk.security.provider.preferred");
+        String actualProvider = null;
+        if (type.equals("sparcv9")) {
+            if (!preferredProvider.equals(
+                    "AES:SunJCE, SHA-256:SUN, SHA-384:SUN, SHA-512:SUN")) {
+                throw new RuntimeException(
+                        "Test Failed: wrong jdk.security.provider.preferred "
+                                + "value on solaris-sparcv9");
+            }
+            for (DataTuple dataTuple : SPARC_DATA) {
+                MessageDigest md = MessageDigest
+                        .getInstance(dataTuple.algorithm);
+                actualProvider = md.getProvider().getName();
+                if (!actualProvider.equals(dataTuple.provider)) {
+                    throw new RuntimeException(String.format(
+                            "Test Failed:Got wrong "
+                                    + "provider from Solaris-sparcv9 platform,"
+                                    + "Expected Provider: %s, Returned Provider: %s",
+                            dataTuple.provider, actualProvider));
+                }
+            }
+        } else if (type.equals("amd64")) {
+            if (!preferredProvider.equals("AES:SunJCE, RSA:SunRsaSign")) {
+                throw new RuntimeException(
+                        "Test Failed: wrong jdk.security.provider.preferred "
+                                + "value on solaris-x86");
+            }
+            for (DataTuple dataTuple : X86_DATA) {
+                KeyFactory keyFactory = KeyFactory
+                        .getInstance(dataTuple.algorithm);
+                actualProvider = keyFactory.getProvider().getName();
+                if (!actualProvider.equals(dataTuple.provider)) {
+                    throw new RuntimeException(String.format(
+                            "Test Failed:Got wrong "
+                                    + "provider from Solaris-x86 platform,"
+                                    + "Expected Provider: %s, Returned Provider: %s",
+                            dataTuple.provider, actualProvider));
+                }
+            }
+        } else {
+            throw new RuntimeException("Test Failed: wrong platform value");
+        }
+
+        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
+        actualProvider = cipher.getProvider().getName();
+        if (!actualProvider.equals("SunJCE")) {
+            throw new RuntimeException(String.format(
+                    "Test Failed:Got wrong provider from Solaris-%s platform, "
+                            + "Expected Provider: SunJCE, Returned Provider: %s",
+                    type, actualProvider));
+        }
+
+        MessageDigest md = MessageDigest.getInstance("MD5");
+        actualProvider = md.getProvider().getName();
+        if (!actualProvider.equals("OracleUcrypto")) {
+            throw new RuntimeException(String.format(
+                    "Test Failed:Got wrong provider from Solaris-%s platform,"
+                            + "Expected Provider: OracleUcrypto, Returned Provider: %s",
+                    type, actualProvider));
+        }
+    }
+
+    private static class DataTuple {
+        private final String provider;
+        private final String algorithm;
+
+        private DataTuple(String algorithm, String provider) {
+            this.algorithm = algorithm;
+            this.provider = provider;
+        }
+    }
+
+    public static void main(String[] args)
+            throws NoSuchAlgorithmException, NoSuchPaddingException {
+
+        String arch = System.getProperty("os.arch");
+        PreferredProviderTest pp = new PreferredProviderTest();
+        pp.RunTest(arch);
+    }
+}
+
--- a/jdk/test/sun/tools/jhsdb/BasicLauncherTest.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/sun/tools/jhsdb/BasicLauncherTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -24,7 +24,7 @@
 /*
  * @test
  * @summary Basic test for jhsdb launcher
- * @library /../../test/lib/share/classes
+ * @library /test/lib/share/classes
  * @library /lib/testlibrary
  * @build jdk.testlibrary.*
  * @build jdk.test.lib.apps.*
--- a/jdk/test/sun/tools/jmap/BasicJMapTest.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/sun/tools/jmap/BasicJMapTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -38,7 +38,7 @@
  * @summary Unit test for jmap utility
  * @key intermittent
  * @library /lib/testlibrary
- * @library /../../test/lib/share/classes
+ * @library /test/lib/share/classes
  * @modules java.management
  * @build jdk.testlibrary.*
  * @build jdk.test.lib.hprof.*
--- a/jdk/test/sun/tools/jmap/heapconfig/JMapHeapConfigTest.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/sun/tools/jmap/heapconfig/JMapHeapConfigTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -36,7 +36,7 @@
  * @test
  * @bug 8042397
  * @summary Unit test for jmap utility test heap configuration reader
- * @library /../../test/lib/share/classes
+ * @library /test/lib/share/classes
  * @library /lib/testlibrary
  * @modules java.management
  * @build jdk.testlibrary.*
--- a/jdk/test/sun/tools/jstack/DeadlockDetectionTest.java	Tue Nov 10 13:46:45 2015 +0300
+++ b/jdk/test/sun/tools/jstack/DeadlockDetectionTest.java	Tue Nov 17 10:29:28 2015 -0800
@@ -37,7 +37,7 @@
 /*
  * @test
  * @summary Test deadlock detection
- * @library /../../test/lib/share/classes
+ * @library /test/lib/share/classes
  * @library /lib/testlibrary
  * @modules java.management
  * @build jdk.testlibrary.*