changeset 16686:94038948b70f

Merge
author prr
date Mon, 06 Feb 2017 09:34:19 -0800
parents 05b82284817f 3ec66890e682
children fbddaaa26e1b
files make/copy/Copy-java.management.gmk make/gensrc/Gensrc-java.management.gmk make/rmic/Rmic-java.management.gmk src/java.management/share/classes/com/sun/jmx/remote/internal/ProxyRef.java src/java.management/share/classes/com/sun/jmx/remote/internal/RMIExporter.java src/java.management/share/classes/com/sun/jmx/remote/internal/Unmarshal.java src/java.management/share/classes/com/sun/jmx/remote/protocol/rmi/ClientProvider.java src/java.management/share/classes/com/sun/jmx/remote/protocol/rmi/ServerProvider.java src/java.management/share/classes/javax/management/remote/rmi/NoCallStackClassLoader.java src/java.management/share/classes/javax/management/remote/rmi/RMIConnection.java src/java.management/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java src/java.management/share/classes/javax/management/remote/rmi/RMIConnector.java src/java.management/share/classes/javax/management/remote/rmi/RMIConnectorServer.java src/java.management/share/classes/javax/management/remote/rmi/RMIIIOPServerImpl.java src/java.management/share/classes/javax/management/remote/rmi/RMIJRMPServerImpl.java src/java.management/share/classes/javax/management/remote/rmi/RMIServer.java src/java.management/share/classes/javax/management/remote/rmi/RMIServerImpl.java src/java.management/share/classes/javax/management/remote/rmi/package.html src/java.management/share/classes/sun/management/Agent.java src/java.management/share/classes/sun/management/AgentConfigurationError.java src/java.management/share/classes/sun/management/ConnectorAddressLink.java src/java.management/share/classes/sun/management/FileSystem.java src/java.management/share/classes/sun/management/jdp/JdpBroadcaster.java src/java.management/share/classes/sun/management/jdp/JdpController.java src/java.management/share/classes/sun/management/jdp/JdpException.java src/java.management/share/classes/sun/management/jdp/JdpGenericPacket.java src/java.management/share/classes/sun/management/jdp/JdpJmxPacket.java src/java.management/share/classes/sun/management/jdp/JdpPacket.java src/java.management/share/classes/sun/management/jdp/JdpPacketReader.java src/java.management/share/classes/sun/management/jdp/JdpPacketWriter.java src/java.management/share/classes/sun/management/jdp/package-info.java src/java.management/share/classes/sun/management/jmxremote/ConnectorBootstrap.java src/java.management/share/classes/sun/management/jmxremote/LocalRMIServerSocketFactory.java src/java.management/share/classes/sun/management/jmxremote/SingleEntryRegistry.java src/java.management/share/classes/sun/management/jmxremote/package.html src/java.management/share/classes/sun/management/resources/agent.properties src/java.management/share/classes/sun/management/resources/agent_de.properties src/java.management/share/classes/sun/management/resources/agent_es.properties src/java.management/share/classes/sun/management/resources/agent_fr.properties src/java.management/share/classes/sun/management/resources/agent_it.properties src/java.management/share/classes/sun/management/resources/agent_ja.properties src/java.management/share/classes/sun/management/resources/agent_ko.properties src/java.management/share/classes/sun/management/resources/agent_pt_BR.properties src/java.management/share/classes/sun/management/resources/agent_sv.properties src/java.management/share/classes/sun/management/resources/agent_zh_CN.properties src/java.management/share/classes/sun/management/resources/agent_zh_TW.properties src/java.management/share/classes/sun/management/spi/AgentProvider.java src/java.management/share/conf/jmxremote.access src/java.management/share/conf/jmxremote.password.template src/java.management/share/conf/management.properties src/java.management/share/conf/snmp.acl.template src/java.management/unix/classes/sun/management/FileSystemImpl.java src/java.management/unix/native/libmanagement/FileSystemImpl.c src/java.management/windows/classes/sun/management/FileSystemImpl.java src/java.management/windows/native/libmanagement/FileSystemImpl.c src/jdk.jconsole/share/classes/sun/tools/jconsole/JConsole.java src/jdk.jvmstat/share/classes/module-info.java src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/AbstractMonitor.java src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/BufferedMonitoredVm.java src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/ByteArrayMonitor.java src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/HostIdentifier.java src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/IntegerMonitor.java src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/LongMonitor.java src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/Monitor.java src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/MonitorException.java src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredHost.java src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredHostService.java src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredVm.java src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/MonitoredVmUtil.java src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/StringMonitor.java src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/Units.java src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/Variability.java src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/VmIdentifier.java src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/event/HostEvent.java src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/event/HostListener.java src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/event/MonitorStatusChangeEvent.java src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/event/VmEvent.java src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/event/VmListener.java src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/event/VmStatusChangeEvent.java src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/event/package.html src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/package.html src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractMonitoredVm.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractPerfDataBuffer.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractPerfDataBufferPrologue.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AliasFileParser.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/CountedTimerTask.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/CountedTimerTaskUtils.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/MonitorDataException.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/MonitorStatus.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/MonitorStructureException.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/MonitorTypeException.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/MonitorVersionException.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/PerfByteArrayMonitor.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/PerfDataBufferImpl.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/PerfIntegerMonitor.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/PerfLongMonitor.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/PerfStringConstantMonitor.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/PerfStringMonitor.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/PerfStringVariableMonitor.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/SyntaxException.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/package.html src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/file/FileMonitoredVm.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/file/MonitoredHostFileService.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/file/MonitoredHostProvider.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/file/PerfDataBuffer.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/file/package.html src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/LocalEventTimer.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/LocalMonitoredVm.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/LocalVmManager.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/MonitoredHostLocalService.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/MonitoredHostProvider.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataBuffer.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/package.html src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/v1_0/BasicType.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/v1_0/PerfDataBuffer.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/v1_0/PerfDataBufferPrologue.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/v2_0/PerfDataBuffer.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/v2_0/PerfDataBufferPrologue.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/v2_0/TypeCode.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/resources/aliasmap test/sun/management/AgentCMETest.java test/sun/management/AgentCheckTest.java
diffstat 579 files changed, 29335 insertions(+), 25737 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Mon Feb 06 09:32:41 2017 -0800
+++ b/.hgtags	Mon Feb 06 09:34:19 2017 -0800
@@ -397,3 +397,4 @@
 a20f2cf90762673e1bc4980fd6597e70a2578045 jdk-9+152
 1c4411322327aea3f91011ec3977a12a05b09629 jdk-9+153
 c97e7a8b8da062b9070df442f9cf308e10845fb7 jdk-9+154
+e170c858888e83d5c0994504599b6ed7a1fb0cfc jdk-9+155
--- a/make/copy/Copy-java.management.gmk	Mon Feb 06 09:32:41 2017 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +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.  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.
-#
-
-include CopyCommon.gmk
-
-################################################################################
-
-MGMT_CONF_DIR := $(CONF_DST_DIR)/management
-MGMT_CONF_SRC := $(JDK_TOPDIR)/src/java.management/share/conf
-MGMT_SRC_FILES := $(wildcard $(MGMT_CONF_SRC)/*)
-MGMT_TARGET_FILES := $(subst $(MGMT_CONF_SRC),$(MGMT_CONF_DIR),$(MGMT_SRC_FILES))
-
-$(MGMT_CONF_DIR)/management.properties: $(MGMT_CONF_SRC)/management.properties
-	$(call install-file)
-	$(CHMOD) 644 $@
-
-# this file has different permissions...don't know why...
-$(MGMT_CONF_DIR)/jmxremote.access: $(MGMT_CONF_SRC)/jmxremote.access
-	$(call install-file)
-	$(CHMOD) 644 $@
-
-$(MGMT_CONF_DIR)/%: $(MGMT_CONF_SRC)/%
-	$(call install-file)
-	$(CHMOD) 444 $@
-
-TARGETS := $(MGMT_TARGET_FILES)
-
-################################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/copy/Copy-jdk.management.agent.gmk	Mon Feb 06 09:34:19 2017 -0800
@@ -0,0 +1,50 @@
+#
+# 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.  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.
+#
+
+include CopyCommon.gmk
+
+################################################################################
+
+MGMT_CONF_DIR := $(CONF_DST_DIR)/management
+MGMT_CONF_SRC := $(JDK_TOPDIR)/src/jdk.management.agent/share/conf
+MGMT_SRC_FILES := $(wildcard $(MGMT_CONF_SRC)/*)
+MGMT_TARGET_FILES := $(subst $(MGMT_CONF_SRC),$(MGMT_CONF_DIR),$(MGMT_SRC_FILES))
+
+$(MGMT_CONF_DIR)/management.properties: $(MGMT_CONF_SRC)/management.properties
+	$(call install-file)
+	$(CHMOD) 644 $@
+
+# this file has different permissions...don't know why...
+$(MGMT_CONF_DIR)/jmxremote.access: $(MGMT_CONF_SRC)/jmxremote.access
+	$(call install-file)
+	$(CHMOD) 644 $@
+
+$(MGMT_CONF_DIR)/%: $(MGMT_CONF_SRC)/%
+	$(call install-file)
+	$(CHMOD) 444 $@
+
+TARGETS := $(MGMT_TARGET_FILES)
+
+################################################################################
--- a/make/gensrc/Gensrc-java.management.gmk	Mon Feb 06 09:32:41 2017 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-#
-# 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
-# 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.
-#
-
-include GensrcCommon.gmk
-
-# Hook to include the corresponding custom file, if present.
-$(eval $(call IncludeCustomExtension, jdk, gensrc/Gensrc-java.management.gmk))
-
-################################################################################
-
-include GensrcProperties.gmk
-
-$(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \
-    SRC_DIRS := $(JDK_TOPDIR)/src/java.management/share/classes/sun/management/resources, \
-    CLASS := ListResourceBundle, \
-))
-
-TARGETS += $(COMPILE_PROPERTIES)
-
-################################################################################
-
-all: $(TARGETS)
-
-.PHONY: all
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/gensrc/Gensrc-jdk.management.agent.gmk	Mon Feb 06 09:34:19 2017 -0800
@@ -0,0 +1,43 @@
+#
+# 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
+# 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.
+#
+
+include GensrcCommon.gmk
+
+################################################################################
+
+include GensrcProperties.gmk
+
+$(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \
+    SRC_DIRS := $(JDK_TOPDIR)/src/jdk.management.agent/share/classes/jdk/internal/agent/resources, \
+    CLASS := ListResourceBundle, \
+))
+
+TARGETS += $(COMPILE_PROPERTIES)
+
+################################################################################
+
+all: $(TARGETS)
+
+.PHONY: all
--- a/make/lib/Lib-java.management.gmk	Mon Feb 06 09:32:41 2017 -0800
+++ b/make/lib/Lib-java.management.gmk	Mon Feb 06 09:34:19 2017 -0800
@@ -30,8 +30,7 @@
 
 ################################################################################
 
-LIBMANAGEMENT_SRC += $(JDK_TOPDIR)/src/java.management/share/native/libmanagement \
-    $(JDK_TOPDIR)/src/java.management/$(OPENJDK_TARGET_OS_TYPE)/native/libmanagement
+LIBMANAGEMENT_SRC += $(JDK_TOPDIR)/src/java.management/share/native/libmanagement 
 LIBMANAGEMENT_CFLAGS := -I$(JDK_TOPDIR)/src/java.management/share/native/include \
     $(addprefix -I,$(LIBMANAGEMENT_SRC)) \
     -I$(SUPPORT_OUTPUTDIR)/headers/java.management \
--- a/make/lib/Lib-java.security.jgss.gmk	Mon Feb 06 09:32:41 2017 -0800
+++ b/make/lib/Lib-java.security.jgss.gmk	Mon Feb 06 09:34:19 2017 -0800
@@ -53,7 +53,7 @@
 
 ################################################################################
 
-ifneq ($(BUILD_CRYPTO), no)
+ifneq ($(BUILD_CRYPTO), false)
   BUILD_LIBKRB5_NAME :=
   ifeq ($(OPENJDK_TARGET_OS), windows)
     BUILD_LIBKRB5_NAME := w2k_lsa_auth
--- a/make/lib/Lib-jdk.crypto.ec.gmk	Mon Feb 06 09:32:41 2017 -0800
+++ b/make/lib/Lib-jdk.crypto.ec.gmk	Mon Feb 06 09:34:19 2017 -0800
@@ -27,7 +27,7 @@
 
 ################################################################################
 
-ifeq ($(ENABLE_INTREE_EC), yes)
+ifeq ($(ENABLE_INTREE_EC), true)
 
   LIBSUNEC_SRC := $(JDK_TOPDIR)/src/jdk.crypto.ec/share/native/libsunec
   BUILD_LIBSUNEC_FLAGS := $(addprefix -I, $(SUNEC_SRC))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/lib/Lib-jdk.management.agent.gmk	Mon Feb 06 09:34:19 2017 -0800
@@ -0,0 +1,59 @@
+#
+# Copyright (c) 2017, 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.
+#
+
+include LibCommon.gmk
+
+################################################################################
+
+LIBMANAGEMENT_AGENT_SRC += $(JDK_TOPDIR)/src/jdk.management.agent/$(OPENJDK_TARGET_OS_TYPE)/native/libmanagement_agent
+LIBMANAGEMENT_AGENT_CFLAGS := $(addprefix -I,$(LIBMANAGEMENT_AGENT_SRC)) \
+    -I$(SUPPORT_OUTPUTDIR)/headers/jdk.management.agent \
+    $(LIBJAVA_HEADER_FLAGS) \
+    #
+
+$(eval $(call SetupNativeCompilation,BUILD_LIBMANAGEMENT_AGENT, \
+    LIBRARY := management_agent, \
+    OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+    SRC := $(LIBMANAGEMENT_AGENT_SRC), \
+    OPTIMIZATION := LOW, \
+    CFLAGS := $(CFLAGS_JDKLIB) $(LIBMANAGEMENT_AGENT_CFLAGS), \
+    MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libmanagement_agent/mapfile-vers, \
+    LDFLAGS := $(LDFLAGS_JDKLIB) \
+        $(call SET_SHARED_LIBRARY_ORIGIN), \
+    LIBS := $(JDKLIB_LIBS), \
+    LIBS_windows := $(WIN_JAVA_LIB) advapi32.lib, \
+    VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
+    RC_FLAGS := $(RC_FLAGS) \
+        -D "JDK_FNAME=management_agent.dll" \
+        -D "JDK_INTERNAL_NAME=management_agent" \
+        -D "JDK_FTYPE=0x2L", \
+    OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libmanagement_agent, \
+))
+
+$(BUILD_LIBMANAGEMENT_AGENT): $(call FindLib, java.base, java)
+
+TARGETS += $(BUILD_LIBMANAGEMENT_AGENT)
+
+################################################################################
--- a/make/lib/NetworkingLibraries.gmk	Mon Feb 06 09:32:41 2017 -0800
+++ b/make/lib/NetworkingLibraries.gmk	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, 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,8 +44,9 @@
     LIBS_linux := $(LIBDL) -lpthread, \
     LIBS_solaris := -lnsl -lsocket $(LIBDL) -lc, \
     LIBS_aix := $(LIBDL),\
-    LIBS_windows := ws2_32.lib jvm.lib secur32.lib iphlpapi.lib \
+    LIBS_windows := ws2_32.lib jvm.lib secur32.lib iphlpapi.lib winhttp.lib \
         delayimp.lib $(WIN_JAVA_LIB) advapi32.lib, \
+    LIBS_macosx := -framework CoreFoundation -framework CoreServices, \
     VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
     RC_FLAGS := $(RC_FLAGS) \
         -D "JDK_FNAME=net.dll" \
--- a/make/mapfiles/libmanagement/mapfile-vers	Mon Feb 06 09:32:41 2017 -0800
+++ b/make/mapfiles/libmanagement/mapfile-vers	Mon Feb 06 09:34:19 2017 -0800
@@ -28,7 +28,6 @@
 SUNWprivate_1.1 {
 	global:
 	    Java_sun_management_ClassLoadingImpl_setVerboseClass;
-            Java_sun_management_FileSystemImpl_isAccessUserOnly0;
             Java_sun_management_GarbageCollectorImpl_getCollectionCount;
 	    Java_sun_management_GarbageCollectorImpl_getCollectionTime;
 	    Java_sun_management_HotspotThread_getInternalThreadCount;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/mapfiles/libmanagement_agent/mapfile-vers	Mon Feb 06 09:34:19 2017 -0800
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2017, 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.
+#
+
+# Define library interface.
+
+SUNWprivate_1.1 {
+	global:
+            Java_jdk_internal_agent_FileSystemImpl_isAccessUserOnly0;
+            JNI_OnLoad;
+	local:
+	    *;
+};
--- a/make/mapfiles/libnet/mapfile-vers	Mon Feb 06 09:32:41 2017 -0800
+++ b/make/mapfiles/libnet/mapfile-vers	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1997, 2017, 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
@@ -97,7 +97,7 @@
 		Java_sun_net_sdp_SdpSupport_convert0;
 		Java_sun_net_sdp_SdpSupport_create0;
 		Java_sun_net_spi_DefaultProxySelector_init;
-		Java_sun_net_spi_DefaultProxySelector_getSystemProxy;
+		Java_sun_net_spi_DefaultProxySelector_getSystemProxies;
 		NET_SockaddrToInetAddress;
                 NET_SockaddrEqualsInetAddress;
 		NET_InetAddressToSockaddr;
--- a/make/mapfiles/libunpack/mapfile-vers-unpack200-solaris-sparc	Mon Feb 06 09:32:41 2017 -0800
+++ b/make/mapfiles/libunpack/mapfile-vers-unpack200-solaris-sparc	Mon Feb 06 09:34:19 2017 -0800
@@ -28,6 +28,7 @@
 SUNWprivate_1.1 {
 	global:
 		# These are needed by the c runtime in SS12u4
+		environ;
 		_environ;
 		__environ_lock;
 		___Argv;
--- a/make/rmic/Rmic-java.management.gmk	Mon Feb 06 09:32:41 2017 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-#
-# Copyright (c) 2011, 2016, 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.
-#
-
-default: all
-
-include RmicCommon.gmk
-
-##########################################################################################
-#
-# Generate RMI stubs
-#
-
-JMX_RMI_CLASSES := javax.management.remote.rmi.RMIConnectionImpl \
-    javax.management.remote.rmi.RMIServerImpl
-
-# Generate into gensrc dir where sources get picked up for javadoc, then move the classes
-# into the stub classes dir.
-$(eval $(call SetupRMICompilation,RMI_GEN, \
-    CLASSES := $(JMX_RMI_CLASSES), \
-    CLASSES_DIR := $(CLASSES_DIR)/java.management, \
-    STUB_CLASSES_DIR := $(RMIC_GENSRC_DIR)/java.management, \
-    RUN_V12 := true, \
-    KEEP_GENERATED := true, \
-))
-
-# Find all classes generated and move them from the gensrc dir to the stub classes dir
-$(RMIC_GENSRC_DIR)/_classes.moved: $(RMI_GEN)
-	$(eval classfiles := $(shell $(FIND) $(RMIC_GENSRC_DIR) -name "*.class"))
-	$(foreach src, $(classfiles), \
-	    $(eval target := $(patsubst $(RMIC_GENSRC_DIR)/%, \
-	        $(STUB_CLASSES_DIR)/%, $(src))) \
-	    $(MKDIR) -p $(dir $(target)) ; \
-	    $(MV) $(src) $(target) $(NEWLINE))
-	$(TOUCH) $@
-
-##########################################################################################
-
-all: $(RMIC_GENSRC_DIR)/_classes.moved $(RMI_GEN)
-
-.PHONY: all
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/rmic/Rmic-java.management.rmi.gmk	Mon Feb 06 09:34:19 2017 -0800
@@ -0,0 +1,62 @@
+#
+# Copyright (c) 2011, 2016, 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.
+#
+
+default: all
+
+include RmicCommon.gmk
+
+##########################################################################################
+#
+# Generate RMI stubs
+#
+
+JMX_RMI_CLASSES := javax.management.remote.rmi.RMIConnectionImpl \
+    javax.management.remote.rmi.RMIServerImpl
+
+# Generate into gensrc dir where sources get picked up for javadoc, then move the classes
+# into the stub classes dir.
+$(eval $(call SetupRMICompilation,RMI_GEN, \
+    CLASSES := $(JMX_RMI_CLASSES), \
+    CLASSES_DIR := $(CLASSES_DIR)/java.management.rmi, \
+    STUB_CLASSES_DIR := $(RMIC_GENSRC_DIR)/java.management.rmi, \
+    RUN_V12 := true, \
+    KEEP_GENERATED := true, \
+))
+
+# Find all classes generated and move them from the gensrc dir to the stub classes dir
+$(RMIC_GENSRC_DIR)/_classes.moved: $(RMI_GEN)
+	$(eval classfiles := $(shell $(FIND) $(RMIC_GENSRC_DIR) -name "*.class"))
+	$(foreach src, $(classfiles), \
+	    $(eval target := $(patsubst $(RMIC_GENSRC_DIR)/%, \
+	        $(STUB_CLASSES_DIR)/%, $(src))) \
+	    $(MKDIR) -p $(dir $(target)) ; \
+	    $(MV) $(src) $(target) $(NEWLINE))
+	$(TOUCH) $@
+
+##########################################################################################
+
+all: $(RMIC_GENSRC_DIR)/_classes.moved $(RMI_GEN)
+
+.PHONY: all
--- a/make/src/classes/build/tools/jigsaw/GenGraphs.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/make/src/classes/build/tools/jigsaw/GenGraphs.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -126,7 +126,7 @@
         ranks.add(Set.of("java.compiler", "java.instrument"));
         ranks.add(Set.of("java.desktop", "java.management"));
         ranks.add(Set.of("java.corba", "java.xml.ws"));
-        ranks.add(Set.of("java.xml.bind", "java.annotations.common"));
+        ranks.add(Set.of("java.xml.bind", "java.xml.ws.annotation"));
 
     }
 
--- a/make/src/classes/build/tools/jigsaw/technology-summary.html	Mon Feb 06 09:32:41 2017 -0800
+++ b/make/src/classes/build/tools/jigsaw/technology-summary.html	Mon Feb 06 09:34:19 2017 -0800
@@ -588,7 +588,7 @@
 <td>Common Annotations</td>
 <td><a href="https://jcp.org/en/jsr/detail?id=250">250</a></td>
 <td>Java SE,EE</td>
-<td><a href="module-summary.html#java.annotations.common">java.annotations.common</a></td>
+<td><a href="module-summary.html#java.xml.ws.annotation">java.xml.ws.annotation</a></td>
 <td>Original JSR</td>
 <td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a> (unlisted)</td>
 <td>SE</td>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/macosx/native/libnet/DefaultProxySelector.c	Mon Feb 06 09:34:19 2017 -0800
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017 SAP SE. 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.
+ */
+
+#include <string.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreServices/CoreServices.h>
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+#include "jvm_md.h"
+
+#include "proxy_util.h"
+
+#include "sun_net_spi_DefaultProxySelector.h"
+
+
+/**
+ * For more information on how to use the APIs in "CFProxySupport.h" see:
+ * https://developer.apple.com/legacy/library/samplecode/CFProxySupportTool/Introduction/Intro.html
+ */
+
+#define kResolveProxyRunLoopMode CFSTR("sun.net.spi.DefaultProxySelector")
+
+#define BUFFER_SIZE 1024
+
+/* Callback for CFNetworkExecuteProxyAutoConfigurationURL. */
+static void proxyUrlCallback(void * client, CFArrayRef proxies, CFErrorRef error) {
+    /* client is a pointer to a CFTypeRef and holds either proxies or an error. */
+    CFTypeRef* resultPtr = (CFTypeRef *)client;
+
+    if (error != NULL) {
+        *resultPtr = CFRetain(error);
+    } else {
+        *resultPtr = CFRetain(proxies);
+    }
+    CFRunLoopStop(CFRunLoopGetCurrent());
+}
+
+/*
+ * Returns a new array of proxies containing all the given non-PAC proxies as
+ * well as the results of executing all the given PAC-based proxies, for the
+ * specified URL. 'proxies' is a list that may contain both PAC and non-PAC
+ * proxies.
+ */
+static CFArrayRef createExpandedProxiesArray(CFArrayRef proxies, CFURLRef url) {
+
+    CFIndex count;
+    CFIndex index;
+    CFMutableArrayRef expandedProxiesArray;
+
+    expandedProxiesArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+    if (expandedProxiesArray == NULL)
+        return NULL;
+
+    /* Iterate over the array of proxies */
+    count = CFArrayGetCount(proxies);
+    for (index = 0; index < count ; index++) {
+        CFDictionaryRef currentProxy;
+        CFStringRef     proxyType;
+
+        currentProxy = (CFDictionaryRef) CFArrayGetValueAtIndex(proxies, index);
+        if(currentProxy == NULL) {
+            CFRelease(expandedProxiesArray);
+            return NULL;
+        }
+        proxyType = (CFStringRef) CFDictionaryGetValue(currentProxy, kCFProxyTypeKey);
+        if (proxyType == NULL) {
+            CFRelease(expandedProxiesArray);
+            return NULL;
+        }
+
+        if (!CFEqual(proxyType, kCFProxyTypeAutoConfigurationURL)) {
+            /* Non-PAC entry, just copy it to the new array */
+            CFArrayAppendValue(expandedProxiesArray, currentProxy);
+        } else {
+            /* PAC-based URL, execute its script append its results */
+            CFRunLoopSourceRef      runLoop;
+            CFURLRef                scriptURL;
+            CFTypeRef               result = NULL;
+            CFStreamClientContext   context = { 0, &result, NULL, NULL, NULL };
+            CFTimeInterval timeout = 5;
+
+            scriptURL = CFDictionaryGetValue(currentProxy, kCFProxyAutoConfigurationURLKey);
+
+            runLoop = CFNetworkExecuteProxyAutoConfigurationURL(scriptURL, url, proxyUrlCallback,
+                                                                &context);
+            if (runLoop != NULL) {
+                /*
+                 * Despite the fact that CFNetworkExecuteProxyAutoConfigurationURL has
+                 * neither a "Create" nor a "Copy" in the name, we are required to
+                 * release the return CFRunLoopSourceRef <rdar://problem/5533931>.
+                 */
+                CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoop, kResolveProxyRunLoopMode);
+                CFRunLoopRunInMode(kResolveProxyRunLoopMode, timeout, false);
+                CFRunLoopRemoveSource(CFRunLoopGetCurrent(), runLoop, kResolveProxyRunLoopMode);
+
+                /*
+                 * Once the runloop returns, there will be either an error result or
+                 * a proxies array result. Do the appropriate thing with that result.
+                 */
+                if (result != NULL) {
+                    if (CFGetTypeID(result) == CFArrayGetTypeID()) {
+                        /*
+                         * Append the new array from the PAC list - it contains
+                         * only non-PAC entries.
+                         */
+                        CFArrayAppendArray(expandedProxiesArray, result,
+                                           CFRangeMake(0, CFArrayGetCount(result)));
+                    }
+                    CFRelease(result);
+                }
+                CFRelease(runLoop);
+            }
+        }
+    }
+    return expandedProxiesArray;
+}
+
+
+/*
+ * Class:     sun_net_spi_DefaultProxySelector
+ * Method:    init
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_sun_net_spi_DefaultProxySelector_init(JNIEnv *env, jclass clazz) {
+    if (!initJavaClass(env)) {
+        return JNI_FALSE;
+    }
+    return JNI_TRUE;
+}
+
+
+/*
+ * Class:     sun_net_spi_DefaultProxySelector
+ * Method:    getSystemProxies
+ * Signature: ([Ljava/lang/String;Ljava/lang/String;)[Ljava/net/Proxy;
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_sun_net_spi_DefaultProxySelector_getSystemProxies(JNIEnv *env,
+                                                       jobject this,
+                                                       jstring proto,
+                                                       jstring host)
+{
+    CFDictionaryRef proxyDicRef = NULL;
+    CFURLRef        urlRef = NULL;
+    bool proxyFound = false;
+    jobjectArray proxyArray = NULL;
+    const char *cproto;
+    const char *chost;
+
+    /* Get system proxy settings */
+    proxyDicRef = CFNetworkCopySystemProxySettings();
+    if (proxyDicRef == NULL) {
+        return NULL;
+    }
+
+    /* Create CFURLRef from proto and host */
+    cproto = (*env)->GetStringUTFChars(env, proto, NULL);
+    if (cproto != NULL) {
+        chost  = (*env)->GetStringUTFChars(env, host, NULL);
+        if (chost != NULL) {
+            char* uri = NULL;
+            size_t protoLen = 0;
+            size_t hostLen = 0;
+
+            protoLen = strlen(cproto);
+            hostLen = strlen(chost);
+
+            /* Construct the uri, cproto + "://" + chost */
+            uri = malloc(protoLen + hostLen + 4);
+            if (uri != NULL) {
+                memcpy(uri, cproto, protoLen);
+                memcpy(uri + protoLen, "://", 3);
+                memcpy(uri + protoLen + 3, chost, hostLen + 1);
+
+                urlRef = CFURLCreateWithBytes(NULL, (const UInt8 *) uri, strlen(uri),
+                                              kCFStringEncodingUTF8, NULL);
+                free(uri);
+            }
+            (*env)->ReleaseStringUTFChars(env, host, chost);
+        }
+        (*env)->ReleaseStringUTFChars(env, proto, cproto);
+    }
+    if (urlRef != NULL) {
+        CFArrayRef urlProxyArrayRef = CFNetworkCopyProxiesForURL(urlRef, proxyDicRef);
+        if (urlProxyArrayRef != NULL) {
+            CFIndex count;
+            CFIndex index;
+
+            CFArrayRef expandedProxyArray = createExpandedProxiesArray(urlProxyArrayRef, urlRef);
+            CFRelease(urlProxyArrayRef);
+
+            if (expandedProxyArray == NULL) {
+                CFRelease(urlRef);
+                CFRelease(proxyDicRef);
+                return NULL;
+            }
+
+            count = CFArrayGetCount(expandedProxyArray);
+
+            proxyArray = (*env)->NewObjectArray(env, count, proxy_class, NULL);
+            if (proxyArray != NULL || (*env)->ExceptionCheck(env)) {
+                /* Iterate over the expanded array of proxies */
+                for (index = 0; index < count ; index++) {
+                    CFDictionaryRef currentProxy;
+                    CFStringRef proxyType;
+                    jobject proxy = NULL;
+
+                    currentProxy = (CFDictionaryRef) CFArrayGetValueAtIndex(expandedProxyArray,
+                                                                            index);
+                    proxyType = (CFStringRef) CFDictionaryGetValue(currentProxy, kCFProxyTypeKey);
+                    if (CFEqual(proxyType, kCFProxyTypeNone)) {
+                        /* This entry states no proxy, therefore just add a NO_PROXY object. */
+                        proxy = (*env)->GetStaticObjectField(env, proxy_class, pr_no_proxyID);
+                    } else {
+                        /*
+                         * Create a proxy object for this entry.
+                         * Differentiate between SOCKS and HTTP type.
+                         */
+                        jfieldID typeID = ptype_httpID;
+                        if (CFEqual(proxyType, kCFProxyTypeSOCKS)) {
+                            typeID = ptype_socksID;
+                        }
+                        CFNumberRef portNumberRef = (CFNumberRef)CFDictionaryGetValue(currentProxy,
+                                                    (const void*)kCFProxyPortNumberKey);
+                        if (portNumberRef  != NULL) {
+                            int port = 0;
+                            if (CFNumberGetValue(portNumberRef, kCFNumberSInt32Type, &port)) {
+                                CFStringRef hostNameRef = (CFStringRef)CFDictionaryGetValue(
+                                              currentProxy, (const void*)kCFProxyHostNameKey);
+                                if (hostNameRef != NULL) {
+                                    char hostNameBuffer[BUFFER_SIZE];
+                                    if (CFStringGetCString(hostNameRef, hostNameBuffer,
+                                                           BUFFER_SIZE, kCFStringEncodingUTF8)) {
+                                        proxy = createProxy(env, typeID, &hostNameBuffer[0], port);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    if (proxy == NULL || (*env)->ExceptionCheck(env)) {
+                        proxyArray = NULL;
+                        break;
+                    }
+                    (*env)->SetObjectArrayElement(env, proxyArray, index, proxy);
+                    if ((*env)->ExceptionCheck(env)) {
+                        proxyArray = NULL;
+                        break;
+                    }
+                }
+            }
+            CFRelease(expandedProxyArray);
+        }
+        CFRelease(urlRef);
+    }
+    CFRelease(proxyDicRef);
+
+    return proxyArray;
+}
--- a/src/java.base/share/classes/com/sun/crypto/provider/OutputFeedback.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/com/sun/crypto/provider/OutputFeedback.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -162,11 +162,11 @@
             for (int i = 0; i < numBytes; i++) {
                 cipher[i + cipherOffset] =
                     (byte)(k[i] ^ plain[i + plainOffset]);
-                if (nShift != 0) {
-                    System.arraycopy(register, numBytes, register, 0, nShift);
-                }
-                System.arraycopy(k, 0, register, nShift, numBytes);
             }
+            if (nShift != 0) {
+                System.arraycopy(register, numBytes, register, 0, nShift);
+            }
+            System.arraycopy(k, 0, register, nShift, numBytes);
         }
         return plainLen;
     }
--- a/src/java.base/share/classes/com/sun/net/ssl/HostnameVerifier.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/com/sun/net/ssl/HostnameVerifier.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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,9 +38,8 @@
  * @deprecated As of JDK 1.4, this implementation-specific class was
  *      replaced by {@link javax.net.ssl.HostnameVerifier} and
  *      {@link javax.net.ssl.CertificateHostnameVerifier}.
- *      This class is subject to removal in a future version of JDK.
  */
-@Deprecated(since="1.4", forRemoval=true)
+@Deprecated(since="1.4")
 public interface HostnameVerifier {
     /**
      * Verify that the hostname from the URL is an acceptable
--- a/src/java.base/share/classes/com/sun/net/ssl/HttpsURLConnection.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/com/sun/net/ssl/HttpsURLConnection.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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,9 +44,8 @@
  *
  * @deprecated As of JDK 1.4, this implementation-specific class was
  *      replaced by {@link javax.net.ssl.HttpsURLConnection}.
- *      This class is subject to removal in a future version of JDK.
  */
-@Deprecated(since="1.4", forRemoval=true)
+@Deprecated(since="1.4")
 public abstract
 class HttpsURLConnection extends HttpURLConnection
 {
--- a/src/java.base/share/classes/com/sun/net/ssl/KeyManager.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/com/sun/net/ssl/KeyManager.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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
@@ -36,8 +36,7 @@
  *
  * @deprecated As of JDK 1.4, this implementation-specific class was
  *      replaced by {@link javax.net.ssl.KeyManager}.
- *      This class is subject to removal in a future version of JDK.
  */
-@Deprecated(since="1.4", forRemoval=true)
+@Deprecated(since="1.4")
 public interface KeyManager {
 }
--- a/src/java.base/share/classes/com/sun/net/ssl/KeyManagerFactory.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/com/sun/net/ssl/KeyManagerFactory.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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,9 +39,8 @@
  *
  * @deprecated As of JDK 1.4, this implementation-specific class was
  *      replaced by {@link javax.net.ssl.KeyManagerFactory}.
- *      This class is subject to removal in a future version of JDK.
  */
-@Deprecated(since="1.4", forRemoval=true)
+@Deprecated(since="1.4")
 public class KeyManagerFactory {
     // The provider
     private Provider provider;
--- a/src/java.base/share/classes/com/sun/net/ssl/KeyManagerFactorySpi.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/com/sun/net/ssl/KeyManagerFactorySpi.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,9 +41,8 @@
  *
  * @deprecated As of JDK 1.4, this implementation-specific class was
  *      replaced by {@link javax.net.ssl.KeyManagerFactorySpi}.
- *      This class is subject to removal in a future version of JDK.
  */
-@Deprecated(since="1.4", forRemoval=true)
+@Deprecated(since="1.4")
 public abstract class KeyManagerFactorySpi {
     /**
      * Initializes this factory with a source of key material. The
--- a/src/java.base/share/classes/com/sun/net/ssl/SSLContext.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/com/sun/net/ssl/SSLContext.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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,9 +44,8 @@
  *
  * @deprecated As of JDK 1.4, this implementation-specific class was
  *      replaced by {@link javax.net.ssl.SSLContext}.
- *      This class is subject to removal in a future version of JDK.
  */
-@Deprecated(since="1.4", forRemoval=true)
+@Deprecated(since="1.4")
 public class SSLContext {
     private Provider provider;
 
--- a/src/java.base/share/classes/com/sun/net/ssl/SSLContextSpi.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/com/sun/net/ssl/SSLContextSpi.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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,9 +43,8 @@
  *
  * @deprecated As of JDK 1.4, this implementation-specific class was
  *      replaced by {@link javax.net.ssl.SSLContextSpi}.
- *      This class is subject to removal in a future version of JDK.
  */
-@Deprecated(since="1.4", forRemoval=true)
+@Deprecated(since="1.4")
 public abstract class SSLContextSpi {
     /**
      * Initializes this context.
--- a/src/java.base/share/classes/com/sun/net/ssl/SSLPermission.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/com/sun/net/ssl/SSLPermission.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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
@@ -97,9 +97,8 @@
  *
  * @deprecated As of JDK 1.4, this implementation-specific class was
  *      replaced by {@link javax.net.ssl.SSLPermission}.
- *      This class is subject to removal in a future version of JDK.
  */
-@Deprecated(since="1.4", forRemoval=true)
+@Deprecated(since="1.4")
 public final class SSLPermission extends BasicPermission {
 
     private static final long serialVersionUID = -2583684302506167542L;
--- a/src/java.base/share/classes/com/sun/net/ssl/TrustManager.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/com/sun/net/ssl/TrustManager.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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
@@ -36,8 +36,7 @@
  *
  * @deprecated As of JDK 1.4, this implementation-specific class was
  *      replaced by {@link javax.net.ssl.TrustManager}.
- *      This class is subject to removal in a future version of JDK.
  */
-@Deprecated(since="1.4", forRemoval=true)
+@Deprecated(since="1.4")
 public interface TrustManager {
 }
--- a/src/java.base/share/classes/com/sun/net/ssl/TrustManagerFactory.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/com/sun/net/ssl/TrustManagerFactory.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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,9 +39,8 @@
  *
  * @deprecated As of JDK 1.4, this implementation-specific class was
  *      replaced by {@link javax.net.ssl.TrustManagerFactory}.
- *      This class is subject to removal in a future version of JDK.
  */
-@Deprecated(since="1.4", forRemoval=true)
+@Deprecated(since="1.4")
 public class TrustManagerFactory {
     // The provider
     private Provider provider;
--- a/src/java.base/share/classes/com/sun/net/ssl/TrustManagerFactorySpi.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/com/sun/net/ssl/TrustManagerFactorySpi.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,9 +41,8 @@
  *
  * @deprecated As of JDK 1.4, this implementation-specific class was
  *      replaced by {@link javax.net.ssl.TrustManagerFactorySpi}.
- *      This class is subject to removal in a future version of JDK.
  */
-@Deprecated(since="1.4", forRemoval=true)
+@Deprecated(since="1.4")
 public abstract class TrustManagerFactorySpi {
     /**
      * Initializes this factory with a source of certificate
--- a/src/java.base/share/classes/com/sun/net/ssl/X509KeyManager.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/com/sun/net/ssl/X509KeyManager.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,9 +41,8 @@
  *
  * @deprecated As of JDK 1.4, this implementation-specific class was
  *      replaced by {@link javax.net.ssl.X509KeyManager}.
- *      This class is subject to removal in a future version of JDK.
  */
-@Deprecated(since="1.4", forRemoval=true)
+@Deprecated(since="1.4")
 public interface X509KeyManager extends KeyManager {
     /**
      * Get the matching aliases for authenticating the client side of a secure
--- a/src/java.base/share/classes/com/sun/net/ssl/X509TrustManager.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/com/sun/net/ssl/X509TrustManager.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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
@@ -40,9 +40,8 @@
  *
  * @deprecated As of JDK 1.4, this implementation-specific class was
  *      replaced by {@link javax.net.ssl.X509TrustManager}.
- *      This class is subject to removal in a future version of JDK.
  */
-@Deprecated(since="1.4", forRemoval=true)
+@Deprecated(since="1.4")
 public interface X509TrustManager extends TrustManager {
     /**
      * Given the partial or complete certificate chain
--- a/src/java.base/share/classes/com/sun/net/ssl/internal/ssl/Provider.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/com/sun/net/ssl/internal/ssl/Provider.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2017, 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,10 +31,8 @@
  * Main class for the SunJSSE provider. The actual code was moved to the
  * class sun.security.ssl.SunJSSE, but for backward compatibility we
  * continue to use this class as the main Provider class.
- *
- * @deprecated This class is subject to removal in a future version of JDK.
  */
-@Deprecated(since="9", forRemoval=true)
+@Deprecated(since="9")
 public final class Provider extends SunJSSE {
 
     private static final long serialVersionUID = 3231825739635378733L;
--- a/src/java.base/share/classes/com/sun/net/ssl/internal/ssl/X509ExtendedTrustManager.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/com/sun/net/ssl/internal/ssl/X509ExtendedTrustManager.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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,8 @@
  *
  * @since 1.6
  * @author Xuelei Fan
- * @deprecated This class is subject to removal in a future version of JDK.
  */
-@Deprecated(since="9", forRemoval=true)
+@Deprecated(since="9")
 public abstract class X509ExtendedTrustManager implements X509TrustManager {
     /**
      * Constructor used by subclasses only.
--- a/src/java.base/share/classes/com/sun/net/ssl/internal/www/protocol/https/DelegateHttpsURLConnection.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/com/sun/net/ssl/internal/www/protocol/https/DelegateHttpsURLConnection.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, 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
@@ -52,9 +52,8 @@
  * of protocol implementation (this one)
  * com.sun.net.ssl.HttpURLConnection is used in the com.sun version.
  *
- * @deprecated This class is subject to removal in a future version of JDK.
  */
-@Deprecated(since="9", forRemoval=true)
+@Deprecated(since="9")
 @SuppressWarnings("deprecation") // HttpsURLConnection is deprecated
 public class DelegateHttpsURLConnection extends AbstractDelegateHttpsURLConnection {
 
--- a/src/java.base/share/classes/com/sun/net/ssl/internal/www/protocol/https/Handler.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/com/sun/net/ssl/internal/www/protocol/https/Handler.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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,9 +34,8 @@
  * only. The HTTPS implementation can now be found in
  * sun.net.www.protocol.https.
  *
- * @deprecated This class is subject to removal in a future version of JDK.
  */
-@Deprecated(since="9", forRemoval=true)
+@Deprecated(since="9")
 public class Handler extends sun.net.www.protocol.https.Handler {
 
     public Handler() {
--- a/src/java.base/share/classes/com/sun/net/ssl/internal/www/protocol/https/HttpsURLConnectionOldImpl.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/com/sun/net/ssl/internal/www/protocol/https/HttpsURLConnectionOldImpl.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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
@@ -60,13 +60,12 @@
  * needs to implement all public methods in it's super class and all
  * the way to Object.
  *
- * @deprecated This class is subject to removal in a future version of JDK.
  */
 
 // For both copies of the file, uncomment one line and comment the other
 // public class HttpsURLConnectionImpl
 //      extends javax.net.ssl.HttpsURLConnection {
-@Deprecated(since="9", forRemoval=true)
+@Deprecated(since="9")
 @SuppressWarnings("deprecation") // HttpsURLConnection is deprecated
 public class HttpsURLConnectionOldImpl
         extends com.sun.net.ssl.HttpsURLConnection {
--- a/src/java.base/share/classes/java/lang/reflect/Layer.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/lang/reflect/Layer.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -458,7 +458,7 @@
             loader.initRemotePackageMap(cf, parents);
             Layer layer =  new Layer(cf, parents, mn -> loader);
             return new Controller(layer);
-        } catch (IllegalArgumentException e) {
+        } catch (IllegalArgumentException | IllegalStateException e) {
             throw new LayerInstantiationException(e.getMessage());
         }
     }
@@ -526,7 +526,7 @@
         try {
             Layer layer = new Layer(cf, parents, pool::loaderFor);
             return new Controller(layer);
-        } catch (IllegalArgumentException e) {
+        } catch (IllegalArgumentException | IllegalStateException e) {
             throw new LayerInstantiationException(e.getMessage());
         }
     }
@@ -610,9 +610,8 @@
         try {
             Layer layer = new Layer(cf, parents, clf);
             return new Controller(layer);
-        } catch (IllegalArgumentException iae) {
-            // IAE is thrown by VM when defining the module fails
-            throw new LayerInstantiationException(iae.getMessage());
+        } catch (IllegalArgumentException | IllegalStateException e) {
+            throw new LayerInstantiationException(e.getMessage());
         }
     }
 
--- a/src/java.base/share/classes/java/lang/reflect/Module.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/lang/reflect/Module.java	Mon Feb 06 09:34:19 2017 -0800
@@ -128,14 +128,8 @@
         Version version = descriptor.version().orElse(null);
         String vs = Objects.toString(version, null);
         String loc = Objects.toString(uri, null);
-        Set<String> packages = descriptor.packages();
-        int n = packages.size();
-        String[] array = new String[n];
-        int i = 0;
-        for (String pn : packages) {
-            array[i++] = pn.replace('.', '/');
-        }
-        defineModule0(this, isOpen, vs, loc, array);
+        String[] packages = descriptor.packages().toArray(new String[0]);
+        defineModule0(this, isOpen, vs, loc, packages);
     }
 
 
@@ -789,13 +783,12 @@
 
         // update VM first, just in case it fails
         if (syncVM) {
-            String pkgInternalForm = pn.replace('.', '/');
             if (other == EVERYONE_MODULE) {
-                addExportsToAll0(this, pkgInternalForm);
+                addExportsToAll0(this, pn);
             } else if (other == ALL_UNNAMED_MODULE) {
-                addExportsToAllUnnamed0(this, pkgInternalForm);
+                addExportsToAllUnnamed0(this, pn);
             } else {
-                addExports0(this, pkgInternalForm, other);
+                addExports0(this, pn, other);
             }
         }
 
@@ -1021,7 +1014,7 @@
 
             // update VM first, just in case it fails
             if (syncVM)
-                addPackage0(this, pn.replace('.', '/'));
+                addPackage0(this, pn);
 
             // replace with new set
             this.extraPackages = extraPackages; // volatile write
@@ -1180,8 +1173,7 @@
         if (descriptor.isOpen()) {
             assert descriptor.opens().isEmpty();
             for (String source : descriptor.packages()) {
-                String sourceInternalForm = source.replace('.', '/');
-                addExportsToAll0(m, sourceInternalForm);
+                addExportsToAll0(m, source);
             }
             return;
         }
@@ -1192,7 +1184,6 @@
         // process the open packages first
         for (Opens opens : descriptor.opens()) {
             String source = opens.source();
-            String sourceInternalForm = source.replace('.', '/');
 
             if (opens.isQualified()) {
                 // qualified opens
@@ -1201,7 +1192,7 @@
                     // only open to modules that are in this configuration
                     Module m2 = nameToModule.get(target);
                     if (m2 != null) {
-                        addExports0(m, sourceInternalForm, m2);
+                        addExports0(m, source, m2);
                         targets.add(m2);
                     }
                 }
@@ -1210,7 +1201,7 @@
                 }
             } else {
                 // unqualified opens
-                addExportsToAll0(m, sourceInternalForm);
+                addExportsToAll0(m, source);
                 openPackages.put(source, EVERYONE_SET);
             }
         }
@@ -1218,7 +1209,6 @@
         // next the exports, skipping exports when the package is open
         for (Exports exports : descriptor.exports()) {
             String source = exports.source();
-            String sourceInternalForm = source.replace('.', '/');
 
             // skip export if package is already open to everyone
             Set<Module> openToTargets = openPackages.get(source);
@@ -1234,7 +1224,7 @@
                     if (m2 != null) {
                         // skip qualified export if already open to m2
                         if (openToTargets == null || !openToTargets.contains(m2)) {
-                            addExports0(m, sourceInternalForm, m2);
+                            addExports0(m, source, m2);
                             targets.add(m2);
                         }
                     }
@@ -1245,7 +1235,7 @@
 
             } else {
                 // unqualified exports
-                addExportsToAll0(m, sourceInternalForm);
+                addExportsToAll0(m, source);
                 exportedPackages.put(source, EVERYONE_SET);
             }
         }
--- a/src/java.base/share/classes/java/net/doc-files/net-properties.html	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/net/doc-files/net-properties.html	Mon Feb 06 09:34:19 2017 -0800
@@ -149,7 +149,7 @@
 		the <B>user.name</B> property will be used with no password.</P>
 	</UL>
 	<LI><P><B>java.net.useSystemProxies</B> (default: false)<BR>
-	On recent Windows systems and on Gnome 2.x systems it is possible to
+	On Windows systems, macOS systems and on Gnome systems it is possible to
 	tell the java.net stack, setting this property to <B>true</B>, to use
 	the system proxy settings (both	these systems let you set proxies
 	globally through their user interface). Note that this property is
--- a/src/java.base/share/classes/java/security/Certificate.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/security/Certificate.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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
@@ -60,10 +60,9 @@
  *             This Certificate interface is entirely deprecated and
  *             is here to allow for a smooth transition to the new
  *             package.
- *             This class is subject to removal in a future version of Java SE.
  * @see java.security.cert.Certificate
  */
-@Deprecated(since="1.2", forRemoval=true)
+@Deprecated(since="1.2")
 public interface Certificate {
 
     /**
--- a/src/java.base/share/classes/java/security/Identity.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/security/Identity.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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
@@ -52,12 +52,11 @@
  *
  * @author Benjamin Renaud
  * @deprecated This class is no longer used. Its functionality has been
- * replaced by {@link java.security.KeyStore}, the
- * {@link java.security.cert} package, and
- * {@link java.security.Principal}.
- * This class is subject to removal in a future version of Java SE.
+ * replaced by {@code java.security.KeyStore}, the
+ * {@code java.security.cert} package, and
+ * {@code java.security.Principal}.
  */
-@Deprecated(since="1.2", forRemoval=true)
+@Deprecated(since="1.2")
 public abstract class Identity implements Principal, Serializable {
 
     /** use serialVersionUID from JDK 1.1.x for interoperability */
--- a/src/java.base/share/classes/java/security/IdentityScope.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/security/IdentityScope.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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
@@ -57,15 +57,11 @@
  * @author Benjamin Renaud
  *
  * @deprecated This class is no longer used. Its functionality has been
- * replaced by {@link java.security.KeyStore}, the
- * {@link java.security.cert} package, and
- * {@link java.security.Principal}.
- * This class is subject to removal in a future version of Java SE.
- *
- * Note that the security property {@code policy.ignoreIdentityScope}
- * is only applicable to these APIs and is also a candidate for removal.
+ * replaced by {@code java.security.KeyStore}, the
+ * {@code java.security.cert} package, and
+ * {@code java.security.Principal}.
  */
-@Deprecated(since="1.2", forRemoval=true)
+@Deprecated(since="1.2")
 public abstract
 class IdentityScope extends Identity {
 
--- a/src/java.base/share/classes/java/security/Signer.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/security/Signer.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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
@@ -40,12 +40,11 @@
  * @author Benjamin Renaud
  *
  * @deprecated This class is no longer used. Its functionality has been
- * replaced by {@link java.security.KeyStore}, the
- * {@link java.security.cert} package, and
- * {@link java.security.Principal}.
- * This class is subject to removal in a future version of Java SE.
+ * replaced by {@code java.security.KeyStore}, the
+ * {@code java.security.cert} package, and
+ * {@code java.security.Principal}.
  */
-@Deprecated(since="1.2", forRemoval=true)
+@Deprecated(since="1.2")
 public abstract class Signer extends Identity {
 
     private static final long serialVersionUID = -1763464102261361480L;
--- a/src/java.base/share/classes/java/security/acl/Acl.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/security/acl/Acl.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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
@@ -85,10 +85,9 @@
  *
  * @deprecated This package has been replaced by {@code java.security.Policy}
  *      and related classes since 1.2.
- *      This class is subject to removal in a future version of Java SE.
  */
 
-@Deprecated(since="9", forRemoval=true)
+@Deprecated(since="9")
 public interface Acl extends Owner {
 
     /**
--- a/src/java.base/share/classes/java/security/acl/AclEntry.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/security/acl/AclEntry.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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
@@ -53,9 +53,8 @@
  *
  * @deprecated This package has been replaced by {@code java.security.Policy}
  *      and related classes since 1.2.
- *      This class is subject to removal in a future version of Java SE.
  */
-@Deprecated(since="9", forRemoval=true)
+@Deprecated(since="9")
 public interface AclEntry extends Cloneable {
 
     /**
--- a/src/java.base/share/classes/java/security/acl/AclNotFoundException.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/security/acl/AclNotFoundException.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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,9 +33,8 @@
  *
  * @deprecated This package has been replaced by {@code java.security.Policy}
  *      and related classes since 1.2.
- *      This class is subject to removal in a future version of Java SE.
  */
-@Deprecated(since="9", forRemoval=true)
+@Deprecated(since="9")
 public class AclNotFoundException extends Exception {
 
     private static final long serialVersionUID = 5684295034092681791L;
--- a/src/java.base/share/classes/java/security/acl/Group.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/security/acl/Group.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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,9 +42,8 @@
  *
  * @deprecated This package has been replaced by {@code java.security.Policy}
  *      and related classes since 1.2.
- *      This class is subject to removal in a future version of Java SE.
  */
-@Deprecated(since="9", forRemoval=true)
+@Deprecated(since="9")
 public interface Group extends Principal {
 
     /**
--- a/src/java.base/share/classes/java/security/acl/LastOwnerException.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/security/acl/LastOwnerException.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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,9 +35,8 @@
  *
  * @deprecated This package has been replaced by {@code java.security.Policy}
  *      and related classes since 1.2.
- *      This class is subject to removal in a future version of Java SE.
  */
-@Deprecated(since="9", forRemoval=true)
+@Deprecated(since="9")
 public class LastOwnerException extends Exception {
 
     private static final long serialVersionUID = -5141997548211140359L;
--- a/src/java.base/share/classes/java/security/acl/NotOwnerException.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/security/acl/NotOwnerException.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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,9 +34,8 @@
  *
  * @deprecated This package has been replaced by {@code java.security.Policy}
  *      and related classes since 1.2.
- *      This class is subject to removal in a future version of Java SE.
  */
-@Deprecated(since="9", forRemoval=true)
+@Deprecated(since="9")
 public class NotOwnerException extends Exception {
 
     private static final long serialVersionUID = -5555597911163362399L;
--- a/src/java.base/share/classes/java/security/acl/Owner.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/security/acl/Owner.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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,9 +38,8 @@
  *
  * @deprecated This package has been replaced by {@code java.security.Policy}
  *      and related classes since 1.2.
- *      This class is subject to removal in a future version of Java SE.
  */
-@Deprecated(since="9", forRemoval=true)
+@Deprecated(since="9")
 public interface Owner {
 
     /**
--- a/src/java.base/share/classes/java/security/acl/Permission.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/security/acl/Permission.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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,9 +34,8 @@
  *
  * @deprecated This package has been replaced by {@code java.security.Policy}
  *      and related classes since 1.2.
- *      This class is subject to removal in a future version of Java SE.
  */
-@Deprecated(since="9", forRemoval=true)
+@Deprecated(since="9")
 public interface Permission {
 
     /**
--- a/src/java.base/share/classes/java/security/acl/package-info.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/security/acl/package-info.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, 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,8 +27,7 @@
  * The classes and interfaces in this package have been deprecated. New
  * classes should not be added to this package. The {@code java.security}
  * package contains suitable replacements. See {@link java.security.Policy}
- * and related classes for details. This package is subject to removal in a
- * future version of Java SE.
+ * and related classes for details.
  *
  * @since 1.1
  */
--- a/src/java.base/share/classes/java/util/PriorityQueue.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/util/PriorityQueue.java	Mon Feb 06 09:34:19 2017 -0800
@@ -734,12 +734,12 @@
     @SuppressWarnings("unchecked")
     private void heapify() {
         final Object[] es = queue;
-        final int half = (size >>> 1) - 1;
+        int i = (size >>> 1) - 1;
         if (comparator == null)
-            for (int i = half; i >= 0; i--)
+            for (; i >= 0; i--)
                 siftDownComparable(i, (E) es[i]);
         else
-            for (int i = half; i >= 0; i--)
+            for (; i >= 0; i--)
                 siftDownUsingComparator(i, (E) es[i]);
     }
 
--- a/src/java.base/share/classes/java/util/ResourceBundle.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/util/ResourceBundle.java	Mon Feb 06 09:34:19 2017 -0800
@@ -61,7 +61,10 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.jar.JarEntry;
+import java.util.spi.ResourceBundleControlProvider;
 import java.util.spi.ResourceBundleProvider;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import jdk.internal.loader.BootLoader;
 import jdk.internal.misc.JavaUtilResourceBundleAccess;
@@ -232,6 +235,8 @@
  * <li>{@code ResourceBundle.Control} is <em>not</em> supported in named modules.
  * If the {@code getBundle} method with a {@code ResourceBundle.Control} is called
  * in a named module, the method will throw an {@code UnsupportedOperationException}.
+ * Any service providers of {@link ResourceBundleControlProvider} are ignored in
+ * named modules.
  * </li>
  * </ul>
  *
@@ -262,6 +267,18 @@
  * {@link #getBundle(String, Locale, ClassLoader, Control) getBundle}
  * factory method for details.
  *
+ * <p><a name="modify_default_behavior">For the {@code getBundle} factory</a>
+ * methods that take no {@link Control} instance, their <a
+ * href="#default_behavior"> default behavior</a> of resource bundle loading
+ * can be modified with custom {@link
+ * ResourceBundleControlProvider} implementations.
+ * If any of the
+ * providers provides a {@link Control} for the given base name, that {@link
+ * Control} will be used instead of the default {@link Control}. If there is
+ * more than one service provider for supporting the same base name,
+ * the first one returned from {@link ServiceLoader} will be used.
+ * A custom {@link Control} implementation is ignored by named modules.
+ *
  * <h3>Cache Management</h3>
  *
  * Resource bundle instances created by the <code>getBundle</code> factory
@@ -367,7 +384,8 @@
                 public ResourceBundle getBundle(String baseName, Locale locale, Module module) {
                     // use the given module as the caller to bypass the access check
                     return getBundleImpl(module, module,
-                                         baseName, locale, Control.INSTANCE);
+                                         baseName, locale,
+                                         getDefaultControl(module, baseName));
                 }
 
                 @Override
@@ -815,7 +833,7 @@
     {
         Class<?> caller = Reflection.getCallerClass();
         return getBundleImpl(baseName, Locale.getDefault(),
-                             caller, Control.INSTANCE);
+                             caller, getDefaultControl(caller, baseName));
     }
 
     /**
@@ -889,7 +907,7 @@
     {
         Class<?> caller = Reflection.getCallerClass();
         return getBundleImpl(baseName, locale,
-                             caller, Control.INSTANCE);
+                             caller, getDefaultControl(caller, baseName));
     }
 
     /**
@@ -925,7 +943,8 @@
     @CallerSensitive
     public static ResourceBundle getBundle(String baseName, Module module) {
         return getBundleFromModule(Reflection.getCallerClass(), module, baseName,
-                                   Locale.getDefault(), Control.INSTANCE);
+                                   Locale.getDefault(),
+                                   getDefaultControl(module, baseName));
     }
 
     /**
@@ -953,7 +972,9 @@
      * equivalent to calling {@link #getBundle(String, Locale, ClassLoader)
      * getBundle(baseName, targetLocale, module.getClassLoader()} to load
      * resource bundles that are visible to the class loader of the given
-     * unnamed module.
+     * unnamed module. Custom {@link java.util.spi.ResourceBundleControlProvider}
+     * implementations, if present, will only be invoked if the specified
+     * module is an unnamed module.
      *
      * @param baseName the base name of the resource bundle,
      *                 a fully qualified class name
@@ -974,7 +995,7 @@
     @CallerSensitive
     public static ResourceBundle getBundle(String baseName, Locale targetLocale, Module module) {
         return getBundleFromModule(Reflection.getCallerClass(), module, baseName, targetLocale,
-                                   Control.INSTANCE);
+                                   getDefaultControl(module, baseName));
     }
 
     /**
@@ -1030,7 +1051,10 @@
      *
      * <p>This method behaves the same as calling
      * {@link #getBundle(String, Locale, ClassLoader, Control)} passing a
-     * default instance of {@link Control}.
+     * default instance of {@link Control} unless another {@link Control} is
+     * provided with the {@link ResourceBundleControlProvider} SPI. Refer to the
+     * description of <a href="#modify_default_behavior">modifying the default
+     * behavior</a>.
      *
      * <p><a name="default_behavior">The following describes the default
      * behavior</a>.
@@ -1228,7 +1252,7 @@
             throw new NullPointerException();
         }
         Class<?> caller = Reflection.getCallerClass();
-        return getBundleImpl(baseName, locale, caller, loader, Control.INSTANCE);
+        return getBundleImpl(baseName, locale, caller, loader, getDefaultControl(caller, baseName));
     }
 
     /**
@@ -1453,6 +1477,39 @@
         return getBundleImpl(baseName, targetLocale, caller, loader, control);
     }
 
+    private static Control getDefaultControl(Class<?> caller, String baseName) {
+        return getDefaultControl(caller.getModule(), baseName);
+    }
+
+    private static Control getDefaultControl(Module targetModule, String baseName) {
+        return targetModule.isNamed() ?
+            Control.INSTANCE :
+            ResourceBundleControlProviderHolder.getControl(baseName);
+    }
+
+    private static class ResourceBundleControlProviderHolder {
+        private static final PrivilegedAction<List<ResourceBundleControlProvider>> pa =
+            () -> {
+                return Collections.unmodifiableList(
+                    ServiceLoader.load(ResourceBundleControlProvider.class,
+                                       ClassLoader.getSystemClassLoader()).stream()
+                        .map(ServiceLoader.Provider::get)
+                        .collect(Collectors.toList()));
+            };
+
+        private static final List<ResourceBundleControlProvider> CONTROL_PROVIDERS =
+            AccessController.doPrivileged(pa);
+
+        private static Control getControl(String baseName) {
+            return CONTROL_PROVIDERS.isEmpty() ?
+                Control.INSTANCE :
+                CONTROL_PROVIDERS.stream()
+                    .flatMap(provider -> Stream.ofNullable(provider.getControl(baseName)))
+                    .findFirst()
+                    .orElse(Control.INSTANCE);
+        }
+    }
+
     private static void checkNamedModule(Class<?> caller) {
         if (caller.getModule().isNamed()) {
             throw new UnsupportedOperationException(
@@ -2414,7 +2471,8 @@
      * @apiNote <a name="note">{@code ResourceBundle.Control} is not supported
      * in named modules.</a> If the {@code ResourceBundle.getBundle} method with
      * a {@code ResourceBundle.Control} is called in a named module, the method
-     * will throw an {@link UnsupportedOperationException}.
+     * will throw an {@link UnsupportedOperationException}. Any service providers
+     * of {@link ResourceBundleControlProvider} are ignored in named modules.
      *
      * @since 1.6
      * @see java.util.spi.ResourceBundleProvider
--- a/src/java.base/share/classes/java/util/Vector.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/util/Vector.java	Mon Feb 06 09:34:19 2017 -0800
@@ -307,8 +307,9 @@
         if (newSize > elementData.length)
             grow(newSize);
         final Object[] es = elementData;
-        for (int to = elementCount, i = elementCount = newSize; i < to; i++)
+        for (int to = elementCount, i = newSize; i < to; i++)
             es[i] = null;
+        elementCount = newSize;
     }
 
     /**
@@ -1443,9 +1444,8 @@
 
         @SuppressWarnings("unchecked")
         public boolean tryAdvance(Consumer<? super E> action) {
+            Objects.requireNonNull(action);
             int i;
-            if (action == null)
-                throw new NullPointerException();
             if (getFence() > (i = index)) {
                 index = i + 1;
                 action.accept((E)array[i]);
@@ -1458,8 +1458,7 @@
 
         @SuppressWarnings("unchecked")
         public void forEachRemaining(Consumer<? super E> action) {
-            if (action == null)
-                throw new NullPointerException();
+            Objects.requireNonNull(action);
             final int hi = getFence();
             final Object[] a = array;
             int i;
--- a/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java	Mon Feb 06 09:34:19 2017 -0800
@@ -72,9 +72,8 @@
  * generally decreases throughput but reduces variability and avoids
  * starvation.
  *
- * <p>This class and its iterator implement all of the
- * <em>optional</em> methods of the {@link Collection} and {@link
- * Iterator} interfaces.
+ * <p>This class and its iterator implement all of the <em>optional</em>
+ * methods of the {@link Collection} and {@link Iterator} interfaces.
  *
  * <p>This class is a member of the
  * <a href="{@docRoot}/../technotes/guides/collections/index.html">
--- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java	Mon Feb 06 09:34:19 2017 -0800
@@ -67,12 +67,12 @@
  * asynchronous nature of these deques, determining the current number
  * of elements requires a traversal of the elements, and so may report
  * inaccurate results if this collection is modified during traversal.
- * Additionally, the bulk operations {@code addAll},
- * {@code removeAll}, {@code retainAll}, {@code containsAll},
- * and {@code toArray} are <em>not</em> guaranteed
- * to be performed atomically. For example, an iterator operating
- * concurrently with an {@code addAll} operation might view only some
- * of the added elements.
+ *
+ * <p>Bulk operations that add, remove, or examine multiple elements,
+ * such as {@link #addAll}, {@link #removeIf} or {@link #forEach},
+ * are <em>not</em> guaranteed to be performed atomically.
+ * For example, a {@code forEach} traversal concurrent with an {@code
+ * addAll} operation might observe only some of the added elements.
  *
  * <p>This class and its iterator implement all of the <em>optional</em>
  * methods of the {@link Deque} and {@link Iterator} interfaces.
@@ -683,8 +683,9 @@
      */
     final Node<E> succ(Node<E> p) {
         // TODO: should we skip deleted nodes here?
-        Node<E> q = p.next;
-        return (p == q) ? first() : q;
+        if (p == (p = p.next))
+            p = first();
+        return p;
     }
 
     /**
@@ -1416,65 +1417,55 @@
         boolean exhausted;  // true when no more nodes
 
         public Spliterator<E> trySplit() {
-            Node<E> p;
-            int b = batch;
-            int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1;
-            if (!exhausted &&
-                ((p = current) != null || (p = first()) != null)) {
-                if (p.item == null && p == (p = p.next))
-                    current = p = first();
-                if (p != null && p.next != null) {
-                    Object[] a = new Object[n];
-                    int i = 0;
-                    do {
-                        if ((a[i] = p.item) != null)
-                            ++i;
-                        if (p == (p = p.next))
-                            p = first();
-                    } while (p != null && i < n);
-                    if ((current = p) == null)
-                        exhausted = true;
-                    if (i > 0) {
-                        batch = i;
-                        return Spliterators.spliterator
-                            (a, 0, i, (Spliterator.ORDERED |
-                                       Spliterator.NONNULL |
-                                       Spliterator.CONCURRENT));
-                    }
+            Node<E> p, q;
+            if ((p = current()) == null || (q = p.next) == null)
+                return null;
+            int i = 0, n = batch = Math.min(batch + 1, MAX_BATCH);
+            Object[] a = null;
+            do {
+                final E e;
+                if ((e = p.item) != null) {
+                    if (a == null)
+                        a = new Object[n];
+                    a[i++] = e;
                 }
-            }
-            return null;
+                if (p == (p = q))
+                    p = first();
+            } while (p != null && (q = p.next) != null && i < n);
+            setCurrent(p);
+            return (i == 0) ? null :
+                Spliterators.spliterator(a, 0, i, (Spliterator.ORDERED |
+                                                   Spliterator.NONNULL |
+                                                   Spliterator.CONCURRENT));
         }
 
         public void forEachRemaining(Consumer<? super E> action) {
+            Objects.requireNonNull(action);
             Node<E> p;
-            if (action == null) throw new NullPointerException();
-            if (!exhausted &&
-                ((p = current) != null || (p = first()) != null)) {
+            if ((p = current()) != null) {
+                current = null;
                 exhausted = true;
                 do {
-                    E e = p.item;
+                    final E e;
+                    if ((e = p.item) != null)
+                        action.accept(e);
                     if (p == (p = p.next))
                         p = first();
-                    if (e != null)
-                        action.accept(e);
                 } while (p != null);
             }
         }
 
         public boolean tryAdvance(Consumer<? super E> action) {
+            Objects.requireNonNull(action);
             Node<E> p;
-            if (action == null) throw new NullPointerException();
-            if (!exhausted &&
-                ((p = current) != null || (p = first()) != null)) {
+            if ((p = current()) != null) {
                 E e;
                 do {
                     e = p.item;
                     if (p == (p = p.next))
                         p = first();
                 } while (e == null && p != null);
-                if ((current = p) == null)
-                    exhausted = true;
+                setCurrent(p);
                 if (e != null) {
                     action.accept(e);
                     return true;
@@ -1483,11 +1474,24 @@
             return false;
         }
 
+        private void setCurrent(Node<E> p) {
+            if ((current = p) == null)
+                exhausted = true;
+        }
+
+        private Node<E> current() {
+            Node<E> p;
+            if ((p = current) == null && !exhausted)
+                setCurrent(p = first());
+            return p;
+        }
+
         public long estimateSize() { return Long.MAX_VALUE; }
 
         public int characteristics() {
-            return Spliterator.ORDERED | Spliterator.NONNULL |
-                Spliterator.CONCURRENT;
+            return (Spliterator.ORDERED |
+                    Spliterator.NONNULL |
+                    Spliterator.CONCURRENT);
         }
     }
 
--- a/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java	Mon Feb 06 09:34:19 2017 -0800
@@ -81,12 +81,12 @@
  * asynchronous nature of these queues, determining the current number
  * of elements requires a traversal of the elements, and so may report
  * inaccurate results if this collection is modified during traversal.
- * Additionally, the bulk operations {@code addAll},
- * {@code removeAll}, {@code retainAll}, {@code containsAll},
- * and {@code toArray} are <em>not</em> guaranteed
- * to be performed atomically. For example, an iterator operating
- * concurrently with an {@code addAll} operation might view only some
- * of the added elements.
+ *
+ * <p>Bulk operations that add, remove, or examine multiple elements,
+ * such as {@link #addAll}, {@link #removeIf} or {@link #forEach},
+ * are <em>not</em> guaranteed to be performed atomically.
+ * For example, a {@code forEach} traversal concurrent with an {@code
+ * addAll} operation might observe only some of the added elements.
  *
  * <p>This class and its iterator implement all of the <em>optional</em>
  * methods of the {@link Queue} and {@link Iterator} interfaces.
@@ -184,16 +184,30 @@
     static final class Node<E> {
         volatile E item;
         volatile Node<E> next;
-    }
 
-    /**
-     * Returns a new node holding item.  Uses relaxed write because item
-     * can only be seen after piggy-backing publication via CAS.
-     */
-    static <E> Node<E> newNode(E item) {
-        Node<E> node = new Node<E>();
-        ITEM.set(node, item);
-        return node;
+        /**
+         * Constructs a node holding item.  Uses relaxed write because
+         * item can only be seen after piggy-backing publication via CAS.
+         */
+        Node(E item) {
+            ITEM.set(this, item);
+        }
+
+        /** Constructs a dead dummy node. */
+        Node() {}
+
+        void appendRelaxed(Node<E> next) {
+            // assert next != null;
+            // assert this.next == null;
+            NEXT.set(this, next);
+        }
+
+        boolean casItem(E cmp, E val) {
+            // assert item == cmp || item == null;
+            // assert cmp != null;
+            // assert val == null;
+            return ITEM.compareAndSet(this, cmp, val);
+        }
     }
 
     /**
@@ -220,7 +234,7 @@
      * - tail.item may or may not be null.
      * - it is permitted for tail to lag behind head, that is, for tail
      *   to not be reachable from head!
-     * - tail.next may or may not be self-pointing to tail.
+     * - tail.next may or may not be self-linked.
      */
     private transient volatile Node<E> tail;
 
@@ -228,7 +242,7 @@
      * Creates a {@code ConcurrentLinkedQueue} that is initially empty.
      */
     public ConcurrentLinkedQueue() {
-        head = tail = newNode(null);
+        head = tail = new Node<E>();
     }
 
     /**
@@ -243,16 +257,14 @@
     public ConcurrentLinkedQueue(Collection<? extends E> c) {
         Node<E> h = null, t = null;
         for (E e : c) {
-            Node<E> newNode = newNode(Objects.requireNonNull(e));
+            Node<E> newNode = new Node<E>(Objects.requireNonNull(e));
             if (h == null)
                 h = t = newNode;
-            else {
-                NEXT.set(t, newNode);
-                t = newNode;
-            }
+            else
+                t.appendRelaxed(t = newNode);
         }
         if (h == null)
-            h = t = newNode(null);
+            h = t = new Node<E>();
         head = h;
         tail = t;
     }
@@ -287,14 +299,17 @@
      * stale pointer that is now off the list.
      */
     final Node<E> succ(Node<E> p) {
-        Node<E> next = p.next;
-        return (p == next) ? head : next;
+        if (p == (p = p.next))
+            p = head;
+        return p;
     }
 
     /**
      * Tries to CAS pred.next (or head, if pred is null) from c to p.
+     * Caller must ensure that we're not unlinking the trailing node.
      */
     private boolean tryCasSuccessor(Node<E> pred, Node<E> c, Node<E> p) {
+        // assert p != null;
         // assert c.item == null;
         // assert c != p;
         if (pred != null)
@@ -307,6 +322,29 @@
     }
 
     /**
+     * Collapse dead nodes between pred and q.
+     * @param pred the last known live node, or null if none
+     * @param c the first dead node
+     * @param p the last dead node
+     * @param q p.next: the next live node, or null if at end
+     * @return either old pred or p if pred dead or CAS failed
+     */
+    private Node<E> skipDeadNodes(Node<E> pred, Node<E> c, Node<E> p, Node<E> q) {
+        // assert pred != c;
+        // assert p != q;
+        // assert c.item == null;
+        // assert p.item == null;
+        if (q == null) {
+            // Never unlink trailing node.
+            if (c == p) return pred;
+            q = p;
+        }
+        return (tryCasSuccessor(pred, c, q)
+                && (pred == null || ITEM.get(pred) != null))
+            ? pred : p;
+    }
+
+    /**
      * Inserts the specified element at the tail of this queue.
      * As the queue is unbounded, this method will never return {@code false}.
      *
@@ -314,7 +352,7 @@
      * @throws NullPointerException if the specified element is null
      */
     public boolean offer(E e) {
-        final Node<E> newNode = newNode(Objects.requireNonNull(e));
+        final Node<E> newNode = new Node<E>(Objects.requireNonNull(e));
 
         for (Node<E> t = tail, p = t;;) {
             Node<E> q = p.next;
@@ -346,8 +384,7 @@
         restartFromHead: for (;;) {
             for (Node<E> h = head, p = h, q;; p = q) {
                 final E item;
-                if ((item = p.item) != null
-                    && ITEM.compareAndSet(p, item, null)) {
+                if ((item = p.item) != null && p.casItem(item, null)) {
                     // Successful CAS is the linearization point
                     // for item to be removed from this queue.
                     if (p != h) // hop two nodes at a time
@@ -451,19 +488,20 @@
     public boolean contains(Object o) {
         if (o == null) return false;
         restartFromHead: for (;;) {
-            for (Node<E> p = head, c = p, pred = null, q; p != null; p = q) {
+            for (Node<E> p = head, pred = null; p != null; ) {
+                Node<E> q = p.next;
                 final E item;
-                if ((item = p.item) != null && o.equals(item))
-                    return true;
-                if (c != p && tryCasSuccessor(pred, c, p))
-                    c = p;
-                q = p.next;
-                if (item != null || c != p) {
-                    pred = p;
-                    c = q;
+                if ((item = p.item) != null) {
+                    if (o.equals(item))
+                        return true;
+                    pred = p; p = q; continue;
                 }
-                else if (p == q)
-                    continue restartFromHead;
+                for (Node<E> c = p;; q = p.next) {
+                    if (q == null || q.item != null) {
+                        pred = skipDeadNodes(pred, c, p, q); p = q; break;
+                    }
+                    if (p == (p = q)) continue restartFromHead;
+                }
             }
             return false;
         }
@@ -483,23 +521,22 @@
     public boolean remove(Object o) {
         if (o == null) return false;
         restartFromHead: for (;;) {
-            for (Node<E> p = head, c = p, pred = null, q; p != null; p = q) {
+            for (Node<E> p = head, pred = null; p != null; ) {
+                Node<E> q = p.next;
                 final E item;
-                final boolean removed =
-                    (item = p.item) != null
-                    && o.equals(item)
-                    && ITEM.compareAndSet(p, item, null);
-                if (c != p && tryCasSuccessor(pred, c, p))
-                    c = p;
-                if (removed)
-                    return true;
-                q = p.next;
-                if (item != null || c != p) {
-                    pred = p;
-                    c = q;
+                if ((item = p.item) != null) {
+                    if (o.equals(item) && p.casItem(item, null)) {
+                        skipDeadNodes(pred, p, p, q);
+                        return true;
+                    }
+                    pred = p; p = q; continue;
                 }
-                else if (p == q)
-                    continue restartFromHead;
+                for (Node<E> c = p;; q = p.next) {
+                    if (q == null || q.item != null) {
+                        pred = skipDeadNodes(pred, c, p, q); p = q; break;
+                    }
+                    if (p == (p = q)) continue restartFromHead;
+                }
             }
             return false;
         }
@@ -525,13 +562,11 @@
         // Copy c into a private chain of Nodes
         Node<E> beginningOfTheEnd = null, last = null;
         for (E e : c) {
-            Node<E> newNode = newNode(Objects.requireNonNull(e));
+            Node<E> newNode = new Node<E>(Objects.requireNonNull(e));
             if (beginningOfTheEnd == null)
                 beginningOfTheEnd = last = newNode;
-            else {
-                NEXT.set(last, newNode);
-                last = newNode;
-            }
+            else
+                last.appendRelaxed(last = newNode);
         }
         if (beginningOfTheEnd == null)
             return false;
@@ -677,7 +712,7 @@
      */
     @SuppressWarnings("unchecked")
     public <T> T[] toArray(T[] a) {
-        if (a == null) throw new NullPointerException();
+        Objects.requireNonNull(a);
         return (T[]) toArrayInternal(a);
     }
 
@@ -757,6 +792,8 @@
             }
         }
 
+        // Default implementation of forEachRemaining is "good enough".
+
         public void remove() {
             Node<E> l = lastRet;
             if (l == null) throw new IllegalStateException();
@@ -806,16 +843,14 @@
         Node<E> h = null, t = null;
         for (Object item; (item = s.readObject()) != null; ) {
             @SuppressWarnings("unchecked")
-            Node<E> newNode = newNode((E) item);
+            Node<E> newNode = new Node<E>((E) item);
             if (h == null)
                 h = t = newNode;
-            else {
-                NEXT.set(t, newNode);
-                t = newNode;
-            }
+            else
+                t.appendRelaxed(t = newNode);
         }
         if (h == null)
-            h = t = newNode(null);
+            h = t = new Node<E>();
         head = h;
         tail = t;
     }
@@ -828,62 +863,49 @@
         boolean exhausted;  // true when no more nodes
 
         public Spliterator<E> trySplit() {
-            Node<E> p;
-            int b = batch;
-            int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1;
-            if (!exhausted &&
-                ((p = current) != null || (p = first()) != null) &&
-                p.next != null) {
-                Object[] a = new Object[n];
-                int i = 0;
-                do {
-                    if ((a[i] = p.item) != null)
-                        ++i;
-                    if (p == (p = p.next))
-                        p = first();
-                } while (p != null && i < n);
-                if ((current = p) == null)
-                    exhausted = true;
-                if (i > 0) {
-                    batch = i;
-                    return Spliterators.spliterator
-                        (a, 0, i, (Spliterator.ORDERED |
-                                   Spliterator.NONNULL |
-                                   Spliterator.CONCURRENT));
+            Node<E> p, q;
+            if ((p = current()) == null || (q = p.next) == null)
+                return null;
+            int i = 0, n = batch = Math.min(batch + 1, MAX_BATCH);
+            Object[] a = null;
+            do {
+                final E e;
+                if ((e = p.item) != null) {
+                    if (a == null)
+                        a = new Object[n];
+                    a[i++] = e;
                 }
-            }
-            return null;
+                if (p == (p = q))
+                    p = first();
+            } while (p != null && (q = p.next) != null && i < n);
+            setCurrent(p);
+            return (i == 0) ? null :
+                Spliterators.spliterator(a, 0, i, (Spliterator.ORDERED |
+                                                   Spliterator.NONNULL |
+                                                   Spliterator.CONCURRENT));
         }
 
         public void forEachRemaining(Consumer<? super E> action) {
-            Node<E> p;
-            if (action == null) throw new NullPointerException();
-            if (!exhausted &&
-                ((p = current) != null || (p = first()) != null)) {
+            Objects.requireNonNull(action);
+            final Node<E> p;
+            if ((p = current()) != null) {
+                current = null;
                 exhausted = true;
-                do {
-                    E e = p.item;
-                    if (p == (p = p.next))
-                        p = first();
-                    if (e != null)
-                        action.accept(e);
-                } while (p != null);
+                forEachFrom(action, p);
             }
         }
 
         public boolean tryAdvance(Consumer<? super E> action) {
+            Objects.requireNonNull(action);
             Node<E> p;
-            if (action == null) throw new NullPointerException();
-            if (!exhausted &&
-                ((p = current) != null || (p = first()) != null)) {
+            if ((p = current()) != null) {
                 E e;
                 do {
                     e = p.item;
                     if (p == (p = p.next))
                         p = first();
                 } while (e == null && p != null);
-                if ((current = p) == null)
-                    exhausted = true;
+                setCurrent(p);
                 if (e != null) {
                     action.accept(e);
                     return true;
@@ -892,11 +914,24 @@
             return false;
         }
 
+        private void setCurrent(Node<E> p) {
+            if ((current = p) == null)
+                exhausted = true;
+        }
+
+        private Node<E> current() {
+            Node<E> p;
+            if ((p = current) == null && !exhausted)
+                setCurrent(p = first());
+            return p;
+        }
+
         public long estimateSize() { return Long.MAX_VALUE; }
 
         public int characteristics() {
-            return Spliterator.ORDERED | Spliterator.NONNULL |
-                Spliterator.CONCURRENT;
+            return (Spliterator.ORDERED |
+                    Spliterator.NONNULL |
+                    Spliterator.CONCURRENT);
         }
     }
 
@@ -963,22 +998,22 @@
             // c will be CASed to collapse intervening dead nodes between
             // pred (or head if null) and p.
             for (Node<E> p = head, c = p, pred = null, q; p != null; p = q) {
+                q = p.next;
                 final E item; boolean pAlive;
                 if (pAlive = ((item = p.item) != null)) {
                     if (filter.test(item)) {
-                        if (ITEM.compareAndSet(p, item, null))
+                        if (p.casItem(item, null))
                             removed = true;
                         pAlive = false;
                     }
                 }
-                if ((q = p.next) == null || pAlive || --hops == 0) {
+                if (pAlive || q == null || --hops == 0) {
                     // p might already be self-linked here, but if so:
                     // - CASing head will surely fail
                     // - CASing pred's next will be useless but harmless.
-                    if (c != p && tryCasSuccessor(pred, c, p))
-                        c = p;
-                    // if c != p, CAS failed, so abandon old pred
-                    if (pAlive || c != p) {
+                    if ((c != p && !tryCasSuccessor(pred, c, c = p))
+                        || pAlive) {
+                        // if CAS failed or alive, abandon old pred
                         hops = MAX_HOPS;
                         pred = p;
                         c = q;
@@ -991,34 +1026,39 @@
     }
 
     /**
+     * Runs action on each element found during a traversal starting at p.
+     * If p is null, the action is not run.
+     */
+    void forEachFrom(Consumer<? super E> action, Node<E> p) {
+        for (Node<E> pred = null; p != null; ) {
+            Node<E> q = p.next;
+            final E item;
+            if ((item = p.item) != null) {
+                action.accept(item);
+                pred = p; p = q; continue;
+            }
+            for (Node<E> c = p;; q = p.next) {
+                if (q == null || q.item != null) {
+                    pred = skipDeadNodes(pred, c, p, q); p = q; break;
+                }
+                if (p == (p = q)) { pred = null; p = head; break; }
+            }
+        }
+    }
+
+    /**
      * @throws NullPointerException {@inheritDoc}
      */
     public void forEach(Consumer<? super E> action) {
         Objects.requireNonNull(action);
-        restartFromHead: for (;;) {
-            for (Node<E> p = head, c = p, pred = null, q; p != null; p = q) {
-                final E item;
-                if ((item = p.item) != null)
-                    action.accept(item);
-                if (c != p && tryCasSuccessor(pred, c, p))
-                    c = p;
-                q = p.next;
-                if (item != null || c != p) {
-                    pred = p;
-                    c = q;
-                }
-                else if (p == q)
-                    continue restartFromHead;
-            }
-            return;
-        }
+        forEachFrom(action, head);
     }
 
     // VarHandle mechanics
     private static final VarHandle HEAD;
     private static final VarHandle TAIL;
-    private static final VarHandle ITEM;
-    private static final VarHandle NEXT;
+    static final VarHandle ITEM;
+    static final VarHandle NEXT;
     static {
         try {
             MethodHandles.Lookup l = MethodHandles.lookup();
--- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java	Mon Feb 06 09:34:19 2017 -0800
@@ -72,12 +72,12 @@
  * asynchronous nature of these sets, determining the current number
  * of elements requires a traversal of the elements, and so may report
  * inaccurate results if this collection is modified during traversal.
- * Additionally, the bulk operations {@code addAll},
- * {@code removeAll}, {@code retainAll}, {@code containsAll},
- * {@code equals}, and {@code toArray} are <em>not</em> guaranteed
- * to be performed atomically. For example, an iterator operating
- * concurrently with an {@code addAll} operation might view only some
- * of the added elements.
+ *
+ * <p>Bulk operations that add, remove, or examine multiple elements,
+ * such as {@link #addAll}, {@link #removeIf} or {@link #forEach},
+ * are <em>not</em> guaranteed to be performed atomically.
+ * For example, a {@code forEach} traversal concurrent with an {@code
+ * addAll} operation might observe only some of the added elements.
  *
  * <p>This class and its iterators implement all of the
  * <em>optional</em> methods of the {@link Set} and {@link Iterator}
--- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java	Mon Feb 06 09:34:19 2017 -0800
@@ -797,7 +797,7 @@
      * @throws NullPointerException {@inheritDoc}
      */
     public void forEach(Consumer<? super E> action) {
-        if (action == null) throw new NullPointerException();
+        Objects.requireNonNull(action);
         for (Object x : getArray()) {
             @SuppressWarnings("unchecked") E e = (E) x;
             action.accept(e);
@@ -808,7 +808,7 @@
      * @throws NullPointerException {@inheritDoc}
      */
     public boolean removeIf(Predicate<? super E> filter) {
-        if (filter == null) throw new NullPointerException();
+        Objects.requireNonNull(filter);
         return bulkRemove(filter);
     }
 
@@ -865,7 +865,7 @@
     }
 
     public void replaceAll(UnaryOperator<E> operator) {
-        if (operator == null) throw new NullPointerException();
+        Objects.requireNonNull(operator);
         synchronized (lock) {
             replaceAll(operator, 0, getArray().length);
         }
@@ -1329,7 +1329,7 @@
         }
 
         public void forEach(Consumer<? super E> action) {
-            if (action == null) throw new NullPointerException();
+            Objects.requireNonNull(action);
             int i, end; final Object[] es;
             synchronized (l.lock) {
                 es = getArrayChecked();
@@ -1341,7 +1341,7 @@
         }
 
         public void replaceAll(UnaryOperator<E> operator) {
-            if (operator == null) throw new NullPointerException();
+            Objects.requireNonNull(operator);
             synchronized (l.lock) {
                 checkForComodification();
                 l.replaceAll(operator, offset, offset + size);
--- a/src/java.base/share/classes/java/util/concurrent/DelayQueue.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/util/concurrent/DelayQueue.java	Mon Feb 06 09:34:19 2017 -0800
@@ -41,6 +41,7 @@
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
+import java.util.Objects;
 import java.util.PriorityQueue;
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.ReentrantLock;
@@ -59,11 +60,11 @@
  * returns the count of both expired and unexpired elements.
  * This queue does not permit null elements.
  *
- * <p>This class and its iterator implement all of the
- * <em>optional</em> methods of the {@link Collection} and {@link
- * Iterator} interfaces.  The Iterator provided in method {@link
- * #iterator()} is <em>not</em> guaranteed to traverse the elements of
- * the DelayQueue in any particular order.
+ * <p>This class and its iterator implement all of the <em>optional</em>
+ * methods of the {@link Collection} and {@link Iterator} interfaces.
+ * The Iterator provided in method {@link #iterator()} is <em>not</em>
+ * guaranteed to traverse the elements of the DelayQueue in any
+ * particular order.
  *
  * <p>This class is a member of the
  * <a href="{@docRoot}/../technotes/guides/collections/index.html">
@@ -339,8 +340,7 @@
      * @throws IllegalArgumentException      {@inheritDoc}
      */
     public int drainTo(Collection<? super E> c) {
-        if (c == null)
-            throw new NullPointerException();
+        Objects.requireNonNull(c);
         if (c == this)
             throw new IllegalArgumentException();
         final ReentrantLock lock = this.lock;
@@ -365,8 +365,7 @@
      * @throws IllegalArgumentException      {@inheritDoc}
      */
     public int drainTo(Collection<? super E> c, int maxElements) {
-        if (c == null)
-            throw new NullPointerException();
+        Objects.requireNonNull(c);
         if (c == this)
             throw new IllegalArgumentException();
         if (maxElements <= 0)
--- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java	Mon Feb 06 09:34:19 2017 -0800
@@ -45,6 +45,7 @@
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.ReentrantLock;
 import java.util.function.Consumer;
+import java.util.function.Predicate;
 
 /**
  * An optionally-bounded {@linkplain BlockingDeque blocking deque} based on
@@ -63,9 +64,8 @@
  * contains}, {@link #iterator iterator.remove()}, and the bulk
  * operations, all of which run in linear time.
  *
- * <p>This class and its iterator implement all of the
- * <em>optional</em> methods of the {@link Collection} and {@link
- * Iterator} interfaces.
+ * <p>This class and its iterator implement all of the <em>optional</em>
+ * methods of the {@link Collection} and {@link Iterator} interfaces.
  *
  * <p>This class is a member of the
  * <a href="{@docRoot}/../technotes/guides/collections/index.html">
@@ -195,18 +195,7 @@
      */
     public LinkedBlockingDeque(Collection<? extends E> c) {
         this(Integer.MAX_VALUE);
-        final ReentrantLock lock = this.lock;
-        lock.lock(); // Never contended, but necessary for visibility
-        try {
-            for (E e : c) {
-                if (e == null)
-                    throw new NullPointerException();
-                if (!linkLast(new Node<E>(e)))
-                    throw new IllegalStateException("Deque full");
-            }
-        } finally {
-            lock.unlock();
-        }
+        addAll(c);
     }
 
 
@@ -299,6 +288,7 @@
      */
     void unlink(Node<E> x) {
         // assert lock.isHeldByCurrentThread();
+        // assert x.item != null;
         Node<E> p = x.prev;
         Node<E> n = x.next;
         if (p == null) {
@@ -834,46 +824,65 @@
         }
     }
 
-    /*
-     * TODO: Add support for more efficient bulk operations.
+    /**
+     * Appends all of the elements in the specified collection to the end of
+     * this deque, in the order that they are returned by the specified
+     * collection's iterator.  Attempts to {@code addAll} of a deque to
+     * itself result in {@code IllegalArgumentException}.
      *
-     * We don't want to acquire the lock for every iteration, but we
-     * also want other threads a chance to interact with the
-     * collection, especially when count is close to capacity.
+     * @param c the elements to be inserted into this deque
+     * @return {@code true} if this deque changed as a result of the call
+     * @throws NullPointerException if the specified collection or any
+     *         of its elements are null
+     * @throws IllegalArgumentException if the collection is this deque
+     * @throws IllegalStateException if this deque is full
+     * @see #add(Object)
      */
+    public boolean addAll(Collection<? extends E> c) {
+        if (c == this)
+            // As historically specified in AbstractQueue#addAll
+            throw new IllegalArgumentException();
 
-//     /**
-//      * Adds all of the elements in the specified collection to this
-//      * queue.  Attempts to addAll of a queue to itself result in
-//      * {@code IllegalArgumentException}. Further, the behavior of
-//      * this operation is undefined if the specified collection is
-//      * modified while the operation is in progress.
-//      *
-//      * @param c collection containing elements to be added to this queue
-//      * @return {@code true} if this queue changed as a result of the call
-//      * @throws ClassCastException            {@inheritDoc}
-//      * @throws NullPointerException          {@inheritDoc}
-//      * @throws IllegalArgumentException      {@inheritDoc}
-//      * @throws IllegalStateException if this deque is full
-//      * @see #add(Object)
-//      */
-//     public boolean addAll(Collection<? extends E> c) {
-//         if (c == null)
-//             throw new NullPointerException();
-//         if (c == this)
-//             throw new IllegalArgumentException();
-//         final ReentrantLock lock = this.lock;
-//         lock.lock();
-//         try {
-//             boolean modified = false;
-//             for (E e : c)
-//                 if (linkLast(e))
-//                     modified = true;
-//             return modified;
-//         } finally {
-//             lock.unlock();
-//         }
-//     }
+        // Copy c into a private chain of Nodes
+        Node<E> beg = null, end = null;
+        int n = 0;
+        for (E e : c) {
+            Objects.requireNonNull(e);
+            n++;
+            Node<E> newNode = new Node<E>(e);
+            if (beg == null)
+                beg = end = newNode;
+            else {
+                end.next = newNode;
+                newNode.prev = end;
+                end = newNode;
+            }
+        }
+        if (beg == null)
+            return false;
+
+        // Atomically append the chain at the end
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            if (count + n <= capacity) {
+                beg.prev = last;
+                if (first == null)
+                    first = beg;
+                else
+                    last.next = beg;
+                last = end;
+                count += n;
+                notEmpty.signalAll();
+                return true;
+            }
+        } finally {
+            lock.unlock();
+        }
+        // Fall back to historic non-atomic implementation, failing
+        // with IllegalStateException when the capacity is exceeded.
+        return super.addAll(c);
+    }
 
     /**
      * Returns an array containing all of the elements in this deque, in
@@ -992,7 +1001,9 @@
      * - (possibly multiple) interior removed nodes (p.item == null)
      */
     Node<E> succ(Node<E> p) {
-        return (p == (p = p.next)) ? first : p;
+        if (p == (p = p.next))
+            p = first;
+        return p;
     }
 
     /**
@@ -1049,7 +1060,9 @@
         abstract Node<E> nextNode(Node<E> n);
 
         private Node<E> succ(Node<E> p) {
-            return (p == (p = nextNode(p))) ? firstNode() : p;
+            if (p == (p = nextNode(p)))
+                p = firstNode();
+            return p;
         }
 
         AbstractItr() {
@@ -1096,7 +1109,7 @@
             lastRet = p;
             next = null;
             final ReentrantLock lock = LinkedBlockingDeque.this.lock;
-            final int batchSize = 32;
+            final int batchSize = 64;
             Object[] es = null;
             int n, len = 1;
             do {
@@ -1175,11 +1188,10 @@
 
         public Spliterator<E> trySplit() {
             Node<E> h;
-            int b = batch;
-            int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1;
             if (!exhausted &&
                 ((h = current) != null || (h = first) != null)
                 && h.next != null) {
+                int n = batch = Math.min(batch + 1, MAX_BATCH);
                 Object[] a = new Object[n];
                 final ReentrantLock lock = LinkedBlockingDeque.this.lock;
                 int i = 0;
@@ -1199,13 +1211,11 @@
                 }
                 else if ((est -= i) < 0L)
                     est = 0L;
-                if (i > 0) {
-                    batch = i;
+                if (i > 0)
                     return Spliterators.spliterator
                         (a, 0, i, (Spliterator.ORDERED |
                                    Spliterator.NONNULL |
                                    Spliterator.CONCURRENT));
-                }
             }
             return null;
         }
@@ -1223,7 +1233,8 @@
                             e = p.item;
                             p = succ(p);
                         } while (e == null && p != null);
-                    exhausted = ((current = p) == null);
+                    if ((current = p) == null)
+                        exhausted = true;
                 } finally {
                     lock.unlock();
                 }
@@ -1288,7 +1299,7 @@
         // Extract batches of elements while holding the lock; then
         // run the action on the elements while not
         final ReentrantLock lock = this.lock;
-        final int batchSize = 32;       // max number of elements per batch
+        final int batchSize = 64;       // max number of elements per batch
         Object[] es = null;             // container for batch of elements
         int n, len = 0;
         do {
@@ -1315,6 +1326,83 @@
     }
 
     /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean removeIf(Predicate<? super E> filter) {
+        Objects.requireNonNull(filter);
+        return bulkRemove(filter);
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean removeAll(Collection<?> c) {
+        Objects.requireNonNull(c);
+        return bulkRemove(e -> c.contains(e));
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean retainAll(Collection<?> c) {
+        Objects.requireNonNull(c);
+        return bulkRemove(e -> !c.contains(e));
+    }
+
+    /** Implementation of bulk remove methods. */
+    @SuppressWarnings("unchecked")
+    private boolean bulkRemove(Predicate<? super E> filter) {
+        boolean removed = false;
+        Node<E> p = null;
+        final ReentrantLock lock = this.lock;
+        Node<E>[] nodes = null;
+        int n, len = 0;
+        do {
+            // 1. Extract batch of up to 64 elements while holding the lock.
+            long deathRow = 0;          // "bitset" of size 64
+            lock.lock();
+            try {
+                if (nodes == null) {
+                    if (p == null) p = first;
+                    for (Node<E> q = p; q != null; q = succ(q))
+                        if (q.item != null && ++len == 64)
+                            break;
+                    nodes = (Node<E>[]) new Node<?>[len];
+                }
+                for (n = 0; p != null && n < len; p = succ(p))
+                    nodes[n++] = p;
+            } finally {
+                lock.unlock();
+            }
+
+            // 2. Run the filter on the elements while lock is free.
+            for (int i = 0; i < n; i++) {
+                final E e;
+                if ((e = nodes[i].item) != null && filter.test(e))
+                    deathRow |= 1L << i;
+            }
+
+            // 3. Remove any filtered elements while holding the lock.
+            if (deathRow != 0) {
+                lock.lock();
+                try {
+                    for (int i = 0; i < n; i++) {
+                        final Node<E> q;
+                        if ((deathRow & (1L << i)) != 0L
+                            && (q = nodes[i]).item != null) {
+                            unlink(q);
+                            removed = true;
+                        }
+                    }
+                } finally {
+                    lock.unlock();
+                }
+            }
+        } while (n > 0 && p != null);
+        return removed;
+    }
+
+    /**
      * Saves this deque to a stream (that is, serializes it).
      *
      * @param s the stream
--- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java	Mon Feb 06 09:34:19 2017 -0800
@@ -46,6 +46,7 @@
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.ReentrantLock;
 import java.util.function.Consumer;
+import java.util.function.Predicate;
 
 /**
  * An optionally-bounded {@linkplain BlockingQueue blocking queue} based on
@@ -66,9 +67,8 @@
  * dynamically created upon each insertion unless this would bring the
  * queue above capacity.
  *
- * <p>This class and its iterator implement all of the
- * <em>optional</em> methods of the {@link Collection} and {@link
- * Iterator} interfaces.
+ * <p>This class and its iterator implement all of the <em>optional</em>
+ * methods of the {@link Collection} and {@link Iterator} interfaces.
  *
  * <p>This class is a member of the
  * <a href="{@docRoot}/../technotes/guides/collections/index.html">
@@ -507,17 +507,17 @@
     }
 
     /**
-     * Unlinks interior Node p with predecessor trail.
+     * Unlinks interior Node p with predecessor pred.
      */
-    void unlink(Node<E> p, Node<E> trail) {
+    void unlink(Node<E> p, Node<E> pred) {
         // assert putLock.isHeldByCurrentThread();
         // assert takeLock.isHeldByCurrentThread();
         // p.next is not changed, to allow iterators that are
         // traversing p to maintain their weak-consistency guarantee.
         p.item = null;
-        trail.next = p.next;
+        pred.next = p.next;
         if (last == p)
-            last = trail;
+            last = pred;
         if (count.getAndDecrement() == capacity)
             notFull.signal();
     }
@@ -537,11 +537,11 @@
         if (o == null) return false;
         fullyLock();
         try {
-            for (Node<E> trail = head, p = trail.next;
+            for (Node<E> pred = head, p = pred.next;
                  p != null;
-                 trail = p, p = p.next) {
+                 pred = p, p = p.next) {
                 if (o.equals(p.item)) {
-                    unlink(p, trail);
+                    unlink(p, pred);
                     return true;
                 }
             }
@@ -740,7 +740,9 @@
      * - (possibly multiple) interior removed nodes (p.item == null)
      */
     Node<E> succ(Node<E> p) {
-        return (p == (p = p.next)) ? head.next : p;
+        if (p == (p = p.next))
+            p = head.next;
+        return p;
     }
 
     /**
@@ -756,16 +758,18 @@
         return new Itr();
     }
 
+    /**
+     * Weakly-consistent iterator.
+     *
+     * Lazily updated ancestor field provides expected O(1) remove(),
+     * but still O(n) in the worst case, whenever the saved ancestor
+     * is concurrently deleted.
+     */
     private class Itr implements Iterator<E> {
-        /*
-         * Basic weakly-consistent iterator.  At all times hold the next
-         * item to hand out so that if hasNext() reports true, we will
-         * still have it to return even if lost race with a take etc.
-         */
-
-        private Node<E> next;
-        private E nextItem;
+        private Node<E> next;           // Node holding nextItem
+        private E nextItem;             // next item to hand out
         private Node<E> lastRet;
+        private Node<E> ancestor;       // Helps unlink lastRet on remove()
 
         Itr() {
             fullyLock();
@@ -807,7 +811,7 @@
             if ((p = next) == null) return;
             lastRet = p;
             next = null;
-            final int batchSize = 32;
+            final int batchSize = 64;
             Object[] es = null;
             int n, len = 1;
             do {
@@ -840,19 +844,17 @@
         }
 
         public void remove() {
-            if (lastRet == null)
+            Node<E> p = lastRet;
+            if (p == null)
                 throw new IllegalStateException();
+            lastRet = null;
             fullyLock();
             try {
-                Node<E> node = lastRet;
-                lastRet = null;
-                for (Node<E> trail = head, p = trail.next;
-                     p != null;
-                     trail = p, p = p.next) {
-                    if (p == node) {
-                        unlink(p, trail);
-                        break;
-                    }
+                if (p.item != null) {
+                    if (ancestor == null)
+                        ancestor = head;
+                    ancestor = findPred(p, ancestor);
+                    unlink(p, ancestor);
                 }
             } finally {
                 fullyUnlock();
@@ -877,11 +879,10 @@
 
         public Spliterator<E> trySplit() {
             Node<E> h;
-            int b = batch;
-            int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1;
             if (!exhausted &&
                 ((h = current) != null || (h = head.next) != null)
                 && h.next != null) {
+                int n = batch = Math.min(batch + 1, MAX_BATCH);
                 Object[] a = new Object[n];
                 int i = 0;
                 Node<E> p = current;
@@ -900,13 +901,11 @@
                 }
                 else if ((est -= i) < 0L)
                     est = 0L;
-                if (i > 0) {
-                    batch = i;
+                if (i > 0)
                     return Spliterators.spliterator
                         (a, 0, i, (Spliterator.ORDERED |
                                    Spliterator.NONNULL |
                                    Spliterator.CONCURRENT));
-                }
             }
             return null;
         }
@@ -923,7 +922,8 @@
                             e = p.item;
                             p = succ(p);
                         } while (e == null && p != null);
-                    exhausted = ((current = p) == null);
+                    if ((current = p) == null)
+                        exhausted = true;
                 } finally {
                     fullyUnlock();
                 }
@@ -987,7 +987,7 @@
     void forEachFrom(Consumer<? super E> action, Node<E> p) {
         // Extract batches of elements while holding the lock; then
         // run the action on the elements while not
-        final int batchSize = 32;       // max number of elements per batch
+        final int batchSize = 64;       // max number of elements per batch
         Object[] es = null;             // container for batch of elements
         int n, len = 0;
         do {
@@ -1014,6 +1014,97 @@
     }
 
     /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean removeIf(Predicate<? super E> filter) {
+        Objects.requireNonNull(filter);
+        return bulkRemove(filter);
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean removeAll(Collection<?> c) {
+        Objects.requireNonNull(c);
+        return bulkRemove(e -> c.contains(e));
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean retainAll(Collection<?> c) {
+        Objects.requireNonNull(c);
+        return bulkRemove(e -> !c.contains(e));
+    }
+
+    /**
+     * Returns the predecessor of live node p, given a node that was
+     * once a live ancestor of p (or head); allows unlinking of p.
+     */
+    Node<E> findPred(Node<E> p, Node<E> ancestor) {
+        // assert p.item != null;
+        if (ancestor.item == null)
+            ancestor = head;
+        // Fails with NPE if precondition not satisfied
+        for (Node<E> q; (q = ancestor.next) != p; )
+            ancestor = q;
+        return ancestor;
+    }
+
+    /** Implementation of bulk remove methods. */
+    @SuppressWarnings("unchecked")
+    private boolean bulkRemove(Predicate<? super E> filter) {
+        boolean removed = false;
+        Node<E> p = null, ancestor = head;
+        Node<E>[] nodes = null;
+        int n, len = 0;
+        do {
+            // 1. Extract batch of up to 64 elements while holding the lock.
+            long deathRow = 0;          // "bitset" of size 64
+            fullyLock();
+            try {
+                if (nodes == null) {
+                    if (p == null) p = head.next;
+                    for (Node<E> q = p; q != null; q = succ(q))
+                        if (q.item != null && ++len == 64)
+                            break;
+                    nodes = (Node<E>[]) new Node<?>[len];
+                }
+                for (n = 0; p != null && n < len; p = succ(p))
+                    nodes[n++] = p;
+            } finally {
+                fullyUnlock();
+            }
+
+            // 2. Run the filter on the elements while lock is free.
+            for (int i = 0; i < n; i++) {
+                final E e;
+                if ((e = nodes[i].item) != null && filter.test(e))
+                    deathRow |= 1L << i;
+            }
+
+            // 3. Remove any filtered elements while holding the lock.
+            if (deathRow != 0) {
+                fullyLock();
+                try {
+                    for (int i = 0; i < n; i++) {
+                        final Node<E> q;
+                        if ((deathRow & (1L << i)) != 0L
+                            && (q = nodes[i]).item != null) {
+                            ancestor = findPred(q, ancestor);
+                            unlink(q, ancestor);
+                            removed = true;
+                        }
+                    }
+                } finally {
+                    fullyUnlock();
+                }
+            }
+        } while (n > 0 && p != null);
+        return removed;
+    }
+
+    /**
      * Saves this queue to a stream (that is, serializes it).
      *
      * @param s the stream
--- a/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java	Mon Feb 06 09:34:19 2017 -0800
@@ -42,11 +42,13 @@
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
+import java.util.Objects;
 import java.util.Queue;
 import java.util.Spliterator;
 import java.util.Spliterators;
 import java.util.concurrent.locks.LockSupport;
 import java.util.function.Consumer;
+import java.util.function.Predicate;
 
 /**
  * An unbounded {@link TransferQueue} based on linked nodes.
@@ -61,16 +63,15 @@
  * asynchronous nature of these queues, determining the current number
  * of elements requires a traversal of the elements, and so may report
  * inaccurate results if this collection is modified during traversal.
- * Additionally, the bulk operations {@code addAll},
- * {@code removeAll}, {@code retainAll}, {@code containsAll},
- * and {@code toArray} are <em>not</em> guaranteed
- * to be performed atomically. For example, an iterator operating
- * concurrently with an {@code addAll} operation might view only some
- * of the added elements.
  *
- * <p>This class and its iterator implement all of the
- * <em>optional</em> methods of the {@link Collection} and {@link
- * Iterator} interfaces.
+ * <p>Bulk operations that add, remove, or examine multiple elements,
+ * such as {@link #addAll}, {@link #removeIf} or {@link #forEach},
+ * are <em>not</em> guaranteed to be performed atomically.
+ * For example, a {@code forEach} traversal concurrent with an {@code
+ * addAll} operation might observe only some of the added elements.
+ *
+ * <p>This class and its iterator implement all of the <em>optional</em>
+ * methods of the {@link Collection} and {@link Iterator} interfaces.
  *
  * <p>Memory consistency effects: As with other concurrent
  * collections, actions in a thread prior to placing an object into a
@@ -158,9 +159,8 @@
      * correctly perform enqueue and dequeue operations by traversing
      * from a pointer to the initial node; CASing the item of the
      * first unmatched node on match and CASing the next field of the
-     * trailing node on appends. (Plus some special-casing when
-     * initially empty).  While this would be a terrible idea in
-     * itself, it does have the benefit of not requiring ANY atomic
+     * trailing node on appends.  While this would be a terrible idea
+     * in itself, it does have the benefit of not requiring ANY atomic
      * updates on head/tail fields.
      *
      * We introduce here an approach that lies between the extremes of
@@ -196,15 +196,15 @@
      * with a given probability per traversal step.
      *
      * In any strategy along these lines, because CASes updating
-     * fields may fail, the actual slack may exceed targeted
-     * slack. However, they may be retried at any time to maintain
-     * targets.  Even when using very small slack values, this
-     * approach works well for dual queues because it allows all
-     * operations up to the point of matching or appending an item
-     * (hence potentially allowing progress by another thread) to be
-     * read-only, thus not introducing any further contention. As
-     * described below, we implement this by performing slack
-     * maintenance retries only after these points.
+     * fields may fail, the actual slack may exceed targeted slack.
+     * However, they may be retried at any time to maintain targets.
+     * Even when using very small slack values, this approach works
+     * well for dual queues because it allows all operations up to the
+     * point of matching or appending an item (hence potentially
+     * allowing progress by another thread) to be read-only, thus not
+     * introducing any further contention.  As described below, we
+     * implement this by performing slack maintenance retries only
+     * after these points.
      *
      * As an accompaniment to such techniques, traversal overhead can
      * be further reduced without increasing contention of head
@@ -223,7 +223,7 @@
      * (Similar issues arise in non-GC environments.)  To cope with
      * this in our implementation, upon CASing to advance the head
      * pointer, we set the "next" link of the previous head to point
-     * only to itself; thus limiting the length of connected dead lists.
+     * only to itself; thus limiting the length of chains of dead nodes.
      * (We also take similar care to wipe out possibly garbage
      * retaining values held in other Node fields.)  However, doing so
      * adds some further complexity to traversal: If any "next"
@@ -266,15 +266,6 @@
      * interior nodes) except in the case of cancellation/removal (see
      * below).
      *
-     * We allow both the head and tail fields to be null before any
-     * nodes are enqueued; initializing upon first append.  This
-     * simplifies some other logic, as well as providing more
-     * efficient explicit control paths instead of letting JVMs insert
-     * implicit NullPointerExceptions when they are null.  While not
-     * currently fully implemented, we also leave open the possibility
-     * of re-nulling these fields when empty (which is complicated to
-     * arrange, for little benefit.)
-     *
      * All enqueue/dequeue operations are handled by the single method
      * "xfer" with parameters indicating whether to act as some form
      * of offer, put, poll, take, or transfer (each possibly with
@@ -282,44 +273,40 @@
      * method outweighs the code bulk and maintenance problems of
      * using separate methods for each case.
      *
-     * Operation consists of up to three phases. The first is
-     * implemented within method xfer, the second in tryAppend, and
-     * the third in method awaitMatch.
+     * Operation consists of up to two phases. The first is implemented
+     * in method xfer, the second in method awaitMatch.
      *
-     * 1. Try to match an existing node
+     * 1. Traverse until matching or appending (method xfer)
      *
-     *    Starting at head, skip already-matched nodes until finding
-     *    an unmatched node of opposite mode, if one exists, in which
-     *    case matching it and returning, also if necessary updating
-     *    head to one past the matched node (or the node itself if the
-     *    list has no other unmatched nodes). If the CAS misses, then
-     *    a loop retries advancing head by two steps until either
-     *    success or the slack is at most two. By requiring that each
-     *    attempt advances head by two (if applicable), we ensure that
-     *    the slack does not grow without bound. Traversals also check
-     *    if the initial head is now off-list, in which case they
-     *    start at the new head.
+     *    Conceptually, we simply traverse all nodes starting from head.
+     *    If we encounter an unmatched node of opposite mode, we match
+     *    it and return, also updating head (by at least 2 hops) to
+     *    one past the matched node (or the node itself if it's the
+     *    pinned trailing node).  Traversals also check for the
+     *    possibility of falling off-list, in which case they restart.
      *
-     *    If no candidates are found and the call was untimed
-     *    poll/offer, (argument "how" is NOW) return.
+     *    If the trailing node of the list is reached, a match is not
+     *    possible.  If this call was untimed poll or tryTransfer
+     *    (argument "how" is NOW), return empty-handed immediately.
+     *    Else a new node is CAS-appended.  On successful append, if
+     *    this call was ASYNC (e.g. offer), an element was
+     *    successfully added to the end of the queue and we return.
      *
-     * 2. Try to append a new node (method tryAppend)
+     *    Of course, this naive traversal is O(n) when no match is
+     *    possible.  We optimize the traversal by maintaining a tail
+     *    pointer, which is expected to be "near" the end of the list.
+     *    It is only safe to fast-forward to tail (in the presence of
+     *    arbitrary concurrent changes) if it is pointing to a node of
+     *    the same mode, even if it is dead (in this case no preceding
+     *    node could still be matchable by this traversal).  If we
+     *    need to restart due to falling off-list, we can again
+     *    fast-forward to tail, but only if it has changed since the
+     *    last traversal (else we might loop forever).  If tail cannot
+     *    be used, traversal starts at head (but in this case we
+     *    expect to be able to match near head).  As with head, we
+     *    CAS-advance the tail pointer by at least two hops.
      *
-     *    Starting at current tail pointer, find the actual last node
-     *    and try to append a new node (or if head was null, establish
-     *    the first node). Nodes can be appended only if their
-     *    predecessors are either already matched or are of the same
-     *    mode. If we detect otherwise, then a new node with opposite
-     *    mode must have been appended during traversal, so we must
-     *    restart at phase 1. The traversal and update steps are
-     *    otherwise similar to phase 1: Retrying upon CAS misses and
-     *    checking for staleness.  In particular, if a self-link is
-     *    encountered, then we can safely jump to a node on the list
-     *    by continuing the traversal at current head.
-     *
-     *    On successful append, if the call was ASYNC, return.
-     *
-     * 3. Await match or cancellation (method awaitMatch)
+     * 2. Await match or cancellation (method awaitMatch)
      *
      *    Wait for another thread to match node; instead cancelling if
      *    the current thread was interrupted or the wait timed out. On
@@ -373,12 +360,12 @@
      * from, the head of list.
      *
      * Without taking these into account, it would be possible for an
-     * unbounded number of supposedly removed nodes to remain
-     * reachable.  Situations leading to such buildup are uncommon but
-     * can occur in practice; for example when a series of short timed
-     * calls to poll repeatedly time out but never otherwise fall off
-     * the list because of an untimed call to take at the front of the
-     * queue.
+     * unbounded number of supposedly removed nodes to remain reachable.
+     * Situations leading to such buildup are uncommon but can occur
+     * in practice; for example when a series of short timed calls to
+     * poll repeatedly time out at the trailing node but otherwise
+     * never fall off the list because of an untimed call to take() at
+     * the front of the queue.
      *
      * When these cases arise, rather than always retraversing the
      * entire list to find an actual predecessor to unlink (which
@@ -391,10 +378,9 @@
      * We perform sweeps by the thread hitting threshold (rather than
      * background threads or by spreading work to other threads)
      * because in the main contexts in which removal occurs, the
-     * caller is already timed-out, cancelled, or performing a
-     * potentially O(n) operation (e.g. remove(x)), none of which are
-     * time-critical enough to warrant the overhead that alternatives
-     * would impose on other threads.
+     * caller is timed-out or cancelled, which are not time-critical
+     * enough to warrant the overhead that alternatives would impose
+     * on other threads.
      *
      * Because the sweepVotes estimate is conservative, and because
      * nodes become unlinked "naturally" as they fall off the head of
@@ -406,6 +392,13 @@
      * quiescent queues. The value defined below was chosen
      * empirically to balance these under various timeout scenarios.
      *
+     * Because traversal operations on the linked list of nodes are a
+     * natural opportunity to sweep dead nodes, we generally do so,
+     * including all the operations that might remove elements as they
+     * traverse, such as removeIf and Iterator.remove.  This largely
+     * eliminates long chains of dead interior nodes, except from
+     * cancelled or timed out blocking operations.
+     *
      * Note that we cannot self-link unlinked interior nodes during
      * sweeps. However, the associated garbage chains terminate when
      * some successor ultimately falls off the head of the list and is
@@ -446,54 +439,71 @@
 
     /**
      * Queue nodes. Uses Object, not E, for items to allow forgetting
-     * them after use.  Relies heavily on VarHandles to minimize
-     * unnecessary ordering constraints: Writes that are intrinsically
-     * ordered wrt other accesses or CASes use simple relaxed forms.
+     * them after use.  Writes that are intrinsically ordered wrt
+     * other accesses or CASes use simple relaxed forms.
      */
     static final class Node {
         final boolean isData;   // false if this is a request node
         volatile Object item;   // initially non-null if isData; CASed to match
         volatile Node next;
-        volatile Thread waiter; // null until waiting
+        volatile Thread waiter; // null when not waiting for a match
 
-        // CAS methods for fields
+        /**
+         * Constructs a data node holding item if item is non-null,
+         * else a request node.  Uses relaxed write because item can
+         * only be seen after piggy-backing publication via CAS.
+         */
+        Node(Object item) {
+            ITEM.set(this, item);
+            isData = (item != null);
+        }
+
+        /** Constructs a (matched data) dummy node. */
+        Node() {
+            isData = true;
+        }
+
         final boolean casNext(Node cmp, Node val) {
+            // assert val != null;
             return NEXT.compareAndSet(this, cmp, val);
         }
 
         final boolean casItem(Object cmp, Object val) {
-            // assert cmp == null || cmp.getClass() != Node.class;
+            // assert isData == (cmp != null);
+            // assert isData == (val == null);
+            // assert !(cmp instanceof Node);
             return ITEM.compareAndSet(this, cmp, val);
         }
 
         /**
-         * Constructs a new node.  Uses relaxed write because item can
-         * only be seen after publication via casNext.
-         */
-        Node(Object item, boolean isData) {
-            ITEM.set(this, item); // relaxed write
-            this.isData = isData;
-        }
-
-        /**
          * Links node to itself to avoid garbage retention.  Called
          * only after CASing head field, so uses relaxed write.
          */
-        final void forgetNext() {
-            NEXT.set(this, this);
+        final void selfLink() {
+            // assert isMatched();
+            NEXT.setRelease(this, this);
+        }
+
+        final void appendRelaxed(Node next) {
+            // assert next != null;
+            // assert this.next == null;
+            NEXT.set(this, next);
         }
 
         /**
-         * Sets item to self and waiter to null, to avoid garbage
-         * retention after matching or cancelling. Uses relaxed writes
-         * because order is already constrained in the only calling
-         * contexts: item is forgotten only after volatile/atomic
-         * mechanics that extract items.  Similarly, clearing waiter
-         * follows either CAS or return from park (if ever parked;
-         * else we don't care).
+         * Sets item (of a request node) to self and waiter to null,
+         * to avoid garbage retention after matching or cancelling.
+         * Uses relaxed writes because order is already constrained in
+         * the only calling contexts: item is forgotten only after
+         * volatile/atomic mechanics that extract items, and visitors
+         * of request nodes only ever check whether item is null.
+         * Similarly, clearing waiter follows either CAS or return
+         * from park (if ever parked; else we don't care).
          */
         final void forgetContents() {
-            ITEM.set(this, this);
+            // assert isMatched();
+            if (!isData)
+                ITEM.set(this, this);
             WAITER.set(this, null);
         }
 
@@ -502,15 +512,16 @@
          * case of artificial matches due to cancellation.
          */
         final boolean isMatched() {
-            Object x = item;
-            return (x == this) || ((x == null) == isData);
+            return isData == (item == null);
         }
 
-        /**
-         * Returns true if this is an unmatched request node.
-         */
-        final boolean isUnmatchedRequest() {
-            return !isData && item == null;
+        /** Tries to CAS-match this node; if successful, wakes waiter. */
+        final boolean tryMatch(Object cmp, Object val) {
+            if (casItem(cmp, val)) {
+                LockSupport.unpark(waiter);
+                return true;
+            }
+            return false;
         }
 
         /**
@@ -520,52 +531,46 @@
          */
         final boolean cannotPrecede(boolean haveData) {
             boolean d = isData;
-            Object x;
-            return d != haveData && (x = item) != this && (x != null) == d;
-        }
-
-        /**
-         * Tries to artificially match a data node -- used by remove.
-         */
-        final boolean tryMatchData() {
-            // assert isData;
-            Object x = item;
-            if (x != null && x != this && casItem(x, null)) {
-                LockSupport.unpark(waiter);
-                return true;
-            }
-            return false;
+            return d != haveData && d != (item == null);
         }
 
         private static final long serialVersionUID = -3375979862319811754L;
-
-        // VarHandle mechanics
-        private static final VarHandle ITEM;
-        private static final VarHandle NEXT;
-        private static final VarHandle WAITER;
-        static {
-            try {
-                MethodHandles.Lookup l = MethodHandles.lookup();
-                ITEM = l.findVarHandle(Node.class, "item", Object.class);
-                NEXT = l.findVarHandle(Node.class, "next", Node.class);
-                WAITER = l.findVarHandle(Node.class, "waiter", Thread.class);
-            } catch (ReflectiveOperationException e) {
-                throw new Error(e);
-            }
-        }
     }
 
-    /** head of the queue; null until first enqueue */
+    /**
+     * A node from which the first live (non-matched) node (if any)
+     * can be reached in O(1) time.
+     * Invariants:
+     * - all live nodes are reachable from head via .next
+     * - head != null
+     * - (tmp = head).next != tmp || tmp != head
+     * Non-invariants:
+     * - head may or may not be live
+     * - it is permitted for tail to lag behind head, that is, for tail
+     *   to not be reachable from head!
+     */
     transient volatile Node head;
 
-    /** tail of the queue; null until first append */
+    /**
+     * A node from which the last node on list (that is, the unique
+     * node with node.next == null) can be reached in O(1) time.
+     * Invariants:
+     * - the last node is always reachable from tail via .next
+     * - tail != null
+     * Non-invariants:
+     * - tail may or may not be live
+     * - it is permitted for tail to lag behind head, that is, for tail
+     *   to not be reachable from head!
+     * - tail.next may or may not be self-linked.
+     */
     private transient volatile Node tail;
 
-    /** The number of apparent failures to unsplice removed nodes */
+    /** The number of apparent failures to unsplice cancelled nodes */
     private transient volatile int sweepVotes;
 
-    // CAS methods for fields
     private boolean casTail(Node cmp, Node val) {
+        // assert cmp != null;
+        // assert val != null;
         return TAIL.compareAndSet(this, cmp, val);
     }
 
@@ -573,13 +578,71 @@
         return HEAD.compareAndSet(this, cmp, val);
     }
 
-    private boolean casSweepVotes(int cmp, int val) {
-        return SWEEPVOTES.compareAndSet(this, cmp, val);
+    /** Atomic version of ++sweepVotes. */
+    private int incSweepVotes() {
+        return (int) SWEEPVOTES.getAndAdd(this, 1) + 1;
     }
 
-    /*
-     * Possible values for "how" argument in xfer method.
+    /**
+     * Tries to CAS pred.next (or head, if pred is null) from c to p.
+     * Caller must ensure that we're not unlinking the trailing node.
      */
+    private boolean tryCasSuccessor(Node pred, Node c, Node p) {
+        // assert p != null;
+        // assert c.isData != (c.item != null);
+        // assert c != p;
+        if (pred != null)
+            return pred.casNext(c, p);
+        if (casHead(c, p)) {
+            c.selfLink();
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Collapses dead (matched) nodes between pred and q.
+     * @param pred the last known live node, or null if none
+     * @param c the first dead node
+     * @param p the last dead node
+     * @param q p.next: the next live node, or null if at end
+     * @return pred if pred still alive and CAS succeeded; else p
+     */
+    private Node skipDeadNodes(Node pred, Node c, Node p, Node q) {
+        // assert pred != c;
+        // assert p != q;
+        // assert c.isMatched();
+        // assert p.isMatched();
+        if (q == null) {
+            // Never unlink trailing node.
+            if (c == p) return pred;
+            q = p;
+        }
+        return (tryCasSuccessor(pred, c, q)
+                && (pred == null || !pred.isMatched()))
+            ? pred : p;
+    }
+
+    /**
+     * Collapses dead (matched) nodes from h (which was once head) to p.
+     * Caller ensures all nodes from h up to and including p are dead.
+     */
+    private void skipDeadNodesNearHead(Node h, Node p) {
+        // assert h != null;
+        // assert h != p;
+        // assert p.isMatched();
+        for (;;) {
+            final Node q;
+            if ((q = p.next) == null) break;
+            else if (!q.isMatched()) { p = q; break; }
+            else if (p == (p = q)) return;
+        }
+        if (casHead(h, p))
+            h.selfLink();
+    }
+
+    /* Possible values for "how" argument in xfer method. */
+
     private static final int NOW   = 0; // for untimed poll, tryTransfer
     private static final int ASYNC = 1; // for offer, put, add
     private static final int SYNC  = 2; // for transfer, take
@@ -595,84 +658,32 @@
      * @return an item if matched, else e
      * @throws NullPointerException if haveData mode but e is null
      */
+    @SuppressWarnings("unchecked")
     private E xfer(E e, boolean haveData, int how, long nanos) {
         if (haveData && (e == null))
             throw new NullPointerException();
-        Node s = null;                        // the node to append, if needed
 
-        retry:
-        for (;;) {                            // restart on append race
-
-            for (Node h = head, p = h; p != null;) { // find & match first node
-                boolean isData = p.isData;
-                Object item = p.item;
-                if (item != p && (item != null) == isData) { // unmatched
-                    if (isData == haveData)   // can't match
-                        break;
-                    if (p.casItem(item, e)) { // match
-                        for (Node q = p; q != h;) {
-                            Node n = q.next;  // update by 2 unless singleton
-                            if (head == h && casHead(h, n == null ? q : n)) {
-                                h.forgetNext();
-                                break;
-                            }                 // advance and retry
-                            if ((h = head)   == null ||
-                                (q = h.next) == null || !q.isMatched())
-                                break;        // unless slack < 2
-                        }
-                        LockSupport.unpark(p.waiter);
-                        @SuppressWarnings("unchecked") E itemE = (E) item;
-                        return itemE;
+        restart: for (Node s = null, t = null, h = null;;) {
+            for (Node p = (t != (t = tail) && t.isData == haveData) ? t
+                     : (h = head);; ) {
+                final Node q; final Object item;
+                if (p.isData != haveData
+                    && haveData == ((item = p.item) == null)) {
+                    if (h == null) h = head;
+                    if (p.tryMatch(item, e)) {
+                        if (h != p) skipDeadNodesNearHead(h, p);
+                        return (E) item;
                     }
                 }
-                Node n = p.next;
-                p = (p != n) ? n : (h = head); // Use head if p offlist
-            }
-
-            if (how != NOW) {                 // No matches available
-                if (s == null)
-                    s = new Node(e, haveData);
-                Node pred = tryAppend(s, haveData);
-                if (pred == null)
-                    continue retry;           // lost race vs opposite mode
-                if (how != ASYNC)
-                    return awaitMatch(s, pred, e, (how == TIMED), nanos);
-            }
-            return e; // not waiting
-        }
-    }
-
-    /**
-     * Tries to append node s as tail.
-     *
-     * @param s the node to append
-     * @param haveData true if appending in data mode
-     * @return null on failure due to losing race with append in
-     * different mode, else s's predecessor, or s itself if no
-     * predecessor
-     */
-    private Node tryAppend(Node s, boolean haveData) {
-        for (Node t = tail, p = t;;) {        // move p to last node and append
-            Node n, u;                        // temps for reads of next & tail
-            if (p == null && (p = head) == null) {
-                if (casHead(null, s))
-                    return s;                 // initialize
-            }
-            else if (p.cannotPrecede(haveData))
-                return null;                  // lost race vs opposite mode
-            else if ((n = p.next) != null)    // not last; keep traversing
-                p = p != t && t != (u = tail) ? (t = u) : // stale tail
-                    (p != n) ? n : null;      // restart if off list
-            else if (!p.casNext(null, s))
-                p = p.next;                   // re-read on CAS failure
-            else {
-                if (p != t) {                 // update if slack now >= 2
-                    while ((tail != t || !casTail(t, s)) &&
-                           (t = tail)   != null &&
-                           (s = t.next) != null && // advance and retry
-                           (s = s.next) != null && s != t);
+                if ((q = p.next) == null) {
+                    if (how == NOW) return e;
+                    if (s == null) s = new Node(e);
+                    if (!p.casNext(null, s)) continue;
+                    if (p != t) casTail(t, s);
+                    if (how == ASYNC) return e;
+                    return awaitMatch(s, p, e, (how == TIMED), nanos);
                 }
-                return p;
+                if (p == (p = q)) continue restart;
             }
         }
     }
@@ -681,9 +692,9 @@
      * Spins/yields/blocks until node s is matched or caller gives up.
      *
      * @param s the waiting node
-     * @param pred the predecessor of s, or s itself if it has no
-     * predecessor, or null if unknown (the null case does not occur
-     * in any current calls but may in possible future extensions)
+     * @param pred the predecessor of s, or null if unknown (the null
+     * case does not occur in any current calls but may in possible
+     * future extensions)
      * @param e the comparison value for checking match
      * @param timed if true, wait only until timeout elapses
      * @param nanos timeout in nanosecs, used only if timed is true
@@ -696,17 +707,20 @@
         ThreadLocalRandom randomYields = null; // bound if needed
 
         for (;;) {
-            Object item = s.item;
-            if (item != e) {                  // matched
+            final Object item;
+            if ((item = s.item) != e) {       // matched
                 // assert item != s;
                 s.forgetContents();           // avoid garbage
                 @SuppressWarnings("unchecked") E itemE = (E) item;
                 return itemE;
             }
             else if (w.isInterrupted() || (timed && nanos <= 0L)) {
-                unsplice(pred, s);           // try to unlink and cancel
-                if (s.casItem(e, s))         // return normally if lost CAS
+                // try to cancel and unlink
+                if (s.casItem(e, s.isData ? null : s)) {
+                    unsplice(pred, s);
                     return e;
+                }
+                // return normally if lost CAS
             }
             else if (spins < 0) {            // establish spins at/near front
                 if ((spins = spinsFor(pred, s.isData)) > 0)
@@ -750,34 +764,33 @@
     /* -------------- Traversal methods -------------- */
 
     /**
-     * Returns the successor of p, or the head node if p.next has been
-     * linked to self, which will only be true if traversing with a
-     * stale pointer that is now off the list.
-     */
-    final Node succ(Node p) {
-        Node next = p.next;
-        return (p == next) ? head : next;
-    }
-
-    /**
      * Returns the first unmatched data node, or null if none.
-     * Callers must recheck if the returned node's item field is null
-     * or self-linked before using.
+     * Callers must recheck if the returned node is unmatched
+     * before using.
      */
     final Node firstDataNode() {
+        Node first = null;
         restartFromHead: for (;;) {
-            for (Node p = head; p != null;) {
-                Object item = p.item;
-                if (p.isData) {
-                    if (item != null && item != p)
-                        return p;
+            Node h = head, p = h;
+            for (; p != null;) {
+                final Object item;
+                if ((item = p.item) != null) {
+                    if (p.isData) {
+                        first = p;
+                        break;
+                    }
                 }
-                else if (item == null)
+                else if (!p.isData)
                     break;
-                if (p == (p = p.next))
+                final Node q;
+                if ((q = p.next) == null)
+                    break;
+                if (p == (p = q))
                     continue restartFromHead;
             }
-            return null;
+            if (p != h && casHead(h, p))
+                h.selfLink();
+            return first;
         }
     }
 
@@ -810,7 +823,7 @@
             for (Node p = head; p != null;) {
                 Object item = p.item;
                 if (p.isData) {
-                    if (item != null && item != p) {
+                    if (item != null) {
                         if (a == null)
                             a = new String[4];
                         else if (size == a.length)
@@ -839,7 +852,7 @@
             for (Node p = head; p != null;) {
                 Object item = p.item;
                 if (p.isData) {
-                    if (item != null && item != p) {
+                    if (item != null) {
                         if (x == null)
                             x = new Object[4];
                         else if (size == x.length)
@@ -918,76 +931,50 @@
      */
     @SuppressWarnings("unchecked")
     public <T> T[] toArray(T[] a) {
-        if (a == null) throw new NullPointerException();
+        Objects.requireNonNull(a);
         return (T[]) toArrayInternal(a);
     }
 
+    /**
+     * Weakly-consistent iterator.
+     *
+     * Lazily updated ancestor is expected to be amortized O(1) remove(),
+     * but O(n) in the worst case, when lastRet is concurrently deleted.
+     */
     final class Itr implements Iterator<E> {
         private Node nextNode;   // next node to return item for
         private E nextItem;      // the corresponding item
         private Node lastRet;    // last returned node, to support remove
-        private Node lastPred;   // predecessor to unlink lastRet
+        private Node ancestor;   // Helps unlink lastRet on remove()
 
         /**
-         * Moves to next node after prev, or first node if prev null.
+         * Moves to next node after pred, or first node if pred null.
          */
-        private void advance(Node prev) {
-            /*
-             * To track and avoid buildup of deleted nodes in the face
-             * of calls to both Queue.remove and Itr.remove, we must
-             * include variants of unsplice and sweep upon each
-             * advance: Upon Itr.remove, we may need to catch up links
-             * from lastPred, and upon other removes, we might need to
-             * skip ahead from stale nodes and unsplice deleted ones
-             * found while advancing.
-             */
-
-            Node r, b; // reset lastPred upon possible deletion of lastRet
-            if ((r = lastRet) != null && !r.isMatched())
-                lastPred = r;    // next lastPred is old lastRet
-            else if ((b = lastPred) == null || b.isMatched())
-                lastPred = null; // at start of list
-            else {
-                Node s, n;       // help with removal of lastPred.next
-                while ((s = b.next) != null &&
-                       s != b && s.isMatched() &&
-                       (n = s.next) != null && n != s)
-                    b.casNext(s, n);
+        @SuppressWarnings("unchecked")
+        private void advance(Node pred) {
+            for (Node p = (pred == null) ? head : pred.next, c = p;
+                 p != null; ) {
+                final Object item;
+                if ((item = p.item) != null && p.isData) {
+                    nextNode = p;
+                    nextItem = (E) item;
+                    if (c != p)
+                        tryCasSuccessor(pred, c, p);
+                    return;
+                }
+                else if (!p.isData && item == null)
+                    break;
+                if (c != p && !tryCasSuccessor(pred, c, c = p)) {
+                    pred = p;
+                    c = p = p.next;
+                }
+                else if (p == (p = p.next)) {
+                    pred = null;
+                    c = p = head;
+                }
             }
-
-            this.lastRet = prev;
-
-            for (Node p = prev, s, n;;) {
-                s = (p == null) ? head : p.next;
-                if (s == null)
-                    break;
-                else if (s == p) {
-                    p = null;
-                    continue;
-                }
-                Object item = s.item;
-                if (s.isData) {
-                    if (item != null && item != s) {
-                        @SuppressWarnings("unchecked") E itemE = (E) item;
-                        nextItem = itemE;
-                        nextNode = s;
-                        return;
-                    }
-                }
-                else if (item == null)
-                    break;
-                // assert s.isMatched();
-                if (p == null)
-                    p = s;
-                else if ((n = s.next) == null)
-                    break;
-                else if (s == n)
-                    p = null;
-                else
-                    p.casNext(s, n);
-            }
+            nextItem = null;
             nextNode = null;
-            nextItem = null;
         }
 
         Itr() {
@@ -999,25 +986,67 @@
         }
 
         public final E next() {
-            Node p = nextNode;
-            if (p == null) throw new NoSuchElementException();
+            final Node p;
+            if ((p = nextNode) == null) throw new NoSuchElementException();
             E e = nextItem;
-            advance(p);
+            advance(lastRet = p);
             return e;
         }
 
+        public void forEachRemaining(Consumer<? super E> action) {
+            Objects.requireNonNull(action);
+            Node q = null;
+            for (Node p; (p = nextNode) != null; advance(q = p))
+                action.accept(nextItem);
+            if (q != null)
+                lastRet = q;
+        }
+
         public final void remove() {
             final Node lastRet = this.lastRet;
             if (lastRet == null)
                 throw new IllegalStateException();
             this.lastRet = null;
-            if (lastRet.tryMatchData())
-                unsplice(lastPred, lastRet);
+            if (lastRet.item == null)   // already deleted?
+                return;
+            // Advance ancestor, collapsing intervening dead nodes
+            Node pred = ancestor;
+            for (Node p = (pred == null) ? head : pred.next, c = p, q;
+                 p != null; ) {
+                if (p == lastRet) {
+                    final Object item;
+                    if ((item = p.item) != null)
+                        p.tryMatch(item, null);
+                    if ((q = p.next) == null) q = p;
+                    if (c != q) tryCasSuccessor(pred, c, q);
+                    ancestor = pred;
+                    return;
+                }
+                final Object item; final boolean pAlive;
+                if (pAlive = ((item = p.item) != null && p.isData)) {
+                    // exceptionally, nothing to do
+                }
+                else if (!p.isData && item == null)
+                    break;
+                if ((c != p && !tryCasSuccessor(pred, c, c = p)) || pAlive) {
+                    pred = p;
+                    c = p = p.next;
+                }
+                else if (p == (p = p.next)) {
+                    pred = null;
+                    c = p = head;
+                }
+            }
+            // traversal failed to find lastRet; must have been deleted;
+            // leave ancestor at original location to avoid overshoot;
+            // better luck next time!
+
+            // assert lastRet.isMatched();
         }
     }
 
     /** A customized variant of Spliterators.IteratorSpliterator */
-    final class LTQSpliterator<E> implements Spliterator<E> {
+    final class LTQSpliterator implements Spliterator<E> {
         static final int MAX_BATCH = 1 << 25;  // max batch array size;
         Node current;       // current node; null until initialized
         int batch;          // batch size for splits
@@ -1025,79 +1054,90 @@
         LTQSpliterator() {}
 
         public Spliterator<E> trySplit() {
-            Node p;
-            int b = batch;
-            int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1;
-            if (!exhausted &&
-                ((p = current) != null || (p = firstDataNode()) != null) &&
-                p.next != null) {
-                Object[] a = new Object[n];
-                int i = 0;
-                do {
-                    Object e = p.item;
-                    if (e != p && (a[i] = e) != null)
-                        ++i;
-                    if (p == (p = p.next))
-                        p = firstDataNode();
-                } while (p != null && i < n && p.isData);
-                if ((current = p) == null)
-                    exhausted = true;
-                if (i > 0) {
-                    batch = i;
-                    return Spliterators.spliterator
-                        (a, 0, i, (Spliterator.ORDERED |
-                                   Spliterator.NONNULL |
-                                   Spliterator.CONCURRENT));
+            Node p, q;
+            if ((p = current()) == null || (q = p.next) == null)
+                return null;
+            int i = 0, n = batch = Math.min(batch + 1, MAX_BATCH);
+            Object[] a = null;
+            do {
+                final Object item = p.item;
+                if (p.isData) {
+                    if (item != null) {
+                        if (a == null)
+                            a = new Object[n];
+                        a[i++] = item;
+                    }
+                } else if (item == null) {
+                    p = null;
+                    break;
                 }
-            }
-            return null;
+                if (p == (p = q))
+                    p = firstDataNode();
+            } while (p != null && (q = p.next) != null && i < n);
+            setCurrent(p);
+            return (i == 0) ? null :
+                Spliterators.spliterator(a, 0, i, (Spliterator.ORDERED |
+                                                   Spliterator.NONNULL |
+                                                   Spliterator.CONCURRENT));
         }
 
-        @SuppressWarnings("unchecked")
         public void forEachRemaining(Consumer<? super E> action) {
-            Node p;
-            if (action == null) throw new NullPointerException();
-            if (!exhausted &&
-                ((p = current) != null || (p = firstDataNode()) != null)) {
+            Objects.requireNonNull(action);
+            final Node p;
+            if ((p = current()) != null) {
+                current = null;
                 exhausted = true;
-                do {
-                    Object e = p.item;
-                    if (e != null && e != p)
-                        action.accept((E)e);
-                    if (p == (p = p.next))
-                        p = firstDataNode();
-                } while (p != null && p.isData);
+                forEachFrom(action, p);
             }
         }
 
         @SuppressWarnings("unchecked")
         public boolean tryAdvance(Consumer<? super E> action) {
+            Objects.requireNonNull(action);
             Node p;
-            if (action == null) throw new NullPointerException();
-            if (!exhausted &&
-                ((p = current) != null || (p = firstDataNode()) != null)) {
-                Object e;
+            if ((p = current()) != null) {
+                E e = null;
                 do {
-                    if ((e = p.item) == p)
-                        e = null;
+                    final Object item = p.item;
+                    final boolean isData = p.isData;
                     if (p == (p = p.next))
-                        p = firstDataNode();
-                } while (e == null && p != null && p.isData);
-                if ((current = p) == null)
-                    exhausted = true;
+                        p = head;
+                    if (isData) {
+                        if (item != null) {
+                            e = (E) item;
+                            break;
+                        }
+                    }
+                    else if (item == null)
+                        p = null;
+                } while (p != null);
+                setCurrent(p);
                 if (e != null) {
-                    action.accept((E)e);
+                    action.accept(e);
                     return true;
                 }
             }
             return false;
         }
 
+        private void setCurrent(Node p) {
+            if ((current = p) == null)
+                exhausted = true;
+        }
+
+        private Node current() {
+            Node p;
+            if ((p = current) == null && !exhausted)
+                setCurrent(p = firstDataNode());
+            return p;
+        }
+
         public long estimateSize() { return Long.MAX_VALUE; }
 
         public int characteristics() {
-            return Spliterator.ORDERED | Spliterator.NONNULL |
-                Spliterator.CONCURRENT;
+            return (Spliterator.ORDERED |
+                    Spliterator.NONNULL |
+                    Spliterator.CONCURRENT);
         }
     }
 
@@ -1118,7 +1158,7 @@
      * @since 1.8
      */
     public Spliterator<E> spliterator() {
-        return new LTQSpliterator<E>();
+        return new LTQSpliterator();
     }
 
     /* -------------- Removal methods -------------- */
@@ -1128,10 +1168,15 @@
      * the given predecessor.
      *
      * @param pred a node that was at one time known to be the
-     * predecessor of s, or null or s itself if s is/was at head
+     * predecessor of s
      * @param s the node to be unspliced
      */
     final void unsplice(Node pred, Node s) {
+        // assert pred != null;
+        // assert pred != s;
+        // assert s != null;
+        // assert s.isMatched();
+        // assert (SWEEP_THRESHOLD & (SWEEP_THRESHOLD - 1)) == 0;
         s.waiter = null; // disable signals
         /*
          * See above for rationale. Briefly: if pred still points to
@@ -1140,13 +1185,13 @@
          * nor s are head or offlist, add to sweepVotes, and if enough
          * votes have accumulated, sweep.
          */
-        if (pred != null && pred != s && pred.next == s) {
+        if (pred != null && pred.next == s) {
             Node n = s.next;
             if (n == null ||
                 (n != s && pred.casNext(s, n) && pred.isMatched())) {
                 for (;;) {               // check if at, or could be, head
                     Node h = head;
-                    if (h == pred || h == s || h == null)
+                    if (h == pred || h == s)
                         return;          // at head or list empty
                     if (!h.isMatched())
                         break;
@@ -1154,21 +1199,12 @@
                     if (hn == null)
                         return;          // now empty
                     if (hn != h && casHead(h, hn))
-                        h.forgetNext();  // advance head
+                        h.selfLink();  // advance head
                 }
-                if (pred.next != pred && s.next != s) { // recheck if offlist
-                    for (;;) {           // sweep now if enough votes
-                        int v = sweepVotes;
-                        if (v < SWEEP_THRESHOLD) {
-                            if (casSweepVotes(v, v + 1))
-                                break;
-                        }
-                        else if (casSweepVotes(v, 0)) {
-                            sweep();
-                            break;
-                        }
-                    }
-                }
+                // sweep every SWEEP_THRESHOLD votes
+                if (pred.next != pred && s.next != s // recheck if offlist
+                    && (incSweepVotes() & (SWEEP_THRESHOLD - 1)) == 0)
+                    sweep();
             }
         }
     }
@@ -1193,35 +1229,10 @@
     }
 
     /**
-     * Main implementation of remove(Object)
-     */
-    private boolean findAndRemove(Object e) {
-        if (e != null) {
-            for (Node pred = null, p = head; p != null; ) {
-                Object item = p.item;
-                if (p.isData) {
-                    if (item != null && item != p && e.equals(item) &&
-                        p.tryMatchData()) {
-                        unsplice(pred, p);
-                        return true;
-                    }
-                }
-                else if (item == null)
-                    break;
-                pred = p;
-                if ((p = p.next) == pred) { // stale
-                    pred = null;
-                    p = head;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
      * Creates an initially empty {@code LinkedTransferQueue}.
      */
     public LinkedTransferQueue() {
+        head = tail = new Node();
     }
 
     /**
@@ -1234,8 +1245,18 @@
      *         of its elements are null
      */
     public LinkedTransferQueue(Collection<? extends E> c) {
-        this();
-        addAll(c);
+        Node h = null, t = null;
+        for (E e : c) {
+            Node newNode = new Node(Objects.requireNonNull(e));
+            if (h == null)
+                h = t = newNode;
+            else
+                t.appendRelaxed(t = newNode);
+        }
+        if (h == null)
+            h = t = new Node();
+        head = h;
+        tail = t;
     }
 
     /**
@@ -1367,15 +1388,12 @@
      * @throws IllegalArgumentException {@inheritDoc}
      */
     public int drainTo(Collection<? super E> c) {
-        if (c == null)
-            throw new NullPointerException();
+        Objects.requireNonNull(c);
         if (c == this)
             throw new IllegalArgumentException();
         int n = 0;
-        for (E e; (e = poll()) != null;) {
+        for (E e; (e = poll()) != null; n++)
             c.add(e);
-            ++n;
-        }
         return n;
     }
 
@@ -1384,15 +1402,12 @@
      * @throws IllegalArgumentException {@inheritDoc}
      */
     public int drainTo(Collection<? super E> c, int maxElements) {
-        if (c == null)
-            throw new NullPointerException();
+        Objects.requireNonNull(c);
         if (c == this)
             throw new IllegalArgumentException();
         int n = 0;
-        for (E e; n < maxElements && (e = poll()) != null;) {
+        for (E e; n < maxElements && (e = poll()) != null; n++)
             c.add(e);
-            ++n;
-        }
         return n;
     }
 
@@ -1414,7 +1429,7 @@
             for (Node p = head; p != null;) {
                 Object item = p.item;
                 if (p.isData) {
-                    if (item != null && item != p) {
+                    if (item != null) {
                         @SuppressWarnings("unchecked") E e = (E) item;
                         return e;
                     }
@@ -1442,7 +1457,7 @@
             for (Node p = head; p != null;) {
                 Object item = p.item;
                 if (p.isData) {
-                    if (item != null && item != p)
+                    if (item != null)
                         break;
                 }
                 else if (item == null)
@@ -1486,7 +1501,31 @@
      * @return {@code true} if this queue changed as a result of the call
      */
     public boolean remove(Object o) {
-        return findAndRemove(o);
+        if (o == null) return false;
+        restartFromHead: for (;;) {
+            for (Node p = head, pred = null; p != null; ) {
+                Node q = p.next;
+                final Object item;
+                if ((item = p.item) != null) {
+                    if (p.isData) {
+                        if (o.equals(item) && p.tryMatch(item, null)) {
+                            skipDeadNodes(pred, p, p, q);
+                            return true;
+                        }
+                        pred = p; p = q; continue;
+                    }
+                }
+                else if (!p.isData)
+                    break;
+                for (Node c = p;; q = p.next) {
+                    if (q == null || !q.isMatched()) {
+                        pred = skipDeadNodes(pred, c, p, q); p = q; break;
+                    }
+                    if (p == (p = q)) continue restartFromHead;
+                }
+            }
+            return false;
+        }
     }
 
     /**
@@ -1498,18 +1537,29 @@
      * @return {@code true} if this queue contains the specified element
      */
     public boolean contains(Object o) {
-        if (o != null) {
-            for (Node p = head; p != null; p = succ(p)) {
-                Object item = p.item;
-                if (p.isData) {
-                    if (item != null && item != p && o.equals(item))
-                        return true;
+        if (o == null) return false;
+        restartFromHead: for (;;) {
+            for (Node p = head, pred = null; p != null; ) {
+                Node q = p.next;
+                final Object item;
+                if ((item = p.item) != null) {
+                    if (p.isData) {
+                        if (o.equals(item))
+                            return true;
+                        pred = p; p = q; continue;
+                    }
                 }
-                else if (item == null)
+                else if (!p.isData)
                     break;
+                for (Node c = p;; q = p.next) {
+                    if (q == null || !q.isMatched()) {
+                        pred = skipDeadNodes(pred, c, p, q); p = q; break;
+                    }
+                    if (p == (p = q)) continue restartFromHead;
+                }
             }
+            return false;
         }
-        return false;
     }
 
     /**
@@ -1550,21 +1600,136 @@
      */
     private void readObject(java.io.ObjectInputStream s)
         throws java.io.IOException, ClassNotFoundException {
-        s.defaultReadObject();
-        for (;;) {
+
+        // Read in elements until trailing null sentinel found
+        Node h = null, t = null;
+        for (Object item; (item = s.readObject()) != null; ) {
             @SuppressWarnings("unchecked")
-            E item = (E) s.readObject();
-            if (item == null)
+            Node newNode = new Node((E) item);
+            if (h == null)
+                h = t = newNode;
+            else
+                t.appendRelaxed(t = newNode);
+        }
+        if (h == null)
+            h = t = new Node();
+        head = h;
+        tail = t;
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean removeIf(Predicate<? super E> filter) {
+        Objects.requireNonNull(filter);
+        return bulkRemove(filter);
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean removeAll(Collection<?> c) {
+        Objects.requireNonNull(c);
+        return bulkRemove(e -> c.contains(e));
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean retainAll(Collection<?> c) {
+        Objects.requireNonNull(c);
+        return bulkRemove(e -> !c.contains(e));
+    }
+
+    public void clear() {
+        bulkRemove(e -> true);
+    }
+
+    /**
+     * Tolerate this many consecutive dead nodes before CAS-collapsing.
+     * Amortized cost of clear() is (1 + 1/MAX_HOPS) CASes per element.
+     */
+    private static final int MAX_HOPS = 8;
+
+    /** Implementation of bulk remove methods. */
+    @SuppressWarnings("unchecked")
+    private boolean bulkRemove(Predicate<? super E> filter) {
+        boolean removed = false;
+        restartFromHead: for (;;) {
+            int hops = MAX_HOPS;
+            // c will be CASed to collapse intervening dead nodes between
+            // pred (or head if null) and p.
+            for (Node p = head, c = p, pred = null, q; p != null; p = q) {
+                q = p.next;
+                final Object item; boolean pAlive;
+                if (pAlive = ((item = p.item) != null && p.isData)) {
+                    if (filter.test((E) item)) {
+                        if (p.tryMatch(item, null))
+                            removed = true;
+                        pAlive = false;
+                    }
+                }
+                else if (!p.isData && item == null)
+                    break;
+                if (pAlive || q == null || --hops == 0) {
+                    // p might already be self-linked here, but if so:
+                    // - CASing head will surely fail
+                    // - CASing pred's next will be useless but harmless.
+                    if ((c != p && !tryCasSuccessor(pred, c, c = p))
+                        || pAlive) {
+                        // if CAS failed or alive, abandon old pred
+                        hops = MAX_HOPS;
+                        pred = p;
+                        c = q;
+                    }
+                } else if (p == q)
+                    continue restartFromHead;
+            }
+            return removed;
+        }
+    }
+
+    /**
+     * Runs action on each element found during a traversal starting at p.
+     * If p is null, the action is not run.
+     */
+    @SuppressWarnings("unchecked")
+    void forEachFrom(Consumer<? super E> action, Node p) {
+        for (Node pred = null; p != null; ) {
+            Node q = p.next;
+            final Object item;
+            if ((item = p.item) != null) {
+                if (p.isData) {
+                    action.accept((E) item);
+                    pred = p; p = q; continue;
+                }
+            }
+            else if (!p.isData)
                 break;
-            else
-                offer(item);
+            for (Node c = p;; q = p.next) {
+                if (q == null || !q.isMatched()) {
+                    pred = skipDeadNodes(pred, c, p, q); p = q; break;
+                }
+                if (p == (p = q)) { pred = null; p = head; break; }
+            }
         }
     }
 
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public void forEach(Consumer<? super E> action) {
+        Objects.requireNonNull(action);
+        forEachFrom(action, head);
+    }
+
     // VarHandle mechanics
     private static final VarHandle HEAD;
     private static final VarHandle TAIL;
     private static final VarHandle SWEEPVOTES;
+    static final VarHandle ITEM;
+    static final VarHandle NEXT;
+    static final VarHandle WAITER;
     static {
         try {
             MethodHandles.Lookup l = MethodHandles.lookup();
@@ -1574,6 +1739,9 @@
                                    Node.class);
             SWEEPVOTES = l.findVarHandle(LinkedTransferQueue.class, "sweepVotes",
                                          int.class);
+            ITEM = l.findVarHandle(Node.class, "item", Object.class);
+            NEXT = l.findVarHandle(Node.class, "next", Node.class);
+            WAITER = l.findVarHandle(Node.class, "waiter", Thread.class);
         } catch (ReflectiveOperationException e) {
             throw new Error(e);
         }
--- a/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java	Mon Feb 06 09:34:19 2017 -0800
@@ -43,6 +43,7 @@
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
+import java.util.Objects;
 import java.util.PriorityQueue;
 import java.util.Queue;
 import java.util.SortedSet;
@@ -62,16 +63,15 @@
  * non-comparable objects (doing so results in
  * {@code ClassCastException}).
  *
- * <p>This class and its iterator implement all of the
- * <em>optional</em> methods of the {@link Collection} and {@link
- * Iterator} interfaces.  The Iterator provided in method {@link
- * #iterator()} and the Spliterator provided in method {@link #spliterator()}
- * are <em>not</em> guaranteed to traverse the elements of
- * the PriorityBlockingQueue in any particular order. If you need
- * ordered traversal, consider using
- * {@code Arrays.sort(pq.toArray())}.  Also, method {@code drainTo}
- * can be used to <em>remove</em> some or all elements in priority
- * order and place them in another collection.
+ * <p>This class and its iterator implement all of the <em>optional</em>
+ * methods of the {@link Collection} and {@link Iterator} interfaces.
+ * The Iterator provided in method {@link #iterator()} and the
+ * Spliterator provided in method {@link #spliterator()} are <em>not</em>
+ * guaranteed to traverse the elements of the PriorityBlockingQueue in
+ * any particular order. If you need ordered traversal, consider using
+ * {@code Arrays.sort(pq.toArray())}.  Also, method {@code drainTo} can
+ * be used to <em>remove</em> some or all elements in priority order and
+ * place them in another collection.
  *
  * <p>Operations on this class make no guarantees about the ordering
  * of elements with equal priority. If you need to enforce an
@@ -437,15 +437,14 @@
      */
     private void heapify() {
         Object[] array = queue;
-        int n = size;
-        int half = (n >>> 1) - 1;
+        int n = size, i = (n >>> 1) - 1;
         Comparator<? super E> cmp = comparator;
         if (cmp == null) {
-            for (int i = half; i >= 0; i--)
+            for (; i >= 0; i--)
                 siftDownComparable(i, (E) array[i], array, n);
         }
         else {
-            for (int i = half; i >= 0; i--)
+            for (; i >= 0; i--)
                 siftDownUsingComparator(i, (E) array[i], array, n, cmp);
         }
     }
@@ -730,8 +729,7 @@
      * @throws IllegalArgumentException      {@inheritDoc}
      */
     public int drainTo(Collection<? super E> c, int maxElements) {
-        if (c == null)
-            throw new NullPointerException();
+        Objects.requireNonNull(c);
         if (c == this)
             throw new IllegalArgumentException();
         if (maxElements <= 0)
@@ -935,21 +933,22 @@
      * Immutable snapshot spliterator that binds to elements "late".
      */
     final class PBQSpliterator implements Spliterator<E> {
-        Object[] array;
+        Object[] array;        // null until late-bound-initialized
         int index;
         int fence;
 
+        PBQSpliterator() {}
+
         PBQSpliterator(Object[] array, int index, int fence) {
             this.array = array;
             this.index = index;
             this.fence = fence;
         }
 
-        final int getFence() {
-            int hi;
-            if ((hi = fence) < 0)
-                hi = fence = (array = toArray()).length;
-            return hi;
+        private int getFence() {
+            if (array == null)
+                fence = (array = toArray()).length;
+            return fence;
         }
 
         public PBQSpliterator trySplit() {
@@ -958,25 +957,19 @@
                 new PBQSpliterator(array, lo, index = mid);
         }
 
-        @SuppressWarnings("unchecked")
         public void forEachRemaining(Consumer<? super E> action) {
-            Object[] a; int i, hi; // hoist accesses and checks from loop
-            if (action == null)
-                throw new NullPointerException();
-            if ((a = array) == null)
-                fence = (a = toArray()).length;
-            if ((hi = fence) <= a.length &&
-                (i = index) >= 0 && i < (index = hi)) {
-                do { action.accept((E)a[i]); } while (++i < hi);
-            }
+            Objects.requireNonNull(action);
+            final int hi = getFence(), lo = index;
+            final Object[] a = array;
+            index = hi;                 // ensure exhaustion
+            for (int i = lo; i < hi; i++)
+                action.accept((E) a[i]);
         }
 
         public boolean tryAdvance(Consumer<? super E> action) {
-            if (action == null)
-                throw new NullPointerException();
+            Objects.requireNonNull(action);
             if (getFence() > index && index >= 0) {
-                @SuppressWarnings("unchecked") E e = (E) array[index++];
-                action.accept(e);
+                action.accept((E) array[index++]);
                 return true;
             }
             return false;
@@ -985,7 +978,9 @@
         public long estimateSize() { return getFence() - index; }
 
         public int characteristics() {
-            return Spliterator.NONNULL | Spliterator.SIZED | Spliterator.SUBSIZED;
+            return (Spliterator.NONNULL |
+                    Spliterator.SIZED |
+                    Spliterator.SUBSIZED);
         }
     }
 
@@ -1007,7 +1002,7 @@
      * @since 1.8
      */
     public Spliterator<E> spliterator() {
-        return new PBQSpliterator(null, 0, -1);
+        return new PBQSpliterator();
     }
 
     // VarHandle mechanics
--- a/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java	Mon Feb 06 09:34:19 2017 -0800
@@ -42,6 +42,7 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
+import java.util.Objects;
 import java.util.Spliterator;
 import java.util.Spliterators;
 import java.util.concurrent.locks.LockSupport;
@@ -75,9 +76,8 @@
  * is not guaranteed. However, a queue constructed with fairness set
  * to {@code true} grants threads access in FIFO order.
  *
- * <p>This class and its iterator implement all of the
- * <em>optional</em> methods of the {@link Collection} and {@link
- * Iterator} interfaces.
+ * <p>This class and its iterator implement all of the <em>optional</em>
+ * methods of the {@link Collection} and {@link Iterator} interfaces.
  *
  * <p>This class is a member of the
  * <a href="{@docRoot}/../technotes/guides/collections/index.html">
@@ -1112,15 +1112,12 @@
      * @throws IllegalArgumentException      {@inheritDoc}
      */
     public int drainTo(Collection<? super E> c) {
-        if (c == null)
-            throw new NullPointerException();
+        Objects.requireNonNull(c);
         if (c == this)
             throw new IllegalArgumentException();
         int n = 0;
-        for (E e; (e = poll()) != null;) {
+        for (E e; (e = poll()) != null; n++)
             c.add(e);
-            ++n;
-        }
         return n;
     }
 
@@ -1131,15 +1128,12 @@
      * @throws IllegalArgumentException      {@inheritDoc}
      */
     public int drainTo(Collection<? super E> c, int maxElements) {
-        if (c == null)
-            throw new NullPointerException();
+        Objects.requireNonNull(c);
         if (c == this)
             throw new IllegalArgumentException();
         int n = 0;
-        for (E e; n < maxElements && (e = poll()) != null;) {
+        for (E e; n < maxElements && (e = poll()) != null; n++)
             c.add(e);
-            ++n;
-        }
         return n;
     }
 
--- a/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1059,17 +1059,17 @@
     static {
         try {
             SEED = U.objectFieldOffset
-                    (Thread.class.getDeclaredField("threadLocalRandomSeed"));
+                (Thread.class.getDeclaredField("threadLocalRandomSeed"));
             PROBE = U.objectFieldOffset
-                    (Thread.class.getDeclaredField("threadLocalRandomProbe"));
+                (Thread.class.getDeclaredField("threadLocalRandomProbe"));
             SECONDARY = U.objectFieldOffset
-                    (Thread.class.getDeclaredField("threadLocalRandomSecondarySeed"));
+                (Thread.class.getDeclaredField("threadLocalRandomSecondarySeed"));
             THREADLOCALS = U.objectFieldOffset
-                    (Thread.class.getDeclaredField("threadLocals"));
+                (Thread.class.getDeclaredField("threadLocals"));
             INHERITABLETHREADLOCALS = U.objectFieldOffset
-                    (Thread.class.getDeclaredField("inheritableThreadLocals"));
+                (Thread.class.getDeclaredField("inheritableThreadLocals"));
             INHERITEDACCESSCONTROLCONTEXT = U.objectFieldOffset
-                    (Thread.class.getDeclaredField("inheritedAccessControlContext"));
+                (Thread.class.getDeclaredField("inheritedAccessControlContext"));
         } catch (ReflectiveOperationException e) {
             throw new Error(e);
         }
--- a/src/java.base/share/classes/java/util/concurrent/locks/LockSupport.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/util/concurrent/locks/LockSupport.java	Mon Feb 06 09:34:19 2017 -0800
@@ -425,11 +425,11 @@
     static {
         try {
             PARKBLOCKER = U.objectFieldOffset
-                    (Thread.class.getDeclaredField("parkBlocker"));
+                (Thread.class.getDeclaredField("parkBlocker"));
             SECONDARY = U.objectFieldOffset
-                    (Thread.class.getDeclaredField("threadLocalRandomSecondarySeed"));
+                (Thread.class.getDeclaredField("threadLocalRandomSecondarySeed"));
             TID = U.objectFieldOffset
-                    (Thread.class.getDeclaredField("tid"));
+                (Thread.class.getDeclaredField("tid"));
 
         } catch (ReflectiveOperationException e) {
             throw new Error(e);
--- a/src/java.base/share/classes/java/util/regex/CharPredicates.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/util/regex/CharPredicates.java	Mon Feb 06 09:34:19 2017 -0800
@@ -32,164 +32,195 @@
 
 class CharPredicates {
 
-    static final CharPredicate ALPHABETIC  = Character::isAlphabetic;
+    static final CharPredicate ALPHABETIC() {
+        return Character::isAlphabetic;
+    }
 
     // \p{gc=Decimal_Number}
-    static final CharPredicate DIGIT       = Character::isDigit;
+    static final CharPredicate DIGIT() {
+        return Character::isDigit;
+    }
 
-    static final CharPredicate LETTER      = Character::isLetter;
+    static final CharPredicate LETTER() {
+        return Character::isLetter;
+    }
 
-    static final CharPredicate IDEOGRAPHIC = Character::isIdeographic;
+    static final CharPredicate IDEOGRAPHIC() {
+        return Character::isIdeographic;
+    }
 
-    static final CharPredicate LOWERCASE   = Character::isLowerCase;
+    static final CharPredicate LOWERCASE() {
+        return Character::isLowerCase;
+    }
 
-    static final CharPredicate UPPERCASE   = Character::isUpperCase;
+    static final CharPredicate UPPERCASE() {
+        return Character::isUpperCase;
+    }
 
-    static final CharPredicate TITLECASE   = Character::isTitleCase;
+    static final CharPredicate TITLECASE() {
+        return Character::isTitleCase;
+    }
 
     // \p{Whitespace}
-    static final CharPredicate WHITE_SPACE = ch ->
-        ((((1 << Character.SPACE_SEPARATOR) |
-           (1 << Character.LINE_SEPARATOR) |
-           (1 << Character.PARAGRAPH_SEPARATOR)) >> Character.getType(ch)) & 1)
-        != 0 || (ch >= 0x9 && ch <= 0xd) || (ch == 0x85);
+    static final CharPredicate WHITE_SPACE() {
+        return ch ->
+            ((((1 << Character.SPACE_SEPARATOR) |
+               (1 << Character.LINE_SEPARATOR) |
+               (1 << Character.PARAGRAPH_SEPARATOR)) >> Character.getType(ch)) & 1)
+            != 0 || (ch >= 0x9 && ch <= 0xd) || (ch == 0x85);
+    }
 
     // \p{gc=Control}
-    static final CharPredicate CONTROL     = ch ->
-        Character.getType(ch) == Character.CONTROL;
+    static final CharPredicate CONTROL() {
+        return ch -> Character.getType(ch) == Character.CONTROL;
+    }
 
     // \p{gc=Punctuation}
-    static final CharPredicate PUNCTUATION = ch ->
-        ((((1 << Character.CONNECTOR_PUNCTUATION) |
-           (1 << Character.DASH_PUNCTUATION) |
-           (1 << Character.START_PUNCTUATION) |
-           (1 << Character.END_PUNCTUATION) |
-           (1 << Character.OTHER_PUNCTUATION) |
-           (1 << Character.INITIAL_QUOTE_PUNCTUATION) |
-           (1 << Character.FINAL_QUOTE_PUNCTUATION)) >> Character.getType(ch)) & 1)
-        != 0;
+    static final CharPredicate PUNCTUATION() {
+        return ch ->
+            ((((1 << Character.CONNECTOR_PUNCTUATION) |
+               (1 << Character.DASH_PUNCTUATION) |
+               (1 << Character.START_PUNCTUATION) |
+               (1 << Character.END_PUNCTUATION) |
+               (1 << Character.OTHER_PUNCTUATION) |
+               (1 << Character.INITIAL_QUOTE_PUNCTUATION) |
+               (1 << Character.FINAL_QUOTE_PUNCTUATION)) >> Character.getType(ch)) & 1)
+            != 0;
+    }
 
     // \p{gc=Decimal_Number}
     // \p{Hex_Digit}    -> PropList.txt: Hex_Digit
-    static final CharPredicate HEX_DIGIT = DIGIT.union(
-        ch -> (ch >= 0x0030 && ch <= 0x0039) ||
-              (ch >= 0x0041 && ch <= 0x0046) ||
-              (ch >= 0x0061 && ch <= 0x0066) ||
-              (ch >= 0xFF10 && ch <= 0xFF19) ||
-              (ch >= 0xFF21 && ch <= 0xFF26) ||
-              (ch >= 0xFF41 && ch <= 0xFF46));
+    static final CharPredicate HEX_DIGIT() {
+        return DIGIT().union(ch -> (ch >= 0x0030 && ch <= 0x0039) ||
+                (ch >= 0x0041 && ch <= 0x0046) ||
+                (ch >= 0x0061 && ch <= 0x0066) ||
+                (ch >= 0xFF10 && ch <= 0xFF19) ||
+                (ch >= 0xFF21 && ch <= 0xFF26) ||
+                (ch >= 0xFF41 && ch <= 0xFF46));
+    }
 
-    static final CharPredicate ASSIGNED = ch ->
-        Character.getType(ch) != Character.UNASSIGNED;
+    static final CharPredicate ASSIGNED() {
+        return ch -> Character.getType(ch) != Character.UNASSIGNED;
+    }
 
     // PropList.txt:Noncharacter_Code_Point
-    static final CharPredicate NONCHARACTER_CODE_POINT = ch ->
-        (ch & 0xfffe) == 0xfffe || (ch >= 0xfdd0 && ch <= 0xfdef);
+    static final CharPredicate NONCHARACTER_CODE_POINT() {
+        return ch -> (ch & 0xfffe) == 0xfffe || (ch >= 0xfdd0 && ch <= 0xfdef);
+    }
 
     // \p{alpha}
     // \p{digit}
-    static final CharPredicate ALNUM = ALPHABETIC.union(DIGIT);
+    static final CharPredicate ALNUM() {
+        return ALPHABETIC().union(DIGIT());
+    }
 
     // \p{Whitespace} --
     // [\N{LF} \N{VT} \N{FF} \N{CR} \N{NEL}  -> 0xa, 0xb, 0xc, 0xd, 0x85
     //  \p{gc=Line_Separator}
     //  \p{gc=Paragraph_Separator}]
-    static final CharPredicate BLANK = ch ->
-        Character.getType(ch) == Character.SPACE_SEPARATOR ||
-        ch == 0x9; // \N{HT}
+    static final CharPredicate BLANK() {
+        return ch ->
+            Character.getType(ch) == Character.SPACE_SEPARATOR ||
+            ch == 0x9; // \N{HT}
+    }
 
     // [^
     //  \p{space}
     //  \p{gc=Control}
     //  \p{gc=Surrogate}
     //  \p{gc=Unassigned}]
-    static final CharPredicate GRAPH = ch ->
-        ((((1 << Character.SPACE_SEPARATOR) |
-           (1 << Character.LINE_SEPARATOR) |
-           (1 << Character.PARAGRAPH_SEPARATOR) |
-           (1 << Character.CONTROL) |
-           (1 << Character.SURROGATE) |
-           (1 << Character.UNASSIGNED)) >> Character.getType(ch)) & 1)
-        == 0;
+    static final CharPredicate GRAPH() {
+        return ch ->
+            ((((1 << Character.SPACE_SEPARATOR) |
+               (1 << Character.LINE_SEPARATOR) |
+               (1 << Character.PARAGRAPH_SEPARATOR) |
+               (1 << Character.CONTROL) |
+               (1 << Character.SURROGATE) |
+               (1 << Character.UNASSIGNED)) >> Character.getType(ch)) & 1)
+            == 0;
+    }
 
     // \p{graph}
     // \p{blank}
     // -- \p{cntrl}
-    static final CharPredicate PRINT = GRAPH.union(BLANK).and(CONTROL.negate());
+    static final CharPredicate PRINT() {
+        return GRAPH().union(BLANK()).and(CONTROL().negate());
+    }
 
     //  200C..200D    PropList.txt:Join_Control
-    static final CharPredicate JOIN_CONTROL = ch -> ch == 0x200C || ch == 0x200D;
+    static final CharPredicate JOIN_CONTROL() {
+        return ch -> ch == 0x200C || ch == 0x200D;
+    }
 
     //  \p{alpha}
     //  \p{gc=Mark}
     //  \p{digit}
     //  \p{gc=Connector_Punctuation}
     //  \p{Join_Control}    200C..200D
-    static final CharPredicate WORD =
-        ALPHABETIC.union(ch -> ((((1 << Character.NON_SPACING_MARK) |
+    static final CharPredicate WORD() {
+        return ALPHABETIC().union(ch -> ((((1 << Character.NON_SPACING_MARK) |
                                   (1 << Character.ENCLOSING_MARK) |
                                   (1 << Character.COMBINING_SPACING_MARK) |
                                   (1 << Character.DECIMAL_DIGIT_NUMBER) |
                                   (1 << Character.CONNECTOR_PUNCTUATION))
                                  >> Character.getType(ch)) & 1) != 0,
-                         JOIN_CONTROL);
+                         JOIN_CONTROL());
+    }
 
     /////////////////////////////////////////////////////////////////////////////
 
-    private static final HashMap<String, CharPredicate> posix = new HashMap<>(12);
-    private static final HashMap<String, CharPredicate> uprops = new HashMap<>(18);
-
-    private static void defPosix(String name, CharPredicate p) {
-        posix.put(name, p);
-    }
-    private static void defUProp(String name, CharPredicate p) {
-        uprops.put(name, p);
+    private static CharPredicate getPosixPredicate(String name) {
+        switch (name) {
+            case "ALPHA": return ALPHABETIC();
+            case "LOWER": return LOWERCASE();
+            case "UPPER": return UPPERCASE();
+            case "SPACE": return WHITE_SPACE();
+            case "PUNCT": return PUNCTUATION();
+            case "XDIGIT": return HEX_DIGIT();
+            case "ALNUM": return ALNUM();
+            case "CNTRL": return CONTROL();
+            case "DIGIT": return DIGIT();
+            case "BLANK": return BLANK();
+            case "GRAPH": return GRAPH();
+            case "PRINT": return PRINT();
+            default: return null;
+        }
     }
 
-    static {
-        defPosix("ALPHA", ALPHABETIC);
-        defPosix("LOWER", LOWERCASE);
-        defPosix("UPPER", UPPERCASE);
-        defPosix("SPACE", WHITE_SPACE);
-        defPosix("PUNCT", PUNCTUATION);
-        defPosix("XDIGIT",HEX_DIGIT);
-        defPosix("ALNUM", ALNUM);
-        defPosix("CNTRL", CONTROL);
-        defPosix("DIGIT", DIGIT);
-        defPosix("BLANK", BLANK);
-        defPosix("GRAPH", GRAPH);
-        defPosix("PRINT", PRINT);
-
-        defUProp("ALPHABETIC", ALPHABETIC);
-        defUProp("ASSIGNED", ASSIGNED);
-        defUProp("CONTROL", CONTROL);
-        defUProp("HEXDIGIT", HEX_DIGIT);
-        defUProp("IDEOGRAPHIC", IDEOGRAPHIC);
-        defUProp("JOINCONTROL", JOIN_CONTROL);
-        defUProp("LETTER", LETTER);
-        defUProp("LOWERCASE", LOWERCASE);
-        defUProp("NONCHARACTERCODEPOINT", NONCHARACTER_CODE_POINT);
-        defUProp("TITLECASE", TITLECASE);
-        defUProp("PUNCTUATION", PUNCTUATION);
-        defUProp("UPPERCASE", UPPERCASE);
-        defUProp("WHITESPACE", WHITE_SPACE);
-        defUProp("WORD", WORD);
-        defUProp("WHITE_SPACE", WHITE_SPACE);
-        defUProp("HEX_DIGIT", HEX_DIGIT);
-        defUProp("NONCHARACTER_CODE_POINT", NONCHARACTER_CODE_POINT);
-        defUProp("JOIN_CONTROL", JOIN_CONTROL);
+    private static CharPredicate getUnicodePredicate(String name) {
+        switch (name) {
+            case "ALPHABETIC": return ALPHABETIC();
+            case "ASSIGNED": return ASSIGNED();
+            case "CONTROL": return CONTROL();
+            case "HEXDIGIT": return HEX_DIGIT();
+            case "IDEOGRAPHIC": return IDEOGRAPHIC();
+            case "JOINCONTROL": return JOIN_CONTROL();
+            case "LETTER": return LETTER();
+            case "LOWERCASE": return LOWERCASE();
+            case "NONCHARACTERCODEPOINT": return NONCHARACTER_CODE_POINT();
+            case "TITLECASE": return TITLECASE();
+            case "PUNCTUATION": return PUNCTUATION();
+            case "UPPERCASE": return UPPERCASE();
+            case "WHITESPACE": return WHITE_SPACE();
+            case "WORD": return WORD();
+            case "WHITE_SPACE": return WHITE_SPACE();
+            case "HEX_DIGIT": return HEX_DIGIT();
+            case "NONCHARACTER_CODE_POINT": return NONCHARACTER_CODE_POINT();
+            case "JOIN_CONTROL": return JOIN_CONTROL();
+            default: return null;
+        }
     }
 
     public static CharPredicate forUnicodeProperty(String propName) {
         propName = propName.toUpperCase(Locale.ROOT);
-        CharPredicate p = uprops.get(propName);
+        CharPredicate p = getUnicodePredicate(propName);
         if (p != null)
             return p;
-        return posix.get(propName);
+        return getPosixPredicate(propName);
     }
 
     public static CharPredicate forPOSIXName(String propName) {
-        return posix.get(propName.toUpperCase(Locale.ENGLISH));
+        return getPosixPredicate(propName.toUpperCase(Locale.ENGLISH));
     }
 
     /////////////////////////////////////////////////////////////////////////////
@@ -223,145 +254,130 @@
 
     // unicode categories, aliases, properties, java methods ...
 
-    private static final HashMap<String, CharPredicate> props = new HashMap<>(128);
+    static CharPredicate forProperty(String name) {
+        // Unicode character property aliases, defined in
+        // http://www.unicode.org/Public/UNIDATA/PropertyValueAliases.txt
+        switch (name) {
+            case "Cn": return category(1<<Character.UNASSIGNED);
+            case "Lu": return category(1<<Character.UPPERCASE_LETTER);
+            case "Ll": return category(1<<Character.LOWERCASE_LETTER);
+            case "Lt": return category(1<<Character.TITLECASE_LETTER);
+            case "Lm": return category(1<<Character.MODIFIER_LETTER);
+            case "Lo": return category(1<<Character.OTHER_LETTER);
+            case "Mn": return category(1<<Character.NON_SPACING_MARK);
+            case "Me": return category(1<<Character.ENCLOSING_MARK);
+            case "Mc": return category(1<<Character.COMBINING_SPACING_MARK);
+            case "Nd": return category(1<<Character.DECIMAL_DIGIT_NUMBER);
+            case "Nl": return category(1<<Character.LETTER_NUMBER);
+            case "No": return category(1<<Character.OTHER_NUMBER);
+            case "Zs": return category(1<<Character.SPACE_SEPARATOR);
+            case "Zl": return category(1<<Character.LINE_SEPARATOR);
+            case "Zp": return category(1<<Character.PARAGRAPH_SEPARATOR);
+            case "Cc": return category(1<<Character.CONTROL);
+            case "Cf": return category(1<<Character.FORMAT);
+            case "Co": return category(1<<Character.PRIVATE_USE);
+            case "Cs": return category(1<<Character.SURROGATE);
+            case "Pd": return category(1<<Character.DASH_PUNCTUATION);
+            case "Ps": return category(1<<Character.START_PUNCTUATION);
+            case "Pe": return category(1<<Character.END_PUNCTUATION);
+            case "Pc": return category(1<<Character.CONNECTOR_PUNCTUATION);
+            case "Po": return category(1<<Character.OTHER_PUNCTUATION);
+            case "Sm": return category(1<<Character.MATH_SYMBOL);
+            case "Sc": return category(1<<Character.CURRENCY_SYMBOL);
+            case "Sk": return category(1<<Character.MODIFIER_SYMBOL);
+            case "So": return category(1<<Character.OTHER_SYMBOL);
+            case "Pi": return category(1<<Character.INITIAL_QUOTE_PUNCTUATION);
+            case "Pf": return category(1<<Character.FINAL_QUOTE_PUNCTUATION);
+            case "L": return category(((1<<Character.UPPERCASE_LETTER) |
+                              (1<<Character.LOWERCASE_LETTER) |
+                              (1<<Character.TITLECASE_LETTER) |
+                              (1<<Character.MODIFIER_LETTER)  |
+                              (1<<Character.OTHER_LETTER)));
+            case "M": return category(((1<<Character.NON_SPACING_MARK) |
+                              (1<<Character.ENCLOSING_MARK)   |
+                              (1<<Character.COMBINING_SPACING_MARK)));
+            case "N": return category(((1<<Character.DECIMAL_DIGIT_NUMBER) |
+                              (1<<Character.LETTER_NUMBER)        |
+                              (1<<Character.OTHER_NUMBER)));
+            case "Z": return category(((1<<Character.SPACE_SEPARATOR) |
+                              (1<<Character.LINE_SEPARATOR)  |
+                              (1<<Character.PARAGRAPH_SEPARATOR)));
+            case "C": return category(((1<<Character.CONTROL)     |
+                              (1<<Character.FORMAT)      |
+                              (1<<Character.PRIVATE_USE) |
+                              (1<<Character.SURROGATE)   |
+                              (1<<Character.UNASSIGNED))); // Other
+            case "P": return category(((1<<Character.DASH_PUNCTUATION)      |
+                              (1<<Character.START_PUNCTUATION)     |
+                              (1<<Character.END_PUNCTUATION)       |
+                              (1<<Character.CONNECTOR_PUNCTUATION) |
+                              (1<<Character.OTHER_PUNCTUATION)     |
+                              (1<<Character.INITIAL_QUOTE_PUNCTUATION) |
+                              (1<<Character.FINAL_QUOTE_PUNCTUATION)));
+            case "S": return category(((1<<Character.MATH_SYMBOL)     |
+                              (1<<Character.CURRENCY_SYMBOL) |
+                              (1<<Character.MODIFIER_SYMBOL) |
+                              (1<<Character.OTHER_SYMBOL)));
+            case "LC": return category(((1<<Character.UPPERCASE_LETTER) |
+                               (1<<Character.LOWERCASE_LETTER) |
+                               (1<<Character.TITLECASE_LETTER)));
+            case "LD": return category(((1<<Character.UPPERCASE_LETTER) |
+                               (1<<Character.LOWERCASE_LETTER) |
+                               (1<<Character.TITLECASE_LETTER) |
+                               (1<<Character.MODIFIER_LETTER)  |
+                               (1<<Character.OTHER_LETTER)     |
+                               (1<<Character.DECIMAL_DIGIT_NUMBER)));
+            case "L1": return range(0x00, 0xFF); // Latin-1
+            case "all": return Pattern.ALL();
+            // Posix regular expression character classes, defined in
+            // http://www.unix.org/onlinepubs/009695399/basedefs/xbd_chap09.html
+            case "ASCII": return range(0x00, 0x7F);   // ASCII
+            case "Alnum": return ctype(ASCII.ALNUM);  // Alphanumeric characters
+            case "Alpha": return ctype(ASCII.ALPHA);  // Alphabetic characters
+            case "Blank": return ctype(ASCII.BLANK);  // Space and tab characters
+            case "Cntrl": return ctype(ASCII.CNTRL);  // Control characters
+            case "Digit": return range('0', '9');     // Numeric characters
+            case "Graph": return ctype(ASCII.GRAPH);  // printable and visible
+            case "Lower": return range('a', 'z');     // Lower-case alphabetic
+            case "Print": return range(0x20, 0x7E);   // Printable characters
+            case "Punct": return ctype(ASCII.PUNCT);  // Punctuation characters
+            case "Space": return ctype(ASCII.SPACE);  // Space characters
+            case "Upper": return range('A', 'Z');     // Upper-case alphabetic
+            case "XDigit": return ctype(ASCII.XDIGIT); // hexadecimal digits
 
-    /**
-     * Returns a predicate matching all characters in a named property.
-     */
-    static CharPredicate forProperty(String name) {
-        return props.get(name);
+            // Java character properties, defined by methods in Character.java
+            case "javaLowerCase": return java.lang.Character::isLowerCase;
+            case "javaUpperCase": return  Character::isUpperCase;
+            case "javaAlphabetic": return java.lang.Character::isAlphabetic;
+            case "javaIdeographic": return java.lang.Character::isIdeographic;
+            case "javaTitleCase": return java.lang.Character::isTitleCase;
+            case "javaDigit": return java.lang.Character::isDigit;
+            case "javaDefined": return java.lang.Character::isDefined;
+            case "javaLetter": return java.lang.Character::isLetter;
+            case "javaLetterOrDigit": return java.lang.Character::isLetterOrDigit;
+            case "javaJavaIdentifierStart": return java.lang.Character::isJavaIdentifierStart;
+            case "javaJavaIdentifierPart": return java.lang.Character::isJavaIdentifierPart;
+            case "javaUnicodeIdentifierStart": return java.lang.Character::isUnicodeIdentifierStart;
+            case "javaUnicodeIdentifierPart": return java.lang.Character::isUnicodeIdentifierPart;
+            case "javaIdentifierIgnorable": return java.lang.Character::isIdentifierIgnorable;
+            case "javaSpaceChar": return java.lang.Character::isSpaceChar;
+            case "javaWhitespace": return java.lang.Character::isWhitespace;
+            case "javaISOControl": return java.lang.Character::isISOControl;
+            case "javaMirrored": return java.lang.Character::isMirrored;
+            default: return null;
+        }
     }
 
-    private static void defProp(String name, CharPredicate p) {
-        props.put(name, p);
+    private static CharPredicate category(final int typeMask) {
+        return ch -> (typeMask & (1 << Character.getType(ch))) != 0;
     }
 
-    private static void defCategory(String name, final int typeMask) {
-        CharPredicate p = ch -> (typeMask & (1 << Character.getType(ch))) != 0;
-        props.put(name, p);
+    private static CharPredicate range(final int lower, final int upper) {
+        return (BmpCharPredicate)ch -> lower <= ch && ch <= upper;
     }
 
-    private static void defRange(String name, final int lower, final int upper) {
-        BmpCharPredicate p = ch -> lower <= ch && ch <= upper;
-        props.put(name, p);
-    }
-
-    private static void defCtype(String name, final int ctype) {
-        BmpCharPredicate p = ch -> ch < 128 && ASCII.isType(ch, ctype);
-        // PrintPattern.pmap.put(p, name);
-        props.put(name, p);
-    }
-
-    static {
-        // Unicode character property aliases, defined in
-        // http://www.unicode.org/Public/UNIDATA/PropertyValueAliases.txt
-        defCategory("Cn", 1<<Character.UNASSIGNED);
-        defCategory("Lu", 1<<Character.UPPERCASE_LETTER);
-        defCategory("Ll", 1<<Character.LOWERCASE_LETTER);
-        defCategory("Lt", 1<<Character.TITLECASE_LETTER);
-        defCategory("Lm", 1<<Character.MODIFIER_LETTER);
-        defCategory("Lo", 1<<Character.OTHER_LETTER);
-        defCategory("Mn", 1<<Character.NON_SPACING_MARK);
-        defCategory("Me", 1<<Character.ENCLOSING_MARK);
-        defCategory("Mc", 1<<Character.COMBINING_SPACING_MARK);
-        defCategory("Nd", 1<<Character.DECIMAL_DIGIT_NUMBER);
-        defCategory("Nl", 1<<Character.LETTER_NUMBER);
-        defCategory("No", 1<<Character.OTHER_NUMBER);
-        defCategory("Zs", 1<<Character.SPACE_SEPARATOR);
-        defCategory("Zl", 1<<Character.LINE_SEPARATOR);
-        defCategory("Zp", 1<<Character.PARAGRAPH_SEPARATOR);
-        defCategory("Cc", 1<<Character.CONTROL);
-        defCategory("Cf", 1<<Character.FORMAT);
-        defCategory("Co", 1<<Character.PRIVATE_USE);
-        defCategory("Cs", 1<<Character.SURROGATE);
-        defCategory("Pd", 1<<Character.DASH_PUNCTUATION);
-        defCategory("Ps", 1<<Character.START_PUNCTUATION);
-        defCategory("Pe", 1<<Character.END_PUNCTUATION);
-        defCategory("Pc", 1<<Character.CONNECTOR_PUNCTUATION);
-        defCategory("Po", 1<<Character.OTHER_PUNCTUATION);
-        defCategory("Sm", 1<<Character.MATH_SYMBOL);
-        defCategory("Sc", 1<<Character.CURRENCY_SYMBOL);
-        defCategory("Sk", 1<<Character.MODIFIER_SYMBOL);
-        defCategory("So", 1<<Character.OTHER_SYMBOL);
-        defCategory("Pi", 1<<Character.INITIAL_QUOTE_PUNCTUATION);
-        defCategory("Pf", 1<<Character.FINAL_QUOTE_PUNCTUATION);
-        defCategory("L", ((1<<Character.UPPERCASE_LETTER) |
-                          (1<<Character.LOWERCASE_LETTER) |
-                          (1<<Character.TITLECASE_LETTER) |
-                          (1<<Character.MODIFIER_LETTER)  |
-                          (1<<Character.OTHER_LETTER)));
-        defCategory("M", ((1<<Character.NON_SPACING_MARK) |
-                          (1<<Character.ENCLOSING_MARK)   |
-                          (1<<Character.COMBINING_SPACING_MARK)));
-        defCategory("N", ((1<<Character.DECIMAL_DIGIT_NUMBER) |
-                          (1<<Character.LETTER_NUMBER)        |
-                          (1<<Character.OTHER_NUMBER)));
-        defCategory("Z", ((1<<Character.SPACE_SEPARATOR) |
-                          (1<<Character.LINE_SEPARATOR)  |
-                          (1<<Character.PARAGRAPH_SEPARATOR)));
-        defCategory("C", ((1<<Character.CONTROL)     |
-                          (1<<Character.FORMAT)      |
-                          (1<<Character.PRIVATE_USE) |
-                          (1<<Character.SURROGATE)   |
-                          (1<<Character.UNASSIGNED))); // Other
-        defCategory("P", ((1<<Character.DASH_PUNCTUATION)      |
-                          (1<<Character.START_PUNCTUATION)     |
-                          (1<<Character.END_PUNCTUATION)       |
-                          (1<<Character.CONNECTOR_PUNCTUATION) |
-                          (1<<Character.OTHER_PUNCTUATION)     |
-                          (1<<Character.INITIAL_QUOTE_PUNCTUATION) |
-                          (1<<Character.FINAL_QUOTE_PUNCTUATION)));
-        defCategory("S", ((1<<Character.MATH_SYMBOL)     |
-                          (1<<Character.CURRENCY_SYMBOL) |
-                          (1<<Character.MODIFIER_SYMBOL) |
-                          (1<<Character.OTHER_SYMBOL)));
-        defCategory("LC", ((1<<Character.UPPERCASE_LETTER) |
-                           (1<<Character.LOWERCASE_LETTER) |
-                           (1<<Character.TITLECASE_LETTER)));
-        defCategory("LD", ((1<<Character.UPPERCASE_LETTER) |
-                           (1<<Character.LOWERCASE_LETTER) |
-                           (1<<Character.TITLECASE_LETTER) |
-                           (1<<Character.MODIFIER_LETTER)  |
-                           (1<<Character.OTHER_LETTER)     |
-                           (1<<Character.DECIMAL_DIGIT_NUMBER)));
-        defRange("L1", 0x00, 0xFF); // Latin-1
-        props.put("all", ch -> true);
-
-        // Posix regular expression character classes, defined in
-        // http://www.unix.org/onlinepubs/009695399/basedefs/xbd_chap09.html
-        defRange("ASCII", 0x00, 0x7F);   // ASCII
-        defCtype("Alnum", ASCII.ALNUM);  // Alphanumeric characters
-        defCtype("Alpha", ASCII.ALPHA);  // Alphabetic characters
-        defCtype("Blank", ASCII.BLANK);  // Space and tab characters
-        defCtype("Cntrl", ASCII.CNTRL);  // Control characters
-        defRange("Digit", '0', '9');     // Numeric characters
-        defCtype("Graph", ASCII.GRAPH);  // printable and visible
-        defRange("Lower", 'a', 'z');     // Lower-case alphabetic
-        defRange("Print", 0x20, 0x7E);   // Printable characters
-        defCtype("Punct", ASCII.PUNCT);  // Punctuation characters
-        defCtype("Space", ASCII.SPACE);  // Space characters
-        defRange("Upper", 'A', 'Z');     // Upper-case alphabetic
-        defCtype("XDigit",ASCII.XDIGIT); // hexadecimal digits
-
-        // Java character properties, defined by methods in Character.java
-        defProp("javaLowerCase", java.lang.Character::isLowerCase);
-        defProp("javaUpperCase",  Character::isUpperCase);
-        defProp("javaAlphabetic", java.lang.Character::isAlphabetic);
-        defProp("javaIdeographic", java.lang.Character::isIdeographic);
-        defProp("javaTitleCase", java.lang.Character::isTitleCase);
-        defProp("javaDigit", java.lang.Character::isDigit);
-        defProp("javaDefined", java.lang.Character::isDefined);
-        defProp("javaLetter", java.lang.Character::isLetter);
-        defProp("javaLetterOrDigit", java.lang.Character::isLetterOrDigit);
-        defProp("javaJavaIdentifierStart", java.lang.Character::isJavaIdentifierStart);
-        defProp("javaJavaIdentifierPart", java.lang.Character::isJavaIdentifierPart);
-        defProp("javaUnicodeIdentifierStart", java.lang.Character::isUnicodeIdentifierStart);
-        defProp("javaUnicodeIdentifierPart", java.lang.Character::isUnicodeIdentifierPart);
-        defProp("javaIdentifierIgnorable", java.lang.Character::isIdentifierIgnorable);
-        defProp("javaSpaceChar", java.lang.Character::isSpaceChar);
-        defProp("javaWhitespace", java.lang.Character::isWhitespace);
-        defProp("javaISOControl", java.lang.Character::isISOControl);
-        defProp("javaMirrored", java.lang.Character::isMirrored);
+    private static CharPredicate ctype(final int ctype) {
+        return (BmpCharPredicate)ch -> ch < 128 && ASCII.isType(ch, ctype);
     }
 
     /////////////////////////////////////////////////////////////////////////////
@@ -369,8 +385,14 @@
     /**
      * Posix ASCII variants, not in the lookup map
      */
-    static final BmpCharPredicate ASCII_DIGIT = ch -> ch < 128 && ASCII.isDigit(ch);
-    static final BmpCharPredicate ASCII_WORD  = ch -> ch < 128 && ASCII.isWord(ch);
-    static final BmpCharPredicate ASCII_SPACE = ch -> ch < 128 && ASCII.isSpace(ch);
+    static final BmpCharPredicate ASCII_DIGIT() {
+        return ch -> ch < 128 && ASCII.isDigit(ch);
+    }
+    static final BmpCharPredicate ASCII_WORD() {
+        return ch -> ch < 128 && ASCII.isWord(ch);
+    }
+    static final BmpCharPredicate ASCII_SPACE() {
+        return ch -> ch < 128 && ASCII.isSpace(ch);
+    }
 
 }
--- a/src/java.base/share/classes/java/util/regex/Pattern.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/util/regex/Pattern.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1495,7 +1495,7 @@
                     altns.add(seq);
                     produceEquivalentAlternation(nfd, altns);
                     dst.append("(?:");
-                    altns.forEach( s -> dst.append(s + "|"));
+                    altns.forEach( s -> dst.append(s).append('|'));
                     dst.delete(dst.length() - 1, dst.length());
                     dst.append(")");
                     continue;
@@ -2142,12 +2142,12 @@
             case '.':
                 next();
                 if (has(DOTALL)) {
-                    node = new CharProperty(ALL);
+                    node = new CharProperty(ALL());
                 } else {
                     if (has(UNIX_LINES)) {
-                        node = new CharProperty(UNIXDOT);
+                        node = new CharProperty(UNIXDOT());
                     } else {
-                        node = new CharProperty(DOT);
+                        node = new CharProperty(DOT());
                     }
                 }
                 break;
@@ -2376,7 +2376,7 @@
         case 'D':
             if (create) {
                 predicate = has(UNICODE_CHARACTER_CLASS) ?
-                            CharPredicates.DIGIT : CharPredicates.ASCII_DIGIT;
+                            CharPredicates.DIGIT() : CharPredicates.ASCII_DIGIT();
                 predicate = predicate.negate();
                 if (!inclass)
                     root = newCharProperty(predicate);
@@ -2391,7 +2391,7 @@
             return -1;
         case 'H':
             if (create) {
-                predicate = HorizWS.negate();
+                predicate = HorizWS().negate();
                 if (!inclass)
                     root = newCharProperty(predicate);
             }
@@ -2415,7 +2415,7 @@
         case 'S':
             if (create) {
                 predicate = has(UNICODE_CHARACTER_CLASS) ?
-                            CharPredicates.WHITE_SPACE : CharPredicates.ASCII_SPACE;
+                            CharPredicates.WHITE_SPACE() : CharPredicates.ASCII_SPACE();
                 predicate = predicate.negate();
                 if (!inclass)
                     root = newCharProperty(predicate);
@@ -2426,7 +2426,7 @@
             break;
         case 'V':
             if (create) {
-                predicate = VertWS.negate();
+                predicate = VertWS().negate();
                 if (!inclass)
                     root = newCharProperty(predicate);
             }
@@ -2434,7 +2434,7 @@
         case 'W':
             if (create) {
                 predicate = has(UNICODE_CHARACTER_CLASS) ?
-                            CharPredicates.WORD : CharPredicates.ASCII_WORD;
+                            CharPredicates.WORD() : CharPredicates.ASCII_WORD();
                 predicate = predicate.negate();
                 if (!inclass)
                     root = newCharProperty(predicate);
@@ -2480,7 +2480,7 @@
         case 'd':
             if (create) {
                 predicate = has(UNICODE_CHARACTER_CLASS) ?
-                            CharPredicates.DIGIT : CharPredicates.ASCII_DIGIT;
+                            CharPredicates.DIGIT() : CharPredicates.ASCII_DIGIT();
                 if (!inclass)
                     root = newCharProperty(predicate);
             }
@@ -2493,7 +2493,7 @@
             break;
         case 'h':
             if (create) {
-                predicate = HorizWS;
+                predicate = HorizWS();
                 if (!inclass)
                     root = newCharProperty(predicate);
             }
@@ -2531,7 +2531,7 @@
         case 's':
             if (create) {
                 predicate = has(UNICODE_CHARACTER_CLASS) ?
-                            CharPredicates.WHITE_SPACE : CharPredicates.ASCII_SPACE;
+                            CharPredicates.WHITE_SPACE() : CharPredicates.ASCII_SPACE();
                 if (!inclass)
                     root = newCharProperty(predicate);
             }
@@ -2552,7 +2552,7 @@
             if (isrange)
                 return '\013';
             if (create) {
-                predicate = VertWS;
+                predicate = VertWS();
                 if (!inclass)
                     root = newCharProperty(predicate);
             }
@@ -2560,7 +2560,7 @@
         case 'w':
             if (create) {
                 predicate = has(UNICODE_CHARACTER_CLASS) ?
-                            CharPredicates.WORD : CharPredicates.ASCII_WORD;
+                            CharPredicates.WORD() : CharPredicates.ASCII_WORD();
                 if (!inclass)
                     root = newCharProperty(predicate);
             }
@@ -2704,7 +2704,6 @@
            (6)AngstromSign u+212b
               toLowerCase(u+212b) ==> u+00e5
         */
-        int d;
         if (ch < 256 &&
             !(has(CASE_INSENSITIVE) && has(UNICODE_CASE) &&
               (ch == 0xff || ch == 0xb5 ||
@@ -5384,7 +5383,7 @@
         }
 
         boolean isWord(int ch) {
-            return useUWORD ? CharPredicates.WORD.is(ch)
+            return useUWORD ? CharPredicates.WORD().is(ch)
                             : (ch == '_' || Character.isLetterOrDigit(ch));
         }
 
@@ -5680,33 +5679,45 @@
     /**
      * matches a Perl vertical whitespace
      */
-    static BmpCharPredicate VertWS = cp ->
-        (cp >= 0x0A && cp <= 0x0D) || cp == 0x85 || cp == 0x2028 || cp == 0x2029;
+    static BmpCharPredicate VertWS() {
+        return cp -> (cp >= 0x0A && cp <= 0x0D) ||
+            cp == 0x85 || cp == 0x2028 || cp == 0x2029;
+    }
 
     /**
      * matches a Perl horizontal whitespace
      */
-    static BmpCharPredicate HorizWS = cp ->
-        cp == 0x09 || cp == 0x20 || cp == 0xa0 || cp == 0x1680 ||
-        cp == 0x180e || cp >= 0x2000 && cp <= 0x200a ||  cp == 0x202f ||
-        cp == 0x205f || cp == 0x3000;
+    static BmpCharPredicate HorizWS() {
+        return cp ->
+            cp == 0x09 || cp == 0x20 || cp == 0xa0 || cp == 0x1680 ||
+            cp == 0x180e || cp >= 0x2000 && cp <= 0x200a ||  cp == 0x202f ||
+            cp == 0x205f || cp == 0x3000;
+    }
 
     /**
      *  for the Unicode category ALL and the dot metacharacter when
      *  in dotall mode.
      */
-    static CharPredicate ALL = ch -> true;
+    static CharPredicate ALL() {
+        return ch -> true;
+    }
 
     /**
      * for the dot metacharacter when dotall is not enabled.
      */
-    static CharPredicate DOT = ch -> (ch != '\n' && ch != '\r'
-                                          && (ch|1) != '\u2029'
-                                          && ch != '\u0085');
+    static CharPredicate DOT() {
+        return ch ->
+            (ch != '\n' && ch != '\r'
+            && (ch|1) != '\u2029'
+            && ch != '\u0085');
+    }
+
     /**
      *  the dot metacharacter when dotall is not enabled but UNIX_LINES is enabled.
      */
-    static CharPredicate UNIXDOT = ch ->  ch != '\n';
+    static CharPredicate UNIXDOT() {
+        return ch ->  ch != '\n';
+    }
 
     /**
      * Indicate that matches a Supplementary Unicode character
--- a/src/java.base/share/classes/java/util/regex/PrintPattern.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/util/regex/PrintPattern.java	Mon Feb 06 09:34:19 2017 -0800
@@ -27,7 +27,6 @@
 
 import java.util.HashMap;
 import java.util.regex.Pattern.CharPredicate;
-import java.util.regex.CharPredicates;
 import static java.util.regex.ASCII.*;
 
 /**
@@ -106,15 +105,15 @@
     static HashMap<CharPredicate, String> pmap;
     static {
         pmap = new HashMap<>();
-        pmap.put(Pattern.ALL, "All");
-        pmap.put(Pattern.DOT, "Dot");
-        pmap.put(Pattern.UNIXDOT, "UnixDot");
-        pmap.put(Pattern.VertWS, "VertWS");
-        pmap.put(Pattern.HorizWS, "HorizWS");
+        pmap.put(Pattern.ALL(), "All");
+        pmap.put(Pattern.DOT(), "Dot");
+        pmap.put(Pattern.UNIXDOT(), "UnixDot");
+        pmap.put(Pattern.VertWS(), "VertWS");
+        pmap.put(Pattern.HorizWS(), "HorizWS");
 
-        pmap.put(CharPredicates.ASCII_DIGIT, "ASCII.DIGIT");
-        pmap.put(CharPredicates.ASCII_WORD,  "ASCII.WORD");
-        pmap.put(CharPredicates.ASCII_SPACE, "ASCII.SPACE");
+        pmap.put(CharPredicates.ASCII_DIGIT(), "ASCII.DIGIT");
+        pmap.put(CharPredicates.ASCII_WORD(),  "ASCII.WORD");
+        pmap.put(CharPredicates.ASCII_SPACE(), "ASCII.SPACE");
     }
 
     static void walk(Pattern.Node node, int depth) {
--- a/src/java.base/share/classes/java/util/spi/ResourceBundleControlProvider.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/java/util/spi/ResourceBundleControlProvider.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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,19 +35,19 @@
  * no {@link java.util.ResourceBundle.Control} instance can be modified with {@code
  * ResourceBundleControlProvider} implementations.
  *
+ * <p>Provider implementations are loaded from the application's class path
+ * using {@link java.util.ServiceLoader} at the first invocation of the
+ * {@code ResourceBundle.getBundle} factory method that takes no
+ * {@link java.util.ResourceBundle.Control} instance.
+ *
+ * <p>All {@code ResourceBundleControlProvider}s are ignored in named modules.
+ *
  * @author Masayoshi Okutsu
  * @since 1.8
  * @see ResourceBundle#getBundle(String, java.util.Locale, ClassLoader, ResourceBundle.Control)
  *      ResourceBundle.getBundle
- * @see java.util.ServiceLoader#loadInstalled(Class)
- * @deprecated There is no longer any mechanism to install a custom
- * {@code ResourceBundleControlProvider} implementation defined
- * by the platform class loader or its ancestor. The recommended
- * way to use a custom {@code Control} implementation to load resource bundle
- * is to use {@link java.util.ResourceBundle#getBundle(String, Control)}
- * or other factory methods that take custom {@link java.util.ResourceBundle.Control}.
+ * @see java.util.ServiceLoader#load(Class)
  */
-@Deprecated(since="9", forRemoval=true)
 public interface ResourceBundleControlProvider {
     /**
      * Returns a {@code ResourceBundle.Control} instance that is used
--- a/src/java.base/share/classes/javax/net/ssl/HandshakeCompletedEvent.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/javax/net/ssl/HandshakeCompletedEvent.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -159,11 +159,10 @@
      * @exception SSLPeerUnverifiedException if the peer is not verified.
      * @see #getPeerPrincipal()
      * @deprecated The {@link #getPeerCertificates()} method that returns an
-     *          array of {@code java.security.cert.Certificate} should
-     *          be used instead.  This method is subject to removal in
-     *          a future version of Java SE.
+     *               array of {@code java.security.cert.Certificate} should
+     *               be used instead.
      */
-    @Deprecated(since="9", forRemoval=true)
+    @Deprecated(since="9")
     public javax.security.cert.X509Certificate [] getPeerCertificateChain()
             throws SSLPeerUnverifiedException
     {
--- a/src/java.base/share/classes/javax/net/ssl/SSLSession.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/javax/net/ssl/SSLSession.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -279,11 +279,10 @@
      *          has not been verified
      * @see #getPeerPrincipal()
      * @deprecated The {@link #getPeerCertificates()} method that returns an
-     *          array of {@code java.security.cert.Certificate} should
-     *          be used instead.  This method is subject to removal in
-     *          a future version of Java SE.
+     *               array of {@code java.security.cert.Certificate} should
+     *               be used instead.
      */
-    @Deprecated(since="9", forRemoval=true)
+    @Deprecated(since="9")
     public javax.security.cert.X509Certificate [] getPeerCertificateChain()
             throws SSLPeerUnverifiedException;
 
--- a/src/java.base/share/classes/javax/security/auth/Policy.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/javax/security/auth/Policy.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, 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
@@ -152,11 +152,10 @@
  *
  * These two APIs provide callers the means to query the
  * Policy for Principal-based Permission entries.
- * This class is subject to removal in a future version of Java SE.
  *
  * @see java.security.Security security properties
  */
-@Deprecated(since="1.4", forRemoval=true)
+@Deprecated(since="1.4")
 public abstract class Policy {
 
     private static Policy policy;
--- a/src/java.base/share/classes/javax/security/cert/Certificate.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/javax/security/cert/Certificate.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -58,11 +58,10 @@
  * @since 1.4
  * @see X509Certificate
  * @deprecated Use the classes in {@code java.security.cert} instead.
- *      This class is subject to removal in a future version of Java SE.
  *
  * @author Hemma Prafullchandra
  */
-@Deprecated(since="9", forRemoval=true)
+@Deprecated(since="9")
 public abstract class Certificate {
 
     /**
--- a/src/java.base/share/classes/javax/security/cert/CertificateEncodingException.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/javax/security/cert/CertificateEncodingException.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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,9 +39,8 @@
  * @since 1.4
  * @author Hemma Prafullchandra
  * @deprecated Use the classes in {@code java.security.cert} instead.
- *      This class is subject to removal in a future version of Java SE.
  */
-@Deprecated(since="9", forRemoval=true)
+@Deprecated(since="9")
 public class CertificateEncodingException extends CertificateException {
 
     private static final long serialVersionUID = -8187642723048403470L;
--- a/src/java.base/share/classes/javax/security/cert/CertificateException.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/javax/security/cert/CertificateException.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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,9 +39,8 @@
  * @since 1.4
  * @see Certificate
  * @deprecated Use the classes in {@code java.security.cert} instead.
- *      This class is subject to removal in a future version of Java SE.
  */
-@Deprecated(since="9", forRemoval=true)
+@Deprecated(since="9")
 public class CertificateException extends Exception {
 
     private static final long serialVersionUID = -5757213374030785290L;
--- a/src/java.base/share/classes/javax/security/cert/CertificateExpiredException.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/javax/security/cert/CertificateExpiredException.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,9 +41,8 @@
  * @since 1.4
  * @author Hemma Prafullchandra
  * @deprecated Use the classes in {@code java.security.cert} instead.
- *      This class is subject to removal in a future version of Java SE.
  */
-@Deprecated(since="9", forRemoval=true)
+@Deprecated(since="9")
 public class CertificateExpiredException extends CertificateException {
 
     private static final long serialVersionUID = 5091601212177261883L;
--- a/src/java.base/share/classes/javax/security/cert/CertificateNotYetValidException.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/javax/security/cert/CertificateNotYetValidException.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,9 +41,8 @@
  * @since 1.4
  * @author Hemma Prafullchandra
  * @deprecated Use the classes in {@code java.security.cert} instead.
- *      This class is subject to removal in a future version of Java SE.
  */
-@Deprecated(since="9", forRemoval=true)
+@Deprecated(since="9")
 public class CertificateNotYetValidException extends CertificateException {
 
     private static final long serialVersionUID = -8976172474266822818L;
--- a/src/java.base/share/classes/javax/security/cert/CertificateParsingException.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/javax/security/cert/CertificateParsingException.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -40,9 +40,8 @@
  * @since 1.4
  * @author Hemma Prafullchandra
  * @deprecated Use the classes in {@code java.security.cert} instead.
- *      This class is subject to removal in a future version of Java SE.
  */
-@Deprecated(since="9", forRemoval=true)
+@Deprecated(since="9")
 public class CertificateParsingException extends CertificateException {
 
     private static final long serialVersionUID = -8449352422951136229L;
--- a/src/java.base/share/classes/javax/security/cert/X509Certificate.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/javax/security/cert/X509Certificate.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -125,9 +125,8 @@
  * @see java.security.cert.X509Extension
  * @see java.security.Security security properties
  * @deprecated Use the classes in {@code java.security.cert} instead.
- *      This class is subject to removal in a future version of Java SE.
  */
-@Deprecated(since="9", forRemoval=true)
+@Deprecated(since="9")
 public abstract class X509Certificate extends Certificate {
 
     /*
--- a/src/java.base/share/classes/module-info.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/module-info.java	Mon Feb 06 09:34:19 2017 -0800
@@ -150,7 +150,7 @@
         java.desktop;
     exports jdk.internal.module to
         java.instrument,
-        java.management,
+        java.management.rmi,
         jdk.jartool,
         jdk.jlink;
     exports jdk.internal.misc to
@@ -177,7 +177,8 @@
     exports jdk.internal.perf to
         java.desktop,
         java.management,
-        jdk.jvmstat;
+        jdk.management.agent,
+        jdk.internal.jvmstat;
     exports jdk.internal.ref to
         java.desktop,
         jdk.unsupported;
@@ -196,8 +197,8 @@
         jdk.jdeps,
         jdk.jlink;
     exports jdk.internal.vm to
-        java.management,
-        jdk.jvmstat;
+        jdk.management.agent,
+        jdk.internal.jvmstat;
     exports sun.net to
         jdk.incubator.httpclient;
     exports sun.net.ext to
@@ -233,6 +234,7 @@
         java.desktop,
         java.datatransfer,
         java.management,
+        java.management.rmi,
         java.rmi,
         java.sql.rowset,
         java.xml,
--- a/src/java.base/share/classes/sun/launcher/LauncherHelper.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/sun/launcher/LauncherHelper.java	Mon Feb 06 09:34:19 2017 -0800
@@ -581,12 +581,18 @@
         }
 
         // load the class from the module
-        Class<?> c = Class.forName(m, mainClass);
-        if (c == null &&  System.getProperty("os.name", "").contains("OS X")
-                && Normalizer.isNormalized(mainClass, Normalizer.Form.NFD)) {
+        Class<?> c = null;
+        try {
+            c = Class.forName(m, mainClass);
+            if (c == null && System.getProperty("os.name", "").contains("OS X")
+                    && Normalizer.isNormalized(mainClass, Normalizer.Form.NFD)) {
 
-            String cn = Normalizer.normalize(mainClass, Normalizer.Form.NFC);
-            c = Class.forName(m, cn);
+                String cn = Normalizer.normalize(mainClass, Normalizer.Form.NFC);
+                c = Class.forName(m, cn);
+            }
+        } catch (LinkageError le) {
+            abort(null, "java.launcher.module.error3",
+                    mainClass, m.getName(), le.getLocalizedMessage());
         }
         if (c == null) {
             abort(null, "java.launcher.module.error2", mainClass, mainModule);
@@ -619,23 +625,27 @@
         Class<?> mainClass = null;
         ClassLoader scl = ClassLoader.getSystemClassLoader();
         try {
-            mainClass = Class.forName(cn, false, scl);
-        } catch (NoClassDefFoundError | ClassNotFoundException cnfe) {
-            if (System.getProperty("os.name", "").contains("OS X")
-                    && Normalizer.isNormalized(cn, Normalizer.Form.NFD)) {
-                try {
-                    // On Mac OS X since all names with diacritical marks are
-                    // given as decomposed it is possible that main class name
-                    // comes incorrectly from the command line and we have
-                    // to re-compose it
-                    String ncn = Normalizer.normalize(cn, Normalizer.Form.NFC);
-                    mainClass = Class.forName(ncn, false, scl);
-                } catch (NoClassDefFoundError | ClassNotFoundException cnfe1) {
+            try {
+                mainClass = Class.forName(cn, false, scl);
+            } catch (NoClassDefFoundError | ClassNotFoundException cnfe) {
+                if (System.getProperty("os.name", "").contains("OS X")
+                        && Normalizer.isNormalized(cn, Normalizer.Form.NFD)) {
+                    try {
+                        // On Mac OS X since all names with diacritical marks are
+                        // given as decomposed it is possible that main class name
+                        // comes incorrectly from the command line and we have
+                        // to re-compose it
+                        String ncn = Normalizer.normalize(cn, Normalizer.Form.NFC);
+                        mainClass = Class.forName(ncn, false, scl);
+                    } catch (NoClassDefFoundError | ClassNotFoundException cnfe1) {
+                        abort(cnfe1, "java.launcher.cls.error1", cn);
+                    }
+                } else {
                     abort(cnfe, "java.launcher.cls.error1", cn);
                 }
-            } else {
-                abort(cnfe, "java.launcher.cls.error1", cn);
             }
+        } catch (LinkageError le) {
+            abort(le, "java.launcher.cls.error6", cn, le.getLocalizedMessage());
         }
         return mainClass;
     }
--- a/src/java.base/share/classes/sun/launcher/resources/launcher.properties	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/sun/launcher/resources/launcher.properties	Mon Feb 06 09:34:19 2017 -0800
@@ -189,6 +189,9 @@
     or a JavaFX application class must extend {1}
 java.launcher.cls.error5=\
     Error: JavaFX runtime components are missing, and are required to run this application
+java.launcher.cls.error6=\
+    Error: LinkageError occurred while loading main class {0}\n\
+    \t{1}
 java.launcher.jar.error1=\
     Error: An unexpected error occurred while trying to open file {0}
 java.launcher.jar.error2=manifest not found in {0}
@@ -201,3 +204,7 @@
     module {0} does not have a MainClass attribute, use -m <module>/<main-class>
 java.launcher.module.error2=\
     Error: Could not find or load main class {0} in module {1}
+java.launcher.module.error3=\
+    Error: Unable to load main class {0} from module {1}\n\
+    \t{2}
+
--- a/src/java.base/share/classes/sun/net/spi/DefaultProxySelector.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/sun/net/spi/DefaultProxySelector.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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,16 +30,19 @@
 import java.net.ProxySelector;
 import java.net.SocketAddress;
 import java.net.URI;
-import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.io.IOException;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.StringJoiner;
 import java.util.regex.Pattern;
+import java.util.stream.Stream;
 import sun.net.NetProperties;
 import sun.net.SocksProxy;
 import static java.util.regex.Pattern.quote;
+import static java.util.stream.Collectors.collectingAndThen;
+import static java.util.stream.Collectors.toList;
 
 /**
  * Supports proxy settings using system properties This proxy selector
@@ -87,6 +90,8 @@
 
     private static boolean hasSystemProxies = false;
 
+    private static final List<Proxy> NO_PROXY_LIST = List.of(Proxy.NO_PROXY);
+
     static {
         final String key = "java.net.useSystemProxies";
         Boolean b = AccessController.doPrivileged(
@@ -149,8 +154,9 @@
      * select() method. Where all the hard work is done.
      * Build a list of proxies depending on URI.
      * Since we're only providing compatibility with the system properties
-     * from previous releases (see list above), that list will always
-     * contain 1 single proxy, default being NO_PROXY.
+     * from previous releases (see list above), that list will typically
+     * contain one single proxy, default being NO_PROXY.
+     * If we can get a system proxy it might contain more entries.
      */
     public java.util.List<Proxy> select(URI uri) {
         if (uri == null) {
@@ -185,7 +191,6 @@
         if (protocol == null || host == null) {
             throw new IllegalArgumentException("protocol = "+protocol+" host = "+host);
         }
-        List<Proxy> proxyl = new ArrayList<Proxy>(1);
 
         NonProxyInfo pinfo = null;
 
@@ -214,9 +219,9 @@
          * System properties it does help having only 1 call to doPrivileged.
          * Be mindful what you do in here though!
          */
-        Proxy p = AccessController.doPrivileged(
-            new PrivilegedAction<Proxy>() {
-                public Proxy run() {
+        Proxy[] proxyArray = AccessController.doPrivileged(
+            new PrivilegedAction<Proxy[]>() {
+                public Proxy[] run() {
                     int i, j;
                     String phost =  null;
                     int pport = 0;
@@ -239,8 +244,8 @@
                                 /**
                                  * No system property defined for that
                                  * protocol. Let's check System Proxy
-                                 * settings (Gnome & Windows) if we were
-                                 * instructed to.
+                                 * settings (Gnome, MacOsX & Windows) if
+                                 * we were instructed to.
                                  */
                                 if (hasSystemProxies) {
                                     String sproto;
@@ -248,12 +253,9 @@
                                         sproto = "socks";
                                     else
                                         sproto = proto;
-                                    Proxy sproxy = getSystemProxy(sproto, urlhost);
-                                    if (sproxy != null) {
-                                        return sproxy;
-                                    }
+                                    return getSystemProxies(sproto, urlhost);
                                 }
-                                return Proxy.NO_PROXY;
+                                return null;
                             }
                             // If a Proxy Host is defined for that protocol
                             // Let's get the NonProxyHosts property
@@ -281,7 +283,7 @@
                                         }
                                     }
                                     if (shouldNotUseProxyFor(nprop.pattern, urlhost)) {
-                                        return Proxy.NO_PROXY;
+                                        return null;
                                     }
                                 }
                             }
@@ -311,22 +313,24 @@
                             saddr = InetSocketAddress.createUnresolved(phost, pport);
                             // Socks is *always* the last on the list.
                             if (j == (props[i].length - 1)) {
-                                return SocksProxy.create(saddr, socksProxyVersion());
-                            } else {
-                                return new Proxy(Proxy.Type.HTTP, saddr);
+                                return new Proxy[] {SocksProxy.create(saddr, socksProxyVersion())};
                             }
+                            return new Proxy[] {new Proxy(Proxy.Type.HTTP, saddr)};
                         }
                     }
-                    return Proxy.NO_PROXY;
+                    return null;
                 }});
 
-        proxyl.add(p);
 
-        /*
-         * If no specific property was set for that URI, we should be
-         * returning an iterator to an empty List.
-         */
-        return proxyl;
+        if (proxyArray != null) {
+            // Remove duplicate entries, while preserving order.
+            return Stream.of(proxyArray).distinct().collect(
+                    collectingAndThen(toList(), Collections::unmodifiableList));
+        }
+
+        // If no specific proxy was found, return a standard list containing
+        // only one NO_PROXY entry.
+        return NO_PROXY_LIST;
     }
 
     public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
@@ -354,7 +358,7 @@
     }
 
     private static native boolean init();
-    private synchronized native Proxy getSystemProxy(String protocol, String host);
+    private synchronized native Proxy[] getSystemProxies(String protocol, String host);
 
     /**
      * @return {@code true} if given this pattern for non-proxy hosts and this
--- a/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, 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
@@ -982,7 +982,7 @@
             new CertEntry((X509Certificate) cert, null, alias, AnyUsage,
                 attributes);
         certificateCount++;
-        entries.put(alias, certEntry);
+        entries.put(alias.toLowerCase(Locale.ENGLISH), certEntry);
 
         if (debug != null) {
             debug.println("Setting a trusted certificate at alias '" + alias +
--- a/src/java.base/share/classes/sun/util/locale/provider/CalendarNameProviderImpl.java	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/classes/sun/util/locale/provider/CalendarNameProviderImpl.java	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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,8 @@
 import java.util.Set;
 import java.util.TreeMap;
 import java.util.spi.CalendarNameProvider;
+import sun.util.calendar.CalendarSystem;
+import sun.util.calendar.Era;
 
 /**
  * Concrete implementation of the  {@link java.util.spi.CalendarDataProvider
@@ -75,7 +77,21 @@
                 if (field == DAY_OF_WEEK || field == YEAR) {
                     --value;
                 }
-                if (value < 0 || value >= strings.length) {
+                if (value < 0 || value > strings.length) {
+                    return null;
+                } else if (value == strings.length) {
+                    if (field == ERA && "japanese".equals(calendarType)) {
+                        // get the supplemental era, if any, specified through
+                        // the property "jdk.calendar.japanese.supplemental.era"
+                        // which is always the last element.
+                        Era[] jeras = CalendarSystem.forName("japanese").getEras();
+                        if (jeras.length == value) {
+                            Era supEra = jeras[value - 1]; // 0-based index
+                            return style == LONG ?
+                                supEra.getName() :
+                                supEra.getAbbreviation();
+                        }
+                    }
                     return null;
                 }
                 name = strings[value];
--- a/src/java.base/share/native/include/jvm.h	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/native/include/jvm.h	Mon Feb 06 09:34:19 2017 -0800
@@ -401,30 +401,67 @@
  * Module support funcions
  */
 
+/*
+ * Define a module with the specified packages and bind the module to the
+ * given class loader.
+ *  module:       module to define
+ *  is_open:      specifies if module is open (currently ignored)
+ *  version:      the module version
+ *  location:     the module location
+ *  packages:     list of packages in the module
+ *  num_packages: number of packages in the module
+ */
 JNIEXPORT void JNICALL
 JVM_DefineModule(JNIEnv *env, jobject module, jboolean is_open, jstring version,
-                 jstring location, jobjectArray packages);
+                 jstring location, const char* const* packages, jsize num_packages);
 
+/*
+ * Set the boot loader's unnamed module.
+ *  module: boot loader's unnamed module
+ */
 JNIEXPORT void JNICALL
 JVM_SetBootLoaderUnnamedModule(JNIEnv *env, jobject module);
 
+/*
+ * Do a qualified export of a package.
+ *  from_module: module containing the package to export
+ *  package:     name of the package to export
+ *  to_module:   module to export the package to
+ */
 JNIEXPORT void JNICALL
-JVM_AddReadsModule(JNIEnv *env, jobject from_module, jobject to_module);
+JVM_AddModuleExports(JNIEnv *env, jobject from_module, const char* package, jobject to_module);
 
+/*
+ * Do an export of a package to all unnamed modules.
+ *  from_module: module containing the package to export
+ *  package:     name of the package to export to all unnamed modules
+ */
 JNIEXPORT void JNICALL
-JVM_AddModuleExports(JNIEnv *env, jobject from_module, jstring package, jobject to_module);
+JVM_AddModuleExportsToAllUnnamed(JNIEnv *env, jobject from_module, const char* package);
 
+/*
+ * Do an unqualified export of a package.
+ *  from_module: module containing the package to export
+ *  package:     name of the package to export
+ */
 JNIEXPORT void JNICALL
-JVM_AddModuleExportsToAll(JNIEnv *env, jobject from_module, jstring package);
+JVM_AddModuleExportsToAll(JNIEnv *env, jobject from_module, const char* package);
 
+/*
+ * Add a module to the list of modules that a given module can read.
+ *  from_module:   module requesting read access
+ *  source_module: module that from_module wants to read
+ */
 JNIEXPORT void JNICALL
-JVM_AddModuleExportsToAllUnnamed(JNIEnv *env, jobject from_module, jstring package);
+JVM_AddReadsModule(JNIEnv *env, jobject from_module, jobject source_module);
 
+/*
+ * Add a package to a module.
+ *  module:  module that will contain the package
+ *  package: package to add to the module
+ */
 JNIEXPORT void JNICALL
-JVM_AddModulePackage(JNIEnv* env,  jobject module, jstring package);
-
-JNIEXPORT jobject JNICALL
-JVM_GetModuleByPackageName(JNIEnv *env, jobject cl, jstring pkg);
+JVM_AddModulePackage(JNIEnv* env,  jobject module, const char* package);
 
 /*
  * Reflection support functions
--- a/src/java.base/share/native/libjava/Module.c	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/native/libjava/Module.c	Mon Feb 06 09:34:19 2017 -0800
@@ -22,18 +22,88 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+#include <stdlib.h>
+#include <string.h>
 
 #include "jni.h"
+#include "jni_util.h"
 #include "jvm.h"
 
 #include "java_lang_reflect_Module.h"
 
+/*
+ * Gets the UTF-8 chars for the string and translates '.' to '/'.  Does no
+ * further validation, assumption being that both calling code in
+ * java.lang.reflect.Module and VM will do deeper validation.
+ */
+static char*
+GetInternalPackageName(JNIEnv *env, jstring pkg, char* buf, jsize buf_size)
+{
+    jsize len;
+    jsize unicode_len;
+    char* p;
+    char* utf_str;
+
+    len = (*env)->GetStringUTFLength(env, pkg);
+    unicode_len = (*env)->GetStringLength(env, pkg);
+    if (len >= buf_size) {
+        utf_str = malloc(len + 1);
+        if (utf_str == NULL) {
+            JNU_ThrowOutOfMemoryError(env, NULL);
+            return NULL;
+        }
+    } else {
+        utf_str = buf;
+    }
+    (*env)->GetStringUTFRegion(env, pkg, 0, unicode_len, utf_str);
+
+    p = utf_str;
+    while (*p != '\0') {
+        if (*p == '.') {
+            *p = '/';
+        }
+        p++;
+    }
+    return utf_str;
+}
+
 JNIEXPORT void JNICALL
 Java_java_lang_reflect_Module_defineModule0(JNIEnv *env, jclass cls, jobject module,
                                             jboolean is_open, jstring version,
                                             jstring location, jobjectArray packages)
 {
-    JVM_DefineModule(env, module, is_open, version, location, packages);
+    char** pkgs = NULL;
+    jsize idx;
+    jsize num_packages = (*env)->GetArrayLength(env, packages);
+
+    if (num_packages != 0 && (pkgs = calloc(num_packages, sizeof(char*))) == NULL) {
+        JNU_ThrowOutOfMemoryError(env, NULL);
+        return;
+    } else {
+        int valid = 1;
+        for (idx = 0; idx < num_packages; idx++) {
+            jstring pkg = (*env)->GetObjectArrayElement(env, packages, idx);
+            pkgs[idx] = GetInternalPackageName(env, pkg, NULL, 0);
+            if (pkgs[idx] == NULL) {
+                valid = 0;
+                break;
+            }
+        }
+
+        if (valid != 0) {
+            JVM_DefineModule(env, module, is_open, version, location,
+                    (const char* const*)pkgs, num_packages);
+        }
+    }
+
+    if (num_packages > 0) {
+        for (idx = 0; idx < num_packages; idx++) {
+            if (pkgs[idx] != NULL) {
+                free(pkgs[idx]);
+            }
+        }
+        free(pkgs);
+    }
 }
 
 JNIEXPORT void JNICALL
@@ -46,25 +116,81 @@
 Java_java_lang_reflect_Module_addExports0(JNIEnv *env, jclass cls, jobject from,
                                           jstring pkg, jobject to)
 {
-    JVM_AddModuleExports(env, from, pkg, to);
+    char buf[128];
+    char* pkg_name;
+
+    if (pkg == NULL) {
+        JNU_ThrowNullPointerException(env, "package is null");
+        return;
+    }
+
+    pkg_name = GetInternalPackageName(env, pkg, buf, (jsize)sizeof(buf));
+    if (pkg_name != NULL) {
+        JVM_AddModuleExports(env, from, pkg_name, to);
+        if (pkg_name != buf) {
+            free(pkg_name);
+        }
+    }
 }
 
 JNIEXPORT void JNICALL
 Java_java_lang_reflect_Module_addExportsToAll0(JNIEnv *env, jclass cls, jobject from,
                                                jstring pkg)
 {
-    JVM_AddModuleExportsToAll(env, from, pkg);
+    char buf[128];
+    char* pkg_name;
+
+    if (pkg == NULL) {
+        JNU_ThrowNullPointerException(env, "package is null");
+        return;
+    }
+
+    pkg_name = GetInternalPackageName(env, pkg, buf, (jsize)sizeof(buf));
+    if (pkg_name != NULL) {
+        JVM_AddModuleExportsToAll(env, from, pkg_name);
+        if (pkg_name != buf) {
+            free(pkg_name);
+        }
+    }
 }
 
 JNIEXPORT void JNICALL
 Java_java_lang_reflect_Module_addExportsToAllUnnamed0(JNIEnv *env, jclass cls,
                                                       jobject from, jstring pkg)
 {
-    JVM_AddModuleExportsToAllUnnamed(env, from, pkg);
+    char buf[128];
+    char* pkg_name;
+
+    if (pkg == NULL) {
+        JNU_ThrowNullPointerException(env, "package is null");
+        return;
+    }
+
+    pkg_name = GetInternalPackageName(env, pkg, buf, (jsize)sizeof(buf));
+    if (pkg_name != NULL) {
+        JVM_AddModuleExportsToAllUnnamed(env, from, pkg_name);
+        if (pkg_name != buf) {
+            free(pkg_name);
+        }
+    }
 }
 
 JNIEXPORT void JNICALL
 Java_java_lang_reflect_Module_addPackage0(JNIEnv *env, jclass cls, jobject m, jstring pkg)
 {
-    JVM_AddModulePackage(env, m, pkg);
+    char buf[128];
+    char* pkg_name;
+
+    if (pkg == NULL) {
+        JNU_ThrowNullPointerException(env, "package is null");
+        return;
+    }
+
+    pkg_name = GetInternalPackageName(env, pkg, buf, (jsize)sizeof(buf));
+    if (pkg_name != NULL) {
+        JVM_AddModulePackage(env, m, pkg_name);
+        if (pkg_name != buf) {
+            free(pkg_name);
+        }
+    }
 }
--- a/src/java.base/share/native/libjli/args.c	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/native/libjli/args.c	Mon Feb 06 09:34:19 2017 -0800
@@ -429,6 +429,10 @@
 }
 
 jboolean JLI_AddArgsFromEnvVar(JLI_List args, const char *var_name) {
+
+#ifndef ENABLE_JAVA_OPTIONS
+    return JNI_FALSE;
+#else
     char *env = getenv(var_name);
     char *p, *arg;
     char quote;
@@ -515,6 +519,7 @@
     }
 
     return JNI_TRUE;
+#endif
 }
 
 #ifdef DEBUG_ARGFILE
--- a/src/java.base/share/native/libjli/java.c	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/share/native/libjli/java.c	Mon Feb 06 09:34:19 2017 -0800
@@ -1587,7 +1587,7 @@
     p = JLI_MemAlloc(optLen + valueLen + 1);
     memcpy(p, arg, optLen);
     memcpy(p + optLen, value, valueLen);
-    p[optLen + valueLen + 1] = '\0';
+    p[optLen + valueLen] = '\0';
     return p;
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/native/libnet/proxy_util.c	Mon Feb 06 09:34:19 2017 -0800
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+
+#include "proxy_util.h"
+
+jclass proxy_class;
+jclass isaddr_class;
+jclass ptype_class;
+jmethodID isaddr_createUnresolvedID;
+jmethodID proxy_ctrID;
+jfieldID pr_no_proxyID;
+jfieldID ptype_httpID;
+jfieldID ptype_socksID;
+
+int initJavaClass(JNIEnv *env) {
+    jclass proxy_cls = NULL;
+    jclass ptype_cls = NULL;
+    jclass isaddr_cls = NULL;
+
+    // Proxy initialization
+    proxy_cls = (*env)->FindClass(env,"java/net/Proxy");
+    CHECK_NULL_RETURN(proxy_cls, 0);
+    proxy_class = (*env)->NewGlobalRef(env, proxy_cls);
+    CHECK_NULL_RETURN(proxy_class, 0);
+    proxy_ctrID = (*env)->GetMethodID(env, proxy_class, "<init>",
+            "(Ljava/net/Proxy$Type;Ljava/net/SocketAddress;)V");
+    CHECK_NULL_RETURN(proxy_ctrID, 0);
+
+    // Proxy$Type initialization
+    ptype_cls = (*env)->FindClass(env,"java/net/Proxy$Type");
+    CHECK_NULL_RETURN(ptype_cls, 0);
+    ptype_class = (*env)->NewGlobalRef(env, ptype_cls);
+    CHECK_NULL_RETURN(ptype_class, 0);
+    ptype_httpID = (*env)->GetStaticFieldID(env, ptype_class, "HTTP",
+                                            "Ljava/net/Proxy$Type;");
+    CHECK_NULL_RETURN(ptype_httpID, 0);
+    ptype_socksID = (*env)->GetStaticFieldID(env, ptype_class, "SOCKS",
+                                             "Ljava/net/Proxy$Type;");
+    CHECK_NULL_RETURN(ptype_socksID, 0);
+
+    // NO_PROXY
+    pr_no_proxyID = (*env)->GetStaticFieldID(env, proxy_class, "NO_PROXY",
+                                             "Ljava/net/Proxy;");
+    CHECK_NULL_RETURN(pr_no_proxyID, 0);
+
+    // InetSocketAddress initialization
+    isaddr_cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
+    CHECK_NULL_RETURN(isaddr_cls, 0);
+    isaddr_class = (*env)->NewGlobalRef(env, isaddr_cls);
+    CHECK_NULL_RETURN(isaddr_class, 0);
+    isaddr_createUnresolvedID = (*env)->GetStaticMethodID(env, isaddr_class,
+            "createUnresolved",
+            "(Ljava/lang/String;I)Ljava/net/InetSocketAddress;");
+
+    return isaddr_createUnresolvedID != NULL ? 1 : 0;
+}
+
+jobject createProxy(JNIEnv *env, jfieldID ptype_ID, const char* phost, unsigned short pport) {
+    jobject jProxy = NULL;
+    jobject type_proxy = NULL;
+    type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_ID);
+    if (type_proxy) {
+        jstring jhost = NULL;
+        jhost = (*env)->NewStringUTF(env, phost);
+        if (jhost) {
+            jobject isa = NULL;
+            isa = (*env)->CallStaticObjectMethod(env, isaddr_class,
+                    isaddr_createUnresolvedID, jhost, pport);
+            if (isa) {
+                jProxy = (*env)->NewObject(env, proxy_class, proxy_ctrID,
+                                          type_proxy, isa);
+            }
+        }
+    }
+    return jProxy;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/native/libnet/proxy_util.h	Mon Feb 06 09:34:19 2017 -0800
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+extern jclass proxy_class;
+extern jclass isaddr_class;
+extern jclass ptype_class;
+extern jmethodID isaddr_createUnresolvedID;
+extern jmethodID proxy_ctrID;
+extern jfieldID pr_no_proxyID;
+extern jfieldID ptype_httpID;
+extern jfieldID ptype_socksID;
+
+int initJavaClass(JNIEnv *env);
+
+jobject createProxy(JNIEnv *env, jfieldID ptype_ID, const char* phost, unsigned short pport);
--- a/src/java.base/unix/native/libnet/DefaultProxySelector.c	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/unix/native/libnet/DefaultProxySelector.c	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2017, 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,24 +23,20 @@
  * questions.
  */
 
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
 #include "jni.h"
 #include "jni_util.h"
 #include "jvm.h"
 #include "jvm_md.h"
-#include "jlong.h"
+
+#include "proxy_util.h"
+
 #include "sun_net_spi_DefaultProxySelector.h"
-#include <dlfcn.h>
-#include <stdio.h>
-#include <stdlib.h>
-#if defined(__linux__) || defined(_ALLBSD_SOURCE)
-#include <string.h>
-#else
-#include <strings.h>
-#endif
 
-#ifndef CHECK_NULL_RETURN
-#define CHECK_NULL_RETURN(x, y) if ((x) == NULL) return y;
-#endif
 
 /**
  * These functions are used by the sun.net.spi.DefaultProxySelector class
@@ -112,43 +108,11 @@
 static g_network_address_get_port_func* g_network_address_get_port = NULL;
 static g_strfreev_func* g_strfreev = NULL;
 
-
-static jclass proxy_class;
-static jclass isaddr_class;
-static jclass ptype_class;
-static jmethodID isaddr_createUnresolvedID;
-static jmethodID proxy_ctrID;
-static jfieldID ptype_httpID;
-static jfieldID ptype_socksID;
-
-
 static void* gconf_client = NULL;
 static int use_gproxyResolver = 0;
 static int use_gconf = 0;
 
 
-static jobject createProxy(JNIEnv *env, jfieldID ptype_ID,
-                           const char* phost, unsigned short pport)
-{
-    jobject jProxy = NULL;
-    jobject type_proxy = NULL;
-    type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_ID);
-    if (type_proxy) {
-        jstring jhost = NULL;
-        jhost = (*env)->NewStringUTF(env, phost);
-        if (jhost) {
-            jobject isa = NULL;
-            isa = (*env)->CallStaticObjectMethod(env, isaddr_class,
-                    isaddr_createUnresolvedID, jhost, pport);
-            if (isa) {
-                jProxy = (*env)->NewObject(env, proxy_class, proxy_ctrID,
-                                          type_proxy, isa);
-            }
-        }
-    }
-    return jProxy;
-}
-
 static int initGConf() {
     /**
      * Let's try to load GConf-2 library
@@ -196,18 +160,18 @@
     return 0;
 }
 
-static jobject getProxyByGConf(JNIEnv *env, const char* cproto,
-                               const char* chost)
+static jobjectArray getProxyByGConf(JNIEnv *env, const char* cproto,
+                                    const char* chost)
 {
     char *phost = NULL;
     char *mode = NULL;
     int pport = 0;
     int use_proxy = 0;
     int use_same_proxy = 0;
-    jobject proxy = NULL;
+    jobjectArray proxy_array = NULL;
     jfieldID ptype_ID = ptype_httpID;
 
-    // We only check manual proxy configurations
+    /* We only check manual proxy configurations */
     mode =  (*my_get_string_func)(gconf_client, "/system/proxy/mode", NULL);
     if (mode && !strcasecmp(mode, "manual")) {
         /*
@@ -293,7 +257,7 @@
         char *s;
 
         /**
-         * check for the exclude list (aka "No Proxy For" list).
+         * Check for the exclude list (aka "No Proxy For" list).
          * It's a list of comma separated suffixes (e.g. domain name).
          */
         noproxyfor = (*my_get_string_func)(gconf_client, "/system/proxy/no_proxy_for", NULL);
@@ -313,11 +277,25 @@
                 s = strtok_r(NULL, ", ", tmpbuf);
             }
         }
-        if (use_proxy)
+        if (use_proxy) {
+            jobject proxy = NULL;
+            /* create a proxy array with one element. */
+            proxy_array = (*env)->NewObjectArray(env, 1, proxy_class, NULL);
+            if (proxy_array == NULL || (*env)->ExceptionCheck(env)) {
+                return NULL;
+            }
             proxy = createProxy(env, ptype_ID, phost, pport);
+            if (proxy == NULL || (*env)->ExceptionCheck(env)) {
+                return NULL;
+            }
+            (*env)->SetObjectArrayElement(env, proxy_array, 0, proxy);
+            if ((*env)->ExceptionCheck(env)) {
+                return NULL;
+            }
+        }
     }
 
-    return proxy;
+    return proxy_array;
 }
 
 static int initGProxyResolver() {
@@ -371,8 +349,8 @@
     return 1;
 }
 
-static jobject getProxyByGProxyResolver(JNIEnv *env, const char* cproto,
-                                        const char* chost)
+static jobjectArray getProxyByGProxyResolver(JNIEnv *env, const char *cproto,
+                                             const char *chost)
 {
     GProxyResolver* resolver = NULL;
     char** proxies = NULL;
@@ -382,19 +360,19 @@
     size_t hostLen = 0;
     char* uri = NULL;
 
-    jobject jProxy = NULL;
+    jobjectArray proxy_array = NULL;
 
     resolver = (*g_proxy_resolver_get_default)();
     if (resolver == NULL) {
         return NULL;
     }
 
-    // Construct the uri, cproto + "://" + chost
+    /* Construct the uri, cproto + "://" + chost */
     protoLen = strlen(cproto);
     hostLen = strlen(chost);
     uri = malloc(protoLen + hostLen + 4);
     if (!uri) {
-        // Out of memory
+        /* Out of memory */
         return NULL;
     }
     memcpy(uri, cproto, protoLen);
@@ -414,22 +392,56 @@
     if (proxies) {
         if (!error) {
             int i;
-            for(i = 0; proxies[i] && !jProxy; i++) {
-                if (strcmp(proxies[i], "direct://")) {
-                    GSocketConnectable* conn =
-                            (*g_network_address_parse_uri)(proxies[i], 0,
-                                                           &error);
-                    if (conn && !error) {
-                        const char* phost = NULL;
-                        unsigned short pport = 0;
-                        phost = (*g_network_address_get_hostname)(conn);
-                        pport = (*g_network_address_get_port)(conn);
-                        if (phost && pport > 0) {
-                            jfieldID ptype_ID = ptype_httpID;
-                            if (!strncmp(proxies[i], "socks", 5))
-                                ptype_ID = ptype_socksID;
+            int nr_proxies = 0;
+            char** p = proxies;
+            /* count the elements in the null terminated string vector. */
+            while (*p) {
+                nr_proxies++;
+                p++;
+            }
+            /* create a proxy array that has to be filled. */
+            proxy_array = (*env)->NewObjectArray(env, nr_proxies, proxy_class, NULL);
+            if (proxy_array != NULL && !(*env)->ExceptionCheck(env)) {
+                for (i = 0; proxies[i]; i++) {
+                    if (strncmp(proxies[i], "direct://", 9)) {
+                        GSocketConnectable* conn =
+                                (*g_network_address_parse_uri)(proxies[i], 0,
+                                                               &error);
+                        if (conn && !error) {
+                            const char *phost = NULL;
+                            unsigned short pport = 0;
+                            phost = (*g_network_address_get_hostname)(conn);
+                            pport = (*g_network_address_get_port)(conn);
+                            if (phost && pport > 0) {
+                                jobject proxy = NULL;
+                                jfieldID ptype_ID = ptype_httpID;
+                                if (!strncmp(proxies[i], "socks", 5))
+                                    ptype_ID = ptype_socksID;
 
-                            jProxy = createProxy(env, ptype_ID, phost, pport);
+                                proxy = createProxy(env, ptype_ID, phost, pport);
+                                if (proxy == NULL || (*env)->ExceptionCheck(env)) {
+                                    proxy_array = NULL;
+                                    break;
+                                }
+                                (*env)->SetObjectArrayElement(env, proxy_array, i, proxy);
+                                if ((*env)->ExceptionCheck(env)) {
+                                    proxy_array = NULL;
+                                    break;
+                                }
+                            }
+                        }
+                    } else {
+                        /* direct connection - no proxy */
+                        jobject proxy = (*env)->GetStaticObjectField(env, proxy_class,
+                                                                     pr_no_proxyID);
+                        if (proxy == NULL || (*env)->ExceptionCheck(env)) {
+                            proxy_array = NULL;
+                            break;
+                        }
+                        (*env)->SetObjectArrayElement(env, proxy_array, i, proxy);
+                        if ((*env)->ExceptionCheck(env)) {
+                            proxy_array = NULL;
+                            break;
                         }
                     }
                 }
@@ -438,48 +450,9 @@
         (*g_strfreev)(proxies);
     }
 
-    return jProxy;
+    return proxy_array;
 }
 
-static int initJavaClass(JNIEnv *env) {
-    jclass proxy_cls = NULL;
-    jclass ptype_cls = NULL;
-    jclass isaddr_cls = NULL;
-
-    // Proxy initialization
-    proxy_cls = (*env)->FindClass(env,"java/net/Proxy");
-    CHECK_NULL_RETURN(proxy_cls, 0);
-    proxy_class = (*env)->NewGlobalRef(env, proxy_cls);
-    CHECK_NULL_RETURN(proxy_class, 0);
-    proxy_ctrID = (*env)->GetMethodID(env, proxy_class, "<init>",
-            "(Ljava/net/Proxy$Type;Ljava/net/SocketAddress;)V");
-    CHECK_NULL_RETURN(proxy_ctrID, 0);
-
-    // Proxy$Type initialization
-    ptype_cls = (*env)->FindClass(env,"java/net/Proxy$Type");
-    CHECK_NULL_RETURN(ptype_cls, 0);
-    ptype_class = (*env)->NewGlobalRef(env, ptype_cls);
-    CHECK_NULL_RETURN(ptype_class, 0);
-    ptype_httpID = (*env)->GetStaticFieldID(env, ptype_class, "HTTP",
-                                            "Ljava/net/Proxy$Type;");
-    CHECK_NULL_RETURN(ptype_httpID, 0);
-    ptype_socksID = (*env)->GetStaticFieldID(env, ptype_class, "SOCKS",
-                                             "Ljava/net/Proxy$Type;");
-    CHECK_NULL_RETURN(ptype_socksID, 0);
-
-    // InetSocketAddress initialization
-    isaddr_cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
-    CHECK_NULL_RETURN(isaddr_cls, 0);
-    isaddr_class = (*env)->NewGlobalRef(env, isaddr_cls);
-    CHECK_NULL_RETURN(isaddr_class, 0);
-    isaddr_createUnresolvedID = (*env)->GetStaticMethodID(env, isaddr_class,
-            "createUnresolved",
-            "(Ljava/lang/String;I)Ljava/net/InetSocketAddress;");
-
-    return isaddr_createUnresolvedID != NULL ? 1 : 0;
-}
-
-
 /*
  * Class:     sun_net_spi_DefaultProxySelector
  * Method:    init
@@ -500,14 +473,14 @@
 
 /*
  * Class:     sun_net_spi_DefaultProxySelector
- * Method:    getSystemProxy
- * Signature: ([Ljava/lang/String;Ljava/lang/String;)Ljava/net/Proxy;
+ * Method:    getSystemProxies
+ * Signature: ([Ljava/lang/String;Ljava/lang/String;)[Ljava/net/Proxy;
  */
-JNIEXPORT jobject JNICALL
-Java_sun_net_spi_DefaultProxySelector_getSystemProxy(JNIEnv *env,
-                                                     jobject this,
-                                                     jstring proto,
-                                                     jstring host)
+JNIEXPORT jobjectArray JNICALL
+Java_sun_net_spi_DefaultProxySelector_getSystemProxies(JNIEnv *env,
+                                                       jobject this,
+                                                       jstring proto,
+                                                       jstring host)
 {
     const char* cproto;
     const char* chost;
@@ -515,7 +488,7 @@
     jboolean isProtoCopy;
     jboolean isHostCopy;
 
-    jobject proxy = NULL;
+    jobjectArray proxyArray = NULL;
 
     cproto = (*env)->GetStringUTFChars(env, proto, &isProtoCopy);
 
@@ -523,16 +496,15 @@
         chost = (*env)->GetStringUTFChars(env, host, &isHostCopy);
         if (chost != NULL) {
             if (use_gproxyResolver)
-                proxy = getProxyByGProxyResolver(env, cproto, chost);
+                proxyArray = getProxyByGProxyResolver(env, cproto, chost);
             else if (use_gconf)
-                proxy = getProxyByGConf(env, cproto, chost);
-
+                proxyArray = getProxyByGConf(env, cproto, chost);
             if (isHostCopy == JNI_TRUE)
                 (*env)->ReleaseStringUTFChars(env, host, chost);
         }
         if (isProtoCopy == JNI_TRUE)
             (*env)->ReleaseStringUTFChars(env, proto, cproto);
     }
-    return proxy;
+    return proxyArray;
 }
 
--- a/src/java.base/windows/native/libnet/DefaultProxySelector.c	Mon Feb 06 09:32:41 2017 -0800
+++ b/src/java.base/windows/native/libnet/DefaultProxySelector.c	Mon Feb 06 09:34:19 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2017, 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,26 +24,24 @@
  */
 
 #include <windows.h>
+#include <Winhttp.h>
+
 #include "jni.h"
 #include "jni_util.h"
 #include "jvm.h"
-#include "jlong.h"
+
+#include "proxy_util.h"
+
 #include "sun_net_spi_DefaultProxySelector.h"
 
-/**
+/*
  * These functions are used by the sun.net.spi.DefaultProxySelector class
  * to access some platform specific settings.
- * This is the Windows code using the registry settings.
+ * On Windows use WinHTTP functions to get the system settings.
  */
 
-static jclass proxy_class;
-static jclass isaddr_class;
-static jclass ptype_class;
-static jmethodID isaddr_createUnresolvedID;
-static jmethodID proxy_ctrID;
-static jfieldID pr_no_proxyID;
-static jfieldID ptype_httpID;
-static jfieldID ptype_socksID;
+/* Keep one static session for all requests. */
+static HINTERNET session = NULL;
 
 /*
  * Class:     sun_net_spi_DefaultProxySelector
@@ -52,233 +50,327 @@
  */
 JNIEXPORT jboolean JNICALL
 Java_sun_net_spi_DefaultProxySelector_init(JNIEnv *env, jclass clazz) {
-  HKEY hKey;
-  LONG ret;
-  jclass cls;
 
-  /**
-   * Get all the method & field IDs for later use.
-   */
-  cls = (*env)->FindClass(env,"java/net/Proxy");
-  CHECK_NULL_RETURN(cls, JNI_FALSE);
-  proxy_class = (*env)->NewGlobalRef(env, cls);
-  CHECK_NULL_RETURN(proxy_class, JNI_FALSE);
-  cls = (*env)->FindClass(env,"java/net/Proxy$Type");
-  CHECK_NULL_RETURN(cls, JNI_FALSE);
-  ptype_class = (*env)->NewGlobalRef(env, cls);
-  CHECK_NULL_RETURN(ptype_class, JNI_FALSE);
-  cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
-  CHECK_NULL_RETURN(cls, JNI_FALSE);
-  isaddr_class = (*env)->NewGlobalRef(env, cls);
-  CHECK_NULL_RETURN(isaddr_class, JNI_FALSE);
-  proxy_ctrID = (*env)->GetMethodID(env, proxy_class, "<init>",
-                                    "(Ljava/net/Proxy$Type;Ljava/net/SocketAddress;)V");
-  CHECK_NULL_RETURN(proxy_ctrID, JNI_FALSE);
-  pr_no_proxyID = (*env)->GetStaticFieldID(env, proxy_class, "NO_PROXY", "Ljava/net/Proxy;");
-  CHECK_NULL_RETURN(pr_no_proxyID, JNI_FALSE);
-  ptype_httpID = (*env)->GetStaticFieldID(env, ptype_class, "HTTP", "Ljava/net/Proxy$Type;");
-  CHECK_NULL_RETURN(ptype_httpID, JNI_FALSE);
-  ptype_socksID = (*env)->GetStaticFieldID(env, ptype_class, "SOCKS", "Ljava/net/Proxy$Type;");
-  CHECK_NULL_RETURN(ptype_socksID, JNI_FALSE);
-  isaddr_createUnresolvedID = (*env)->GetStaticMethodID(env, isaddr_class, "createUnresolved",
-                                                        "(Ljava/lang/String;I)Ljava/net/InetSocketAddress;");
-  CHECK_NULL_RETURN(isaddr_createUnresolvedID, JNI_FALSE);
+    /*
+     * Get one WinHTTP session handle to initialize the WinHTTP internal data
+     * structures. Keep and use only this one for the whole life time.
+     */
+    session = WinHttpOpen(L"Only used internal", /* we need no real agent string here */
+                          WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
+                          WINHTTP_NO_PROXY_NAME,
+                          WINHTTP_NO_PROXY_BYPASS,
+                          0);
+    if (session == NULL) {
+        return JNI_FALSE;
+    }
 
-  /**
-   * Let's see if we can find the proper Registry entry.
-   */
-  ret = RegOpenKeyEx(HKEY_CURRENT_USER,
-                     "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
-                     0, KEY_READ, (PHKEY)&hKey);
-  if (ret == ERROR_SUCCESS) {
-    RegCloseKey(hKey);
-    /**
-     * It worked, we can probably rely on it then.
-     */
+    if (!initJavaClass(env)) {
+        return JNI_FALSE;
+    }
+
     return JNI_TRUE;
-  }
+}
 
-  return JNI_FALSE;
-}
 
 #define MAX_STR_LEN 1024
 
+/* A linked list element for a proxy */
+typedef struct list_item {
+    wchar_t *host;
+    int port;
+    struct list_item *next;
+} list_item;
+
+/* Free the linked list */
+static void freeList(list_item *head) {
+    list_item *next = NULL;
+    list_item *current = head;
+    while (current != NULL) {
+        next = current->next;
+        free(current->host);
+        free(current);
+        current = next;
+    }
+}
+
+
+/*
+ * Creates a linked list of list_item elements that has to be freed later on.
+ * Returns the size of the array as int.
+ */
+static int createProxyList(LPWSTR win_proxy, const WCHAR *pproto, list_item **head) {
+    static const wchar_t separators[] = L"\t\r\n ;";
+    list_item *current = NULL;
+    int nr_elems = 0;
+    wchar_t *context = NULL;
+    wchar_t *current_proxy = NULL;
+    BOOL error = FALSE;
+
+    /*
+     * The proxy server list contains one or more of the following strings
+     * separated by semicolons or whitespace:
+     *    ([<scheme>=][<scheme>"://"]<server>[":"<port>])
+     */
+    current_proxy = wcstok_s(win_proxy, separators, &context);
+    while (current_proxy != NULL) {
+        LPWSTR pport;
+        LPWSTR phost;
+        int portVal = 0;
+        wchar_t *next_proxy = NULL;
+        list_item *proxy = NULL;
+        wchar_t* pos = NULL;
+
+        /* Filter based on the scheme, if there is one */
+        pos = wcschr(current_proxy, L'=');
+        if (pos) {
+          *pos = L'\0';
+          if (wcscmp(current_proxy, pproto) != 0) {
+              current_proxy = wcstok_s(NULL, separators, &context);
+              continue;
+          }
+          current_proxy = pos + 1;
+        }
+
+        /* Let's check for a scheme and ignore it. */
+        if ((phost = wcsstr(current_proxy, L"://")) != NULL) {
+            phost += 3;
+        } else {
+            phost = current_proxy;
+        }
+
+        /* Get the port */
+        pport = wcschr(phost, L':');
+        if (pport != NULL) {
+            *pport = 0;
+            pport++;
+            swscanf(pport, L"%d", &portVal);
+        }
+
+        proxy = (list_item *)malloc(sizeof(list_item));
+        if (proxy != NULL) {
+            proxy->next = NULL;
+            proxy->port = portVal;
+            proxy->host = _wcsdup(phost);
+
+            if (proxy->host != NULL) {
+                if (*head == NULL) {
+                    *head = proxy; /* first elem */
+                }
+                if (current != NULL) {
+                    current->next = proxy;
+                }
+                current = proxy;
+                nr_elems++;
+            } else {
+                free(proxy); /* cleanup */
+            }
+        }
+        /* goto next proxy if available... */
+        current_proxy = wcstok_s(NULL, separators, &context);
+    }
+    return nr_elems;
+}
+
+
+
 /*
  * Class:     sun_net_spi_DefaultProxySelector
- * Method:    getSystemProxy
- * Signature: ([Ljava/lang/String;Ljava/lang/String;)Ljava/net/Proxy;
+ * Method:    getSystemProxies
+ * Signature: ([Ljava/lang/String;Ljava/lang/String;)[Ljava/net/Proxy;
  */
-JNIEXPORT jobject JNICALL
-Java_sun_net_spi_DefaultProxySelector_getSystemProxy(JNIEnv *env,
-                                                     jobject this,
-                                                     jstring proto,
-                                                     jstring host)
+JNIEXPORT jobjectArray JNICALL
+Java_sun_net_spi_DefaultProxySelector_getSystemProxies(JNIEnv *env,
+                                                       jobject this,
+                                                       jstring proto,
+                                                       jstring host)
 {
-  jobject isa = NULL;
-  jobject proxy = NULL;
-  jobject type_proxy = NULL;
-  jobject no_proxy = NULL;
-  jboolean isCopy;
-  HKEY hKey;
-  LONG ret;
-  const char* cproto;
-  const char* urlhost;
-  char pproto[MAX_STR_LEN];
-  char regserver[MAX_STR_LEN];
-  char override[MAX_STR_LEN];
-  char *s, *s2;
-  char *ctx = NULL;
-  int pport = 0;
-  int defport = 0;
-  char *phost;
+    jobjectArray proxy_array = NULL;
+    jobject type_proxy = NULL;
+    LPCWSTR lpProto;
+    LPCWSTR lpHost;
+    list_item *head = NULL;
 
-  /**
-   * Let's open the Registry entry. We'll check a few values in it:
-   *
-   * - ProxyEnable: 0 means no proxy, 1 means use the proxy
-   * - ProxyServer: a string that can take 2 forms:
-   *    "server[:port]"
-   *    or
-   *    "protocol1=server[:port][;protocol2=server[:port]]..."
-   * - ProxyOverride: a string containing a list of prefixes for hostnames.
-   *   e.g.: hoth;localhost;<local>
-   */
-  ret = RegOpenKeyEx(HKEY_CURRENT_USER,
-                     "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
-                     0, KEY_READ, (PHKEY)&hKey);
-  if (ret == ERROR_SUCCESS) {
-    DWORD dwLen;
-    DWORD dwProxyEnabled;
-    ULONG ulType;
-    dwLen = sizeof(dwProxyEnabled);
+    BOOL                                   use_auto_proxy = FALSE;
+    WINHTTP_CURRENT_USER_IE_PROXY_CONFIG   ie_proxy_config;
+    WINHTTP_AUTOPROXY_OPTIONS              auto_proxy_options;
+    WINHTTP_PROXY_INFO                     proxy_info;
+    LPWSTR win_proxy = NULL;
+    LPWSTR win_bypass_proxy = NULL;
 
-    /**
-     * Let's see if the proxy settings are to be used.
-     */
-    ret = RegQueryValueEx(hKey, "ProxyEnable",  NULL, &ulType,
-                          (LPBYTE)&dwProxyEnabled, &dwLen);
-    if ((ret == ERROR_SUCCESS) && (dwProxyEnabled > 0)) {
-      /*
-       * Yes, ProxyEnable == 1
-       */
-      dwLen = sizeof(override);
-      override[0] = 0;
-      ret = RegQueryValueEx(hKey, "ProxyOverride", NULL, &ulType,
-                            (LPBYTE)&override, &dwLen);
-      dwLen = sizeof(regserver);
-      regserver[0] = 0;
-      ret = RegQueryValueEx(hKey, "ProxyServer",  NULL, &ulType,
-                            (LPBYTE)&regserver, &dwLen);
-      RegCloseKey(hKey);
-      if (ret == ERROR_SUCCESS) {
-        if (strlen(override) > 0) {
-          /**
-           * we did get ProxyServer and may have an override.
-           * So let's check the override list first, by walking down the list
-           * The semicolons (;) separated entries have to be matched with the
-           * the beginning of the hostname.
-           */
-          s = strtok_s(override, "; ", &ctx);
-          urlhost = (*env)->GetStringUTFChars(env, host, &isCopy);
-          if (urlhost == NULL) {
-            if (!(*env)->ExceptionCheck(env))
-              JNU_ThrowOutOfMemoryError(env, NULL);
-            return NULL;
-          }
-          while (s != NULL) {
-            if (strncmp(s, urlhost, strlen(s)) == 0) {
-              /**
-               * the URL host name matches with one of the prefixes,
-               * therefore we have to use a direct connection.
-               */
-              if (isCopy == JNI_TRUE)
-                (*env)->ReleaseStringUTFChars(env, host, urlhost);
-              goto noproxy;
+    memset(&ie_proxy_config, 0, sizeof(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG));
+    memset(&auto_proxy_options, 0, sizeof(WINHTTP_AUTOPROXY_OPTIONS));
+    memset(&proxy_info, 0, sizeof(WINHTTP_PROXY_INFO));
+
+    lpHost = (*env)->GetStringChars(env, host, NULL);
+    if (lpHost == NULL) {
+        if (!(*env)->ExceptionCheck(env))
+            JNU_ThrowOutOfMemoryError(env, NULL);
+        return NULL;
+    }
+
+    lpProto = (*env)->GetStringChars(env, proto, NULL);
+    if (lpProto == NULL) {
+        (*env)->ReleaseStringChars(env, host, lpHost);
+        if (!(*env)->ExceptionCheck(env))
+            JNU_ThrowOutOfMemoryError(env, NULL);
+        return NULL;
+    }
+
+    if (WinHttpGetIEProxyConfigForCurrentUser(&ie_proxy_config) == FALSE) {
+        /* cleanup and exit */
+        (*env)->ReleaseStringChars(env, host, lpHost);
+        (*env)->ReleaseStringChars(env, proto, lpProto);
+        return NULL;
+    }
+
+    if (ie_proxy_config.fAutoDetect) {
+        /* Windows uses WPAD */
+        auto_proxy_options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP |
+                                               WINHTTP_AUTO_DETECT_TYPE_DNS_A;
+        auto_proxy_options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
+        auto_proxy_options.fAutoLogonIfChallenged = TRUE;
+        use_auto_proxy = TRUE;
+    } else if (ie_proxy_config.lpszAutoConfigUrl != NULL) {
+        /* Windows uses PAC file */
+        auto_proxy_options.lpszAutoConfigUrl = ie_proxy_config.lpszAutoConfigUrl;
+        auto_proxy_options.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
+        use_auto_proxy = TRUE;
+    } else if (ie_proxy_config.lpszProxy != NULL) {
+        /* Windows uses manually entered proxy. */
+        use_auto_proxy = FALSE;
+        win_bypass_proxy = ie_proxy_config.lpszProxyBypass;
+        win_proxy = ie_proxy_config.lpszProxy;
+    }
+
+    if (use_auto_proxy) {
+        WCHAR url[MAX_STR_LEN];
+        /* Create url for WinHttpGetProxyForUrl */
+        _snwprintf(url, sizeof(url) - 1, L"%s://%s", lpProto, lpHost);
+        /* Get proxy for URL from Windows */
+        use_auto_proxy = WinHttpGetProxyForUrl(session, &url[0], &auto_proxy_options, &proxy_info);
+        if (use_auto_proxy) {
+            win_proxy = proxy_info.lpszProxy;
+            win_bypass_proxy = proxy_info.lpszProxyBypass;
+        }
+    }
+
+    /* Check the bypass entry. */
+    if (NULL != win_bypass_proxy) {
+        /*
+         * From MSDN:
+         * The proxy bypass list contains one or more server names separated by
+         * semicolons or whitespace. The proxy bypass list can also contain the
+         * string "<local>" to indicate that all local intranet sites are
+         * bypassed. Local intranet sites are considered to be all servers that
+         * do not contain a period in their name.
+         */
+        wchar_t *context = NULL;
+        LPWSTR s = wcstok_s(win_bypass_proxy, L"; ", &context);
+
+        while (s != NULL) {
+            size_t maxlen = wcslen(s);
+            if (wcsncmp(s, lpHost, maxlen) == 0) {
+                /*
+                 * The URL host name matches with one of the prefixes, use a
+                 * direct connection.
+                 */
+                goto noproxy;
             }
-            s = strtok_s(NULL, "; ", &ctx);
-          }
-          if (isCopy == JNI_TRUE)
-            (*env)->ReleaseStringUTFChars(env, host, urlhost);
+            if (wcsncmp(s, L"<local>", maxlen) == 0) {
+                /*
+                 * All local intranet sites are bypassed - Microsoft consider all
+                 * servers that do not contain a period in their name to be local.
+                 */
+                if (wcschr(lpHost, '.') == NULL) {
+                    goto noproxy;
+                }
+            }
+            s = wcstok_s(NULL, L"; ", &context);
+        }
+    }
+
+    if (win_proxy != NULL) {
+        wchar_t *context = NULL;
+        int defport = 0;
+        int nr_elems = 0;
+
+        /* Set the default port value & proxy type from protocol. */
+        if ((wcscmp(lpProto, L"http") == 0) ||
+            (wcscmp(lpProto, L"ftp") == 0) ||
+            (wcscmp(lpProto, L"gopher") == 0))
+            defport = 80;
+        if (wcscmp(lpProto, L"https") == 0)
+            defport = 443;
+        if (wcscmp(lpProto, L"socks") == 0) {
+            defport = 1080;
+            type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_socksID);
+        } else {
+            type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_httpID);
+        }
+        if (type_proxy == NULL || (*env)->ExceptionCheck(env)) {
+            goto noproxy;
         }
 
-        cproto = (*env)->GetStringUTFChars(env, proto, &isCopy);
-        if (cproto == NULL) {
-          if (!(*env)->ExceptionCheck(env))
-            JNU_ThrowOutOfMemoryError(env, NULL);
-          return NULL;
+        nr_elems = createProxyList(win_proxy, lpProto, &head);
+        if (nr_elems != 0 && head != NULL) {
+            int index = 0;
+            proxy_array = (*env)->NewObjectArray(env, nr_elems, proxy_class, NULL);
+            if (proxy_array == NULL || (*env)->ExceptionCheck(env)) {
+                goto noproxy;
+            }
+            while (head != NULL && index < nr_elems) {
+                jstring jhost;
+                jobject isa;
+                jobject proxy;
+
+                if (head->host != NULL && proxy_array != NULL) {
+                    /* Let's create the appropriate Proxy object then. */
+                    if (head->port == 0) {
+                        head->port = defport;
+                    }
+                    jhost = (*env)->NewString(env, head->host, (jsize)wcslen(head->host));
+                    if (jhost == NULL || (*env)->ExceptionCheck(env)) {
+                        proxy_array = NULL;
+                    }
+                    isa = (*env)->CallStaticObjectMethod(env, isaddr_class,
+                                                         isaddr_createUnresolvedID, jhost,
+                                                         head->port);
+                    if (isa == NULL || (*env)->ExceptionCheck(env)) {
+                        proxy_array = NULL;
+                    }
+                    proxy = (*env)->NewObject(env, proxy_class, proxy_ctrID, type_proxy, isa);
+                    if (proxy == NULL || (*env)->ExceptionCheck(env)) {
+                        proxy_array = NULL;
+                    }
+                    (*env)->SetObjectArrayElement(env, proxy_array, index, proxy);
+                    if ((*env)->ExceptionCheck(env)) {
+                        proxy_array = NULL;
+                    }
+                    index++;
+                }
+                head = head->next;
+            }
         }
-
-        /*
-         * Set default port value & proxy type from protocol.
-         */
-        if ((strcmp(cproto, "http") == 0) ||
-            (strcmp(cproto, "ftp") == 0) ||
-            (strcmp(cproto, "gopher") == 0))
-          defport = 80;
-        if (strcmp(cproto, "https") == 0)
-          defport = 443;
-        if (strcmp(cproto, "socks") == 0) {
-          defport = 1080;
-          type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_socksID);
-        } else {
-          type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_httpID);
-        }
-
-        sprintf(pproto,"%s=", cproto);
-        if (isCopy == JNI_TRUE)
-          (*env)->ReleaseStringUTFChars(env, proto, cproto);
-        /**
-         * Let's check the protocol specific form first.
-         */
-        if ((s = strstr(regserver, pproto)) != NULL) {
-          s += strlen(pproto);
-        } else {
-          /**
-           * If we couldn't find *this* protocol but the string is in the
-           * protocol specific format, then don't use proxy
-           */
-          if (strchr(regserver, '=') != NULL)
-            goto noproxy;
-          s = regserver;
-        }
-        s2 = strchr(s, ';');
-        if (s2 != NULL)
-          *s2 = 0;
-
-        /**
-         * Is there a port specified?
-         */
-        s2 = strchr(s, ':');
-        if (s2 != NULL) {
-          *s2 = 0;
-          s2++;
-          sscanf(s2, "%d", &pport);
-        }
-        phost = s;
-
-        if (phost != NULL) {
-          /**
-           * Let's create the appropriate Proxy object then.
-           */
-          jstring jhost;
-          if (pport == 0)
-            pport = defport;
-          jhost = (*env)->NewStringUTF(env, phost);
-          CHECK_NULL_RETURN(jhost, NULL);
-          isa = (*env)->CallStaticObjectMethod(env, isaddr_class, isaddr_createUnresolvedID, jhost, pport);
-          CHECK_NULL_RETURN(isa, NULL);
-          proxy = (*env)->NewObject(env, proxy_class, proxy_ctrID, type_proxy, isa);
-          return proxy;
-        }
-      }
-    } else {
-      /* ProxyEnable == 0 or Query failed      */
-      /* close the handle to the registry key  */
-      RegCloseKey(hKey);
     }
-  }
 
 noproxy:
-  no_proxy = (*env)->GetStaticObjectField(env, proxy_class, pr_no_proxyID);
-  return no_proxy;
+    if (head != NULL) {
+        freeList(head);
+    }
+    if (proxy_info.lpszProxy != NULL)
+      GlobalFree(proxy_info.lpszProxy);
+    if (proxy_info.lpszProxyBypass != NULL)
+      GlobalFree(proxy_info.lpszProxyBypass);
+    if (ie_proxy_config.lpszAutoConfigUrl != NULL)
+      GlobalFree(ie_proxy_config.lpszAutoConfigUrl);
+    if (ie_proxy_config.lpszProxy != NULL)
+      GlobalFree(ie_proxy_config.lpszProxy);
+    if (ie_proxy_config.lpszProxyBypass != NULL)
+      GlobalFree(ie_proxy_config.lpszProxyBypass);
+    if (lpHost != NULL)
+      (*env)->ReleaseStringChars(env, host, lpHost);
+    if (lpProto != NULL)
+      (*env)->ReleaseStringChars(env, proto, lpProto);
+
+    return proxy_array;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.management.rmi/share/classes/com/sun/jmx/remote/internal/rmi/ProxyRef.java	Mon Feb 06 09:34:19 2017 -0800
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2003, 2008, 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 com.sun.jmx.remote.internal.rmi;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.lang.reflect.Method;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.server.RemoteObject;
+import java.rmi.server.RemoteRef;
+
+
+@SuppressWarnings("deprecation")
+public class ProxyRef implements RemoteRef {
+    private static final long serialVersionUID = -6503061366316814723L;
+
+    public ProxyRef(RemoteRef ref) {
+        this.ref = ref;
+    }
+
+    public void readExternal(ObjectInput in)
+            throws IOException, ClassNotFoundException {
+        ref.readExternal(in);
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException {
+        ref.writeExternal(out);
+    }
+
+    /**
+     * @deprecated
+     */
+    @Deprecated
+    public void invoke(java.rmi.server.RemoteCall call) throws Exception {
+        ref.invoke(call);
+    }
+
+    public Object invoke(Remote obj, Method method, Object[] params,
+                         long opnum) throws Exception {
+        return ref.invoke(obj, method, params, opnum);
+    }
+
+    /**
+     * @deprecated
+     */
+    @Deprecated
+    public void done(java.rmi.server.RemoteCall call) throws RemoteException {
+        ref.done(call);
+    }
+
+    public String getRefClass(ObjectOutput out) {
+        return ref.getRefClass(out);
+    }
+
+    /**
+     * @deprecated
+     */
+    @Deprecated
+    public java.rmi.server.RemoteCall newCall(RemoteObject obj,
+            java.rmi.server.Operation[] op, int opnum,
+                              long hash) throws RemoteException {
+        return ref.newCall(obj, op, opnum, hash);
+    }
+
+    public boolean remoteEquals(RemoteRef obj) {
+        return ref.remoteEquals(obj);
+    }
+
+    public int remoteHashCode() {
+        return ref.remoteHashCode();
+    }
+
+    public String remoteToString() {
+        return ref.remoteToString();
+    }
+
+    protected RemoteRef ref;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.management.rmi/share/classes/com/sun/jmx/remote/internal/rmi/RMIExporter.java	Mon Feb 06 09:34:19 2017 -0800
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2003, 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