changeset 14473:08a5c72f79e3

Merge
author sspitsyn
date Sun, 08 May 2016 08:25:10 +0000
parents c43aba5fc69b b1c3c979ef6e
children 5178f8538a52
files make/launcher/Launcher-jdk.jvmstat.rmi.gmk src/java.base/share/classes/jdk/internal/module/Hasher.java src/java.base/share/classes/jdk/net/ExtendedSocketOptions.java src/java.base/share/classes/jdk/net/NetworkPermission.java src/java.base/share/classes/jdk/net/SocketFlow.java src/java.base/share/classes/jdk/net/Sockets.java src/java.base/share/classes/jdk/net/package-info.java src/java.base/share/classes/sun/net/ExtendedOptionsImpl.java src/java.base/share/classes/sun/security/action/GetBooleanSecurityPropertyAction.java src/java.base/unix/native/libnet/ExtendedOptionsImpl.c src/java.base/windows/native/libnet/ExtendedOptionsImpl.c src/java.desktop/share/classes/sun/swing/UIClientPropertyKey.java src/java.desktop/unix/native/common/awt/extutil.h src/java.desktop/unix/native/libawt_headless/awt/VDrawingArea.c src/java.desktop/unix/native/libawt_headless/awt/VDrawingArea.h src/java.desktop/unix/native/libawt_headless/awt/VDrawingAreaP.h src/jdk.jlink/share/classes/jdk/tools/jimage/ExtractedImage.java src/jdk.jvmstat.rmi/share/classes/module-info.java src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/RemoteHost.java src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/RemoteVm.java src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/package.html src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostProvider.java src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostRmiService.java src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/PerfDataBuffer.java src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteMonitoredVm.java src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteVmManager.java src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/package.html src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/Jstatd.java src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/RemoteHostImpl.java src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/RemoteVmImpl.java src/jdk.unsupported/share/classes/sun/misc/ManagedLocalsThread.java test/javax/transaction/testng/TEST.properties test/sanity/client/lib/Jemmy2Ext/src/org/jemmy2ext/JemmyExt.java test/tools/jlink/hashes/HashesTest.java test/tools/jlink/hashes/newsrc/m2/module-info.java test/tools/jlink/hashes/newsrc/m2/org/m2/Util.java test/tools/jlink/hashes/newsrc/not_matched/module-info.java test/tools/jlink/hashes/newsrc/not_matched/org/not_matched/Name.java test/tools/jlink/hashes/src/m1/module-info.java test/tools/jlink/hashes/src/m1/org/m1/Main.java test/tools/jlink/hashes/src/m2/module-info.java test/tools/jlink/hashes/src/m2/org/m2/Util.java test/tools/jlink/hashes/src/not_matched/module-info.java test/tools/jlink/hashes/src/not_matched/org/not_matched/Name.java test/tools/launcher/modules/addmods/src/app/Main.java test/tools/launcher/modules/addmods/src/lib/jdk/lib/Util.java test/tools/launcher/modules/addmods/src/lib/module-info.java
diffstat 782 files changed, 31727 insertions(+), 11416 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Mon Apr 25 15:32:35 2016 +0200
+++ b/.hgtags	Sun May 08 08:25:10 2016 +0000
@@ -358,3 +358,4 @@
 68f8be44b6a6b33dfa841ec671c0ba6e4056b372 jdk-9+113
 bb8379287f3736f38c52b2d1418784e2592461d1 jdk-9+114
 35225b837d66582037eeadeb471c13235dfd793d jdk-9+115
+baeb5edb38939cdb78ae0ac6f4fd368465cbf188 jdk-9+116
--- a/make/Tools.gmk	Mon Apr 25 15:32:35 2016 +0200
+++ b/make/Tools.gmk	Sun May 08 08:25:10 2016 +0000
@@ -96,7 +96,13 @@
 TOOL_SPP = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes build.tools.spp.Spp
 
 # Nimbus is used somewhere in the swing build.
+
+ifeq ($(BOOT_JDK_MODULAR), true)
+  COMPILENIMBUS_ADD_MODS := -addmods java.xml.bind
+endif
+
 TOOL_GENERATENIMBUS = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
+    $(COMPILENIMBUS_ADD_MODS) \
     build.tools.generatenimbus.Generator
 
 TOOL_WRAPPERGENERATOR = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
--- a/make/gendata/Gendata-java.base.gmk	Mon Apr 25 15:32:35 2016 +0200
+++ b/make/gendata/Gendata-java.base.gmk	Sun May 08 08:25:10 2016 +0000
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# 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
@@ -41,7 +41,7 @@
 GENDATA_UNINAME := $(JDK_OUTPUTDIR)/modules/java.base/java/lang/uniName.dat
 
 $(GENDATA_UNINAME): $(JDK_TOPDIR)/make/data/unicodedata/UnicodeData.txt $(BUILD_TOOLS_JDK)
-	$(MKDIR) -p $(@D)
+	$(call MakeDir, $(@D))
 	$(TOOL_CHARACTERNAME) $< $@
 
 TARGETS += $(GENDATA_UNINAME)
@@ -51,7 +51,7 @@
 GENDATA_CURDATA := $(JDK_OUTPUTDIR)/modules/java.base/java/util/currency.data
 
 $(GENDATA_CURDATA): $(JDK_TOPDIR)/make/data/currency/CurrencyData.properties $(BUILD_TOOLS_JDK)
-	$(MKDIR) -p $(@D)
+	$(call MakeDir, $(@D))
 	$(RM) $@
 	$(TOOL_GENERATECURRENCYDATA) -o $@.tmp < $<
 	$(MV) $@.tmp $@
@@ -67,10 +67,10 @@
 # RESTRICTED_PKGS_SRC is optionally set in custom extension for this makefile
 
 $(GENDATA_JAVA_SECURITY): $(BUILD_TOOLS) $(GENDATA_JAVA_SECURITY_SRC) $(RESTRICTED_PKGS_SRC)
-	$(ECHO) "Generating java.security"
-	$(MKDIR) -p $(@D)
+	$(call LogInfo, Generating java.security)
+	$(call MakeDir, $(@D))
 	$(TOOL_MAKEJAVASECURITY) $(GENDATA_JAVA_SECURITY_SRC) $@ $(OPENJDK_TARGET_OS) \
-		$(OPENJDK_TARGET_CPU_ARCH) $(RESTRICTED_PKGS_SRC) || exit 1
+	    $(OPENJDK_TARGET_CPU_ARCH) $(RESTRICTED_PKGS_SRC)
 
 TARGETS += $(GENDATA_JAVA_SECURITY)
 
@@ -78,7 +78,7 @@
 
 $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/classlist: \
     $(JDK_TOPDIR)/make/data/classlist/classlist.$(OPENJDK_TARGET_OS)
-	$(MKDIR) -p $(@D)
+	$(call MakeDir, $(@D))
 	$(RM) $@ $@.tmp
 	$(TOOL_ADDJSUM) $< $@.tmp
 	$(MV) $@.tmp $@
--- a/make/gendata/GendataBreakIterator.gmk	Mon Apr 25 15:32:35 2016 +0200
+++ b/make/gendata/GendataBreakIterator.gmk	Sun May 08 08:25:10 2016 +0000
@@ -62,10 +62,13 @@
     BIN := $(BREAK_ITERATOR_CLASSES)/jdk.localedata))
 
 ifeq ($(BOOT_JDK_MODULAR), true)
-  BREAK_ITERATOR_BOOTCLASSPATH := -Xpatch:$(BREAK_ITERATOR_CLASSES) \
-        -XaddExports:java.base/sun.text=ALL-UNNAMED \
-        -XaddExports:java.base/sun.text.resources=ALL-UNNAMED \
-        -XaddExports:jdk.localedata/sun.text.resources.ext=ALL-UNNAMED
+  BREAK_ITERATOR_BOOTCLASSPATH := \
+      -Xpatch:java.base=$(BREAK_ITERATOR_CLASSES)/java.base \
+      -Xpatch:jdk.localedata=$(BREAK_ITERATOR_CLASSES)/jdk.localedata \
+      -XaddExports:java.base/sun.text=ALL-UNNAMED \
+      -XaddExports:java.base/sun.text.resources=ALL-UNNAMED \
+      -XaddExports:jdk.localedata/sun.text.resources.ext=ALL-UNNAMED \
+      #
 else
   BREAK_ITERATOR_BOOTCLASSPATH := -Xbootclasspath/p:$(call PathList, \
       $(BREAK_ITERATOR_CLASSES)/java.base \
--- a/make/launcher/Launcher-java.desktop.gmk	Mon Apr 25 15:32:35 2016 +0200
+++ b/make/launcher/Launcher-java.desktop.gmk	Sun May 08 08:25:10 2016 +0000
@@ -31,7 +31,7 @@
 ifndef BUILD_HEADLESS_ONLY
   $(eval $(call SetupBuildLauncher, appletviewer, \
       MAIN_CLASS := sun.applet.Main, \
-      JAVA_ARGS := -addmods ALL-SYSTEM, \
+      JAVA_ARGS := -addmods ALL-DEFAULT, \
       LIBS_unix := $(X_LIBS), \
   ))
 endif
--- a/make/launcher/Launcher-java.scripting.gmk	Mon Apr 25 15:32:35 2016 +0200
+++ b/make/launcher/Launcher-java.scripting.gmk	Sun May 08 08:25:10 2016 +0000
@@ -27,4 +27,5 @@
 
 $(eval $(call SetupBuildLauncher, jrunscript, \
     MAIN_CLASS := com.sun.tools.script.shell.Main, \
+    JAVA_ARGS := -addmods ALL-DEFAULT, \
 ))
--- a/make/launcher/Launcher-jdk.compiler.gmk	Mon Apr 25 15:32:35 2016 +0200
+++ b/make/launcher/Launcher-jdk.compiler.gmk	Sun May 08 08:25:10 2016 +0000
@@ -27,7 +27,8 @@
 
 $(eval $(call SetupBuildLauncher, javac, \
    MAIN_CLASS := com.sun.tools.javac.Main, \
-    CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \
+   JAVA_ARGS := -addmods ALL-DEFAULT, \
+   CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \
         -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \
 ))
 
--- a/make/launcher/Launcher-jdk.javadoc.gmk	Mon Apr 25 15:32:35 2016 +0200
+++ b/make/launcher/Launcher-jdk.javadoc.gmk	Sun May 08 08:25:10 2016 +0000
@@ -27,6 +27,7 @@
 
 $(eval $(call SetupBuildLauncher, javadoc, \
     MAIN_CLASS := jdk.javadoc.internal.tool.Main, \
+    JAVA_ARGS := -addmods ALL-DEFAULT, \
     CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \
         -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \
 ))
--- a/make/launcher/Launcher-jdk.jlink.gmk	Mon Apr 25 15:32:35 2016 +0200
+++ b/make/launcher/Launcher-jdk.jlink.gmk	Sun May 08 08:25:10 2016 +0000
@@ -32,6 +32,7 @@
 
 $(eval $(call SetupBuildLauncher, jlink,\
     MAIN_CLASS := jdk.tools.jlink.internal.Main, \
+    JAVA_ARGS := -addmods ALL-DEFAULT, \
     CFLAGS := -DENABLE_ARG_FILES \
         -DEXPAND_CLASSPATH_WILDCARDS \
         -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/launcher/Launcher-jdk.jstatd.gmk	Sun May 08 08:25:10 2016 +0000
@@ -0,0 +1,30 @@
+#
+# 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 LauncherCommon.gmk
+
+$(eval $(call SetupBuildLauncher, jstatd, \
+    MAIN_CLASS := sun.tools.jstatd.Jstatd, \
+))
--- a/make/launcher/Launcher-jdk.jvmstat.rmi.gmk	Mon Apr 25 15:32:35 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +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 LauncherCommon.gmk
-
-$(eval $(call SetupBuildLauncher, jstatd, \
-    MAIN_CLASS := sun.tools.jstatd.Jstatd, \
-))
--- a/make/launcher/Launcher-jdk.scripting.nashorn.shell.gmk	Mon Apr 25 15:32:35 2016 +0200
+++ b/make/launcher/Launcher-jdk.scripting.nashorn.shell.gmk	Sun May 08 08:25:10 2016 +0000
@@ -27,6 +27,6 @@
 
 $(eval $(call SetupBuildLauncher, jjs, \
     MAIN_CLASS := jdk.nashorn.tools.jjs.Main, \
-    JAVA_ARGS := -addmods ALL-SYSTEM, \
+    JAVA_ARGS := -addmods ALL-DEFAULT, \
     CFLAGS := -DENABLE_ARG_FILES, \
 ))
--- a/make/lib/CoreLibraries.gmk	Mon Apr 25 15:32:35 2016 +0200
+++ b/make/lib/CoreLibraries.gmk	Sun May 08 08:25:10 2016 +0000
@@ -267,7 +267,7 @@
     LDFLAGS_windows := -export:JIMAGE_Open -export:JIMAGE_Close \
         -export:JIMAGE_PackageToModule \
         -export:JIMAGE_FindResource -export:JIMAGE_GetResource \
-        -export:JIMAGE_ResourceIterator, \
+        -export:JIMAGE_ResourceIterator -export:JIMAGE_ResourcePath, \
     LIBS_unix := -ljvm -ldl $(LIBCXX), \
     LIBS_solaris := -lc, \
     LIBS_macosx := -lc++, \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/lib/Lib-jdk.net.gmk	Sun May 08 08:25:10 2016 +0000
@@ -0,0 +1,51 @@
+#
+# Copyright (c) 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.
+#
+
+include LibCommon.gmk
+
+################################################################################
+
+ifeq ($(OPENJDK_TARGET_OS), solaris)
+
+  $(eval $(call SetupNativeCompilation, BUILD_LIBEXTNET, \
+      LIBRARY := extnet, \
+      OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+      SRC := $(JDK_TOPDIR)/src/jdk.net/solaris/native/libextnet, \
+      OPTIMIZATION := LOW, \
+      CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/jdk.net, \
+      MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libextnet/mapfile-vers, \
+      LDFLAGS := $(LDFLAGS_JDKLIB) \
+          $(call SET_SHARED_LIBRARY_ORIGIN), \
+      LIBS := -lsocket -lc -ljava, \
+      OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libextnet, \
+  ))
+
+  $(BUILD_LIBEXTNET): $(call FindLib, java.base, java)
+
+  TARGETS += $(BUILD_LIBEXTNET)
+endif
+
+
+################################################################################
--- a/make/mapfiles/libawt_xawt/mapfile-vers	Mon Apr 25 15:32:35 2016 +0200
+++ b/make/mapfiles/libawt_xawt/mapfile-vers	Sun May 08 08:25:10 2016 +0000
@@ -179,6 +179,7 @@
         Java_sun_awt_UNIXToolkit_load_1gtk_1icon;
         Java_sun_awt_UNIXToolkit_nativeSync;
         Java_sun_awt_UNIXToolkit_gtkCheckVersionImpl;
+        Java_sun_awt_UNIXToolkit_get_1gtk_1version;
         Java_java_awt_AWTEvent_initIDs;
         Java_java_awt_event_InputEvent_initIDs;
         Java_java_awt_event_KeyEvent_initIDs;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/mapfiles/libextnet/mapfile-vers	Sun May 08 08:25:10 2016 +0000
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 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.
+#
+
+SUNWprivate_1.1 {
+	global:
+	    Java_jdk_net_SolarisSocketOptions_init;
+	    Java_jdk_net_SolarisSocketOptions_setFlowOption;
+	    Java_jdk_net_SolarisSocketOptions_getFlowOption;
+	    Java_jdk_net_SolarisSocketOptions_flowSupported;
+	local:
+	    *;
+};
--- a/make/mapfiles/libjimage/mapfile-vers	Mon Apr 25 15:32:35 2016 +0200
+++ b/make/mapfiles/libjimage/mapfile-vers	Sun May 08 08:25:10 2016 +0000
@@ -34,6 +34,7 @@
         JIMAGE_FindResource;
         JIMAGE_GetResource;
         JIMAGE_ResourceIterator;
+        JIMAGE_ResourcePath;
     local:
         *;
 };
--- a/make/mapfiles/libnet/mapfile-vers	Mon Apr 25 15:32:35 2016 +0200
+++ b/make/mapfiles/libnet/mapfile-vers	Sun May 08 08:25:10 2016 +0000
@@ -98,10 +98,6 @@
 		Java_sun_net_sdp_SdpSupport_create0;
 		Java_sun_net_spi_DefaultProxySelector_init;
 		Java_sun_net_spi_DefaultProxySelector_getSystemProxy;
-		Java_sun_net_ExtendedOptionsImpl_init;
-		Java_sun_net_ExtendedOptionsImpl_setFlowOption;
-		Java_sun_net_ExtendedOptionsImpl_getFlowOption;
-		Java_sun_net_ExtendedOptionsImpl_flowSupported;
 		NET_AllocSockaddr;
 		NET_SockaddrToInetAddress;
                 NET_SockaddrEqualsInetAddress;
--- a/make/netbeans/client_sanity/nbproject/genfiles.properties	Mon Apr 25 15:32:35 2016 +0200
+++ b/make/netbeans/client_sanity/nbproject/genfiles.properties	Sun May 08 08:25:10 2016 +0000
@@ -3,6 +3,6 @@
 build.xml.stylesheet.CRC32=8064a381@1.75.2.48
 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
 # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
-nbproject/build-impl.xml.data.CRC32=55414227
+nbproject/build-impl.xml.data.CRC32=16caf60f
 nbproject/build-impl.xml.script.CRC32=c12f9d04
 nbproject/build-impl.xml.stylesheet.CRC32=05530350@1.79.1.48
--- a/make/netbeans/client_sanity/nbproject/project.properties	Mon Apr 25 15:32:35 2016 +0200
+++ b/make/netbeans/client_sanity/nbproject/project.properties	Sun May 08 08:25:10 2016 +0000
@@ -76,4 +76,4 @@
 src.src.dir=..\\..\\..\\test\\sanity\\client\\SwingSet\\src
 src.src2.dir=..\\..\\..\\test\\sanity\\client\\lib\\SwingSet3\\src
 src.src3.dir=..\\..\\..\\test\\sanity\\client\\lib\\jemmy\\src
-src.src4.dir=..\\..\\..\\test\\sanity\\client\\lib\\Jemmy2Ext\\src
+src.src4.dir=..\\..\\..\\test\\sanity\\client\\lib\\Extensions\\src
--- a/make/netbeans/client_sanity/nbproject/project.xml	Mon Apr 25 15:32:35 2016 +0200
+++ b/make/netbeans/client_sanity/nbproject/project.xml	Sun May 08 08:25:10 2016 +0000
@@ -6,7 +6,7 @@
             <name>SanityTests</name>
             <source-roots>
                 <root id="src.src3.dir" name="lib\jemmy\src"/>
-                <root id="src.src4.dir" name="lib\Jemmy2Ext\src"/>
+                <root id="src.src4.dir" name="lib\Extensions\src"/>
                 <root id="src.src2.dir" name="lib\SwingSet3\src"/>
                 <root id="src.src.dir" name="SwingSet\src"/>
             </source-roots>
--- a/make/src/classes/build/tools/generatenimbus/UIProperty.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/make/src/classes/build/tools/generatenimbus/UIProperty.java	Sun May 08 08:25:10 2016 +0000
@@ -54,13 +54,13 @@
                 return String.format("        d.put(\"%s%s\", \"%s\");\n",
                                      prefix, getName(), getValue());
             case INT:
-                return String.format("        d.put(\"%s%s\", new Integer(%s));\n",
+                return String.format("        d.put(\"%s%s\", Integer.valueOf(%s));\n",
                                      prefix, getName(), getValue());
             case FLOAT:
-                return String.format("        d.put(\"%s%s\", new Float(%sf));\n",
+                return String.format("        d.put(\"%s%s\", Float.valueOf(%sf));\n",
                                      prefix, getName(), getValue());
             case DOUBLE:
-                return String.format("        d.put(\"%s%s\", new Double(%s));\n",
+                return String.format("        d.put(\"%s%s\", Double.valueOf(%s));\n",
                                      prefix, getName(), getValue());
             case COLOR:
                 return String.format("        addColor(d, \"%s%s\", %s);\n",
--- a/make/src/classes/build/tools/module/GenModuleInfoSource.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/make/src/classes/build/tools/module/GenModuleInfoSource.java	Sun May 08 08:25:10 2016 +0000
@@ -52,7 +52,7 @@
         "Usage: GenModuleInfoSource [option] -o <output file> <module-info-java>\n" +
         "Options are:\n" +
         "  -exports  <package-name>\n" +
-        "  -exports  <package-name>/<module-name>\n" +
+        "  -exports  <package-name>[/<module-name>]\n" +
         "  -uses     <service>\n" +
         "  -provides <service>/<provider-impl-classname>\n";
 
--- a/src/java.base/aix/native/libnet/aix_close.c	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/aix/native/libnet/aix_close.c	Sun May 08 08:25:10 2016 +0000
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, SAP SE and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -50,6 +51,8 @@
    ...
 */
 
+#include <assert.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <signal.h>
@@ -86,10 +89,35 @@
 static int sigWakeup = (SIGRTMAX - 1);
 
 /*
- * The fd table and the number of file descriptors
+ * fdTable holds one entry per file descriptor, up to a certain
+ * maximum.
+ * Theoretically, the number of possible file descriptors can get
+ * large, though usually it does not. Entries for small value file
+ * descriptors are kept in a simple table, which covers most scenarios.
+ * Entries for large value file descriptors are kept in an overflow
+ * table, which is organized as a sparse two dimensional array whose
+ * slabs are allocated on demand. This covers all corner cases while
+ * keeping memory consumption reasonable.
  */
-static fdEntry_t *fdTable = NULL;
-static int fdCount = 0;
+
+/* Base table for low value file descriptors */
+static fdEntry_t* fdTable = NULL;
+/* Maximum size of base table (in number of entries). */
+static const int fdTableMaxSize = 0x1000; /* 4K */
+/* Actual size of base table (in number of entries) */
+static int fdTableLen = 0;
+/* Max. theoretical number of file descriptors on system. */
+static int fdLimit = 0;
+
+/* Overflow table, should base table not be large enough. Organized as
+ *   an array of n slabs, each holding 64k entries.
+ */
+static fdEntry_t** fdOverflowTable = NULL;
+/* Number of slabs in the overflow table */
+static int fdOverflowTableLen = 0;
+/* Number of entries in one slab */
+static const int fdOverflowTableSlabSize = 0x10000; /* 64k */
+pthread_mutex_t fdOverflowTableLock = PTHREAD_MUTEX_INITIALIZER;
 
 /*
  * Null signal handler
@@ -108,42 +136,42 @@
     struct rlimit nbr_files;
     sigset_t sigset;
     struct sigaction sa;
+    int i = 0;
 
-    /* Check already initialized */
-    if (fdCount > 0 && fdTable != NULL) {
-        return;
-    }
-
-    /*
-     * Allocate table based on the maximum number of
-     * file descriptors.
-     */
+    /* Determine the maximum number of possible file descriptors. */
     if (-1 == getrlimit(RLIMIT_NOFILE, &nbr_files)) {
         fprintf(stderr, "library initialization failed - "
                 "unable to get max # of allocated fds\n");
         abort();
     }
-    fdCount = nbr_files.rlim_max;
-    /*
-     * We have a conceptual problem here, when the number of files is
-     * unlimited. As a kind of workaround, we ensure the table is big
-     * enough for handle even a large number of files. Since SAP itself
-     * recommends a limit of 32000 files, we just use 64000 as 'infinity'.
-     */
-    if (nbr_files.rlim_max == RLIM_INFINITY) {
-        fdCount = 64000;
+    if (nbr_files.rlim_max != RLIM_INFINITY) {
+        fdLimit = nbr_files.rlim_max;
+    } else {
+        /* We just do not know. */
+        fdLimit = INT_MAX;
     }
-    fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t));
+
+    /* Allocate table for low value file descriptors. */
+    fdTableLen = fdLimit < fdTableMaxSize ? fdLimit : fdTableMaxSize;
+    fdTable = (fdEntry_t*) calloc(fdTableLen, sizeof(fdEntry_t));
     if (fdTable == NULL) {
         fprintf(stderr, "library initialization failed - "
                 "unable to allocate file descriptor table - out of memory");
         abort();
+    } else {
+        for (i = 0; i < fdTableLen; i ++) {
+            pthread_mutex_init(&fdTable[i].lock, NULL);
+        }
     }
 
-    {
-        int i;
-        for (i=0; i < fdCount; i++) {
-            pthread_mutex_init(&fdTable[i].lock, NULL);
+    /* Allocate overflow table, if needed */
+    if (fdLimit > fdTableMaxSize) {
+        fdOverflowTableLen = ((fdLimit - fdTableMaxSize) / fdOverflowTableSlabSize) + 1;
+        fdOverflowTable = (fdEntry_t**) calloc(fdOverflowTableLen, sizeof(fdEntry_t*));
+        if (fdOverflowTable == NULL) {
+            fprintf(stderr, "library initialization failed - "
+                    "unable to allocate file descriptor overflow table - out of memory");
+            abort();
         }
     }
 
@@ -161,17 +189,60 @@
 }
 
 /*
- * Return the fd table for this fd or NULL is fd out
- * of range.
+ * Return the fd table for this fd.
  */
 static inline fdEntry_t *getFdEntry(int fd)
 {
-    if (fd < 0 || fd >= fdCount) {
+    fdEntry_t* result = NULL;
+
+    if (fd < 0) {
         return NULL;
     }
-    return &fdTable[fd];
+
+    /* This should not happen. If it does, our assumption about
+     * max. fd value was wrong. */
+    assert(fd < fdLimit);
+
+    if (fd < fdTableMaxSize) {
+        /* fd is in base table. */
+        assert(fd < fdTableLen);
+        result = &fdTable[fd];
+    } else {
+        /* fd is in overflow table. */
+        const int indexInOverflowTable = fd - fdTableMaxSize;
+        const int rootindex = indexInOverflowTable / fdOverflowTableSlabSize;
+        const int slabindex = indexInOverflowTable % fdOverflowTableSlabSize;
+        fdEntry_t* slab = NULL;
+        assert(rootindex < fdOverflowTableLen);
+        assert(slabindex < fdOverflowTableSlabSize);
+        pthread_mutex_lock(&fdOverflowTableLock);
+        /* Allocate new slab in overflow table if needed */
+        if (fdOverflowTable[rootindex] == NULL) {
+            fdEntry_t* const newSlab =
+                (fdEntry_t*)calloc(fdOverflowTableSlabSize, sizeof(fdEntry_t));
+            if (newSlab == NULL) {
+                fprintf(stderr, "Unable to allocate file descriptor overflow"
+                        " table slab - out of memory");
+                pthread_mutex_unlock(&fdOverflowTableLock);
+                abort();
+            } else {
+                int i;
+                for (i = 0; i < fdOverflowTableSlabSize; i ++) {
+                    pthread_mutex_init(&newSlab[i].lock, NULL);
+                }
+                fdOverflowTable[rootindex] = newSlab;
+            }
+        }
+        pthread_mutex_unlock(&fdOverflowTableLock);
+        slab = fdOverflowTable[rootindex];
+        result = &slab[slabindex];
+    }
+
+    return result;
+
 }
 
+
 /*
  * Start a blocking operation :-
  *    Insert thread onto thread list for the fd.
--- a/src/java.base/linux/classes/sun/nio/fs/LinuxFileSystemProvider.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/linux/classes/sun/nio/fs/LinuxFileSystemProvider.java	Sun May 08 08:25:10 2016 +0000
@@ -102,7 +102,7 @@
 
     @Override
     FileTypeDetector getFileTypeDetector() {
-        String userHome = GetPropertyAction.getProperty("user.home");
+        String userHome = GetPropertyAction.privilegedGetProperty("user.home");
         Path userMimeTypes = Paths.get(userHome, ".mime.types");
         Path etcMimeTypes = Paths.get("/etc/mime.types");
 
--- a/src/java.base/linux/native/libnet/linux_close.c	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/linux/native/libnet/linux_close.c	Sun May 08 08:25:10 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -23,6 +23,8 @@
  * questions.
  */
 
+#include <assert.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <signal.h>
@@ -59,10 +61,35 @@
 static int sigWakeup = (__SIGRTMAX - 2);
 
 /*
- * The fd table and the number of file descriptors
+ * fdTable holds one entry per file descriptor, up to a certain
+ * maximum.
+ * Theoretically, the number of possible file descriptors can get
+ * large, though usually it does not. Entries for small value file
+ * descriptors are kept in a simple table, which covers most scenarios.
+ * Entries for large value file descriptors are kept in an overflow
+ * table, which is organized as a sparse two dimensional array whose
+ * slabs are allocated on demand. This covers all corner cases while
+ * keeping memory consumption reasonable.
  */
-static fdEntry_t *fdTable;
-static int fdCount;
+
+/* Base table for low value file descriptors */
+static fdEntry_t* fdTable = NULL;
+/* Maximum size of base table (in number of entries). */
+static const int fdTableMaxSize = 0x1000; /* 4K */
+/* Actual size of base table (in number of entries) */
+static int fdTableLen = 0;
+/* Max. theoretical number of file descriptors on system. */
+static int fdLimit = 0;
+
+/* Overflow table, should base table not be large enough. Organized as
+ *   an array of n slabs, each holding 64k entries.
+ */
+static fdEntry_t** fdOverflowTable = NULL;
+/* Number of slabs in the overflow table */
+static int fdOverflowTableLen = 0;
+/* Number of entries in one slab */
+static const int fdOverflowTableSlabSize = 0x10000; /* 64k */
+pthread_mutex_t fdOverflowTableLock = PTHREAD_MUTEX_INITIALIZER;
 
 /*
  * Null signal handler
@@ -78,18 +105,43 @@
     struct rlimit nbr_files;
     sigset_t sigset;
     struct sigaction sa;
+    int i = 0;
 
-    /*
-     * Allocate table based on the maximum number of
-     * file descriptors.
-     */
-    getrlimit(RLIMIT_NOFILE, &nbr_files);
-    fdCount = nbr_files.rlim_max;
-    fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t));
+    /* Determine the maximum number of possible file descriptors. */
+    if (-1 == getrlimit(RLIMIT_NOFILE, &nbr_files)) {
+        fprintf(stderr, "library initialization failed - "
+                "unable to get max # of allocated fds\n");
+        abort();
+    }
+    if (nbr_files.rlim_max != RLIM_INFINITY) {
+        fdLimit = nbr_files.rlim_max;
+    } else {
+        /* We just do not know. */
+        fdLimit = INT_MAX;
+    }
+
+    /* Allocate table for low value file descriptors. */
+    fdTableLen = fdLimit < fdTableMaxSize ? fdLimit : fdTableMaxSize;
+    fdTable = (fdEntry_t*) calloc(fdTableLen, sizeof(fdEntry_t));
     if (fdTable == NULL) {
         fprintf(stderr, "library initialization failed - "
                 "unable to allocate file descriptor table - out of memory");
         abort();
+    } else {
+        for (i = 0; i < fdTableLen; i ++) {
+            pthread_mutex_init(&fdTable[i].lock, NULL);
+        }
+    }
+
+    /* Allocate overflow table, if needed */
+    if (fdLimit > fdTableMaxSize) {
+        fdOverflowTableLen = ((fdLimit - fdTableMaxSize) / fdOverflowTableSlabSize) + 1;
+        fdOverflowTable = (fdEntry_t**) calloc(fdOverflowTableLen, sizeof(fdEntry_t*));
+        if (fdOverflowTable == NULL) {
+            fprintf(stderr, "library initialization failed - "
+                    "unable to allocate file descriptor overflow table - out of memory");
+            abort();
+        }
     }
 
     /*
@@ -106,15 +158,57 @@
 }
 
 /*
- * Return the fd table for this fd or NULL is fd out
- * of range.
+ * Return the fd table for this fd.
  */
 static inline fdEntry_t *getFdEntry(int fd)
 {
-    if (fd < 0 || fd >= fdCount) {
+    fdEntry_t* result = NULL;
+
+    if (fd < 0) {
         return NULL;
     }
-    return &fdTable[fd];
+
+    /* This should not happen. If it does, our assumption about
+     * max. fd value was wrong. */
+    assert(fd < fdLimit);
+
+    if (fd < fdTableMaxSize) {
+        /* fd is in base table. */
+        assert(fd < fdTableLen);
+        result = &fdTable[fd];
+    } else {
+        /* fd is in overflow table. */
+        const int indexInOverflowTable = fd - fdTableMaxSize;
+        const int rootindex = indexInOverflowTable / fdOverflowTableSlabSize;
+        const int slabindex = indexInOverflowTable % fdOverflowTableSlabSize;
+        fdEntry_t* slab = NULL;
+        assert(rootindex < fdOverflowTableLen);
+        assert(slabindex < fdOverflowTableSlabSize);
+        pthread_mutex_lock(&fdOverflowTableLock);
+        /* Allocate new slab in overflow table if needed */
+        if (fdOverflowTable[rootindex] == NULL) {
+            fdEntry_t* const newSlab =
+                (fdEntry_t*)calloc(fdOverflowTableSlabSize, sizeof(fdEntry_t));
+            if (newSlab == NULL) {
+                fprintf(stderr, "Unable to allocate file descriptor overflow"
+                        " table slab - out of memory");
+                pthread_mutex_unlock(&fdOverflowTableLock);
+                abort();
+            } else {
+                int i;
+                for (i = 0; i < fdOverflowTableSlabSize; i ++) {
+                    pthread_mutex_init(&newSlab[i].lock, NULL);
+                }
+                fdOverflowTable[rootindex] = newSlab;
+            }
+        }
+        pthread_mutex_unlock(&fdOverflowTableLock);
+        slab = fdOverflowTable[rootindex];
+        result = &slab[slabindex];
+    }
+
+    return result;
+
 }
 
 /*
--- a/src/java.base/linux/native/libnio/ch/EPollArrayWrapper.c	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/linux/native/libnio/ch/EPollArrayWrapper.c	Sun May 08 08:25:10 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -53,7 +53,7 @@
     start = t.tv_sec * 1000 + t.tv_usec / 1000;
 
     for (;;) {
-        int res = epoll_wait(epfd, events, numfds, timeout);
+        int res = epoll_wait(epfd, events, numfds, remaining);
         if (res < 0 && errno == EINTR) {
             if (remaining >= 0) {
                 gettimeofday(&t, NULL);
--- a/src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java	Sun May 08 08:25:10 2016 +0000
@@ -84,7 +84,8 @@
     static {
         IOUtil.load();
         initStructSizes();
-        String datamodel = GetPropertyAction.getProperty("sun.arch.data.model");
+        String datamodel =
+                GetPropertyAction.privilegedGetProperty("sun.arch.data.model");
         is64bit = "64".equals(datamodel);
     }
 
--- a/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystem.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystem.java	Sun May 08 08:25:10 2016 +0000
@@ -29,8 +29,6 @@
 import java.io.IOException;
 import java.util.*;
 import java.util.regex.Pattern;
-import java.security.AccessController;
-import sun.security.action.GetPropertyAction;
 
 import static sun.nio.fs.MacOSXNativeDispatcher.*;
 
--- a/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystemProvider.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystemProvider.java	Sun May 08 08:25:10 2016 +0000
@@ -46,8 +46,8 @@
 
     @Override
     FileTypeDetector getFileTypeDetector() {
-        Path userMimeTypes = Paths.get(
-            GetPropertyAction.getProperty("user.home"), ".mime.types");
+        Path userMimeTypes = Paths.get(GetPropertyAction
+                .privilegedGetProperty("user.home"), ".mime.types");
 
         return chain(new MimeTypesFileTypeDetector(userMimeTypes),
                      new UTIFileTypeDetector());
--- a/src/java.base/macosx/native/libnet/bsd_close.c	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/macosx/native/libnet/bsd_close.c	Sun May 08 08:25:10 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -23,6 +23,8 @@
  * questions.
  */
 
+#include <assert.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/param.h>
@@ -61,18 +63,35 @@
 static int sigWakeup = SIGIO;
 
 /*
- * The fd table and the number of file descriptors
+ * fdTable holds one entry per file descriptor, up to a certain
+ * maximum.
+ * Theoretically, the number of possible file descriptors can get
+ * large, though usually it does not. Entries for small value file
+ * descriptors are kept in a simple table, which covers most scenarios.
+ * Entries for large value file descriptors are kept in an overflow
+ * table, which is organized as a sparse two dimensional array whose
+ * slabs are allocated on demand. This covers all corner cases while
+ * keeping memory consumption reasonable.
  */
-static fdEntry_t *fdTable;
-static int fdCount;
 
-/*
- * This limit applies if getlimit() returns unlimited.
- * Unfortunately, this means if someone wants a higher limit
- * then they have to set an explicit limit, higher than this,
- * which is probably counter-intuitive.
+/* Base table for low value file descriptors */
+static fdEntry_t* fdTable = NULL;
+/* Maximum size of base table (in number of entries). */
+static const int fdTableMaxSize = 0x1000; /* 4K */
+/* Actual size of base table (in number of entries) */
+static int fdTableLen = 0;
+/* Max. theoretical number of file descriptors on system. */
+static int fdLimit = 0;
+
+/* Overflow table, should base table not be large enough. Organized as
+ *   an array of n slabs, each holding 64k entries.
  */
-#define MAX_FD_COUNT 4096
+static fdEntry_t** fdOverflowTable = NULL;
+/* Number of slabs in the overflow table */
+static int fdOverflowTableLen = 0;
+/* Number of entries in one slab */
+static const int fdOverflowTableSlabSize = 0x10000; /* 64k */
+pthread_mutex_t fdOverflowTableLock = PTHREAD_MUTEX_INITIALIZER;
 
 /*
  * Null signal handler
@@ -88,26 +107,43 @@
     struct rlimit nbr_files;
     sigset_t sigset;
     struct sigaction sa;
-    int i;
+    int i = 0;
 
-    /*
-     * Allocate table based on the maximum number of
-     * file descriptors.
-     */
-    getrlimit(RLIMIT_NOFILE, &nbr_files);
-    if (nbr_files.rlim_max == RLIM_INFINITY) {
-        fdCount = MAX_FD_COUNT;
+    /* Determine the maximum number of possible file descriptors. */
+    if (-1 == getrlimit(RLIMIT_NOFILE, &nbr_files)) {
+        fprintf(stderr, "library initialization failed - "
+                "unable to get max # of allocated fds\n");
+        abort();
+    }
+    if (nbr_files.rlim_max != RLIM_INFINITY) {
+        fdLimit = nbr_files.rlim_max;
     } else {
-        fdCount = nbr_files.rlim_max;
+        /* We just do not know. */
+        fdLimit = INT_MAX;
     }
-    fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t));
+
+    /* Allocate table for low value file descriptors. */
+    fdTableLen = fdLimit < fdTableMaxSize ? fdLimit : fdTableMaxSize;
+    fdTable = (fdEntry_t*) calloc(fdTableLen, sizeof(fdEntry_t));
     if (fdTable == NULL) {
         fprintf(stderr, "library initialization failed - "
                 "unable to allocate file descriptor table - out of memory");
         abort();
+    } else {
+        for (i = 0; i < fdTableLen; i ++) {
+            pthread_mutex_init(&fdTable[i].lock, NULL);
+        }
     }
-    for (i=0; i<fdCount; i++) {
-        pthread_mutex_init(&fdTable[i].lock, NULL);
+
+    /* Allocate overflow table, if needed */
+    if (fdLimit > fdTableMaxSize) {
+        fdOverflowTableLen = ((fdLimit - fdTableMaxSize) / fdOverflowTableSlabSize) + 1;
+        fdOverflowTable = (fdEntry_t**) calloc(fdOverflowTableLen, sizeof(fdEntry_t*));
+        if (fdOverflowTable == NULL) {
+            fprintf(stderr, "library initialization failed - "
+                    "unable to allocate file descriptor overflow table - out of memory");
+            abort();
+        }
     }
 
     /*
@@ -124,17 +160,60 @@
 }
 
 /*
- * Return the fd table for this fd or NULL is fd out
- * of range.
+ * Return the fd table for this fd.
  */
 static inline fdEntry_t *getFdEntry(int fd)
 {
-    if (fd < 0 || fd >= fdCount) {
+    fdEntry_t* result = NULL;
+
+    if (fd < 0) {
         return NULL;
     }
-    return &fdTable[fd];
+
+    /* This should not happen. If it does, our assumption about
+     * max. fd value was wrong. */
+    assert(fd < fdLimit);
+
+    if (fd < fdTableMaxSize) {
+        /* fd is in base table. */
+        assert(fd < fdTableLen);
+        result = &fdTable[fd];
+    } else {
+        /* fd is in overflow table. */
+        const int indexInOverflowTable = fd - fdTableMaxSize;
+        const int rootindex = indexInOverflowTable / fdOverflowTableSlabSize;
+        const int slabindex = indexInOverflowTable % fdOverflowTableSlabSize;
+        fdEntry_t* slab = NULL;
+        assert(rootindex < fdOverflowTableLen);
+        assert(slabindex < fdOverflowTableSlabSize);
+        pthread_mutex_lock(&fdOverflowTableLock);
+        /* Allocate new slab in overflow table if needed */
+        if (fdOverflowTable[rootindex] == NULL) {
+            fdEntry_t* const newSlab =
+                (fdEntry_t*)calloc(fdOverflowTableSlabSize, sizeof(fdEntry_t));
+            if (newSlab == NULL) {
+                fprintf(stderr, "Unable to allocate file descriptor overflow"
+                        " table slab - out of memory");
+                pthread_mutex_unlock(&fdOverflowTableLock);
+                abort();
+            } else {
+                int i;
+                for (i = 0; i < fdOverflowTableSlabSize; i ++) {
+                    pthread_mutex_init(&newSlab[i].lock, NULL);
+                }
+                fdOverflowTable[rootindex] = newSlab;
+            }
+        }
+        pthread_mutex_unlock(&fdOverflowTableLock);
+        slab = fdOverflowTable[rootindex];
+        result = &slab[slabindex];
+    }
+
+    return result;
+
 }
 
+
 /*
  * Start a blocking operation :-
  *    Insert thread onto thread list for the fd.
--- a/src/java.base/share/classes/java/io/File.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/io/File.java	Sun May 08 08:25:10 2016 +0000
@@ -1896,7 +1896,7 @@
 
         // temporary directory location
         private static final File tmpdir = new File(
-                GetPropertyAction.getProperty("java.io.tmpdir"));
+                GetPropertyAction.privilegedGetProperty("java.io.tmpdir"));
         static File location() {
             return tmpdir;
         }
--- a/src/java.base/share/classes/java/lang/Class.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/Class.java	Sun May 08 08:25:10 2016 +0000
@@ -470,7 +470,7 @@
      * expression with an empty argument list.  The class is initialized if it
      * has not already been initialized.
      *
-     * <p>Note that this method propagates any exception thrown by the
+     * @deprecated This method propagates any exception thrown by the
      * nullary constructor, including a checked exception.  Use of
      * this method effectively bypasses the compile-time exception
      * checking that would otherwise be performed by the compiler.
@@ -500,6 +500,7 @@
      *          of this class.
      */
     @CallerSensitive
+    @Deprecated(since="9")
     public T newInstance()
         throws InstantiationException, IllegalAccessException
     {
--- a/src/java.base/share/classes/java/lang/ClassLoader.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/ClassLoader.java	Sun May 08 08:25:10 2016 +0000
@@ -2615,7 +2615,7 @@
     ServicesCatalog createOrGetServicesCatalog() {
         ServicesCatalog catalog = servicesCatalog;
         if (catalog == null) {
-            catalog = new ServicesCatalog();
+            catalog = ServicesCatalog.create();
             boolean set = trySetObjectField("servicesCatalog", catalog);
             if (!set) {
                 // beaten by someone else
--- a/src/java.base/share/classes/java/lang/ProcessBuilder.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/ProcessBuilder.java	Sun May 08 08:25:10 2016 +0000
@@ -468,7 +468,7 @@
      */
     public abstract static class Redirect {
         private static final File NULL_FILE = new File(
-                (GetPropertyAction.getProperty("os.name")
+                (GetPropertyAction.privilegedGetProperty("os.name")
                         .startsWith("Windows") ? "NUL" : "/dev/null")
         );
 
--- a/src/java.base/share/classes/java/lang/Runtime.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/Runtime.java	Sun May 08 08:25:10 2016 +0000
@@ -718,41 +718,27 @@
     }
 
     /**
-     * Enables/Disables tracing of instructions.
-     * If the {@code boolean} argument is {@code true}, this
-     * method suggests that the Java virtual machine emit debugging
-     * information for each instruction in the virtual machine as it
-     * is executed. The format of this information, and the file or other
-     * output stream to which it is emitted, depends on the host environment.
-     * The virtual machine may ignore this request if it does not support
-     * this feature. The destination of the trace output is system
-     * dependent.
-     * <p>
-     * If the {@code boolean} argument is {@code false}, this
-     * method causes the virtual machine to stop performing the
-     * detailed instruction trace it is performing.
+     * Not implemented, does nothing.
      *
-     * @param   on   {@code true} to enable instruction tracing;
-     *               {@code false} to disable this feature.
+     * @deprecated
+     * This method was intended to control instruction tracing.
+     * It has been superseded by JVM-specific tracing mechanisms.
+     *
+     * @param on ignored
      */
+    @Deprecated(since="9", forRemoval=true)
     public void traceInstructions(boolean on) { }
 
     /**
-     * Enables/Disables tracing of method calls.
-     * If the {@code boolean} argument is {@code true}, this
-     * method suggests that the Java virtual machine emit debugging
-     * information for each method in the virtual machine as it is
-     * called. The format of this information, and the file or other output
-     * stream to which it is emitted, depends on the host environment. The
-     * virtual machine may ignore this request if it does not support
-     * this feature.
-     * <p>
-     * Calling this method with argument false suggests that the
-     * virtual machine cease emitting per-call debugging information.
+     * Not implemented, does nothing.
      *
-     * @param   on   {@code true} to enable instruction tracing;
-     *               {@code false} to disable this feature.
+     * @deprecated
+     * This method was intended to control method call tracing.
+     * It has been superseded by JVM-specific tracing mechanisms.
+     *
+     * @param on ignored
      */
+    @Deprecated(since="9", forRemoval=true)
     public void traceMethodCalls(boolean on) { }
 
     /**
--- a/src/java.base/share/classes/java/lang/StackStreamFactory.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/StackStreamFactory.java	Sun May 08 08:25:10 2016 +0000
@@ -78,7 +78,8 @@
      * Performance work and extensive testing is needed to replace the
      * VM built-in backtrace filled in Throwable with the StackWalker.
      */
-    final static boolean isDebug = getProperty("stackwalk.debug", false);
+    final static boolean isDebug =
+            "true".equals(GetPropertyAction.privilegedGetProperty("stackwalk.debug"));
 
     static <T> StackFrameTraverser<T>
         makeStackTraverser(StackWalker walker, Function<? super Stream<StackFrame>, ? extends T> function)
@@ -988,11 +989,4 @@
                 c.getName().startsWith("java.lang.invoke.LambdaForm");
     }
 
-    private static boolean getProperty(String key, boolean value) {
-        String s = GetPropertyAction.getProperty(key);
-        if (s != null) {
-            return Boolean.parseBoolean(s);
-        }
-        return value;
-    }
 }
--- a/src/java.base/share/classes/java/lang/String.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/String.java	Sun May 08 08:25:10 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 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
@@ -78,14 +78,8 @@
  * <p>
  * The Java language provides special support for the string
  * concatenation operator (&nbsp;+&nbsp;), and for conversion of
- * other objects to strings. String concatenation is implemented
- * through the {@code StringBuilder}(or {@code StringBuffer})
- * class and its {@code append} method.
- * String conversions are implemented through the method
- * {@code toString}, defined by {@code Object} and
- * inherited by all classes in Java. For additional information on
- * string concatenation and conversion, see Gosling, Joy, and Steele,
- * <i>The Java Language Specification</i>.
+ * other objects to strings. For additional information on string
+ * concatenation and conversion, see <i>The Java&trade; Language Specification</i>.
  *
  * <p> Unless otherwise noted, passing a {@code null} argument to a constructor
  * or method in this class will cause a {@link NullPointerException} to be
@@ -106,6 +100,14 @@
  * into account.  The {@link java.text.Collator} class provides methods for
  * finer-grain, locale-sensitive String comparison.
  *
+ * @implNote The implementation of the string concatenation operator is left to
+ * the discretion of a Java compiler, as long as the compiler ultimately conforms
+ * to <i>The Java&trade; Language Specification</i>. For example, the {@code javac} compiler
+ * may implement the operator with {@code StringBuffer}, {@code StringBuilder},
+ * or {@code java.lang.invoke.StringConcatFactory} depending on the JDK version. The
+ * implementation of string conversion is typically through the method {@code toString},
+ * defined by {@code Object} and inherited by all classes in Java.
+ *
  * @author  Lee Boynton
  * @author  Arthur van Hoff
  * @author  Martin Buchholz
@@ -115,6 +117,7 @@
  * @see     java.lang.StringBuilder
  * @see     java.nio.charset.Charset
  * @since   1.0
+ * @jls     15.18.1 String Concatenation Operator +
  */
 
 public final class String
@@ -2977,6 +2980,7 @@
      *
      * @return  a string that has the same contents as this string, but is
      *          guaranteed to be from a pool of unique strings.
+     * @jls 3.10.5 String Literals
      */
     public native String intern();
 
--- a/src/java.base/share/classes/java/lang/System.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/System.java	Sun May 08 08:25:10 2016 +0000
@@ -69,7 +69,6 @@
 import jdk.internal.logger.LocalizedLoggerWrapper;
 
 import jdk.internal.module.ModuleBootstrap;
-import jdk.internal.module.Modules;
 import jdk.internal.module.ServicesCatalog;
 
 /**
@@ -1155,8 +1154,9 @@
          * @param level the log message level.
          * @param msg the string message (or a key in the message catalog, if
          * this logger is a {@link
-         * LoggerFinder#getLocalizedLogger(java.lang.String, java.util.ResourceBundle, java.lang.Class)
-         * localized logger}); can be {@code null}.
+         * LoggerFinder#getLocalizedLogger(java.lang.String,
+         * java.util.ResourceBundle, java.lang.reflect.Module) localized logger});
+         * can be {@code null}.
          *
          * @throws NullPointerException if {@code level} is {@code null}.
          */
@@ -1222,8 +1222,9 @@
          * @param level the log message level.
          * @param msg the string message (or a key in the message catalog, if
          * this logger is a {@link
-         * LoggerFinder#getLocalizedLogger(java.lang.String, java.util.ResourceBundle, java.lang.Class)
-         * localized logger}); can be {@code null}.
+         * LoggerFinder#getLocalizedLogger(java.lang.String,
+         * java.util.ResourceBundle, java.lang.reflect.Module) localized logger});
+         * can be {@code null}.
          * @param thrown a {@code Throwable} associated with the log message;
          *        can be {@code null}.
          *
@@ -1270,8 +1271,9 @@
          * @param format the string message format in {@link
          * java.text.MessageFormat} format, (or a key in the message
          * catalog, if this logger is a {@link
-         * LoggerFinder#getLocalizedLogger(java.lang.String, java.util.ResourceBundle, java.lang.Class)
-         * localized logger}); can be {@code null}.
+         * LoggerFinder#getLocalizedLogger(java.lang.String,
+         * java.util.ResourceBundle, java.lang.reflect.Module) localized logger});
+         * can be {@code null}.
          * @param params an optional list of parameters to the message (may be
          * none).
          *
@@ -1453,30 +1455,30 @@
 
         /**
          * Returns an instance of {@link Logger Logger}
-         * for the given {@code caller}.
+         * for the given {@code module}.
          *
          * @param name the name of the logger.
-         * @param caller the class for which the logger is being requested.
+         * @param module the module for which the logger is being requested.
          *
-         * @return a {@link Logger logger} suitable for the given caller's
-         *         use.
+         * @return a {@link Logger logger} suitable for use within the given
+         *         module.
          * @throws NullPointerException if {@code name} is {@code null} or
-         *        {@code caller} is {@code null}.
+         *        {@code module} is {@code null}.
          * @throws SecurityException if a security manager is present and its
          *         {@code checkPermission} method doesn't allow the
          *         {@code RuntimePermission("loggerFinder")}.
          */
-        public abstract Logger getLogger(String name, /* Module */ Class<?> caller);
+        public abstract Logger getLogger(String name, Module module);
 
         /**
          * Returns a localizable instance of {@link Logger Logger}
-         * for the given {@code caller}.
+         * for the given {@code module}.
          * The returned logger will use the provided resource bundle for
          * message localization.
          *
          * @implSpec By default, this method calls {@link
-         * #getLogger(java.lang.String, java.lang.Class)
-         * this.getLogger(name, caller)} to obtain a logger, then wraps that
+         * #getLogger(java.lang.String, java.lang.reflect.Module)
+         * this.getLogger(name, module)} to obtain a logger, then wraps that
          * logger in a {@link Logger} instance where all methods that do not
          * take a {@link ResourceBundle} as parameter are redirected to one
          * which does - passing the given {@code bundle} for
@@ -1499,19 +1501,19 @@
          *
          * @param name    the name of the logger.
          * @param bundle  a resource bundle; can be {@code null}.
-         * @param caller the class for which the logger is being requested.
+         * @param module  the module for which the logger is being requested.
          * @return an instance of {@link Logger Logger}  which will use the
          * provided resource bundle for message localization.
          *
          * @throws NullPointerException if {@code name} is {@code null} or
-         *         {@code caller} is {@code null}.
+         *         {@code module} is {@code null}.
          * @throws SecurityException if a security manager is present and its
          *         {@code checkPermission} method doesn't allow the
          *         {@code RuntimePermission("loggerFinder")}.
          */
         public Logger getLocalizedLogger(String name, ResourceBundle bundle,
-                                          /* Module */ Class<?> caller) {
-            return new LocalizedLoggerWrapper<>(getLogger(name, caller), bundle);
+                                         Module module) {
+            return new LocalizedLoggerWrapper<>(getLogger(name, module), bundle);
         }
 
         /**
@@ -1558,12 +1560,13 @@
      *
      * @implSpec
      * Instances returned by this method route messages to loggers
-     * obtained by calling {@link LoggerFinder#getLogger(java.lang.String, java.lang.Class)
-     * LoggerFinder.getLogger(name, caller)}.
+     * obtained by calling {@link LoggerFinder#getLogger(java.lang.String,
+     * java.lang.reflect.Module) LoggerFinder.getLogger(name, module)}, where
+     * {@code module} is the caller's module.
      *
      * @apiNote
      * This method may defer calling the {@link
-     * LoggerFinder#getLogger(java.lang.String, java.lang.Class)
+     * LoggerFinder#getLogger(java.lang.String, java.lang.reflect.Module)
      * LoggerFinder.getLogger} method to create an actual logger supplied by
      * the logging backend, for instance, to allow loggers to be obtained during
      * the system initialization time.
@@ -1579,7 +1582,7 @@
     public static Logger getLogger(String name) {
         Objects.requireNonNull(name);
         final Class<?> caller = Reflection.getCallerClass();
-        return LazyLoggers.getLogger(name, caller);
+        return LazyLoggers.getLogger(name, caller.getModule());
     }
 
     /**
@@ -1591,8 +1594,9 @@
      * @implSpec
      * The returned logger will perform message localization as specified
      * by {@link LoggerFinder#getLocalizedLogger(java.lang.String,
-     * java.util.ResourceBundle, java.lang.Class)
-     * LoggerFinder.getLocalizedLogger(name, bundle, caller}.
+     * java.util.ResourceBundle, java.lang.reflect.Module)
+     * LoggerFinder.getLocalizedLogger(name, bundle, module}, where
+     * {@code module} is the caller's module.
      *
      * @apiNote
      * This method is intended to be used after the system is fully initialized.
@@ -1624,12 +1628,14 @@
         // Bootstrap sensitive classes in the JDK do not use resource bundles
         // when logging. This could be revisited later, if it needs to.
         if (sm != null) {
-            return AccessController.doPrivileged((PrivilegedAction<Logger>)
-                    () -> LoggerFinder.accessProvider().getLocalizedLogger(name, rb, caller),
-                    null,
-                    LoggerFinder.LOGGERFINDER_PERMISSION);
+            final PrivilegedAction<Logger> pa =
+                    () -> LoggerFinder.accessProvider()
+                            .getLocalizedLogger(name, rb, caller.getModule());
+            return AccessController.doPrivileged(pa, null,
+                                         LoggerFinder.LOGGERFINDER_PERMISSION);
         }
-        return LoggerFinder.accessProvider().getLocalizedLogger(name, rb, caller);
+        return LoggerFinder.accessProvider()
+                .getLocalizedLogger(name, rb, caller.getModule());
     }
 
     /**
@@ -1917,10 +1923,6 @@
         // initialize the module system
         System.bootLayer = ModuleBootstrap.boot();
 
-        // base module needs to be loose (CODETOOLS-7901619)
-        Module base = Object.class.getModule();
-        Modules.addReads(base, null);
-
         // module system initialized
         VM.initLevel(2);
     }
--- a/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java	Sun May 08 08:25:10 2016 +0000
@@ -88,7 +88,7 @@
 
     static {
         final String key = "jdk.internal.lambda.dumpProxyClasses";
-        String path = GetPropertyAction.getProperty(key);
+        String path = GetPropertyAction.privilegedGetProperty(key);
         dumper = (null == path) ? null : ProxyClassesDumper.getInstance(path);
     }
 
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Sun May 08 08:25:10 2016 +0000
@@ -25,6 +25,7 @@
 
 package java.lang.invoke;
 
+import java.lang.reflect.Array;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.Arrays;
@@ -1892,7 +1893,8 @@
             MH_tryFinallyExec        = 12,
             MH_tryFinallyVoidExec    = 13,
             MH_decrementCounter      = 14,
-            MH_LIMIT                 = 15;
+            MH_Array_newInstance     = 15,
+            MH_LIMIT                 = 16;
 
     static MethodHandle getConstantHandle(int idx) {
         MethodHandle handle = HANDLES[idx];
@@ -1965,6 +1967,9 @@
                 case MH_decrementCounter:
                     return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "decrementCounter",
                             MethodType.methodType(int.class, int.class));
+                case MH_Array_newInstance:
+                    return IMPL_LOOKUP.findStatic(Array.class, "newInstance",
+                            MethodType.methodType(Object.class, Class.class, int.class));
             }
         } catch (ReflectiveOperationException ex) {
             throw newInternalError(ex);
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java	Sun May 08 08:25:10 2016 +0000
@@ -53,7 +53,7 @@
     static final boolean VAR_HANDLE_GUARDS;
 
     static {
-        Properties props = GetPropertyAction.getProperties();
+        Properties props = GetPropertyAction.privilegedGetProperties();
         DEBUG_METHOD_HANDLE_NAMES = Boolean.parseBoolean(
                 props.getProperty("java.lang.invoke.MethodHandle.DEBUG_NAMES"));
         DUMP_CLASS_FILES = Boolean.parseBoolean(
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Sun May 08 08:25:10 2016 +0000
@@ -25,34 +25,38 @@
 
 package java.lang.invoke;
 
-import java.lang.reflect.*;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.reflect.CallerSensitive;
+import jdk.internal.reflect.Reflection;
+import sun.invoke.util.ValueConversions;
+import sun.invoke.util.VerifyAccess;
+import sun.invoke.util.Wrapper;
+import sun.reflect.misc.ReflectUtil;
+import sun.security.util.SecurityConstants;
+
+import java.lang.invoke.LambdaForm.BasicType;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ReflectPermission;
+import java.nio.ByteOrder;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.BitSet;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Arrays;
 import java.util.Objects;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-import sun.invoke.util.ValueConversions;
-import sun.invoke.util.VerifyAccess;
-import sun.invoke.util.Wrapper;
-import jdk.internal.reflect.CallerSensitive;
-import jdk.internal.reflect.Reflection;
-import sun.reflect.misc.ReflectUtil;
-import sun.security.util.SecurityConstants;
-import java.lang.invoke.LambdaForm.BasicType;
-
-import static java.lang.invoke.MethodHandleImpl.Intrinsic;
-import static java.lang.invoke.MethodHandleNatives.Constants.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
-import jdk.internal.org.objectweb.asm.ClassWriter;
-import jdk.internal.org.objectweb.asm.Opcodes;
-
+import static java.lang.invoke.MethodHandleImpl.Intrinsic;
+import static java.lang.invoke.MethodHandleNatives.Constants.*;
 import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
 import static java.lang.invoke.MethodType.methodType;
 
@@ -741,10 +745,13 @@
             if (name.startsWith("java.lang.invoke."))
                 throw newIllegalArgumentException("illegal lookupClass: "+lookupClass);
 
-            // For caller-sensitive MethodHandles.lookup()
-            // disallow lookup more restricted packages
+            // For caller-sensitive MethodHandles.lookup() disallow lookup from
+            // restricted packages.  This a fragile and blunt approach.
+            // TODO replace with a more formal and less fragile mechanism
+            // that does not bluntly restrict classes under packages within
+            // java.base from looking up MethodHandles or VarHandles.
             if (allowedModes == ALL_MODES && lookupClass.getClassLoader() == null) {
-                if (name.startsWith("java.") ||
+                if ((name.startsWith("java.") && !name.startsWith("java.util.concurrent.")) ||
                         (name.startsWith("sun.") && !name.startsWith("sun.invoke."))) {
                     throw newIllegalArgumentException("illegal lookupClass: " + lookupClass);
                 }
@@ -1003,6 +1010,9 @@
          * @throws NullPointerException if any argument is null
          */
         public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
+            if (refc.isArray()) {
+                throw new NoSuchMethodException("no constructor for array class: " + refc.getName());
+            }
             String name = "<init>";
             MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
             return getDirectConstructor(refc, ctor);
@@ -2214,6 +2224,27 @@
     }
 
     /**
+     * Produces a method handle constructing arrays of a desired type.
+     * The return type of the method handle will be the array type.
+     * The type of its sole argument will be {@code int}, which specifies the size of the array.
+     * @param arrayClass an array type
+     * @return a method handle which can create arrays of the given type
+     * @throws NullPointerException if the argument is {@code null}
+     * @throws IllegalArgumentException if {@code arrayClass} is not an array type
+     * @see java.lang.reflect.Array#newInstance(Class, int)
+     * @since 9
+     */
+    public static
+    MethodHandle arrayConstructor(Class<?> arrayClass) throws IllegalArgumentException {
+        if (!arrayClass.isArray()) {
+            throw newIllegalArgumentException("not an array class: " + arrayClass.getName());
+        }
+        MethodHandle ani = MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_Array_newInstance).
+                bindTo(arrayClass.getComponentType());
+        return ani.asType(ani.type().changeReturnType(arrayClass));
+    }
+
+    /**
      * Produces a method handle giving read access to elements of an array.
      * The type of the method handle will have a return type of the array's
      * element type.  Its first argument will be the array type,
@@ -2337,13 +2368,12 @@
      *
      * @param viewArrayClass the view array class, with a component type of
      * type {@code T}
-     * @param bigEndian true if the endianness of the view array elements, as
-     * stored in the underlying {@code byte} array, is big endian, otherwise
-     * little endian
+     * @param byteOrder the endianness of the view array elements, as
+     * stored in the underlying {@code byte} array
      * @return a VarHandle giving access to elements of a {@code byte[]} array
      * viewed as if elements corresponding to the components type of the view
      * array class
-     * @throws NullPointerException if viewArrayClass is null
+     * @throws NullPointerException if viewArrayClass or byteOrder is null
      * @throws IllegalArgumentException if viewArrayClass is not an array type
      * @throws UnsupportedOperationException if the component type of
      * viewArrayClass is not supported as a variable type
@@ -2351,8 +2381,10 @@
      */
     public static
     VarHandle byteArrayViewVarHandle(Class<?> viewArrayClass,
-                                     boolean bigEndian) throws IllegalArgumentException {
-        return VarHandles.byteArrayViewHandle(viewArrayClass, bigEndian);
+                                     ByteOrder byteOrder) throws IllegalArgumentException {
+        Objects.requireNonNull(byteOrder);
+        return VarHandles.byteArrayViewHandle(viewArrayClass,
+                                              byteOrder == ByteOrder.BIG_ENDIAN);
     }
 
     /**
@@ -2422,14 +2454,13 @@
      *
      * @param viewArrayClass the view array class, with a component type of
      * type {@code T}
-     * @param bigEndian true if the endianness of the view array elements, as
-     * stored in the underlying {@code ByteBuffer}, is big endian, otherwise
-     * little endian (Note this overrides the endianness of a
-     * {@code ByteBuffer})
+     * @param byteOrder the endianness of the view array elements, as
+     * stored in the underlying {@code ByteBuffer} (Note this overrides the
+     * endianness of a {@code ByteBuffer})
      * @return a VarHandle giving access to elements of a {@code ByteBuffer}
      * viewed as if elements corresponding to the components type of the view
      * array class
-     * @throws NullPointerException if viewArrayClass is null
+     * @throws NullPointerException if viewArrayClass or byteOrder is null
      * @throws IllegalArgumentException if viewArrayClass is not an array type
      * @throws UnsupportedOperationException if the component type of
      * viewArrayClass is not supported as a variable type
@@ -2437,8 +2468,10 @@
      */
     public static
     VarHandle byteBufferViewVarHandle(Class<?> viewArrayClass,
-                                      boolean bigEndian) throws IllegalArgumentException {
-        return VarHandles.makeByteBufferViewHandle(viewArrayClass, bigEndian);
+                                      ByteOrder byteOrder) throws IllegalArgumentException {
+        Objects.requireNonNull(byteOrder);
+        return VarHandles.makeByteBufferViewHandle(viewArrayClass,
+                                                   byteOrder == ByteOrder.BIG_ENDIAN);
     }
 
 
@@ -4476,12 +4509,24 @@
      * @since 9
      */
     public static MethodHandle countedLoop(MethodHandle start, MethodHandle end, MethodHandle init, MethodHandle body) {
-        MethodHandle returnVar = dropArguments(init == null || init.type().returnType() == void.class ?
-                zero(void.class) : identity(init.type().returnType()), 0, int.class, int.class);
+        Class<?> resultType;
+        MethodHandle actualInit;
+        if (init == null) {
+            resultType = body == null ? void.class : body.type().returnType();
+            actualInit = empty(methodType(resultType));
+        } else {
+            resultType = init.type().returnType();
+            actualInit = init;
+        }
+        MethodHandle defaultResultHandle = resultType == void.class ? zero(void.class) : identity(resultType);
+        MethodHandle actualBody = body == null ? dropArguments(defaultResultHandle, 0, int.class) : body;
+        MethodHandle returnVar = dropArguments(defaultResultHandle, 0, int.class, int.class);
+        MethodHandle actualEnd = end == null ? constant(int.class, 0) : end;
         MethodHandle[] indexVar = {start, MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_countedLoopStep)};
-        MethodHandle[] loopLimit = {end, null, MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_countedLoopPred), returnVar};
-        MethodHandle[] bodyClause = {init,
-                filterArgument(dropArguments(body, 1, int.class), 0,
+        MethodHandle[] loopLimit = {actualEnd, null,
+                MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_countedLoopPred), returnVar};
+        MethodHandle[] bodyClause = {actualInit,
+                filterArgument(dropArguments(actualBody, 1, int.class), 0,
                         MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_decrementCounter))};
         return loop(indexVar, loopLimit, bodyClause);
     }
@@ -4572,17 +4617,24 @@
      */
     public static MethodHandle iteratedLoop(MethodHandle iterator, MethodHandle init, MethodHandle body) {
         checkIteratedLoop(iterator, body);
-        final boolean voidInit = init == null || init.type().returnType() == void.class;
+        Class<?> resultType = init == null ?
+                body == null ? void.class : body.type().returnType() :
+                init.type().returnType();
+        boolean voidResult = resultType == void.class;
 
-        MethodHandle initit = MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_initIterator);
-        MethodHandle initIterator = iterator == null ?
-                initit.asType(initit.type().changeParameterType(0, body.type().parameterType(voidInit ? 1 : 2))) :
-                iterator;
-        Class<?> itype = initIterator.type().returnType();
+        MethodHandle initIterator;
+        if (iterator == null) {
+            MethodHandle initit = MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_initIterator);
+            initIterator = initit.asType(initit.type().changeParameterType(0,
+                    body.type().parameterType(voidResult ? 1 : 2)));
+        } else {
+            initIterator = iterator.asType(iterator.type().changeReturnType(Iterator.class));
+        }
+
         Class<?> ttype = body.type().parameterType(0);
 
         MethodHandle returnVar =
-                dropArguments(voidInit ? zero(void.class) : identity(init.type().returnType()), 0, itype);
+                dropArguments(voidResult ? zero(void.class) : identity(resultType), 0, Iterator.class);
         MethodHandle initnx = MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_iterateNext);
         MethodHandle nextVal = initnx.asType(initnx.type().changeReturnType(ttype));
 
--- a/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Sun May 08 08:25:10 2016 +0000
@@ -123,7 +123,7 @@
      * Concatenation strategy to use. See {@link Strategy} for possible options.
      * This option is controllable with -Djava.lang.invoke.stringConcat JDK option.
      */
-    private static final Strategy STRATEGY;
+    private static Strategy STRATEGY;
 
     /**
      * Default strategy to use for concatenation.
@@ -187,7 +187,17 @@
     private static final ProxyClassesDumper DUMPER;
 
     static {
-        Properties props = GetPropertyAction.getProperties();
+        // In case we need to double-back onto the StringConcatFactory during this
+        // static initialization, make sure we have the reasonable defaults to complete
+        // the static initialization properly. After that, actual users would use the
+        // the proper values we have read from the the properties.
+        STRATEGY = DEFAULT_STRATEGY;
+        // CACHE_ENABLE = false; // implied
+        // CACHE = null;         // implied
+        // DEBUG = false;        // implied
+        // DUMPER = null;        // implied
+
+        Properties props = GetPropertyAction.privilegedGetProperties();
         final String strategy =
                 props.getProperty("java.lang.invoke.stringConcat");
         CACHE_ENABLE = Boolean.parseBoolean(
--- a/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Sun May 08 08:25:10 2016 +0000
@@ -136,6 +136,7 @@
  * consists of the methods
  * {@link #compareAndSet compareAndSet},
  * {@link #weakCompareAndSet weakCompareAndSet},
+ * {@link #weakCompareAndSetVolatile weakCompareAndSetVolatile},
  * {@link #weakCompareAndSetAcquire weakCompareAndSetAcquire},
  * {@link #weakCompareAndSetRelease weakCompareAndSetRelease},
  * {@link #compareAndExchangeAcquire compareAndExchangeAcquire},
@@ -458,7 +459,7 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code get}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.get)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.GET)} on this VarHandle.
      *
      * <p>This access mode is supported by all VarHandle instances and never
      * throws {@code UnsupportedOperationException}.
@@ -488,7 +489,7 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code set}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.set)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.SET)} on this VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T newValue)}
@@ -516,7 +517,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code getVolatile}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.getVolatile)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.GET_VOLATILE)} on this
+     * VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT)}
@@ -544,7 +546,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code setVolatile}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.setVolatile)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.SET_VOLATILE)} on this
+     * VarHandle.
      *
      * @apiNote
      * Ignoring the many semantic differences from C and C++, this method has
@@ -574,7 +577,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code getOpaque}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.getOpaque)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.GET_OPAQUE)} on this
+     * VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT)}
@@ -603,7 +607,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code setOpaque}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.setOpaque)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.SET_OPAQUE)} on this
+     * VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T newValue)}
@@ -631,7 +636,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code getAcquire}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.getAcquire)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.GET_ACQUIRE)} on this
+     * VarHandle.
      *
      * @apiNote
      * Ignoring the many semantic differences from C and C++, this method has
@@ -664,7 +670,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code setRelease}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.setRelease)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.SET_RELEASE)} on this
+     * VarHandle.
      *
      * @apiNote
      * Ignoring the many semantic differences from C and C++, this method has
@@ -700,7 +707,7 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code
      * compareAndSet} must match the access mode type that is the result of
-     * calling {@code accessModeType(VarHandle.AccessMode.compareAndSet)} on
+     * calling {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_SET)} on
      * this VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
@@ -734,7 +741,7 @@
      * <p>The symbolic type descriptor at the call site of {@code
      * compareAndExchangeVolatile}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.compareAndExchangeVolatile)}
+     * {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE)}
      * on this VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
@@ -769,7 +776,7 @@
      * <p>The symbolic type descriptor at the call site of {@code
      * compareAndExchangeAcquire}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.compareAndExchangeAcquire)} on
+     * {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE)} on
      * this VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
@@ -804,7 +811,8 @@
      * <p>The symbolic type descriptor at the call site of {@code
      * compareAndExchangeRelease}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.compareAndExchangeRelease)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE)}
+     * on this VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T expectedValue, T newValue)}
@@ -836,14 +844,14 @@
      * {@link #get}.
      *
      * <p>This operation may fail spuriously (typically, due to memory
-     * contention) even if the current value does match the expected value.
+     * contention) even if the witness value does match the expected value.
      *
      * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}.
      *
      * <p>The symbolic type descriptor at the call site of {@code
      * weakCompareAndSet} must match the access mode type that is the result of
-     * calling {@code accessModeType(VarHandle.AccessMode.weakCompareAndSet)} on
-     * this VarHandle.
+     * calling {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET)}
+     * on this VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T expectedValue, T newValue)}
@@ -867,20 +875,58 @@
 
     /**
      * Possibly atomically sets the value of a variable to the {@code newValue}
+     * with the memory semantics of {@link #setVolatile} if the variable's
+     * current value, referred to as the <em>witness value</em>, {@code ==} the
+     * {@code expectedValue}, as accessed with the memory semantics of
+     * {@link #getVolatile}.
+     *
+     * <p>This operation may fail spuriously (typically, due to memory
+     * contention) even if the witness value does match the expected value.
+     *
+     * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code
+     * weakCompareAndSetVolatile} must match the access mode type that is the
+     * result of calling {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE)}
+     * on this VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT, T expectedValue, T newValue)}
+     * , statically represented using varargs.
+     * @return {@code true} if successful, otherwise {@code false} if the
+     * witness value was not the same as the {@code expectedValue} or if this
+     * operation spuriously failed.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type is not
+     * compatible with the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type is compatible with the
+     * caller's symbolic type descriptor, but a reference cast fails.
+     * @see #setVolatile(Object...)
+     * @see #getVolatile(Object...)
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    @HotSpotIntrinsicCandidate
+    boolean weakCompareAndSetVolatile(Object... args);
+
+    /**
+     * Possibly atomically sets the value of a variable to the {@code newValue}
      * with the semantics of {@link #set} if the variable's current value,
      * referred to as the <em>witness value</em>, {@code ==} the
      * {@code expectedValue}, as accessed with the memory semantics of
      * {@link #getAcquire}.
      *
      * <p>This operation may fail spuriously (typically, due to memory
-     * contention) even if the current value does match the expected value.
+     * contention) even if the witness value does match the expected value.
      *
      * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}.
      *
      * <p>The symbolic type descriptor at the call site of {@code
      * weakCompareAndSetAcquire}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.weakCompareAndSetAcquire)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE)}
+     * on this VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T expectedValue, T newValue)}
@@ -910,14 +956,15 @@
      * {@link #get}.
      *
      * <p>This operation may fail spuriously (typically, due to memory
-     * contention) even if the current value does match the expected value.
+     * contention) even if the witness value does match the expected value.
      *
      * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}.
      *
      * <p>The symbolic type descriptor at the call site of {@code
      * weakCompareAndSetRelease}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.weakCompareAndSetRelease)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE)}
+     * on this VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T expectedValue, T newValue)}
@@ -949,7 +996,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code getAndSet}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.getAndSet)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.GET_AND_SET)} on this
+     * VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T newValue)}
@@ -985,7 +1033,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code getAndAdd}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.getAndAdd)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.GET_AND_ADD)} on this
+     * VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T value)}
@@ -1017,7 +1066,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code addAndGet}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.addAndGet)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.ADD_AND_GET)} on this
+     * VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T value)}
@@ -1083,109 +1133,115 @@
          * method
          * {@link VarHandle#get VarHandle.get}
          */
-        GET("get", AccessType.GET, Object.class),   // 0
+        GET("get", AccessType.GET, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#set VarHandle.set}
          */
-        SET("set", AccessType.SET, void.class),     // 1
+        SET("set", AccessType.SET, void.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getVolatile VarHandle.getVolatile}
          */
-        GET_VOLATILE("getVolatile", AccessType.GET, Object.class),  // 2
+        GET_VOLATILE("getVolatile", AccessType.GET, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#setVolatile VarHandle.setVolatile}
          */
-        SET_VOLATILE("setVolatile", AccessType.SET, void.class),    // 3
+        SET_VOLATILE("setVolatile", AccessType.SET, void.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getAcquire VarHandle.getAcquire}
          */
-        GET_ACQUIRE("getAcquire", AccessType.GET, Object.class),   // 4
+        GET_ACQUIRE("getAcquire", AccessType.GET, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#setRelease VarHandle.setRelease}
          */
-        SET_RELEASE("setRelease", AccessType.SET, void.class),     // 5
+        SET_RELEASE("setRelease", AccessType.SET, void.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getOpaque VarHandle.getOpaque}
          */
-        GET_OPAQUE("getOpaque", AccessType.GET, Object.class),    // 6
+        GET_OPAQUE("getOpaque", AccessType.GET, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#setOpaque VarHandle.setOpaque}
          */
-        SET_OPAQUE("setOpaque", AccessType.SET, void.class),      // 7
+        SET_OPAQUE("setOpaque", AccessType.SET, void.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#compareAndSet VarHandle.compareAndSet}
          */
-        COMPARE_AND_SET("compareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class),    // 8
+        COMPARE_AND_SET("compareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#compareAndExchangeVolatile VarHandle.compareAndExchangeVolatile}
          */
-        COMPARE_AND_EXCHANGE_VOLATILE("compareAndExchangeVolatile", AccessType.COMPARE_AND_EXCHANGE, Object.class), // 9
+        COMPARE_AND_EXCHANGE_VOLATILE("compareAndExchangeVolatile", AccessType.COMPARE_AND_EXCHANGE, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#compareAndExchangeAcquire VarHandle.compareAndExchangeAcquire}
          */
-        COMPARE_AND_EXCHANGE_ACQUIRE("compareAndExchangeAcquire", AccessType.COMPARE_AND_EXCHANGE, Object.class),  // 10
+        COMPARE_AND_EXCHANGE_ACQUIRE("compareAndExchangeAcquire", AccessType.COMPARE_AND_EXCHANGE, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#compareAndExchangeRelease VarHandle.compareAndExchangeRelease}
          */
-        COMPARE_AND_EXCHANGE_RELEASE("compareAndExchangeRelease", AccessType.COMPARE_AND_EXCHANGE, Object.class),  // 11
+        COMPARE_AND_EXCHANGE_RELEASE("compareAndExchangeRelease", AccessType.COMPARE_AND_EXCHANGE, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#weakCompareAndSet VarHandle.weakCompareAndSet}
          */
-        WEAK_COMPARE_AND_SET("weakCompareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class),        // 12
+        WEAK_COMPARE_AND_SET("weakCompareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#weakCompareAndSetVolatile VarHandle.weakCompareAndSetVolatile}
+         */
+        WEAK_COMPARE_AND_SET_VOLATILE("weakCompareAndSetVolatile", AccessType.COMPARE_AND_SWAP, boolean.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#weakCompareAndSetAcquire VarHandle.weakCompareAndSetAcquire}
          */
-        WEAK_COMPARE_AND_SET_ACQUIRE("weakCompareAndSetAcquire", AccessType.COMPARE_AND_SWAP, boolean.class), // 13
+        WEAK_COMPARE_AND_SET_ACQUIRE("weakCompareAndSetAcquire", AccessType.COMPARE_AND_SWAP, boolean.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#weakCompareAndSetRelease VarHandle.weakCompareAndSetRelease}
          */
-        WEAK_COMPARE_AND_SET_RELEASE("weakCompareAndSetRelease", AccessType.COMPARE_AND_SWAP, boolean.class), // 14
+        WEAK_COMPARE_AND_SET_RELEASE("weakCompareAndSetRelease", AccessType.COMPARE_AND_SWAP, boolean.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getAndSet VarHandle.getAndSet}
          */
-        GET_AND_SET("getAndSet", AccessType.GET_AND_UPDATE, Object.class),   // 15
+        GET_AND_SET("getAndSet", AccessType.GET_AND_UPDATE, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getAndAdd VarHandle.getAndAdd}
          */
-        GET_AND_ADD("getAndAdd", AccessType.GET_AND_UPDATE, Object.class),   // 16
+        GET_AND_ADD("getAndAdd", AccessType.GET_AND_UPDATE, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#addAndGet VarHandle.addAndGet}
          */
-        ADD_AND_GET("addAndGet", AccessType.GET_AND_UPDATE, Object.class),   // 17
+        ADD_AND_GET("addAndGet", AccessType.GET_AND_UPDATE, Object.class),
         ;
 
         static final Map<String, AccessMode> methodNameToAccessMode;
--- a/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template	Sun May 08 08:25:10 2016 +0000
@@ -155,6 +155,15 @@
         }
 
         @ForceInline
+        static boolean weakCompareAndSetVolatile(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
+            // TODO defer to strong form until new Unsafe method is added
+            return UNSAFE.compareAndSwap$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
+                                               handle.fieldOffset,
+                                               {#if[Object]?handle.fieldType.cast(expected):expected},
+                                               {#if[Object]?handle.fieldType.cast(value):value});
+        }
+
+        @ForceInline
         static boolean weakCompareAndSetAcquire(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
             return UNSAFE.weakCompareAndSwap$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
                                                handle.fieldOffset,
@@ -319,6 +328,15 @@
         }
 
         @ForceInline
+        static boolean weakCompareAndSetVolatile(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
+            // TODO defer to strong form until new Unsafe method is added
+            return UNSAFE.compareAndSwap$Type$(handle.base,
+                                               handle.fieldOffset,
+                                               {#if[Object]?handle.fieldType.cast(expected):expected},
+                                               {#if[Object]?handle.fieldType.cast(value):value});
+        }
+
+        @ForceInline
         static boolean weakCompareAndSetAcquire(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
             return UNSAFE.weakCompareAndSwap$Type$Acquire(handle.base,
                                                handle.fieldOffset,
@@ -535,6 +553,20 @@
         }
 
         @ForceInline
+        static boolean weakCompareAndSetVolatile(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
+#if[Object]
+            Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+            $type$[] array = ($type$[]) oarray;
+#end[Object]
+            // TODO defer to strong form until new Unsafe method is added
+            return UNSAFE.compareAndSwap$Type$(array,
+                    (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+                    {#if[Object]?handle.componentType.cast(expected):expected},
+                    {#if[Object]?handle.componentType.cast(value):value});
+        }
+
+        @ForceInline
         static boolean weakCompareAndSetAcquire(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
 #if[Object]
             Object[] array = (Object[]) handle.arrayType.cast(oarray);
--- a/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template	Sun May 08 08:25:10 2016 +0000
@@ -228,6 +228,16 @@
         }
 
         @ForceInline
+        static boolean weakCompareAndSetVolatile(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
+            byte[] ba = (byte[]) oba;
+            // TODO defer to strong form until new Unsafe method is added
+            return UNSAFE.compareAndSwap$RawType$(
+                    ba,
+                    address(ba, index(ba, index)),
+                    convEndian(handle.be, expected), convEndian(handle.be, value));
+        }
+
+        @ForceInline
         static boolean weakCompareAndSetAcquire(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
             byte[] ba = (byte[]) oba;
             return UNSAFE.weakCompareAndSwap$RawType$Acquire(
@@ -444,6 +454,16 @@
         }
 
         @ForceInline
+        static boolean weakCompareAndSetVolatile(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
+            ByteBuffer bb = (ByteBuffer) obb;
+            // TODO defer to strong form until new Unsafe method is added
+            return UNSAFE.compareAndSwap$RawType$(
+                    UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+                    address(bb, indexRO(bb, index)),
+                    convEndian(handle.be, expected), convEndian(handle.be, value));
+        }
+
+        @ForceInline
         static boolean weakCompareAndSetAcquire(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
             ByteBuffer bb = (ByteBuffer) obb;
             return UNSAFE.weakCompareAndSwap$RawType$Acquire(
--- a/src/java.base/share/classes/java/lang/module/Configuration.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/module/Configuration.java	Sun May 08 08:25:10 2016 +0000
@@ -25,6 +25,7 @@
 
 package java.lang.module;
 
+import java.io.PrintStream;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -183,17 +184,20 @@
         this.nameToModule = Collections.emptyMap();
     }
 
-    private Configuration(Configuration parent, Resolver resolver) {
-        Map<ResolvedModule, Set<ResolvedModule>> graph = resolver.finish(this);
+    private Configuration(Configuration parent,
+                          Resolver resolver,
+                          boolean check)
+    {
+        Map<ResolvedModule, Set<ResolvedModule>> g = resolver.finish(this, check);
 
         Map<String, ResolvedModule> nameToModule = new HashMap<>();
-        for (ResolvedModule resolvedModule : graph.keySet()) {
+        for (ResolvedModule resolvedModule : g.keySet()) {
             nameToModule.put(resolvedModule.name(), resolvedModule);
         }
 
         this.parent = parent;
-        this.graph = graph;
-        this.modules = Collections.unmodifiableSet(graph.keySet());
+        this.graph = g;
+        this.modules = Collections.unmodifiableSet(g.keySet());
         this.nameToModule = Collections.unmodifiableMap(nameToModule);
     }
 
@@ -283,10 +287,10 @@
         Objects.requireNonNull(after);
         Objects.requireNonNull(roots);
 
-        Resolver resolver = new Resolver(before, this, after);
+        Resolver resolver = new Resolver(before, this, after, null);
         resolver.resolveRequires(roots);
 
-        return new Configuration(this, resolver);
+        return new Configuration(this, resolver, true);
     }
 
 
@@ -340,10 +344,32 @@
         Objects.requireNonNull(after);
         Objects.requireNonNull(roots);
 
-        Resolver resolver = new Resolver(before, this, after);
+        Resolver resolver = new Resolver(before, this, after, null);
         resolver.resolveRequires(roots).resolveUses();
 
-        return new Configuration(this, resolver);
+        return new Configuration(this, resolver, true);
+    }
+
+
+    /**
+     * Resolves a collection of root modules, with service binding, and with
+     * the empty configuration as its parent. The post resolution checks
+     * are optionally run.
+     *
+     * This method is used to create the configuration for the boot layer.
+     */
+    static Configuration resolveRequiresAndUses(ModuleFinder finder,
+                                                Collection<String> roots,
+                                                boolean check,
+                                                PrintStream traceOutput)
+    {
+        Configuration parent = empty();
+
+        Resolver resolver
+            = new Resolver(finder, parent, ModuleFinder.empty(), traceOutput);
+        resolver.resolveRequires(roots).resolveUses();
+
+        return new Configuration(parent, resolver, check);
     }
 
 
--- a/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java	Sun May 08 08:25:10 2016 +0000
@@ -27,13 +27,17 @@
 
 import java.io.InputStream;
 import java.io.IOException;
+import java.io.PrintStream;
 import java.io.UncheckedIOException;
+import java.net.URI;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -45,7 +49,7 @@
 import static java.util.Objects.*;
 
 import jdk.internal.module.Checks;
-import jdk.internal.module.Hasher.DependencyHashes;
+import jdk.internal.module.ModuleHashes;
 
 
 /**
@@ -372,8 +376,9 @@
 
         private Provides(String service, Set<String> providers, boolean check) {
             this.service = check ? requireServiceTypeName(service) : service;
-            providers = check ? Collections.unmodifiableSet(new HashSet<>(providers))
-                              : Collections.unmodifiableSet(providers);
+            providers = check
+                ? Collections.unmodifiableSet(new LinkedHashSet<>(providers))
+                : Collections.unmodifiableSet(providers);
             if (providers.isEmpty())
                 throw new IllegalArgumentException("Empty providers set");
             if (check)
@@ -787,7 +792,7 @@
     private final String osVersion;
     private final Set<String> conceals;
     private final Set<String> packages;
-    private final DependencyHashes hashes;
+    private final ModuleHashes hashes;
 
     private ModuleDescriptor(String name,
                              boolean automatic,
@@ -802,7 +807,7 @@
                              String osArch,
                              String osVersion,
                              Set<String> conceals,
-                             DependencyHashes hashes)
+                             ModuleHashes hashes)
     {
 
         this.name = name;
@@ -878,7 +883,8 @@
                      String osArch,
                      String osVersion,
                      Set<String> conceals,
-                     Set<String> packages) {
+                     Set<String> packages,
+                     ModuleHashes hashes) {
         this.name = name;
         this.automatic = automatic;
         this.synthetic = synthetic;
@@ -894,7 +900,7 @@
         this.osName = osName;
         this.osArch = osArch;
         this.osVersion = osVersion;
-        this.hashes = null;
+        this.hashes = hashes;
     }
 
     /**
@@ -1063,9 +1069,9 @@
     }
 
     /**
-     * Returns the object with the hashes of the dependences.
+     * Returns the object with the hashes of other modules
      */
-    Optional<DependencyHashes> hashes() {
+    Optional<ModuleHashes> hashes() {
         return Optional.ofNullable(hashes);
     }
 
@@ -1103,7 +1109,7 @@
         String osArch;
         String osVersion;
         String mainClass;
-        DependencyHashes hashes;
+        ModuleHashes hashes;
 
         /**
          * Initializes a new builder with the given module name.
@@ -1580,7 +1586,7 @@
             return this;
         }
 
-        /* package */ Builder hashes(DependencyHashes hashes) {
+        /* package */ Builder hashes(ModuleHashes hashes) {
             this.hashes = hashes;
             return this;
         }
@@ -1719,7 +1725,9 @@
             hc = hc * 43 + Objects.hashCode(osVersion);
             hc = hc * 43 + Objects.hashCode(conceals);
             hc = hc * 43 + Objects.hashCode(hashes);
-            if (hc != 0) hash = hc;
+            if (hc == 0)
+                hc = -1;
+            hash = hc;
         }
         return hc;
     }
@@ -1925,11 +1933,12 @@
 
     static {
         /**
-         * Setup the shared secret to allow code in other packages create
-         * ModuleDescriptor and associated objects directly.
+         * Setup the shared secret to allow code in other packages access
+         * private package methods in java.lang.module.
          */
         jdk.internal.misc.SharedSecrets
             .setJavaLangModuleAccess(new jdk.internal.misc.JavaLangModuleAccess() {
+
                 @Override
                 public Requires newRequires(Set<Requires.Modifier> ms, String mn) {
                     return new Requires(ms, mn, false);
@@ -1974,7 +1983,8 @@
                                                             String osArch,
                                                             String osVersion,
                                                             Set<String> conceals,
-                                                            Set<String> packages) {
+                                                            Set<String> packages,
+                                                            ModuleHashes hashes) {
                     return new ModuleDescriptor(name,
                                                 automatic,
                                                 synthetic,
@@ -1988,7 +1998,29 @@
                                                 osArch,
                                                 osVersion,
                                                 conceals,
-                                                packages);
+                                                packages,
+                                                hashes);
+                }
+
+                @Override
+                public Configuration resolveRequiresAndUses(ModuleFinder finder,
+                                                            Collection<String> roots,
+                                                            boolean check,
+                                                            PrintStream traceOutput)
+                {
+                    return Configuration.resolveRequiresAndUses(finder, roots, check, traceOutput);
+                }
+
+                @Override
+                public ModuleReference newPatchedModule(ModuleDescriptor descriptor,
+                                                        URI location,
+                                                        Supplier<ModuleReader> s) {
+                    return new ModuleReference(descriptor, location, s, true, null);
+                }
+
+                @Override
+                public Optional<ModuleHashes> hashes(ModuleDescriptor descriptor) {
+                    return descriptor.hashes();
                 }
             });
     }
--- a/src/java.base/share/classes/java/lang/module/ModuleInfo.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/module/ModuleInfo.java	Sun May 08 08:25:10 2016 +0000
@@ -37,11 +37,12 @@
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.function.Supplier;
 
-import jdk.internal.module.Hasher.DependencyHashes;
+import jdk.internal.module.ModuleHashes;
 
 import static jdk.internal.module.ClassFileConstants.*;
 
@@ -337,7 +338,7 @@
                 // computeIfAbsent
                 Set<String> providers = pm.get(sn);
                 if (providers == null) {
-                    providers = new HashSet<>();
+                    providers = new LinkedHashSet<>(); // preserve order
                     pm.put(sn, providers);
                 }
                 providers.add(cn);
@@ -425,7 +426,7 @@
             map.put(dn, hash);
         }
 
-        builder.hashes(new DependencyHashes(algorithm, map));
+        builder.hashes(new ModuleHashes(algorithm, map));
     }
 
 
--- a/src/java.base/share/classes/java/lang/module/ModulePath.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/module/ModulePath.java	Sun May 08 08:25:10 2016 +0000
@@ -40,7 +40,7 @@
 import java.nio.file.attribute.BasicFileAttributes;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
@@ -52,7 +52,6 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
-import java.util.stream.Stream;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 
@@ -190,18 +189,16 @@
                 }
             }
 
-            if (attrs.isRegularFile() || attrs.isDirectory()) {
-                // packaged or exploded module
-                ModuleReference mref = readModule(entry, attrs);
-                if (mref != null) {
-                    String name = mref.descriptor().name();
-                    return Collections.singletonMap(name, mref);
-                }
+            // packaged or exploded module
+            ModuleReference mref = readModule(entry, attrs);
+            if (mref != null) {
+                String name = mref.descriptor().name();
+                return Collections.singletonMap(name, mref);
+            } else {
+                // skipped
+                return Collections.emptyMap();
             }
 
-            // not recognized
-            throw new FindException("Unrecognized module: " + entry);
-
         } catch (IOException ioe) {
             throw new FindException(ioe);
         }
@@ -238,16 +235,13 @@
 
                 // module found
                 if (mref != null) {
-
                     // can have at most one version of a module in the directory
                     String name = mref.descriptor().name();
                     if (nameToReference.put(name, mref) != null) {
                         throw new FindException("Two versions of module "
-                                + name + " found in " + dir);
+                                                  + name + " found in " + dir);
                     }
-
                 }
-
             }
         }
 
@@ -257,28 +251,40 @@
 
     /**
      * Locates a packaged or exploded module, returning a {@code ModuleReference}
-     * to the module. Returns {@code null} if the module is not recognized
-     * as a packaged or exploded module.
+     * to the module. Returns {@code null} if the entry is skipped because it is
+     * to a directory that does not contain a module-info.class or it's a hidden
+     * file.
      *
      * @throws IOException if an I/O error occurs
-     * @throws FindException if an error occurs parsing the module descriptor
+     * @throws FindException if the file is not recognized as a module or an
+     *         error occurs parsing its module descriptor
      */
     private ModuleReference readModule(Path entry, BasicFileAttributes attrs)
         throws IOException
     {
         try {
 
-            ModuleReference mref = null;
             if (attrs.isDirectory()) {
-                mref = readExplodedModule(entry);
-            } if (attrs.isRegularFile()) {
-                if (entry.toString().endsWith(".jar")) {
-                    mref = readJar(entry);
-                } else if (isLinkPhase && entry.toString().endsWith(".jmod")) {
-                    mref = readJMod(entry);
+                return readExplodedModule(entry); // may return null
+            }
+
+            String fn = entry.getFileName().toString();
+            if (attrs.isRegularFile()) {
+                if (fn.endsWith(".jar")) {
+                    return readJar(entry);
+                } else if (fn.endsWith(".jmod")) {
+                    if (isLinkPhase)
+                        return readJMod(entry);
+                    throw new FindException("JMOD files not supported: " + entry);
                 }
             }
-            return mref;
+
+            // skip hidden files
+            if (fn.startsWith(".") || Files.isHidden(entry)) {
+                return null;
+            } else {
+                throw new FindException("Unrecognized module: " + entry);
+            }
 
         } catch (InvalidModuleDescriptorException e) {
             throw new FindException("Error reading module: " + entry, e);
@@ -292,15 +298,17 @@
         return zf.stream()
             .filter(e -> e.getName().startsWith("classes/") &&
                     e.getName().endsWith(".class"))
-            .map(e -> toPackageName(e))
+            .map(e -> toPackageName(e.getName().substring(8)))
             .filter(pkg -> pkg.length() > 0) // module-info
-            .distinct()
             .collect(Collectors.toSet());
     }
 
     /**
      * Returns a {@code ModuleReference} to a module in jmod file on the
      * file system.
+     *
+     * @throws IOException
+     * @throws InvalidModuleDescriptorException
      */
     private ModuleReference readJMod(Path file) throws IOException {
         try (ZipFile zf = new ZipFile(file.toString())) {
@@ -419,13 +427,12 @@
 
         // scan the entries in the JAR file to locate the .class and service
         // configuration file
-        Stream<String> stream = jf.stream()
-            .map(e -> e.getName())
-            .filter(e -> (e.endsWith(".class") || e.startsWith(SERVICES_PREFIX)))
-            .distinct();
-        Map<Boolean, Set<String>> map
-            = stream.collect(Collectors.partitioningBy(s -> s.endsWith(".class"),
-                             Collectors.toSet()));
+        Map<Boolean, Set<String>> map =
+            jf.stream()
+              .map(JarEntry::getName)
+              .filter(s -> (s.endsWith(".class") ^ s.startsWith(SERVICES_PREFIX)))
+              .collect(Collectors.partitioningBy(s -> s.endsWith(".class"),
+                                                 Collectors.toSet()));
         Set<String> classFiles = map.get(Boolean.TRUE);
         Set<String> configFiles = map.get(Boolean.FALSE);
 
@@ -433,19 +440,18 @@
         classFiles.stream()
             .map(c -> toPackageName(c))
             .distinct()
-            .forEach(p -> builder.exports(p));
+            .forEach(builder::exports);
 
         // map names of service configuration files to service names
         Set<String> serviceNames = configFiles.stream()
             .map(this::toServiceName)
-            .filter(Optional::isPresent)
-            .map(Optional::get)
+            .flatMap(Optional::stream)
             .collect(Collectors.toSet());
 
         // parse each service configuration file
         for (String sn : serviceNames) {
             JarEntry entry = jf.getJarEntry(SERVICES_PREFIX + sn);
-            Set<String> providerClasses = new HashSet<>();
+            Set<String> providerClasses = new LinkedHashSet<>();
             try (InputStream in = jf.getInputStream(entry)) {
                 BufferedReader reader
                     = new BufferedReader(new InputStreamReader(in, "UTF-8"));
@@ -475,19 +481,25 @@
     private Set<String> jarPackages(JarFile jf) {
         return jf.stream()
             .filter(e -> e.getName().endsWith(".class"))
-            .map(e -> toPackageName(e))
+            .map(e -> toPackageName(e.getName()))
             .filter(pkg -> pkg.length() > 0)   // module-info
-            .distinct()
             .collect(Collectors.toSet());
     }
 
     /**
      * Returns a {@code ModuleReference} to a module in modular JAR file on
      * the file system.
+     *
+     * @throws IOException
+     * @throws FindException
+     * @throws InvalidModuleDescriptorException
      */
     private ModuleReference readJar(Path file) throws IOException {
-        try (JarFile jf = new JarFile(file.toString())) {
-
+        try (JarFile jf = new JarFile(file.toFile(),
+                                      true,               // verify
+                                      ZipFile.OPEN_READ,
+                                      JarFile.Release.RUNTIME))
+        {
             ModuleDescriptor md;
             JarEntry entry = jf.getJarEntry(MODULE_INFO);
             if (entry == null) {
@@ -520,7 +532,6 @@
                                path.toString().endsWith(".class")))
                 .map(path -> toPackageName(dir.relativize(path)))
                 .filter(pkg -> pkg.length() > 0)   // module-info
-                .distinct()
                 .collect(Collectors.toSet());
         } catch (IOException x) {
             throw new UncheckedIOException(x);
@@ -530,6 +541,9 @@
     /**
      * Returns a {@code ModuleReference} to an exploded module on the file
      * system or {@code null} if {@code module-info.class} not found.
+     *
+     * @throws IOException
+     * @throws InvalidModuleDescriptorException
      */
     private ModuleReference readExplodedModule(Path dir) throws IOException {
         Path mi = dir.resolve(MODULE_INFO);
@@ -559,19 +573,6 @@
         }
     }
 
-    private String toPackageName(ZipEntry entry) {
-        String name = entry.getName();
-        assert name.endsWith(".class");
-        // jmod classes in classes/, jar in /
-        int start = name.startsWith("classes/") ? 8 : 0;
-        int index = name.lastIndexOf("/");
-        if (index > start) {
-            return name.substring(start, index).replace('/', '.');
-        } else {
-            return "";
-        }
-    }
-
     private String toPackageName(Path path) {
         String name = path.toString();
         assert name.endsWith(".class");
--- a/src/java.base/share/classes/java/lang/module/ModuleReader.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/module/ModuleReader.java	Sun May 08 08:25:10 2016 +0000
@@ -142,10 +142,11 @@
      * @see ClassLoader#defineClass(String, ByteBuffer, java.security.ProtectionDomain)
      */
     default Optional<ByteBuffer> read(String name) throws IOException {
-        Optional<InputStream> in = open(name);
-        if (in.isPresent()) {
-            byte[] bytes = in.get().readAllBytes();
-            return Optional.of(ByteBuffer.wrap(bytes));
+        Optional<InputStream> oin = open(name);
+        if (oin.isPresent()) {
+            try (InputStream in = oin.get()) {
+                return Optional.of(ByteBuffer.wrap(in.readAllBytes()));
+            }
         } else {
             return Optional.empty();
         }
--- a/src/java.base/share/classes/java/lang/module/ModuleReference.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/module/ModuleReference.java	Sun May 08 08:25:10 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -32,7 +32,7 @@
 import java.util.Optional;
 import java.util.function.Supplier;
 
-import jdk.internal.module.Hasher.HashSupplier;
+import jdk.internal.module.ModuleHashes.HashSupplier;
 
 
 /**
@@ -54,12 +54,33 @@
     private final URI location;
     private final Supplier<ModuleReader> readerSupplier;
 
+    // true if this is a reference to a patched module
+    private boolean patched;
+
     // the function that computes the hash of this module reference
     private final HashSupplier hasher;
 
     // cached hash string to avoid needing to compute it many times
     private String cachedHash;
 
+
+    /**
+     * Constructs a new instance of this class.
+     */
+    ModuleReference(ModuleDescriptor descriptor,
+                    URI location,
+                    Supplier<ModuleReader> readerSupplier,
+                    boolean patched,
+                    HashSupplier hasher)
+
+    {
+        this.descriptor = Objects.requireNonNull(descriptor);
+        this.location = location;
+        this.readerSupplier = Objects.requireNonNull(readerSupplier);
+        this.patched = patched;
+        this.hasher = hasher;
+    }
+
     /**
      * Constructs a new instance of this class.
      */
@@ -67,11 +88,9 @@
                     URI location,
                     Supplier<ModuleReader> readerSupplier,
                     HashSupplier hasher)
+
     {
-        this.descriptor = Objects.requireNonNull(descriptor);
-        this.location = location;
-        this.readerSupplier = Objects.requireNonNull(readerSupplier);
-        this.hasher = hasher;
+        this(descriptor, location, readerSupplier, false, hasher);
     }
 
 
@@ -96,10 +115,9 @@
                            URI location,
                            Supplier<ModuleReader> readerSupplier)
     {
-        this(descriptor, location, readerSupplier, null);
+        this(descriptor, location, readerSupplier, false, null);
     }
 
-
     /**
      * Returns the module descriptor.
      *
@@ -151,6 +169,20 @@
 
 
     /**
+     * Returns {@code true} if this module has been patched via -Xpatch.
+     */
+    boolean isPatched() {
+        return patched;
+    }
+
+    /**
+     * Returns the hash supplier for this module.
+     */
+    HashSupplier hasher() {
+        return hasher;
+    }
+
+    /**
      * Computes the hash of this module, returning it as a hex string.
      * Returns {@code null} if the hash cannot be computed.
      *
@@ -166,8 +198,6 @@
         return result;
     }
 
-    private int hash;
-
     /**
      * Computes a hash code for this module reference.
      *
@@ -181,12 +211,17 @@
     public int hashCode() {
         int hc = hash;
         if (hc == 0) {
-            hc = Objects.hash(descriptor, location, readerSupplier, hasher);
-            if (hc != 0) hash = hc;
+            hc = Objects.hash(descriptor, location, readerSupplier, hasher,
+                    Boolean.valueOf(patched));
+            if (hc == 0)
+                hc = -1;
+            hash = hc;
         }
         return hc;
     }
 
+    private int hash;
+
     /**
      * Tests this module reference for equality with the given object.
      *
@@ -214,7 +249,8 @@
         return Objects.equals(this.descriptor, that.descriptor)
                 && Objects.equals(this.location, that.location)
                 && Objects.equals(this.readerSupplier, that.readerSupplier)
-                && Objects.equals(this.hasher, that.hasher);
+                && Objects.equals(this.hasher, that.hasher)
+                && this.patched == that.patched;
     }
 
     /**
--- a/src/java.base/share/classes/java/lang/module/ModuleReferences.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/module/ModuleReferences.java	Sun May 08 08:25:10 2016 +0000
@@ -48,8 +48,8 @@
 
 import jdk.internal.misc.JavaLangAccess;
 import jdk.internal.misc.SharedSecrets;
-import jdk.internal.module.Hasher;
-import jdk.internal.module.Hasher.HashSupplier;
+import jdk.internal.module.ModuleHashes;
+import jdk.internal.module.ModuleHashes.HashSupplier;
 import jdk.internal.module.ModulePatcher;
 import sun.net.www.ParseUtil;
 
@@ -89,7 +89,7 @@
     static ModuleReference newJarModule(ModuleDescriptor md, Path file) {
         URI uri = file.toUri();
         Supplier<ModuleReader> supplier = () -> new JarModuleReader(file, uri);
-        HashSupplier hasher = (algorithm) -> Hasher.generate(file, algorithm);
+        HashSupplier hasher = (a) -> ModuleHashes.computeHashAsString(file, a);
         return newModule(md, uri, supplier, hasher);
     }
 
@@ -99,7 +99,7 @@
     static ModuleReference newJModModule(ModuleDescriptor md, Path file) {
         URI uri = file.toUri();
         Supplier<ModuleReader> supplier = () -> new JModModuleReader(file, uri);
-        HashSupplier hasher = (algorithm) -> Hasher.generate(file, algorithm);
+        HashSupplier hasher = (a) -> ModuleHashes.computeHashAsString(file, a);
         return newModule(md, file.toUri(), supplier, hasher);
     }
 
@@ -122,7 +122,7 @@
         private final ReadWriteLock lock = new ReentrantReadWriteLock();
         private final Lock readLock = lock.readLock();
         private final Lock writeLock = lock.writeLock();
-        private volatile boolean closed;
+        private boolean closed;
 
         SafeCloseModuleReader() { }
 
@@ -198,7 +198,10 @@
 
         static JarFile newJarFile(Path path) {
             try {
-                return new JarFile(path.toFile());
+                return new JarFile(path.toFile(),
+                                   true,               // verify
+                                   ZipFile.OPEN_READ,
+                                   JarFile.Release.RUNTIME);
             } catch (IOException ioe) {
                 throw new UncheckedIOException(ioe);
             }
@@ -219,6 +222,8 @@
             if (je != null) {
                 String encodedPath = ParseUtil.encodePath(name, false);
                 String uris = "jar:" + uri + "!/" + encodedPath;
+                if (jf.isMultiRelease())
+                    uris += "#runtime";
                 return Optional.of(URI.create(uris));
             } else {
                 return Optional.empty();
--- a/src/java.base/share/classes/java/lang/module/Resolver.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/module/Resolver.java	Sun May 08 08:25:10 2016 +0000
@@ -25,8 +25,8 @@
 
 package java.lang.module;
 
+import java.io.PrintStream;
 import java.lang.module.ModuleDescriptor.Requires.Modifier;
-import java.lang.reflect.Layer;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -43,7 +43,7 @@
 import java.util.StringJoiner;
 import java.util.stream.Collectors;
 
-import jdk.internal.module.Hasher;
+import jdk.internal.module.ModuleHashes;
 
 /**
  * The resolver used by {@link Configuration#resolveRequires} and
@@ -55,6 +55,7 @@
     private final ModuleFinder beforeFinder;
     private final Configuration parent;
     private final ModuleFinder afterFinder;
+    private final PrintStream traceOutput;
 
     // maps module name to module reference
     private final Map<String, ModuleReference> nameToReference = new HashMap<>();
@@ -62,10 +63,12 @@
 
     Resolver(ModuleFinder beforeFinder,
              Configuration parent,
-             ModuleFinder afterFinder) {
+             ModuleFinder afterFinder,
+             PrintStream traceOutput) {
         this.beforeFinder = beforeFinder;
         this.parent = parent;
         this.afterFinder = afterFinder;
+        this.traceOutput = traceOutput;
     }
 
 
@@ -76,8 +79,6 @@
      */
     Resolver resolveRequires(Collection<String> roots) {
 
-        long start = trace_start("Resolve");
-
         // create the visit stack to get us started
         Deque<ModuleDescriptor> q = new ArrayDeque<>();
         for (String root : roots) {
@@ -95,10 +96,9 @@
                 }
             }
 
-            if (TRACE) {
+            if (isTracing()) {
                 trace("Root module %s located", root);
-                if (mref.location().isPresent())
-                    trace("  (%s)", mref.location().get());
+                mref.location().ifPresent(uri -> trace("  (%s)", uri));
             }
 
             assert mref.descriptor().name().equals(root);
@@ -108,13 +108,6 @@
 
         resolve(q);
 
-        if (TRACE) {
-            long duration = System.currentTimeMillis() - start;
-            Set<String> names = nameToReference.keySet();
-            trace("Resolver completed in %s ms", duration);
-            names.stream().sorted().forEach(name -> trace("  %s", name));
-        }
-
         return this;
     }
 
@@ -153,11 +146,10 @@
                     q.offer(mref.descriptor());
                     resolved.add(mref.descriptor());
 
-                    if (TRACE) {
+                    if (isTracing()) {
                         trace("Module %s located, required by %s",
                                 dn, descriptor.name());
-                        if (mref.location().isPresent())
-                            trace("  (%s)", mref.location().get());
+                        mref.location().ifPresent(uri -> trace("  (%s)", uri));
                     }
                 }
 
@@ -175,8 +167,6 @@
      */
     Resolver resolveUses() {
 
-        long start = trace_start("Bind");
-
         // Scan the finders for all available service provider modules. As
         // java.base uses services then then module finders will be scanned
         // anyway.
@@ -230,10 +220,10 @@
 
                                     String pn = provider.name();
                                     if (!nameToReference.containsKey(pn)) {
-
-                                        if (TRACE && mref.location().isPresent())
-                                            trace("  (%s)", mref.location().get());
-
+                                        if (isTracing()) {
+                                            mref.location()
+                                                .ifPresent(uri -> trace("  (%s)", uri));
+                                        }
                                         nameToReference.put(pn, mref);
                                         q.push(provider);
                                     }
@@ -248,14 +238,6 @@
 
         } while (!candidateConsumers.isEmpty());
 
-
-        if (TRACE) {
-            long duration = System.currentTimeMillis() - start;
-            Set<String> names = nameToReference.keySet();
-            trace("Bind completed in %s ms", duration);
-            names.stream().sorted().forEach(name -> trace("  %s", name));
-        }
-
         return this;
     }
 
@@ -264,23 +246,33 @@
      * Execute post-resolution checks and returns the module graph of resolved
      * modules as {@code Map}. The resolved modules will be in the given
      * configuration.
+     *
+     * @param check {@true} to execute the post resolution checks
      */
-    Map<ResolvedModule, Set<ResolvedModule>> finish(Configuration cf) {
+    Map<ResolvedModule, Set<ResolvedModule>> finish(Configuration cf,
+                                                    boolean check)
+    {
+        if (isTracing()) {
+            trace("Result:");
+            Set<String> names = nameToReference.keySet();
+            names.stream().sorted().forEach(name -> trace("  %s", name));
+        }
 
-        detectCycles();
-
-        checkPlatformConstraints();
-
-        checkHashes();
+        if (check) {
+            detectCycles();
+            checkPlatformConstraints();
+            checkHashes();
+        }
 
         Map<ResolvedModule, Set<ResolvedModule>> graph = makeGraph(cf);
 
-        checkExportSuppliers(graph);
+        if (check) {
+            checkExportSuppliers(graph);
+        }
 
         return graph;
     }
 
-
     /**
      * Checks the given module graph for cycles.
      *
@@ -420,52 +412,44 @@
 
     }
 
-
     /**
      * Checks the hashes in the module descriptor to ensure that they match
-     * the hash of the dependency's module reference.
+     * any recorded hashes.
      */
     private void checkHashes() {
-
         for (ModuleReference mref : nameToReference.values()) {
             ModuleDescriptor descriptor = mref.descriptor();
 
-            // get map of module names to hash
-            Optional<Hasher.DependencyHashes> ohashes = descriptor.hashes();
+            // get map of module hashes
+            Optional<ModuleHashes> ohashes = descriptor.hashes();
             if (!ohashes.isPresent())
                 continue;
-            Hasher.DependencyHashes hashes = ohashes.get();
+            ModuleHashes hashes = ohashes.get();
 
-            // check dependences
-            for (ModuleDescriptor.Requires d : descriptor.requires()) {
-                String dn = d.name();
-                String recordedHash = hashes.hashFor(dn);
+            String algorithm = hashes.algorithm();
+            for (String dn : hashes.names()) {
+                ModuleReference other = nameToReference.get(dn);
+                if (other == null) {
+                    other = parent.findModule(dn)
+                            .map(ResolvedModule::reference)
+                            .orElse(null);
+                }
 
-                if (recordedHash != null) {
-
-                    ModuleReference other = nameToReference.get(dn);
-                    if (other == null) {
-                        other = parent.findModule(dn)
-                                .map(ResolvedModule::reference)
-                                .orElse(null);
-                    }
-                    if (other == null)
-                        throw new InternalError(dn + " not found");
-
-                    String actualHash = other.computeHash(hashes.algorithm());
+                // skip checking the hash if the module has been patched
+                if (other != null && !other.isPatched()) {
+                    String recordedHash = hashes.hashFor(dn);
+                    String actualHash = other.computeHash(algorithm);
                     if (actualHash == null)
                         fail("Unable to compute the hash of module %s", dn);
+                    if (!recordedHash.equals(actualHash)) {
+                        fail("Hash of %s (%s) differs to expected hash (%s)" +
+                             " recorded in %s", dn, actualHash, recordedHash,
+                             descriptor.name());
+                    }
+                }
+            }
 
-                    if (!recordedHash.equals(actualHash)) {
-                        fail("Hash of %s (%s) differs to expected hash (%s)",
-                                dn, actualHash, recordedHash);
-                    }
-
-                }
-
-            }
         }
-
     }
 
 
@@ -666,7 +650,7 @@
                     // source is exported to descriptor2
                     String source = export.source();
                     ModuleDescriptor other
-                            = packageToExporter.put(source, descriptor2);
+                        = packageToExporter.put(source, descriptor2);
 
                     if (other != null && other != descriptor2) {
                         // package might be local to descriptor1
@@ -690,33 +674,38 @@
                 }
             }
 
-            // uses S
-            for (String service : descriptor1.uses()) {
-                String pn = packageName(service);
-                if (!packageToExporter.containsKey(pn)) {
-                    fail("Module %s does not read a module that exports %s",
-                            descriptor1.name(), pn);
-                }
-            }
+            // uses/provides checks not applicable to automatic modules
+            if (!descriptor1.isAutomatic()) {
 
-            // provides S
-            for (Map.Entry<String, ModuleDescriptor.Provides> entry :
-                    descriptor1.provides().entrySet()) {
-                String service = entry.getKey();
-                ModuleDescriptor.Provides provides = entry.getValue();
-
-                String pn = packageName(service);
-                if (!packageToExporter.containsKey(pn)) {
-                    fail("Module %s does not read a module that exports %s",
-                            descriptor1.name(), pn);
+                // uses S
+                for (String service : descriptor1.uses()) {
+                    String pn = packageName(service);
+                    if (!packageToExporter.containsKey(pn)) {
+                        fail("Module %s does not read a module that exports %s",
+                             descriptor1.name(), pn);
+                    }
                 }
 
-                for (String provider : provides.providers()) {
-                    if (!packages.contains(packageName(provider))) {
-                        fail("Provider %s not in module %s",
-                                provider, descriptor1.name());
+                // provides S
+                for (Map.Entry<String, ModuleDescriptor.Provides> entry :
+                        descriptor1.provides().entrySet()) {
+                    String service = entry.getKey();
+                    ModuleDescriptor.Provides provides = entry.getValue();
+
+                    String pn = packageName(service);
+                    if (!packageToExporter.containsKey(pn)) {
+                        fail("Module %s does not read a module that exports %s",
+                             descriptor1.name(), pn);
+                    }
+
+                    for (String provider : provides.providers()) {
+                        if (!packages.contains(packageName(provider))) {
+                            fail("Provider %s not in module %s",
+                                 provider, descriptor1.name());
+                        }
                     }
                 }
+
             }
 
         }
@@ -796,27 +785,18 @@
         throw new ResolutionException(msg);
     }
 
-
     /**
-     * Tracing support, limited to boot layer for now.
+     * Tracing support
      */
 
-    private final static boolean TRACE
-        = Boolean.getBoolean("jdk.launcher.traceResolver")
-            && (Layer.boot() == null);
-
-    private String op;
-
-    private long trace_start(String op) {
-        this.op = op;
-        return System.currentTimeMillis();
+    private boolean isTracing() {
+        return traceOutput != null;
     }
 
     private void trace(String fmt, Object ... args) {
-        if (TRACE) {
-            System.out.print("[" + op + "] ");
-            System.out.format(fmt, args);
-            System.out.println();
+        if (traceOutput != null) {
+            traceOutput.format("[Resolver] " + fmt, args);
+            traceOutput.println();
         }
     }
 
--- a/src/java.base/share/classes/java/lang/module/SystemModuleFinder.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/module/SystemModuleFinder.java	Sun May 08 08:25:10 2016 +0000
@@ -44,6 +44,7 @@
 import jdk.internal.jimage.ImageLocation;
 import jdk.internal.jimage.ImageReader;
 import jdk.internal.jimage.ImageReaderFactory;
+import jdk.internal.module.ModuleHashes;
 import jdk.internal.module.SystemModules;
 import jdk.internal.module.ModulePatcher;
 import jdk.internal.perf.PerfCounter;
@@ -101,13 +102,16 @@
         for (int i = 0; i < n; i++) {
             String mn = moduleNames[i];
             ModuleDescriptor md;
+            String hash;
             if (fastLoad) {
                 md = descriptors[i];
+                hash = SystemModules.MODULES_TO_HASH[i];
             } else {
                 // fallback to read module-info.class
                 // if fast loading of ModuleDescriptors is disabled
                 ImageLocation location = imageReader.findLocation(mn, "module-info.class");
                 md = ModuleDescriptor.read(imageReader.getResourceBuffer(location));
+                hash = null;
             }
             if (!md.name().equals(mn))
                 throw new InternalError();
@@ -123,7 +127,8 @@
                 }
             };
 
-            ModuleReference mref = new ModuleReference(md, uri, readerSupplier);
+            ModuleReference mref =
+                new ModuleReference(md, uri, readerSupplier, hashSupplier(hash));
 
             // may need a reference to a patched module if -Xpatch specified
             mref = ModulePatcher.interposeIfNeeded(mref);
@@ -142,6 +147,18 @@
         initTime.addElapsedTimeFrom(t0);
     }
 
+    private static ModuleHashes.HashSupplier hashSupplier(String hash) {
+        if (hash == null)
+            return null;
+
+        return new ModuleHashes.HashSupplier() {
+            @Override
+            public String generate(String algorithm) {
+                return hash;
+            }
+        };
+    }
+
     SystemModuleFinder() { }
 
     @Override
--- a/src/java.base/share/classes/java/lang/reflect/Layer.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/reflect/Layer.java	Sun May 08 08:25:10 2016 +0000
@@ -27,6 +27,7 @@
 
 import java.lang.module.Configuration;
 import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleDescriptor.Provides;
 import java.lang.module.ResolvedModule;
 import java.util.Collections;
 import java.util.HashMap;
@@ -41,6 +42,8 @@
 import jdk.internal.loader.Loader;
 import jdk.internal.loader.LoaderPool;
 import jdk.internal.misc.SharedSecrets;
+import jdk.internal.module.ServicesCatalog;
+import jdk.internal.module.ServicesCatalog.ServiceProvider;
 import sun.security.util.SecurityConstants;
 
 
@@ -549,4 +552,55 @@
     public static Layer boot() {
         return SharedSecrets.getJavaLangAccess().getBootLayer();
     }
+
+
+    /**
+     * Returns the ServicesCatalog for this Layer, creating it if not
+     * already created.
+     */
+    ServicesCatalog getServicesCatalog() {
+        ServicesCatalog servicesCatalog = this.servicesCatalog;
+        if (servicesCatalog != null)
+            return servicesCatalog;
+
+        Map<String, Set<ServiceProvider>> map = new HashMap<>();
+        for (Module m : nameToModule.values()) {
+            ModuleDescriptor descriptor = m.getDescriptor();
+            for (Provides provides : descriptor.provides().values()) {
+                String service = provides.service();
+                Set<ServiceProvider> providers
+                    = map.computeIfAbsent(service, k -> new HashSet<>());
+                for (String pn : provides.providers()) {
+                    providers.add(new ServiceProvider(m, pn));
+                }
+            }
+        }
+
+        ServicesCatalog catalog = new ServicesCatalog() {
+            @Override
+            public void register(Module module) {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public Set<ServiceProvider> findServices(String service) {
+                Set<ServiceProvider> providers = map.get(service);
+                if (providers == null) {
+                    return Collections.emptySet();
+                } else {
+                    return Collections.unmodifiableSet(providers);
+                }
+            }
+        };
+
+        synchronized (this) {
+            servicesCatalog = this.servicesCatalog;
+            if (servicesCatalog == null) {
+                this.servicesCatalog = servicesCatalog = catalog;
+            }
+        }
+
+        return servicesCatalog;
+    }
+
+    private volatile ServicesCatalog servicesCatalog;
 }
--- a/src/java.base/share/classes/java/lang/reflect/Module.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/reflect/Module.java	Sun May 08 08:25:10 2016 +0000
@@ -43,11 +43,7 @@
 import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
-import java.util.WeakHashMap;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
 import java.util.function.Function;
 import java.util.stream.Stream;
 
@@ -142,9 +138,6 @@
         this.name = null;
         this.loader = loader;
         this.descriptor = null;
-
-        // unnamed modules are loose
-        this.loose = true;
     }
 
 
@@ -245,17 +238,27 @@
     }
 
 
+    // --
+
+    // the special Module to mean reads or exported to "all unnamed modules"
+    private static final Module ALL_UNNAMED_MODULE = new Module(null);
+
+    // special Module to mean exported to "everyone"
+    private static final Module EVERYONE_MODULE = new Module(null);
+
+    // exported to all modules
+    private static final Set<Module> EVERYONE = Collections.singleton(EVERYONE_MODULE);
+
+
     // -- readability --
 
-    // true if this module reads all unnamed modules (a.k.a. loose module)
-    private volatile boolean loose;
-
     // the modules that this module permanently reads
     // (will be final when the modules are defined in reverse topology order)
     private volatile Set<Module> reads;
 
-    // created lazily, additional modules that this module reflectively reads
-    private volatile WeakSet<Module> transientReads;
+    // additional module (2nd key) that some module (1st key) reflectively reads
+    private static final WeakPairMap<Module, Module, Boolean> transientReads
+        = new WeakPairMap<>();
 
 
     /**
@@ -284,22 +287,19 @@
 
         // check if this module reads other
         if (other.isNamed()) {
-
             Set<Module> reads = this.reads; // volatile read
             if (reads != null && reads.contains(other))
                 return true;
-
-        } else {
-
-            // loose modules read all unnamed modules
-            if (this.loose)
-                return true;
-
         }
 
         // check if this module reads the other module reflectively
-        WeakSet<Module> tr = this.transientReads; // volatile read
-        if (tr != null && tr.contains(other))
+        if (transientReads.containsKeyPair(this, other))
+            return true;
+
+        // if other is an unnamed module then check if this module reads
+        // all unnamed modules
+        if (!other.isNamed()
+            && transientReads.containsKeyPair(this, ALL_UNNAMED_MODULE))
             return true;
 
         return false;
@@ -346,8 +346,7 @@
     }
 
     /**
-     * Makes the given {@code Module} readable to this module without
-     * notifying the VM.
+     * Updates this module to read another module without notifying the VM.
      *
      * @apiNote This method is for VM white-box testing.
      */
@@ -361,40 +360,28 @@
      * If {@code syncVM} is {@code true} then the VM is notified.
      */
     private void implAddReads(Module other, boolean syncVM) {
+        Objects.requireNonNull(other);
 
         // nothing to do
         if (other == this || !this.isNamed())
             return;
 
-        // if the other is null then change this module to be loose.
-        if (other == null) {
-            if (syncVM)
-                addReads0(this, null);
-            this.loose = true;
-            return;
-        }
-
         // check if we already read this module
         Set<Module> reads = this.reads;
         if (reads != null && reads.contains(other))
             return;
 
         // update VM first, just in case it fails
-        if (syncVM)
-            addReads0(this, other);
+        if (syncVM) {
+            if (other == ALL_UNNAMED_MODULE) {
+                addReads0(this, null);
+            } else {
+                addReads0(this, other);
+            }
+        }
 
         // add reflective read
-        WeakSet<Module> tr = this.transientReads;
-        if (tr == null) {
-            synchronized (this) {
-                tr = this.transientReads;
-                if (tr == null) {
-                    tr = new WeakSet<>();
-                    this.transientReads = tr;
-                }
-            }
-        }
-        tr.add(other);
+        transientReads.putIfAbsent(this, other, Boolean.TRUE);
     }
 
 
@@ -404,15 +391,10 @@
     // (will be final when the modules are defined in reverse topology order)
     private volatile Map<String, Set<Module>> exports;
 
-    // created lazily, additional exports added at run-time
-    private volatile Map<String, WeakSet<Module>> transientExports;
-
-    // the special Module to mean exported to all modules
-    private static final Module EVERYONE_MODULE = new Module(null);
-    private static final Set<Module> EVERYONE = Collections.singleton(EVERYONE_MODULE);
-
-    // the special Module to mean exported to all unnamed modules
-    private static final Module ALL_UNNAMED_MODULE = new Module(null);
+    // additional exports added at run-time
+    // this module (1st key), other module (2nd key), exported packages (value)
+    private static final WeakPairMap<Module, Module, Map<String, Boolean>>
+        transientExports = new WeakPairMap<>();
 
 
     /**
@@ -489,23 +471,9 @@
         if (exports != null) {
             Set<Module> targets = exports.get(pn);
 
-            if (targets != null) {
-
-                // exported to all modules
-                if (targets.contains(EVERYONE_MODULE))
-                    return true;
-
-                if (other != EVERYONE_MODULE) {
-                    // exported to other
-                    if (targets.contains(other))
-                        return true;
-
-                    // other is an unnamed module && exported to all unnamed
-                    if (!other.isNamed() && targets.contains(ALL_UNNAMED_MODULE))
-                        return true;
-                }
-
-            }
+            if ((targets != null)
+                && (targets.contains(other) || targets.contains(EVERYONE_MODULE)))
+                return true;
         }
         return false;
     }
@@ -515,29 +483,27 @@
      * package package to the given module.
      */
     private boolean isExportedReflectively(String pn, Module other) {
-        Map<String, WeakSet<Module>> te = this.transientExports;
-        if (te != null) {
-            WeakSet<Module> targets = te.get(pn);
+        // exported to all modules
+        Map<String, ?> exports = transientExports.get(this, EVERYONE_MODULE);
+        if (exports != null && exports.containsKey(pn))
+            return true;
 
-            if (targets != null) {
+        if (other != EVERYONE_MODULE) {
 
-                // exported to all modules
-                if (targets.contains(EVERYONE_MODULE))
+            // exported to other
+            exports = transientExports.get(this, other);
+            if (exports != null && exports.containsKey(pn))
+                return true;
+
+            // other is an unnamed module && exported to all unnamed
+            if (!other.isNamed()) {
+                exports = transientExports.get(this, ALL_UNNAMED_MODULE);
+                if (exports != null && exports.containsKey(pn))
                     return true;
-
-                if (other != EVERYONE_MODULE) {
-
-                    // exported to other
-                    if (targets.contains(other))
-                        return true;
-
-                    // other is an unnamed module && exported to all unnamed
-                    if (!other.isNamed() && targets.contains(ALL_UNNAMED_MODULE))
-                        return true;
-                }
             }
 
         }
+
         return false;
     }
 
@@ -638,34 +604,19 @@
             }
         }
 
-        // create transientExports if needed
-        Map<String, WeakSet<Module>> te = this.transientExports; // read
-        if (te == null) {
-            synchronized (this) {
-                te = this.transientExports;
-                if (te == null) {
-                    te = new ConcurrentHashMap<>();
-                    this.transientExports = te;  // volatile write
-                }
-            }
-        }
-
         // add package name to transientExports if absent
-        WeakSet<Module> s = te.get(pn);
-        if (s == null) {
-            s = new WeakSet<>();
-            WeakSet<Module> prev = te.putIfAbsent(pn, s);
-            if (prev != null)
-                s = prev;
-        }
-        s.add(other);
+        transientExports
+            .computeIfAbsent(this, other,
+                             (_this, _other) -> new ConcurrentHashMap<>())
+            .putIfAbsent(pn, Boolean.TRUE);
     }
 
 
     // -- services --
 
-    // created lazily, additional service types that this module uses
-    private volatile WeakSet<Class<?>> transientUses;
+    // additional service type (2nd key) that some module (1st key) uses
+    private static final WeakPairMap<Module, Class<?>, Boolean> transientUses
+        = new WeakPairMap<>();
 
     /**
      * If the caller's module is this module then update this module to add a
@@ -702,17 +653,7 @@
             }
 
             if (!canUse(st)) {
-                WeakSet<Class<?>> uses = this.transientUses;
-                if (uses == null) {
-                    synchronized (this) {
-                        uses = this.transientUses;
-                        if (uses == null) {
-                            uses = new WeakSet<>();
-                            this.transientUses = uses;
-                        }
-                    }
-                }
-                uses.add(st);
+                transientUses.putIfAbsent(this, st, Boolean.TRUE);
             }
 
         }
@@ -746,11 +687,7 @@
             return true;
 
         // uses added via addUses
-        WeakSet<Class<?>> uses = this.transientUses;
-        if (uses != null && uses.contains(st))
-            return true;
-
-        return false;
+        return transientUses.containsKeyPair(this, st);
     }
 
 
@@ -885,7 +822,7 @@
     // -- creating Module objects --
 
     /**
-     * Find the runtime Module corresponding to the given ReadDependence
+     * Find the runtime Module corresponding to the given ResolvedModule
      * in the given parent Layer (or its parents).
      */
     private static Module find(ResolvedModule resolvedModule, Layer layer) {
@@ -969,7 +906,7 @@
 
             // automatic modules reads all unnamed modules
             if (descriptor.isAutomatic()) {
-                m.implAddReads(null, true);
+                m.implAddReads(ALL_UNNAMED_MODULE, true);
             }
 
             // exports
@@ -1097,7 +1034,7 @@
      * the representation is the string {@code "module"}, followed by a space,
      * and then the module name. For an unnamed module, the representation is
      * the string {@code "unnamed module"}, followed by a space, and then an
-     * implementation specific identifier for the unnamed module.
+     * implementation specific string that identifies the unnamed module.
      *
      * @return The string representation of this module
      */
@@ -1112,46 +1049,6 @@
     }
 
 
-    // -- supporting classes --
-
-
-    /**
-     * A "not-a-Set" set of weakly referenced objects that supports concurrent
-     * access.
-     */
-    private static class WeakSet<E> {
-        private final ReadWriteLock lock = new ReentrantReadWriteLock();
-        private final Lock readLock = lock.readLock();
-        private final Lock writeLock = lock.writeLock();
-
-        private final WeakHashMap<E, Boolean> map = new WeakHashMap<>();
-
-        /**
-         * Adds the specified element to the set.
-         */
-        void add(E e) {
-            writeLock.lock();
-            try {
-                map.put(e, Boolean.TRUE);
-            } finally {
-                writeLock.unlock();
-            }
-        }
-
-        /**
-         * Returns {@code true} if this set contains the specified element.
-         */
-        boolean contains(E e) {
-            readLock.lock();
-            try {
-                return map.containsKey(e);
-            } finally {
-                readLock.unlock();
-            }
-        }
-    }
-
-
     // -- native methods --
 
     // JVM_DefineModule
@@ -1196,8 +1093,12 @@
                     m1.implAddReads(m2, true);
                 }
                 @Override
+                public void addReadsAllUnnamed(Module m) {
+                    m.implAddReads(Module.ALL_UNNAMED_MODULE);
+                }
+                @Override
                 public void addExports(Module m, String pn, Module other) {
-                    m.implAddExports(pn, Objects.requireNonNull(other), true);
+                    m.implAddExports(pn, other, true);
                 }
                 @Override
                 public void addExportsToAll(Module m, String pn) {
@@ -1211,6 +1112,10 @@
                 public void addPackage(Module m, String pn) {
                     m.implAddPackage(pn, true);
                 }
+                @Override
+                public ServicesCatalog getServicesCatalog(Layer layer) {
+                    return layer.getServicesCatalog();
+                }
             });
     }
 }
--- a/src/java.base/share/classes/java/lang/reflect/Proxy.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/lang/reflect/Proxy.java	Sun May 08 08:25:10 2016 +0000
@@ -582,7 +582,7 @@
         }
 
         private static final String DEBUG =
-                GetPropertyAction.getProperty("jdk.proxy.debug", "");
+                GetPropertyAction.privilegedGetProperty("jdk.proxy.debug", "");
 
         private static boolean isDebug() {
             return !DEBUG.isEmpty();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/reflect/WeakPairMap.java	Sun May 08 08:25:10 2016 +0000
@@ -0,0 +1,354 @@
+/*
+ * Copyright (c) 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.
+ */
+package java.lang.reflect;
+
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.util.Collection;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.BiFunction;
+
+/**
+ * A WeakHashMap-like data structure that uses a pair of weakly-referenced keys
+ * with identity equality semantics to associate a strongly-referenced value.
+ * Unlike WeakHashMap, this data structure is thread-safe.
+ *
+ * @param <K1> the type of 1st key in key pair
+ * @param <K2> the type of 2nd key in key pair
+ * @param <V>  the type of value
+ * @author Peter Levart
+ */
+final class WeakPairMap<K1, K2, V> {
+
+    private final ConcurrentHashMap<Pair<K1, K2>, V> map = new ConcurrentHashMap<>();
+    private final ReferenceQueue<Object> queue = new ReferenceQueue<>();
+
+    /**
+     * Tests if the specified pair of keys are associated with a value
+     * in the WeakPairMap.
+     *
+     * @param k1 the 1st of the pair of keys
+     * @param k2 the 2nd of the pair of keys
+     * @return true if and only if the specified key pair is in this WeakPairMap,
+     * as determined by the identity comparison; false otherwise
+     * @throws NullPointerException if any of the specified keys is null
+     */
+    public boolean containsKeyPair(K1 k1, K2 k2) {
+        expungeStaleAssociations();
+        return map.containsKey(Pair.lookup(k1, k2));
+    }
+
+    /**
+     * Returns the value to which the specified pair of keys is mapped, or null
+     * if this WeakPairMap contains no mapping for the key pair.
+     * <p>More formally, if this WeakPairMap contains a mapping from a key pair
+     * {@code (_k1, _k2)} to a value {@code v} such that
+     * {@code k1 == _k1 && k2 == _k2}, then this method returns {@code v};
+     * otherwise it returns {@code null}.
+     * (There can be at most one such mapping.)
+     *
+     * @param k1 the 1st of the pair of keys for which the mapped value is to
+     *           be returned
+     * @param k2 the 2nd of the pair of keys for which the mapped value is to
+     *           be returned
+     * @return the value to which the specified key pair is mapped, or null if
+     * this map contains no mapping for the key pair
+     * @throws NullPointerException if any of the specified keys is null
+     */
+    public V get(K1 k1, K2 k2) {
+        expungeStaleAssociations();
+        return map.get(Pair.lookup(k1, k2));
+    }
+
+    /**
+     * Maps the specified key pair to the specified value in this WeakPairMap.
+     * Neither the keys nor the value can be null.
+     * <p>The value can be retrieved by calling the {@link #get} method
+     * with the the same keys (compared by identity).
+     *
+     * @param k1 the 1st of the pair of keys with which the specified value is to
+     *           be associated
+     * @param k2 the 2nd of the pair of keys with which the specified value is to
+     *           be associated
+     * @param v  value to be associated with the specified key pair
+     * @return the previous value associated with key pair, or {@code null} if
+     * there was no mapping for key pair
+     * @throws NullPointerException if any of the specified keys or value is null
+     */
+    public V put(K1 k1, K2 k2, V v) {
+        expungeStaleAssociations();
+        return map.put(Pair.weak(k1, k2, queue), v);
+    }
+
+    /**
+     * If the specified key pair is not already associated with a value,
+     * associates it with the given value and returns {@code null}, else does
+     * nothing and returns the currently associated value.
+     *
+     * @param k1 the 1st of the pair of keys with which the specified value is to
+     *           be associated
+     * @param k2 the 2nd of the pair of keys with which the specified value is to
+     *           be associated
+     * @param v  value to be associated with the specified key pair
+     * @return the previous value associated with key pair, or {@code null} if
+     * there was no mapping for key pair
+     * @throws NullPointerException if any of the specified keys or value is null
+     */
+    public V putIfAbsent(K1 k1, K2 k2, V v) {
+        expungeStaleAssociations();
+        return map.putIfAbsent(Pair.weak(k1, k2, queue), v);
+    }
+
+    /**
+     * If the specified key pair is not already associated with a value,
+     * attempts to compute its value using the given mapping function
+     * and enters it into this WeakPairMap unless {@code null}. The entire
+     * method invocation is performed atomically, so the function is
+     * applied at most once per key pair. Some attempted update operations
+     * on this WeakPairMap by other threads may be blocked while computation
+     * is in progress, so the computation should be short and simple,
+     * and must not attempt to update any other mappings of this WeakPairMap.
+     *
+     * @param k1              the 1st of the pair of keys with which the
+     *                        computed value is to be associated
+     * @param k2              the 2nd of the pair of keys with which the
+     *                        computed value is to be associated
+     * @param mappingFunction the function to compute a value
+     * @return the current (existing or computed) value associated with
+     * the specified key pair, or null if the computed value is null
+     * @throws NullPointerException  if any of the specified keys or
+     *                               mappingFunction is null
+     * @throws IllegalStateException if the computation detectably
+     *                               attempts a recursive update to this map
+     *                               that would otherwise never complete
+     * @throws RuntimeException      or Error if the mappingFunction does so, in
+     *                               which case the mapping is left unestablished
+     */
+    public V computeIfAbsent(K1 k1, K2 k2,
+                             BiFunction<? super K1, ? super K2, ? extends V>
+                                 mappingFunction) {
+        expungeStaleAssociations();
+        try {
+            return map.computeIfAbsent(
+                Pair.weak(k1, k2, queue),
+                pair -> mappingFunction.apply(pair.first(), pair.second()));
+        } finally {
+            Reference.reachabilityFence(k1);
+            Reference.reachabilityFence(k2);
+        }
+    }
+
+    /**
+     * Returns a {@link Collection} view of the values contained in this
+     * WeakPairMap. The collection is backed by the WeakPairMap, so changes to
+     * the map are reflected in the collection, and vice-versa.  The collection
+     * supports element removal, which removes the corresponding
+     * mapping from this map, via the {@code Iterator.remove},
+     * {@code Collection.remove}, {@code removeAll},
+     * {@code retainAll}, and {@code clear} operations.  It does not
+     * support the {@code add} or {@code addAll} operations.
+     *
+     * @return the collection view
+     */
+    public Collection<V> values() {
+        expungeStaleAssociations();
+        return map.values();
+    }
+
+    /**
+     * Removes associations from this WeakPairMap for which at least one of the
+     * keys in key pair has been found weakly-reachable and corresponding
+     * WeakRefPeer(s) enqueued. Called as part of each public operation.
+     */
+    private void expungeStaleAssociations() {
+        WeakRefPeer<?> peer;
+        while ((peer = (WeakRefPeer<?>) queue.poll()) != null) {
+            map.remove(peer.weakPair());
+        }
+    }
+
+    /**
+     * Common interface of both {@link Weak} and {@link Lookup} key pairs.
+     */
+    private interface Pair<K1, K2> {
+
+        static <K1, K2> Pair<K1, K2> weak(K1 k1, K2 k2,
+                                          ReferenceQueue<Object> queue) {
+            return new Weak<>(k1, k2, queue);
+        }
+
+        static <K1, K2> Pair<K1, K2> lookup(K1 k1, K2 k2) {
+            return new Lookup<>(k1, k2);
+        }
+
+        /**
+         * @return The 1st of the pair of keys (may be null for {@link Weak}
+         * when it gets cleared)
+         */
+        K1 first();
+
+        /**
+         * @return The 2nd of the pair of keys (may be null for {@link Weak}
+         * when it gets cleared)
+         */
+        K2 second();
+
+        static int hashCode(Object first, Object second) {
+            // assert first != null && second != null;
+            return System.identityHashCode(first) ^
+                   System.identityHashCode(second);
+        }
+
+        static boolean equals(Object first, Object second, Pair<?, ?> p) {
+            return first != null && second != null &&
+                   first == p.first() && second == p.second();
+        }
+
+        /**
+         * A Pair where both keys are weakly-referenced.
+         * It is composed of two instances of {@link WeakRefPeer}s:
+         * <pre>{@code
+         *
+         *     +-referent-> [K1]                +-referent-> [K2]
+         *     |                                |
+         *   +----------------+               +----------------+
+         *   | Pair.Weak <:   |-----peer----->| (anonymous) <: |
+         *   | WeakRefPeer,   |               | WeakRefPeer    |
+         *   | Pair           |<--weakPair()--|                |
+         *   +----------------+               +----------------+
+         *     |            ^
+         *     |            |
+         *     +-weakPair()-+
+         *
+         * }</pre>
+         * <p>
+         * Pair.Weak is used for CHM keys. Both peers are associated with the
+         * same {@link ReferenceQueue} so when either of their referents
+         * becomes weakly-reachable, the corresponding entries can be
+         * {@link #expungeStaleAssociations() expunged} from the map.
+         */
+        final class Weak<K1, K2> extends WeakRefPeer<K1> implements Pair<K1, K2> {
+
+            // saved hash so it can be retrieved after the reference is cleared
+            private final int hash;
+            // link to <K2> peer
+            private final WeakRefPeer<K2> peer;
+
+            Weak(K1 k1, K2 k2, ReferenceQueue<Object> queue) {
+                super(k1, queue);
+                hash = Pair.hashCode(k1, k2);
+                peer = new WeakRefPeer<>(k2, queue) {
+                    // link back to <K1> peer
+                    @Override
+                    Weak<?, ?> weakPair() { return Weak.this; }
+                };
+            }
+
+            @Override
+            Weak<?, ?> weakPair() {
+                return this;
+            }
+
+            @Override
+            public K1 first() {
+                return get();
+            }
+
+            @Override
+            public K2 second() {
+                return peer.get();
+            }
+
+            @Override
+            public int hashCode() {
+                return hash;
+            }
+
+            @Override
+            public boolean equals(Object obj) {
+                return this == obj ||
+                       (obj instanceof Pair &&
+                        Pair.equals(first(), second(), (Pair<?, ?>) obj));
+            }
+        }
+
+        /**
+         * Optimized lookup Pair, used as lookup key in methods like
+         * {@link java.util.Map#get(Object)} or
+         * {@link java.util.Map#containsKey(Object)}) where
+         * there is a great chance its allocation is eliminated
+         * by escape analysis when such lookups are inlined by JIT.
+         * All its methods are purposely designed so that 'this' is never
+         * passed to any other method or used as identity.
+         */
+        final class Lookup<K1, K2> implements Pair<K1, K2> {
+            private final K1 k1;
+            private final K2 k2;
+
+            Lookup(K1 k1, K2 k2) {
+                this.k1 = Objects.requireNonNull(k1);
+                this.k2 = Objects.requireNonNull(k2);
+            }
+
+            @Override
+            public K1 first() {
+                return k1;
+            }
+
+            @Override
+            public K2 second() {
+                return k2;
+            }
+
+            @Override
+            public int hashCode() {
+                return Pair.hashCode(k1, k2);
+            }
+
+            @Override
+            public boolean equals(Object obj) {
+                return obj instanceof Pair &&
+                       Pair.equals(k1, k2, (Pair<?, ?>) obj);
+            }
+        }
+    }
+
+    /**
+     * Common abstract supertype of a pair of WeakReference peers.
+     */
+    private static abstract class WeakRefPeer<K> extends WeakReference<K> {
+
+        WeakRefPeer(K k, ReferenceQueue<Object> queue) {
+            super(Objects.requireNonNull(k), queue);
+        }
+
+        /**
+         * @return the {@link Pair.Weak} side of the pair of peers.
+         */
+        abstract Pair.Weak<?, ?> weakPair();
+    }
+}
--- a/src/java.base/share/classes/java/math/BigDecimal.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/math/BigDecimal.java	Sun May 08 08:25:10 2016 +0000
@@ -1536,7 +1536,7 @@
      * be performed to generate a result with the specified scale, the
      * specified rounding mode is applied.
      *
-     * <p>The new {@link #divide(BigDecimal, int, RoundingMode)} method
+     * @deprecated The method {@link #divide(BigDecimal, int, RoundingMode)}
      * should be used in preference to this legacy method.
      *
      * @param  divisor value by which this {@code BigDecimal} is to be divided.
@@ -1558,6 +1558,7 @@
      * @see    #ROUND_HALF_EVEN
      * @see    #ROUND_UNNECESSARY
      */
+    @Deprecated(since="9")
     public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) {
         if (roundingMode < ROUND_UP || roundingMode > ROUND_UNNECESSARY)
             throw new IllegalArgumentException("Invalid rounding mode");
@@ -1602,7 +1603,7 @@
      * rounding must be performed to generate a result with the given
      * scale, the specified rounding mode is applied.
      *
-     * <p>The new {@link #divide(BigDecimal, RoundingMode)} method
+     * @deprecated The method {@link #divide(BigDecimal, RoundingMode)}
      * should be used in preference to this legacy method.
      *
      * @param  divisor value by which this {@code BigDecimal} is to be divided.
@@ -1623,6 +1624,7 @@
      * @see    #ROUND_HALF_EVEN
      * @see    #ROUND_UNNECESSARY
      */
+    @Deprecated(since="9")
     public BigDecimal divide(BigDecimal divisor, int roundingMode) {
         return this.divide(divisor, scale, roundingMode);
     }
@@ -2267,14 +2269,20 @@
      * Rounding mode to round away from zero.  Always increments the
      * digit prior to a nonzero discarded fraction.  Note that this rounding
      * mode never decreases the magnitude of the calculated value.
+     *
+     * @deprecated Use {@link RoundingMode#UP} instead.
      */
+    @Deprecated(since="9")
     public static final int ROUND_UP =           0;
 
     /**
      * Rounding mode to round towards zero.  Never increments the digit
      * prior to a discarded fraction (i.e., truncates).  Note that this
      * rounding mode never increases the magnitude of the calculated value.
+     *
+     * @deprecated Use {@link RoundingMode#DOWN} instead.
      */
+    @Deprecated(since="9")
     public static final int ROUND_DOWN =         1;
 
     /**
@@ -2283,7 +2291,10 @@
      * {@code ROUND_UP}; if negative, behaves as for
      * {@code ROUND_DOWN}.  Note that this rounding mode never
      * decreases the calculated value.
+     *
+     * @deprecated Use {@link RoundingMode#CEILING} instead.
      */
+    @Deprecated(since="9")
     public static final int ROUND_CEILING =      2;
 
     /**
@@ -2292,7 +2303,10 @@
      * {@code ROUND_DOWN}; if negative, behave as for
      * {@code ROUND_UP}.  Note that this rounding mode never
      * increases the calculated value.
+     *
+     * @deprecated Use {@link RoundingMode#FLOOR} instead.
      */
+    @Deprecated(since="9")
     public static final int ROUND_FLOOR =        3;
 
     /**
@@ -2302,7 +2316,10 @@
      * &ge; 0.5; otherwise, behaves as for {@code ROUND_DOWN}.  Note
      * that this is the rounding mode that most of us were taught in
      * grade school.
+     *
+     * @deprecated Use {@link RoundingMode#HALF_UP} instead.
      */
+    @Deprecated(since="9")
     public static final int ROUND_HALF_UP =      4;
 
     /**
@@ -2311,7 +2328,10 @@
      * down.  Behaves as for {@code ROUND_UP} if the discarded
      * fraction is {@literal >} 0.5; otherwise, behaves as for
      * {@code ROUND_DOWN}.
+     *
+     * @deprecated Use {@link RoundingMode#HALF_DOWN} instead.
      */
+    @Deprecated(since="9")
     public static final int ROUND_HALF_DOWN =    5;
 
     /**
@@ -2323,7 +2343,10 @@
      * {@code ROUND_HALF_DOWN} if it's even.  Note that this is the
      * rounding mode that minimizes cumulative error when applied
      * repeatedly over a sequence of calculations.
+     *
+     * @deprecated Use {@link RoundingMode#HALF_EVEN} instead.
      */
+    @Deprecated(since="9")
     public static final int ROUND_HALF_EVEN =    6;
 
     /**
@@ -2331,7 +2354,10 @@
      * result, hence no rounding is necessary.  If this rounding mode is
      * specified on an operation that yields an inexact result, an
      * {@code ArithmeticException} is thrown.
+     *
+     * @deprecated Use {@link RoundingMode#UNNECESSARY} instead.
      */
+    @Deprecated(since="9")
     public static final int ROUND_UNNECESSARY =  7;
 
 
@@ -2408,7 +2434,7 @@
      * Instead, {@code setScale} returns an object with the proper
      * scale; the returned object may or may not be newly allocated.
      *
-     * <p>The new {@link #setScale(int, RoundingMode)} method should
+     * @deprecated The method {@link #setScale(int, RoundingMode)} should
      * be used in preference to this legacy method.
      *
      * @param  newScale scale of the {@code BigDecimal} value to be returned.
@@ -2431,6 +2457,7 @@
      * @see    #ROUND_HALF_EVEN
      * @see    #ROUND_UNNECESSARY
      */
+    @Deprecated(since="9")
     public BigDecimal setScale(int newScale, int roundingMode) {
         if (roundingMode < ROUND_UP || roundingMode > ROUND_UNNECESSARY)
             throw new IllegalArgumentException("Invalid rounding mode");
--- a/src/java.base/share/classes/java/math/RoundingMode.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/math/RoundingMode.java	Sun May 08 08:25:10 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -90,6 +90,7 @@
  * @author  Joseph D. Darcy
  * @since 1.5
  */
+@SuppressWarnings("deprecation") // Legacy rounding mode constants in BigDecimal
 public enum RoundingMode {
 
         /**
--- a/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java	Sun May 08 08:25:10 2016 +0000
@@ -52,7 +52,8 @@
     protected InetAddress connectedAddress = null;
     private int connectedPort = -1;
 
-    private static final String os = GetPropertyAction.getProperty("os.name");
+    private static final String os =
+            GetPropertyAction.privilegedGetProperty("os.name");
 
     /**
      * flag set if the native connect() call not to be used
--- a/src/java.base/share/classes/java/net/InetAddress.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/net/InetAddress.java	Sun May 08 08:25:10 2016 +0000
@@ -1124,7 +1124,7 @@
     private static NameService createNameService() {
 
         String hostsFileName =
-                GetPropertyAction.getProperty("jdk.net.hosts.file");
+                GetPropertyAction.privilegedGetProperty("jdk.net.hosts.file");
         NameService theNameService;
         if (hostsFileName != null) {
             theNameService = new HostsFileNameService(hostsFileName);
@@ -1643,9 +1643,11 @@
          * property can vary across implementations of the java.
          * classes.  The default is an empty String "".
          */
-        String prefix = GetPropertyAction.getProperty("impl.prefix", "");
+        String prefix = GetPropertyAction.privilegedGetProperty("impl.prefix", "");
         try {
-            impl = Class.forName("java.net." + prefix + implName).newInstance();
+            @SuppressWarnings("deprecation")
+            Object tmp = Class.forName("java.net." + prefix + implName).newInstance();
+            impl = tmp;
         } catch (ClassNotFoundException e) {
             System.err.println("Class not found: java.net." + prefix +
                                implName + ":\ncheck impl.prefix property " +
@@ -1662,7 +1664,9 @@
 
         if (impl == null) {
             try {
-                impl = Class.forName(implName).newInstance();
+                @SuppressWarnings("deprecation")
+                Object tmp = Class.forName(implName).newInstance();
+                impl = tmp;
             } catch (Exception e) {
                 throw new Error("System property impl.prefix incorrect");
             }
--- a/src/java.base/share/classes/java/net/ProxySelector.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/net/ProxySelector.java	Sun May 08 08:25:10 2016 +0000
@@ -71,7 +71,9 @@
         try {
             Class<?> c = Class.forName("sun.net.spi.DefaultProxySelector");
             if (c != null && ProxySelector.class.isAssignableFrom(c)) {
-                theProxySelector = (ProxySelector) c.newInstance();
+                @SuppressWarnings("deprecation")
+                ProxySelector tmp = (ProxySelector) c.newInstance();
+                theProxySelector = tmp;
             }
         } catch (Exception e) {
             theProxySelector = null;
--- a/src/java.base/share/classes/java/net/SocksSocketImpl.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/net/SocksSocketImpl.java	Sun May 08 08:25:10 2016 +0000
@@ -178,7 +178,7 @@
                 userName = pw.getUserName();
                 password = new String(pw.getPassword());
             } else {
-                userName = GetPropertyAction.getProperty("user.name");
+                userName = GetPropertyAction.privilegedGetProperty("user.name");
             }
             if (userName == null)
                 return false;
@@ -1088,7 +1088,7 @@
                 userName = System.getProperty("user.name");
             } catch (SecurityException se) { /* swallow Exception */ }
         } else {
-            userName = GetPropertyAction.getProperty("user.name");
+            userName = GetPropertyAction.privilegedGetProperty("user.name");
         }
         return userName;
     }
--- a/src/java.base/share/classes/java/net/URL.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/net/URL.java	Sun May 08 08:25:10 2016 +0000
@@ -1198,8 +1198,9 @@
         public URLStreamHandler createURLStreamHandler(String protocol) {
             String name = PREFIX + "." + protocol + ".Handler";
             try {
-                Class<?> c = Class.forName(name);
-                return (URLStreamHandler)c.newInstance();
+                @SuppressWarnings("deprecation")
+                Object o = Class.forName(name).newInstance();
+                return (URLStreamHandler)o;
             } catch (ClassNotFoundException x) {
                 // ignore
             } catch (Exception e) {
@@ -1212,7 +1213,7 @@
 
     private static URLStreamHandler lookupViaProperty(String protocol) {
         String packagePrefixList =
-                GetPropertyAction.getProperty(protocolPathProp);
+                GetPropertyAction.privilegedGetProperty(protocolPathProp);
         if (packagePrefixList == null) {
             // not set
             return null;
@@ -1234,7 +1235,9 @@
                     }
                 }
                 if (cls != null) {
-                    handler = (URLStreamHandler)cls.newInstance();
+                    @SuppressWarnings("deprecation")
+                    Object tmp = cls.newInstance();
+                    handler = (URLStreamHandler)tmp;
                 }
             } catch (Exception e) {
                 // any number of exceptions can get thrown here
--- a/src/java.base/share/classes/java/net/URLConnection.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/net/URLConnection.java	Sun May 08 08:25:10 2016 +0000
@@ -1323,7 +1323,9 @@
                     }
                 }
                 if (cls != null) {
-                    return (ContentHandler) cls.newInstance();
+                    @SuppressWarnings("deprecation")
+                    Object tmp = cls.newInstance();
+                    return (ContentHandler) tmp;
                 }
             } catch(Exception ignored) { }
         }
@@ -1397,7 +1399,7 @@
      */
     private String getContentHandlerPkgPrefixes() {
         String packagePrefixList =
-                GetPropertyAction.getProperty(contentPathProp, "");
+                GetPropertyAction.privilegedGetProperty(contentPathProp, "");
 
         if (packagePrefixList != "") {
             packagePrefixList += "|";
--- a/src/java.base/share/classes/java/net/URLEncoder.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/net/URLEncoder.java	Sun May 08 08:25:10 2016 +0000
@@ -133,7 +133,7 @@
         dontNeedEncoding.set('.');
         dontNeedEncoding.set('*');
 
-        dfltEncName = GetPropertyAction.getProperty("file.encoding");
+        dfltEncName = GetPropertyAction.privilegedGetProperty("file.encoding");
     }
 
     /**
--- a/src/java.base/share/classes/java/nio/channels/spi/AsynchronousChannelProvider.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/nio/channels/spi/AsynchronousChannelProvider.java	Sun May 08 08:25:10 2016 +0000
@@ -94,9 +94,10 @@
             if (cn == null)
                 return null;
             try {
-                Class<?> c = Class.forName(cn, true,
-                                           ClassLoader.getSystemClassLoader());
-                return (AsynchronousChannelProvider)c.newInstance();
+                @SuppressWarnings("deprecation")
+                Object tmp = Class.forName(cn, true,
+                                           ClassLoader.getSystemClassLoader()).newInstance();
+                return (AsynchronousChannelProvider)tmp;
             } catch (ClassNotFoundException x) {
                 throw new ServiceConfigurationError(null, x);
             } catch (IllegalAccessException x) {
--- a/src/java.base/share/classes/java/nio/channels/spi/SelectorProvider.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/nio/channels/spi/SelectorProvider.java	Sun May 08 08:25:10 2016 +0000
@@ -95,9 +95,10 @@
         if (cn == null)
             return false;
         try {
-            Class<?> c = Class.forName(cn, true,
-                                       ClassLoader.getSystemClassLoader());
-            provider = (SelectorProvider)c.newInstance();
+            @SuppressWarnings("deprecation")
+            Object tmp = Class.forName(cn, true,
+                                       ClassLoader.getSystemClassLoader()).newInstance();
+            provider = (SelectorProvider)tmp;
             return true;
         } catch (ClassNotFoundException x) {
             throw new ServiceConfigurationError(null, x);
--- a/src/java.base/share/classes/java/nio/charset/Charset.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/nio/charset/Charset.java	Sun May 08 08:25:10 2016 +0000
@@ -283,8 +283,8 @@
         if (level == null) {
             if (!VM.isBooted())
                 return false;
-            bugLevel = level =
-                    GetPropertyAction.getProperty("sun.nio.cs.bugLevel", "");
+            bugLevel = level = GetPropertyAction
+                    .privilegedGetProperty("sun.nio.cs.bugLevel", "");
         }
         return level.equals(bl);
     }
@@ -609,7 +609,8 @@
     public static Charset defaultCharset() {
         if (defaultCharset == null) {
             synchronized (Charset.class) {
-                String csn = GetPropertyAction.getProperty("file.encoding");
+                String csn = GetPropertyAction
+                        .privilegedGetProperty("file.encoding");
                 Charset cs = lookup(csn);
                 if (cs != null)
                     defaultCharset = cs;
--- a/src/java.base/share/classes/java/nio/file/TempFileHelper.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/nio/file/TempFileHelper.java	Sun May 08 08:25:10 2016 +0000
@@ -46,7 +46,7 @@
 
     // temporary directory location
     private static final Path tmpdir =
-        Paths.get(GetPropertyAction.getProperty("java.io.tmpdir"));
+        Paths.get(GetPropertyAction.privilegedGetProperty("java.io.tmpdir"));
 
     private static final boolean isPosix =
         FileSystems.getDefault().supportedFileAttributeViews().contains("posix");
--- a/src/java.base/share/classes/java/security/Policy.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/security/Policy.java	Sun May 08 08:25:10 2016 +0000
@@ -222,8 +222,9 @@
             public Policy run() {
                 try {
                     ClassLoader scl = ClassLoader.getSystemClassLoader();
-                    Class<?> c = Class.forName(policyProvider, true, scl);
-                    return (Policy)c.newInstance();
+                    @SuppressWarnings("deprecation")
+                    Object o = Class.forName(policyProvider, true, scl).newInstance();
+                    return (Policy)o;
                 } catch (Exception e) {
                     if (debug != null) {
                         debug.println("policy provider " + policyProvider +
--- a/src/java.base/share/classes/java/time/format/DateTimeFormatter.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/time/format/DateTimeFormatter.java	Sun May 08 08:25:10 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -284,6 +284,7 @@
  *   D       day-of-year                 number            189
  *   M/L     month-of-year               number/text       7; 07; Jul; July; J
  *   d       day-of-month                number            10
+ *   g       modified-julian-day         number            2451334
  *
  *   Q/q     quarter-of-year             number/text       3; 03; Q3; 3rd quarter
  *   Y       week-based-year             year              1996; 96
@@ -308,10 +309,10 @@
  *
  *   V       time-zone ID                zone-id           America/Los_Angeles; Z; -08:30
  *   z       time-zone name              zone-name         Pacific Standard Time; PST
- *   O       localized zone-offset       offset-O          GMT+8; GMT+08:00; UTC-08:00;
- *   X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15;
- *   x       zone-offset                 offset-x          +0000; -08; -0830; -08:30; -083015; -08:30:15;
- *   Z       zone-offset                 offset-Z          +0000; -0800; -08:00;
+ *   O       localized zone-offset       offset-O          GMT+8; GMT+08:00; UTC-08:00
+ *   X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15
+ *   x       zone-offset                 offset-x          +0000; -08; -0830; -08:30; -083015; -08:30:15
+ *   Z       zone-offset                 offset-Z          +0000; -0800; -08:00
  *
  *   p       pad next                    pad modifier      1
  *
--- a/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java	Sun May 08 08:25:10 2016 +0000
@@ -90,6 +90,7 @@
 import java.time.format.DateTimeTextProvider.LocaleStore;
 import java.time.temporal.ChronoField;
 import java.time.temporal.IsoFields;
+import java.time.temporal.JulianFields;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalField;
 import java.time.temporal.TemporalQueries;
@@ -666,8 +667,11 @@
      * No rounding occurs due to the maximum width - digits are simply dropped.
      * <p>
      * When parsing in strict mode, the number of parsed digits must be between
-     * the minimum and maximum width. When parsing in lenient mode, the minimum
-     * width is considered to be zero and the maximum is nine.
+     * the minimum and maximum width. In strict mode, if the minimum and maximum widths
+     * are equal and there is no decimal point then the parser will
+     * participate in adjacent value parsing, see
+     * {@link appendValue(java.time.temporal.TemporalField, int)}. When parsing in lenient mode,
+     * the minimum width is considered to be zero and the maximum is nine.
      * <p>
      * If the value cannot be obtained then an exception will be thrown.
      * If the value is negative an exception will be thrown.
@@ -686,7 +690,12 @@
      */
     public DateTimeFormatterBuilder appendFraction(
             TemporalField field, int minWidth, int maxWidth, boolean decimalPoint) {
-        appendInternal(new FractionPrinterParser(field, minWidth, maxWidth, decimalPoint));
+        if (minWidth == maxWidth && decimalPoint == false) {
+            // adjacent parsing
+            appendValue(new FractionPrinterParser(field, minWidth, maxWidth, decimalPoint));
+        } else {
+            appendInternal(new FractionPrinterParser(field, minWidth, maxWidth, decimalPoint));
+        }
         return this;
     }
 
@@ -1383,6 +1392,7 @@
      *   D       day-of-year                 number            189
      *   M/L     month-of-year               number/text       7; 07; Jul; July; J
      *   d       day-of-month                number            10
+     *   g       modified-julian-day         number            2451334
      *
      *   Q/q     quarter-of-year             number/text       3; 03; Q3; 3rd quarter
      *   Y       week-based-year             year              1996; 96
@@ -1408,9 +1418,9 @@
      *   V       time-zone ID                zone-id           America/Los_Angeles; Z; -08:30
      *   z       time-zone name              zone-name         Pacific Standard Time; PST
      *   O       localized zone-offset       offset-O          GMT+8; GMT+08:00; UTC-08:00;
-     *   X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15;
-     *   x       zone-offset                 offset-x          +0000; -08; -0830; -08:30; -083015; -08:30:15;
-     *   Z       zone-offset                 offset-Z          +0000; -0800; -08:00;
+     *   X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15
+     *   x       zone-offset                 offset-x          +0000; -08; -0830; -08:30; -083015; -08:30:15
+     *   Z       zone-offset                 offset-Z          +0000; -0800; -08:00
      *
      *   p       pad next                    pad modifier      1
      *
@@ -1437,37 +1447,37 @@
      *    GGGG    4      appendText(ChronoField.ERA, TextStyle.FULL)
      *    GGGGG   5      appendText(ChronoField.ERA, TextStyle.NARROW)
      *
-     *    u       1      appendValue(ChronoField.YEAR, 1, 19, SignStyle.NORMAL);
-     *    uu      2      appendValueReduced(ChronoField.YEAR, 2, 2000);
-     *    uuu     3      appendValue(ChronoField.YEAR, 3, 19, SignStyle.NORMAL);
-     *    u..u    4..n   appendValue(ChronoField.YEAR, n, 19, SignStyle.EXCEEDS_PAD);
-     *    y       1      appendValue(ChronoField.YEAR_OF_ERA, 1, 19, SignStyle.NORMAL);
-     *    yy      2      appendValueReduced(ChronoField.YEAR_OF_ERA, 2, 2000);
-     *    yyy     3      appendValue(ChronoField.YEAR_OF_ERA, 3, 19, SignStyle.NORMAL);
-     *    y..y    4..n   appendValue(ChronoField.YEAR_OF_ERA, n, 19, SignStyle.EXCEEDS_PAD);
+     *    u       1      appendValue(ChronoField.YEAR, 1, 19, SignStyle.NORMAL)
+     *    uu      2      appendValueReduced(ChronoField.YEAR, 2, 2000)
+     *    uuu     3      appendValue(ChronoField.YEAR, 3, 19, SignStyle.NORMAL)
+     *    u..u    4..n   appendValue(ChronoField.YEAR, n, 19, SignStyle.EXCEEDS_PAD)
+     *    y       1      appendValue(ChronoField.YEAR_OF_ERA, 1, 19, SignStyle.NORMAL)
+     *    yy      2      appendValueReduced(ChronoField.YEAR_OF_ERA, 2, 2000)
+     *    yyy     3      appendValue(ChronoField.YEAR_OF_ERA, 3, 19, SignStyle.NORMAL)
+     *    y..y    4..n   appendValue(ChronoField.YEAR_OF_ERA, n, 19, SignStyle.EXCEEDS_PAD)
      *    Y       1      append special localized WeekFields element for numeric week-based-year
-     *    YY      2      append special localized WeekFields element for reduced numeric week-based-year 2 digits;
-     *    YYY     3      append special localized WeekFields element for numeric week-based-year (3, 19, SignStyle.NORMAL);
-     *    Y..Y    4..n   append special localized WeekFields element for numeric week-based-year (n, 19, SignStyle.EXCEEDS_PAD);
+     *    YY      2      append special localized WeekFields element for reduced numeric week-based-year 2 digits
+     *    YYY     3      append special localized WeekFields element for numeric week-based-year (3, 19, SignStyle.NORMAL)
+     *    Y..Y    4..n   append special localized WeekFields element for numeric week-based-year (n, 19, SignStyle.EXCEEDS_PAD)
      *
-     *    Q       1      appendValue(IsoFields.QUARTER_OF_YEAR);
-     *    QQ      2      appendValue(IsoFields.QUARTER_OF_YEAR, 2);
+     *    Q       1      appendValue(IsoFields.QUARTER_OF_YEAR)
+     *    QQ      2      appendValue(IsoFields.QUARTER_OF_YEAR, 2)
      *    QQQ     3      appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.SHORT)
      *    QQQQ    4      appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.FULL)
      *    QQQQQ   5      appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.NARROW)
-     *    q       1      appendValue(IsoFields.QUARTER_OF_YEAR);
-     *    qq      2      appendValue(IsoFields.QUARTER_OF_YEAR, 2);
+     *    q       1      appendValue(IsoFields.QUARTER_OF_YEAR)
+     *    qq      2      appendValue(IsoFields.QUARTER_OF_YEAR, 2)
      *    qqq     3      appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.SHORT_STANDALONE)
      *    qqqq    4      appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.FULL_STANDALONE)
      *    qqqqq   5      appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.NARROW_STANDALONE)
      *
-     *    M       1      appendValue(ChronoField.MONTH_OF_YEAR);
-     *    MM      2      appendValue(ChronoField.MONTH_OF_YEAR, 2);
+     *    M       1      appendValue(ChronoField.MONTH_OF_YEAR)
+     *    MM      2      appendValue(ChronoField.MONTH_OF_YEAR, 2)
      *    MMM     3      appendText(ChronoField.MONTH_OF_YEAR, TextStyle.SHORT)
      *    MMMM    4      appendText(ChronoField.MONTH_OF_YEAR, TextStyle.FULL)
      *    MMMMM   5      appendText(ChronoField.MONTH_OF_YEAR, TextStyle.NARROW)
-     *    L       1      appendValue(ChronoField.MONTH_OF_YEAR);
-     *    LL      2      appendValue(ChronoField.MONTH_OF_YEAR, 2);
+     *    L       1      appendValue(ChronoField.MONTH_OF_YEAR)
+     *    LL      2      appendValue(ChronoField.MONTH_OF_YEAR, 2)
      *    LLL     3      appendText(ChronoField.MONTH_OF_YEAR, TextStyle.SHORT_STANDALONE)
      *    LLLL    4      appendText(ChronoField.MONTH_OF_YEAR, TextStyle.FULL_STANDALONE)
      *    LLLLL   5      appendText(ChronoField.MONTH_OF_YEAR, TextStyle.NARROW_STANDALONE)
@@ -1481,6 +1491,7 @@
      *    DD      2      appendValue(ChronoField.DAY_OF_YEAR, 2)
      *    DDD     3      appendValue(ChronoField.DAY_OF_YEAR, 3)
      *    F       1      appendValue(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH)
+     *    g..g    1..n   appendValue(JulianFields.MODIFIED_JULIAN_DAY, n, 19, SignStyle.NORMAL)
      *    E       1      appendText(ChronoField.DAY_OF_WEEK, TextStyle.SHORT)
      *    EE      2      appendText(ChronoField.DAY_OF_WEEK, TextStyle.SHORT)
      *    EEE     3      appendText(ChronoField.DAY_OF_WEEK, TextStyle.SHORT)
@@ -1539,8 +1550,8 @@
      * <pre>
      *  Pattern  Count  Equivalent builder methods
      *  -------  -----  --------------------------
-     *    O       1      appendLocalizedOffset(TextStyle.SHORT);
-     *    OOOO    4      appendLocalizedOffset(TextStyle.FULL);
+     *    O       1      appendLocalizedOffset(TextStyle.SHORT)
+     *    OOOO    4      appendLocalizedOffset(TextStyle.FULL)
      *    X       1      appendOffset("+HHmm","Z")
      *    XX      2      appendOffset("+HHMM","Z")
      *    XXX     3      appendOffset("+HH:MM","Z")
@@ -1554,7 +1565,7 @@
      *    Z       1      appendOffset("+HHMM","+0000")
      *    ZZ      2      appendOffset("+HHMM","+0000")
      *    ZZZ     3      appendOffset("+HHMM","+0000")
-     *    ZZZZ    4      appendLocalizedOffset(TextStyle.FULL);
+     *    ZZZZ    4      appendLocalizedOffset(TextStyle.FULL)
      *    ZZZZZ   5      appendOffset("+HH:MM:ss","Z")
      * </pre>
      * <p>
@@ -1836,6 +1847,9 @@
                     throw new IllegalArgumentException("Too many pattern letters: " + cur);
                 }
                 break;
+            case 'g':
+                appendValue(field, count, 19, SignStyle.NORMAL);
+                break;
             default:
                 if (count == 1) {
                     appendValue(field);
@@ -1874,6 +1888,7 @@
         FIELD_MAP.put('A', ChronoField.MILLI_OF_DAY);              // LDML
         FIELD_MAP.put('n', ChronoField.NANO_OF_SECOND);            // 310 (proposed for LDML)
         FIELD_MAP.put('N', ChronoField.NANO_OF_DAY);               // 310 (proposed for LDML)
+        FIELD_MAP.put('g', JulianFields.MODIFIED_JULIAN_DAY);
         // 310 - z - time-zone names, matches LDML and SimpleDateFormat 1 to 4
         // 310 - Z - matches SimpleDateFormat and LDML
         // 310 - V - time-zone id, matches LDML
@@ -1884,7 +1899,6 @@
         // LDML - U - cycle year name, not supported by 310 yet
         // LDML - l - deprecated
         // LDML - j - not relevant
-        // LDML - g - modified-julian-day
         // LDML - v,V - extended time-zone names
     }
 
@@ -2919,11 +2933,8 @@
     /**
      * Prints and parses a numeric date-time field with optional padding.
      */
-    static final class FractionPrinterParser implements DateTimePrinterParser {
-        private final TemporalField field;
-        private final int minWidth;
-        private final int maxWidth;
-        private final boolean decimalPoint;
+    static final class FractionPrinterParser extends NumberPrinterParser {
+       private final boolean decimalPoint;
 
         /**
          * Constructor.
@@ -2934,6 +2945,7 @@
          * @param decimalPoint  whether to output the localized decimal point symbol
          */
         FractionPrinterParser(TemporalField field, int minWidth, int maxWidth, boolean decimalPoint) {
+            this(field, minWidth, maxWidth, decimalPoint, 0);
             Objects.requireNonNull(field, "field");
             if (field.range().isFixed() == false) {
                 throw new IllegalArgumentException("Field must have a fixed set of values: " + field);
@@ -2948,12 +2960,61 @@
                 throw new IllegalArgumentException("Maximum width must exceed or equal the minimum width but " +
                         maxWidth + " < " + minWidth);
             }
-            this.field = field;
-            this.minWidth = minWidth;
-            this.maxWidth = maxWidth;
+        }
+
+        /**
+         * Constructor.
+         *
+         * @param field  the field to output, not null
+         * @param minWidth  the minimum width to output, from 0 to 9
+         * @param maxWidth  the maximum width to output, from 0 to 9
+         * @param decimalPoint  whether to output the localized decimal point symbol
+         * @param subsequentWidth the subsequentWidth for this instance
+         */
+        FractionPrinterParser(TemporalField field, int minWidth, int maxWidth, boolean decimalPoint, int subsequentWidth) {
+            super(field, minWidth, maxWidth, SignStyle.NOT_NEGATIVE, subsequentWidth);
             this.decimalPoint = decimalPoint;
         }
 
+        /**
+         * Returns a new instance with fixed width flag set.
+         *
+         * @return a new updated printer-parser, not null
+         */
+        @Override
+        FractionPrinterParser withFixedWidth() {
+            if (subsequentWidth == -1) {
+                return this;
+            }
+            return new FractionPrinterParser(field, minWidth, maxWidth, decimalPoint, -1);
+        }
+
+        /**
+         * Returns a new instance with an updated subsequent width.
+         *
+         * @param subsequentWidth  the width of subsequent non-negative numbers, 0 or greater
+         * @return a new updated printer-parser, not null
+         */
+        @Override
+        FractionPrinterParser withSubsequentWidth(int subsequentWidth) {
+            return new FractionPrinterParser(field, minWidth, maxWidth, decimalPoint, this.subsequentWidth + subsequentWidth);
+        }
+
+        /**
+         * For FractionPrinterPrinterParser, the width is fixed if context is sttrict,
+         * minWidth equal to maxWidth and decimalpoint is absent.
+         * @param context the context
+         * @return if the field is fixed width
+         * @see DateTimeFormatterBuilder#appendValueFraction(java.time.temporal.TemporalField, int, int, boolean)
+         */
+        @Override
+        boolean isFixedWidth(DateTimeParseContext context) {
+            if (context.isStrict() && minWidth == maxWidth && decimalPoint == false) {
+                return true;
+            }
+            return false;
+        }
+
         @Override
         public boolean format(DateTimePrintContext context, StringBuilder buf) {
             Long value = context.getValue(field);
@@ -2986,8 +3047,8 @@
 
         @Override
         public int parse(DateTimeParseContext context, CharSequence text, int position) {
-            int effectiveMin = (context.isStrict() ? minWidth : 0);
-            int effectiveMax = (context.isStrict() ? maxWidth : 9);
+            int effectiveMin = (context.isStrict() || isFixedWidth(context) ? minWidth : 0);
+            int effectiveMax = (context.isStrict() || isFixedWidth(context) ? maxWidth : 9);
             int length = text.length();
             if (position == length) {
                 // valid if whole field is optional, invalid if minimum width
--- a/src/java.base/share/classes/java/time/temporal/JulianFields.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/time/temporal/JulianFields.java	Sun May 08 08:25:10 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -117,7 +117,13 @@
      *
      * <h3>Astronomical and Scientific Notes</h3>
      * The standard astronomical definition uses a fraction to indicate the time-of-day,
-     * thus 3.25 would represent the time 18:00, since days start at midday.
+     * where each day is counted from midday to midday. For example,
+     * a fraction of 0 represents midday, a fraction of 0.25
+     * represents 18:00, a fraction of 0.5 represents midnight and a fraction
+     * of 0.75 represents 06:00.
+     * <p>
+     * By contrast, this implementation has no fractional part, and counts
+     * days from midnight to midnight.
      * This implementation uses an integer and days starting at midnight.
      * The integer value for the Julian Day Number is the astronomical Julian Day value at midday
      * of the date in question.
--- a/src/java.base/share/classes/java/time/zone/ZoneRulesProvider.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/time/zone/ZoneRulesProvider.java	Sun May 08 08:25:10 2016 +0000
@@ -147,6 +147,7 @@
                 if (prop != null) {
                     try {
                         Class<?> c = Class.forName(prop, true, ClassLoader.getSystemClassLoader());
+                        @SuppressWarnings("deprecation")
                         ZoneRulesProvider provider = ZoneRulesProvider.class.cast(c.newInstance());
                         registerProvider(provider);
                         loaded.add(provider);
--- a/src/java.base/share/classes/java/util/Arrays.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/util/Arrays.java	Sun May 08 08:25:10 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -4403,6 +4403,35 @@
         public void sort(Comparator<? super E> c) {
             Arrays.sort(a, c);
         }
+
+        @Override
+        public Iterator<E> iterator() {
+            return new ArrayItr<>(a);
+        }
+    }
+
+    private static class ArrayItr<E> implements Iterator<E> {
+        private int cursor;
+        private final E[] a;
+
+        ArrayItr(E[] a) {
+            this.a = a;
+        }
+
+        @Override
+        public boolean hasNext() {
+            return cursor < a.length;
+        }
+
+        @Override
+        public E next() {
+            int i = cursor;
+            if (i >= a.length) {
+                throw new NoSuchElementException();
+            }
+            cursor = i + 1;
+            return a[i];
+        }
     }
 
     /**
--- a/src/java.base/share/classes/java/util/Locale.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/util/Locale.java	Sun May 08 08:25:10 2016 +0000
@@ -858,7 +858,7 @@
 
     private static Locale initDefault() {
         String language, region, script, country, variant;
-        Properties props = GetPropertyAction.getProperties();
+        Properties props = GetPropertyAction.privilegedGetProperties();
         language = props.getProperty("user.language", "en");
         // for compatibility, check for old user.region property
         region = props.getProperty("user.region");
@@ -883,7 +883,7 @@
     }
 
     private static Locale initDefault(Locale.Category category) {
-        Properties props = GetPropertyAction.getProperties();
+        Properties props = GetPropertyAction.privilegedGetProperties();
         return getInstance(
             props.getProperty(category.languageKey,
                     defaultLocale.getLanguage()),
--- a/src/java.base/share/classes/java/util/Observable.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/util/Observable.java	Sun May 08 08:25:10 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 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
@@ -58,7 +58,19 @@
  * @see     java.util.Observer
  * @see     java.util.Observer#update(java.util.Observable, java.lang.Object)
  * @since   1.0
+ *
+ * @deprecated
+ * This class and the {@link Observer} interface have been deprecated.
+ * The event model supported by {@code Observer} and {@code Observable}
+ * is quite limited, the order of notifications delivered by
+ * {@code Observable} is unspecified, and state changes are not in
+ * one-for-one correspondence with notifications.
+ * For a richer event model, consider using the
+ * {@link java.beans} package.  For reliable and ordered
+ * messaging among threads, consider using one of the concurrent data
+ * structures in the {@link java.util.concurrent} package.
  */
+@Deprecated(since="9")
 public class Observable {
     private boolean changed = false;
     private Vector<Observer> obs;
--- a/src/java.base/share/classes/java/util/Observer.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/util/Observer.java	Sun May 08 08:25:10 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 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
@@ -31,7 +31,12 @@
  * @author  Chris Warth
  * @see     java.util.Observable
  * @since   1.0
+ *
+ * @deprecated
+ * This interface has been deprecated. See the {@link Observable}
+ * class for further information.
  */
+@Deprecated(since="9")
 public interface Observer {
     /**
      * This method is called whenever the observed object is changed. An
--- a/src/java.base/share/classes/java/util/PropertyResourceBundle.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/util/PropertyResourceBundle.java	Sun May 08 08:25:10 2016 +0000
@@ -140,9 +140,8 @@
 
     // Check whether the strict encoding is specified.
     // The possible encoding is either "ISO-8859-1" or "UTF-8".
-    private static final String encoding =
-        GetPropertyAction
-                .getProperty("java.util.PropertyResourceBundle.encoding", "")
+    private static final String encoding = GetPropertyAction
+        .privilegedGetProperty("java.util.PropertyResourceBundle.encoding", "")
         .toUpperCase(Locale.ROOT);
 
     /**
--- a/src/java.base/share/classes/java/util/ServiceLoader.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/util/ServiceLoader.java	Sun May 08 08:25:10 2016 +0000
@@ -29,8 +29,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.lang.module.ModuleDescriptor;
-import java.lang.module.ModuleDescriptor.Provides;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Layer;
@@ -85,7 +83,7 @@
  * and deployed as a named module must have an appropriate <i>uses</i> clause
  * in its <i>module descriptor</i> to declare that the module uses
  * implementations of the service. A corresponding requirement is that a
- * provider deployed as a named modules must have an appropriate
+ * provider deployed as a named module must have an appropriate
  * <i>provides</i> clause in its module descriptor to declare that the module
  * provides an implementation of the service. The <i>uses</i> and
  * <i>provides</i> allow consumers of a service to be <i>linked</i> to
@@ -550,35 +548,29 @@
     /**
      * Implements lazy service provider lookup of service providers that
      * are provided by modules in a module Layer.
-     *
-     * For now, this iterator examines all modules in each Layer. This will
-     * be replaced once we decide on how the service-use graph is exposed
-     * in the module API.
      */
     private class LayerLookupIterator
         extends RestrictedIterator<S>
     {
         final String serviceName;
         Layer currentLayer;
-        Iterator<ModuleDescriptor> descriptorIterator;
-        Iterator<String> providersIterator;
-
-        Module nextModule;
-        String nextProvider;
+        Iterator<ServiceProvider> iterator;
+        ServiceProvider nextProvider;
 
         LayerLookupIterator() {
             serviceName = service.getName();
             currentLayer = layer;
 
             // need to get us started
-            descriptorIterator = descriptors(layer, serviceName);
+            iterator = providers(currentLayer, serviceName);
         }
 
-        Iterator<ModuleDescriptor> descriptors(Layer layer, String service) {
-            return layer.modules().stream()
-                    .map(Module::getDescriptor)
-                    .filter(d -> d.provides().get(service) != null)
-                    .iterator();
+        Iterator<ServiceProvider> providers(Layer layer, String service) {
+            ServicesCatalog catalog = SharedSecrets
+                    .getJavaLangReflectModuleAccess()
+                    .getServicesCatalog(layer);
+
+            return catalog.findServices(serviceName).iterator();
         }
 
         @Override
@@ -591,30 +583,18 @@
             while (true) {
 
                 // next provider
-                if (providersIterator != null && providersIterator.hasNext()) {
-                    nextProvider = providersIterator.next();
+                if (iterator != null && iterator.hasNext()) {
+                    nextProvider = iterator.next();
                     return true;
                 }
 
-                // next descriptor
-                if (descriptorIterator.hasNext()) {
-                    ModuleDescriptor descriptor = descriptorIterator.next();
-
-                    nextModule = currentLayer.findModule(descriptor.name()).get();
-
-                    Provides provides = descriptor.provides().get(serviceName);
-                    providersIterator = provides.providers().iterator();
-
-                    continue;
-                }
-
                 // next layer
                 Layer parent = currentLayer.parent().orElse(null);
                 if (parent == null)
                     return false;
 
                 currentLayer = parent;
-                descriptorIterator = descriptors(currentLayer, serviceName);
+                iterator = providers(currentLayer, serviceName);
             }
         }
 
@@ -623,13 +603,14 @@
             if (!hasNextService())
                 throw new NoSuchElementException();
 
-            assert nextModule != null && nextProvider != null;
-
-            String cn = nextProvider;
+            ServiceProvider provider = nextProvider;
             nextProvider = null;
 
+            Module module = provider.module();
+            String cn = provider.providerName();
+
             // attempt to load the provider
-            Class<?> c = loadClassInModule(nextModule, cn);
+            Class<?> c = loadClassInModule(module, cn);
             if (c == null)
                 fail(service, "Provider " + cn  + " not found");
             if (!service.isAssignableFrom(c))
@@ -830,7 +811,9 @@
             }
             S p = null;
             try {
-                p = service.cast(c.newInstance());
+                @SuppressWarnings("deprecation")
+                Object tmp = c.newInstance();
+                p = service.cast(tmp);
             } catch (Throwable x) {
                 fail(service,
                      "Provider " + cn + " could not be instantiated",
--- a/src/java.base/share/classes/java/util/TimeZone.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/util/TimeZone.java	Sun May 08 08:25:10 2016 +0000
@@ -42,6 +42,7 @@
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.time.ZoneId;
+import java.util.Properties;
 import sun.security.action.GetPropertyAction;
 import sun.util.calendar.ZoneInfo;
 import sun.util.calendar.ZoneInfoFile;
@@ -660,12 +661,13 @@
     private static synchronized TimeZone setDefaultZone() {
         TimeZone tz;
         // get the time zone ID from the system properties
-        String zoneID = GetPropertyAction.getProperty("user.timezone");
+        Properties props = GetPropertyAction.privilegedGetProperties();
+        String zoneID = props.getProperty("user.timezone");
 
         // if the time zone ID is not set (yet), perform the
         // platform to Java time zone ID mapping.
         if (zoneID == null || zoneID.isEmpty()) {
-            String javaHome = GetPropertyAction.getProperty("java.home");
+            String javaHome = props.getProperty("java.home");
             try {
                 zoneID = getSystemTimeZoneID(javaHome);
                 if (zoneID == null) {
@@ -693,13 +695,7 @@
         assert tz != null;
 
         final String id = zoneID;
-        AccessController.doPrivileged(new PrivilegedAction<>() {
-            @Override
-                public Void run() {
-                    System.setProperty("user.timezone", id);
-                    return null;
-                }
-            });
+        props.setProperty("user.timezone", id);
 
         defaultTimeZone = tz;
         return tz;
--- a/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java	Sun May 08 08:25:10 2016 +0000
@@ -3507,6 +3507,7 @@
      * Creates and returns the common pool, respecting user settings
      * specified via system properties.
      */
+    @SuppressWarnings("deprecation") // Class.newInstance
     static ForkJoinPool makeCommonPool() {
         int parallelism = -1;
         ForkJoinWorkerThreadFactory factory = null;
--- a/src/java.base/share/classes/java/util/jar/JarFile.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/util/jar/JarFile.java	Sun May 08 08:25:10 2016 +0000
@@ -155,7 +155,7 @@
         BASE_VERSION = 8;  // one less than lowest version for versioned entries
         int runtimeVersion = jdk.Version.current().major();
         String jarVersion =
-                GetPropertyAction.getProperty("jdk.util.jar.version");
+                GetPropertyAction.privilegedGetProperty("jdk.util.jar.version");
         if (jarVersion != null) {
             int jarVer = Integer.parseInt(jarVersion);
             runtimeVersion = (jarVer > runtimeVersion)
@@ -163,7 +163,7 @@
         }
         RUNTIME_VERSION = runtimeVersion;
         String enableMultiRelease = GetPropertyAction
-                .getProperty("jdk.util.jar.enableMultiRelease", "true");
+                .privilegedGetProperty("jdk.util.jar.enableMultiRelease", "true");
         switch (enableMultiRelease) {
             case "true":
             default:
@@ -658,6 +658,28 @@
         return vze == null ? ze : vze;
     }
 
+    /**
+     * Returns the real name of a {@code JarEntry}.  If this {@code JarFile} is
+     * a multi-release jar file and is configured to be processed as such, the
+     * name returned by this method is the path name of the versioned entry
+     * that the {@code JarEntry} represents, rather than the path name of the
+     * base entry that {@link JarEntry#getName()} returns.  If the
+     * {@code JarEntry} does not represent a versioned entry, or the
+     * jar file is not a multi-release jar file or {@code JarFile} is not
+     * configured for processing a multi-release jar file, this method returns
+     * the same name that {@link JarEntry#getName()} returns.
+     *
+     * @param entry the JarEntry
+     * @return the real name of the JarEntry
+     * @since 9
+     */
+    String getRealName(JarEntry entry) {
+        if (entry instanceof JarFileEntry) {
+            return ((JarFileEntry)entry).realName();
+        }
+        return entry.getName();
+    }
+
     private class JarFileEntry extends JarEntry {
         final private String name;
 
@@ -684,7 +706,7 @@
                 throw new RuntimeException(e);
             }
             if (certs == null && jv != null) {
-                certs = jv.getCerts(JarFile.this, reifiedEntry());
+                certs = jv.getCerts(JarFile.this, realEntry());
             }
             return certs == null ? null : certs.clone();
         }
@@ -695,17 +717,20 @@
                 throw new RuntimeException(e);
             }
             if (signers == null && jv != null) {
-                signers = jv.getCodeSigners(JarFile.this, reifiedEntry());
+                signers = jv.getCodeSigners(JarFile.this, realEntry());
             }
             return signers == null ? null : signers.clone();
         }
-        JarFileEntry reifiedEntry() {
+        JarFileEntry realEntry() {
             if (isMultiRelease()) {
                 String entryName = super.getName();
                 return entryName.equals(this.name) ? this : new JarFileEntry(entryName, this);
             }
             return this;
         }
+        String realName() {
+            return super.getName();
+        }
 
         @Override
         public String getName() {
@@ -876,11 +901,11 @@
     private JarEntry verifiableEntry(ZipEntry ze) {
         if (ze instanceof JarFileEntry) {
             // assure the name and entry match for verification
-            return ((JarFileEntry)ze).reifiedEntry();
+            return ((JarFileEntry)ze).realEntry();
         }
         ze = getJarEntry(ze.getName());
         if (ze instanceof JarFileEntry) {
-            return ((JarFileEntry)ze).reifiedEntry();
+            return ((JarFileEntry)ze).realEntry();
         }
         return (JarEntry)ze;
     }
--- a/src/java.base/share/classes/java/util/jar/JavaUtilJarAccessImpl.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/util/jar/JavaUtilJarAccessImpl.java	Sun May 08 08:25:10 2016 +0000
@@ -60,4 +60,8 @@
     public List<Object> getManifestDigests(JarFile jar) {
         return jar.getManifestDigests();
     }
+
+    public String getRealName(JarFile jar, JarEntry entry) {
+        return jar.getRealName(entry);
+    }
 }
--- a/src/java.base/share/classes/java/util/jar/Pack200.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/util/jar/Pack200.java	Sun May 08 08:25:10 2016 +0000
@@ -695,7 +695,7 @@
             Class<?> impl = (PACK_PROVIDER.equals(prop))? packerImpl: unpackerImpl;
             if (impl == null) {
                 // The first time, we must decide which class to use.
-                implName = GetPropertyAction.getProperty(prop,"");
+                implName = GetPropertyAction.privilegedGetProperty(prop,"");
                 if (implName != null && !implName.equals(""))
                     impl = Class.forName(implName);
                 else if (PACK_PROVIDER.equals(prop))
@@ -704,7 +704,9 @@
                     impl = com.sun.java.util.jar.pack.UnpackerImpl.class;
             }
             // We have a class.  Now instantiate it.
-            return impl.newInstance();
+            @SuppressWarnings("deprecation")
+            Object result = impl.newInstance();
+            return result;
         } catch (ClassNotFoundException e) {
             throw new Error("Class not found: " + implName +
                                 ":\ncheck property " + prop +
--- a/src/java.base/share/classes/java/util/regex/PatternSyntaxException.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/util/regex/PatternSyntaxException.java	Sun May 08 08:25:10 2016 +0000
@@ -94,7 +94,7 @@
     }
 
     private static final String nl =
-            GetPropertyAction.getProperty("line.separator");
+            GetPropertyAction.privilegedGetProperty("line.separator");
 
     /**
      * Returns a multi-line string containing the description of the syntax
--- a/src/java.base/share/classes/java/util/stream/DoublePipeline.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/util/stream/DoublePipeline.java	Sun May 08 08:25:10 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -167,6 +167,19 @@
         return Nodes.doubleBuilder(exactSizeIfKnown);
     }
 
+    private <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper, int opFlags) {
+        return new ReferencePipeline.StatelessOp<Double, U>(this, StreamShape.DOUBLE_VALUE, opFlags) {
+            @Override
+            Sink<Double> opWrapSink(int flags, Sink<U> sink) {
+                return new Sink.ChainedDouble<U>(sink) {
+                    @Override
+                    public void accept(double t) {
+                        downstream.accept(mapper.apply(t));
+                    }
+                };
+            }
+        };
+    }
 
     // DoubleStream
 
@@ -184,7 +197,7 @@
 
     @Override
     public final Stream<Double> boxed() {
-        return mapToObj(Double::valueOf);
+        return mapToObj(Double::valueOf, 0);
     }
 
     @Override
@@ -207,18 +220,7 @@
     @Override
     public final <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper) {
         Objects.requireNonNull(mapper);
-        return new ReferencePipeline.StatelessOp<Double, U>(this, StreamShape.DOUBLE_VALUE,
-                                                            StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
-            @Override
-            Sink<Double> opWrapSink(int flags, Sink<U> sink) {
-                return new Sink.ChainedDouble<U>(sink) {
-                    @Override
-                    public void accept(double t) {
-                        downstream.accept(mapper.apply(t));
-                    }
-                };
-            }
-        };
+        return mapToObj(mapper, StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT);
     }
 
     @Override
--- a/src/java.base/share/classes/java/util/stream/IntPipeline.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/util/stream/IntPipeline.java	Sun May 08 08:25:10 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -170,6 +170,19 @@
         return Nodes.intBuilder(exactSizeIfKnown);
     }
 
+    private <U> Stream<U> mapToObj(IntFunction<? extends U> mapper, int opFlags) {
+        return new ReferencePipeline.StatelessOp<Integer, U>(this, StreamShape.INT_VALUE, opFlags) {
+            @Override
+            Sink<Integer> opWrapSink(int flags, Sink<U> sink) {
+                return new Sink.ChainedInt<U>(sink) {
+                    @Override
+                    public void accept(int t) {
+                        downstream.accept(mapper.apply(t));
+                    }
+                };
+            }
+        };
+    }
 
     // IntStream
 
@@ -187,8 +200,7 @@
 
     @Override
     public final LongStream asLongStream() {
-        return new LongPipeline.StatelessOp<Integer>(this, StreamShape.INT_VALUE,
-                                                     StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
+        return new LongPipeline.StatelessOp<Integer>(this, StreamShape.INT_VALUE, 0) {
             @Override
             Sink<Integer> opWrapSink(int flags, Sink<Long> sink) {
                 return new Sink.ChainedInt<Long>(sink) {
@@ -203,8 +215,7 @@
 
     @Override
     public final DoubleStream asDoubleStream() {
-        return new DoublePipeline.StatelessOp<Integer>(this, StreamShape.INT_VALUE,
-                                                       StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
+        return new DoublePipeline.StatelessOp<Integer>(this, StreamShape.INT_VALUE, 0) {
             @Override
             Sink<Integer> opWrapSink(int flags, Sink<Double> sink) {
                 return new Sink.ChainedInt<Double>(sink) {
@@ -219,7 +230,7 @@
 
     @Override
     public final Stream<Integer> boxed() {
-        return mapToObj(Integer::valueOf);
+        return mapToObj(Integer::valueOf, 0);
     }
 
     @Override
@@ -242,18 +253,7 @@
     @Override
     public final <U> Stream<U> mapToObj(IntFunction<? extends U> mapper) {
         Objects.requireNonNull(mapper);
-        return new ReferencePipeline.StatelessOp<Integer, U>(this, StreamShape.INT_VALUE,
-                                                             StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
-            @Override
-            Sink<Integer> opWrapSink(int flags, Sink<U> sink) {
-                return new Sink.ChainedInt<U>(sink) {
-                    @Override
-                    public void accept(int t) {
-                        downstream.accept(mapper.apply(t));
-                    }
-                };
-            }
-        };
+        return mapToObj(mapper, StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT);
     }
 
     @Override
--- a/src/java.base/share/classes/java/util/stream/LongPipeline.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/util/stream/LongPipeline.java	Sun May 08 08:25:10 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -167,6 +167,19 @@
         return Nodes.longBuilder(exactSizeIfKnown);
     }
 
+    private <U> Stream<U> mapToObj(LongFunction<? extends U> mapper, int opFlags) {
+        return new ReferencePipeline.StatelessOp<Long, U>(this, StreamShape.LONG_VALUE, opFlags) {
+            @Override
+            Sink<Long> opWrapSink(int flags, Sink<U> sink) {
+                return new Sink.ChainedLong<U>(sink) {
+                    @Override
+                    public void accept(long t) {
+                        downstream.accept(mapper.apply(t));
+                    }
+                };
+            }
+        };
+    }
 
     // LongStream
 
@@ -184,8 +197,7 @@
 
     @Override
     public final DoubleStream asDoubleStream() {
-        return new DoublePipeline.StatelessOp<Long>(this, StreamShape.LONG_VALUE,
-                                                    StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
+        return new DoublePipeline.StatelessOp<Long>(this, StreamShape.LONG_VALUE, StreamOpFlag.NOT_DISTINCT) {
             @Override
             Sink<Long> opWrapSink(int flags, Sink<Double> sink) {
                 return new Sink.ChainedLong<Double>(sink) {
@@ -200,7 +212,7 @@
 
     @Override
     public final Stream<Long> boxed() {
-        return mapToObj(Long::valueOf);
+        return mapToObj(Long::valueOf, 0);
     }
 
     @Override
@@ -223,18 +235,7 @@
     @Override
     public final <U> Stream<U> mapToObj(LongFunction<? extends U> mapper) {
         Objects.requireNonNull(mapper);
-        return new ReferencePipeline.StatelessOp<Long, U>(this, StreamShape.LONG_VALUE,
-                                                          StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
-            @Override
-            Sink<Long> opWrapSink(int flags, Sink<U> sink) {
-                return new Sink.ChainedLong<U>(sink) {
-                    @Override
-                    public void accept(long t) {
-                        downstream.accept(mapper.apply(t));
-                    }
-                };
-            }
-        };
+        return mapToObj(mapper, StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT);
     }
 
     @Override
--- a/src/java.base/share/classes/java/util/stream/StreamSpliterators.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/util/stream/StreamSpliterators.java	Sun May 08 08:25:10 2016 +0000
@@ -28,6 +28,7 @@
 import java.util.Objects;
 import java.util.Spliterator;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ForkJoinPool;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.function.BooleanSupplier;
 import java.util.function.Consumer;
@@ -905,6 +906,7 @@
         // The spliterator to slice
         protected final T_SPLITR s;
         protected final boolean unlimited;
+        protected final int chunkSize;
         private final long skipThreshold;
         private final AtomicLong permits;
 
@@ -912,6 +914,8 @@
             this.s = s;
             this.unlimited = limit < 0;
             this.skipThreshold = limit >= 0 ? limit : 0;
+            this.chunkSize = limit >= 0 ? (int)Math.min(CHUNK_SIZE,
+                ((skip + limit) / AbstractTask.LEAF_TARGET) + 1) : CHUNK_SIZE;
             this.permits = new AtomicLong(limit >= 0 ? skip + limit : skip);
         }
 
@@ -921,6 +925,7 @@
             this.unlimited = parent.unlimited;
             this.permits = parent.permits;
             this.skipThreshold = parent.skipThreshold;
+            this.chunkSize = parent.chunkSize;
         }
 
         /**
@@ -1029,13 +1034,13 @@
                 PermitStatus permitStatus;
                 while ((permitStatus = permitStatus()) != PermitStatus.NO_MORE) {
                     if (permitStatus == PermitStatus.MAYBE_MORE) {
-                        // Optimistically traverse elements up to a threshold of CHUNK_SIZE
+                        // Optimistically traverse elements up to a threshold of chunkSize
                         if (sb == null)
-                            sb = new ArrayBuffer.OfRef<>(CHUNK_SIZE);
+                            sb = new ArrayBuffer.OfRef<>(chunkSize);
                         else
                             sb.reset();
                         long permitsRequested = 0;
-                        do { } while (s.tryAdvance(sb) && ++permitsRequested < CHUNK_SIZE);
+                        do { } while (s.tryAdvance(sb) && ++permitsRequested < chunkSize);
                         if (permitsRequested == 0)
                             return;
                         sb.forEach(action, acquirePermits(permitsRequested));
@@ -1102,15 +1107,15 @@
                 PermitStatus permitStatus;
                 while ((permitStatus = permitStatus()) != PermitStatus.NO_MORE) {
                     if (permitStatus == PermitStatus.MAYBE_MORE) {
-                        // Optimistically traverse elements up to a threshold of CHUNK_SIZE
+                        // Optimistically traverse elements up to a threshold of chunkSize
                         if (sb == null)
-                            sb = bufferCreate(CHUNK_SIZE);
+                            sb = bufferCreate(chunkSize);
                         else
                             sb.reset();
                         @SuppressWarnings("unchecked")
                         T_CONS sbc = (T_CONS) sb;
                         long permitsRequested = 0;
-                        do { } while (s.tryAdvance(sbc) && ++permitsRequested < CHUNK_SIZE);
+                        do { } while (s.tryAdvance(sbc) && ++permitsRequested < chunkSize);
                         if (permitsRequested == 0)
                             return;
                         sb.forEach(action, acquirePermits(permitsRequested));
--- a/src/java.base/share/classes/java/util/zip/ZipOutputStream.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/java/util/zip/ZipOutputStream.java	Sun May 08 08:25:10 2016 +0000
@@ -55,7 +55,7 @@
      */
     private static final boolean inhibitZip64 =
         Boolean.parseBoolean(
-            GetPropertyAction.getProperty("jdk.util.zip.inhibitZip64"));
+            GetPropertyAction.privilegedGetProperty("jdk.util.zip.inhibitZip64"));
 
     private static class XEntry {
         final ZipEntry entry;
--- a/src/java.base/share/classes/javax/net/ssl/SSLServerSocketFactory.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/javax/net/ssl/SSLServerSocketFactory.java	Sun May 08 08:25:10 2016 +0000
@@ -97,6 +97,7 @@
                         }
                     }
                     log("class " + clsName + " is loaded");
+                    @SuppressWarnings("deprecation")
                     SSLServerSocketFactory fac = (SSLServerSocketFactory)cls.newInstance();
                     log("instantiated an instance of class " + clsName);
                     theFactory = fac;
--- a/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java	Sun May 08 08:25:10 2016 +0000
@@ -51,7 +51,7 @@
     static final boolean DEBUG;
 
     static {
-        String s = GetPropertyAction.getProperty("javax.net.debug", "")
+        String s = GetPropertyAction.privilegedGetProperty("javax.net.debug", "")
                 .toLowerCase(Locale.ENGLISH);
 
         DEBUG = s.contains("all") || s.contains("ssl");
@@ -106,6 +106,7 @@
                         }
                     }
                     log("class " + clsName + " is loaded");
+                    @SuppressWarnings("deprecation")
                     SSLSocketFactory fac = (SSLSocketFactory)cls.newInstance();
                     log("instantiated an instance of class " + clsName);
                     theFactory = fac;
--- a/src/java.base/share/classes/javax/security/auth/login/Configuration.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/javax/security/auth/login/Configuration.java	Sun May 08 08:25:10 2016 +0000
@@ -250,7 +250,9 @@
                                             finalClass, false,
                                             Thread.currentThread().getContextClassLoader()
                                     ).asSubclass(Configuration.class);
-                                    return implClass.newInstance();
+                                    @SuppressWarnings("deprecation")
+                                    Configuration result = implClass.newInstance();
+                                    return result;
                                 }
                             });
                     AccessController.doPrivileged(
--- a/src/java.base/share/classes/javax/security/auth/login/LoginContext.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/javax/security/auth/login/LoginContext.java	Sun May 08 08:25:10 2016 +0000
@@ -304,7 +304,9 @@
                     Class<? extends CallbackHandler> c = Class.forName(
                             defaultHandler, true,
                             finalLoader).asSubclass(CallbackHandler.class);
-                    return c.newInstance();
+                    @SuppressWarnings("deprecation")
+                    CallbackHandler result = c.newInstance();
+                    return result;
                 }
             });
         } catch (java.security.PrivilegedActionException pae) {
@@ -697,8 +699,9 @@
 
                     if (moduleStack[i].module == null) {
                         try {
-                            moduleStack[i].module = (LoginModule) Class.forName(
-                                    name, false, contextClassLoader).newInstance();
+                            @SuppressWarnings("deprecation")
+                            Object tmp = Class.forName(name, false, contextClassLoader).newInstance();
+                            moduleStack[i].module = (LoginModule) tmp;
                             if (debug != null) {
                                 debug.println(name + " loaded via reflection");
                             }
--- a/src/java.base/share/classes/jdk/Version.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/jdk/Version.java	Sun May 08 08:25:10 2016 +0000
@@ -273,7 +273,8 @@
      */
     public static Version current() {
         if (current == null) {
-            current = parse(GetPropertyAction.getProperty("java.version"));
+            current = parse(
+                    GetPropertyAction.privilegedGetProperty("java.version"));
         }
         return current;
     }
--- a/src/java.base/share/classes/jdk/internal/jimage/BasicImageReader.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/jdk/internal/jimage/BasicImageReader.java	Sun May 08 08:25:10 2016 +0000
@@ -183,7 +183,9 @@
     }
 
     public static void releaseByteBuffer(ByteBuffer buffer) {
-        ImageBufferCache.releaseBuffer(buffer);
+        if (!MAP_ALL) {
+            ImageBufferCache.releaseBuffer(buffer);
+        }
     }
 
     public String getName() {
--- a/src/java.base/share/classes/jdk/internal/jimage/ImageReader.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/jdk/internal/jimage/ImageReader.java	Sun May 08 08:25:10 2016 +0000
@@ -25,6 +25,7 @@
 package jdk.internal.jimage;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.UncheckedIOException;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
@@ -36,8 +37,11 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
 import java.util.function.Consumer;
 
 /**
@@ -47,80 +51,486 @@
  * but also compiled and delivered as part of the jrtfs.jar to support access
  * to the jimage file provided by the shipped JDK by tools running on JDK 8.
  */
-public class ImageReader extends BasicImageReader {
+public final class ImageReader implements AutoCloseable {
+    private SharedImageReader reader;
 
-    private static final int SIZE_OF_OFFSET = 4;
-
-    // Map of files opened as LITTLE_ENDIAN
-    private static final HashMap<Path, ImageReader> OPEN_LE_FILES
-            = new HashMap<>();
-
-    // Map of files opened as BIG_ENDIAN
-    private static final HashMap<Path, ImageReader> OPEN_BE_FILES
-            = new HashMap<>();
-
-    private int openCount;
-
-    // attributes of the .jimage file. jimage file does not contain
-    // attributes for the individual resources (yet). We use attributes
-    // of the jimage file itself (creation, modification, access times).
-    // Iniitalized lazily, see {@link #imageFileAttributes()}.
-    private BasicFileAttributes imageFileAttributes;
-
-    // directory management implementation
-    private final HashMap<String, Node> nodes;
-    private volatile Directory rootDir;
-
-    private Directory packagesDir;
-    private Directory modulesDir;
-
-    private ImageReader(Path imagePath, ByteOrder byteOrder) throws IOException {
-        super(imagePath, byteOrder);
-        this.nodes = new HashMap<>();
+    private ImageReader(SharedImageReader reader) {
+        this.reader = reader;
     }
 
     public static ImageReader open(Path imagePath, ByteOrder byteOrder) throws IOException {
-        HashMap<Path, ImageReader> openFiles = getOpenFilesMap(byteOrder);
-        ImageReader reader;
-        synchronized (openFiles) {
-            reader = openFiles.get(imagePath);
-            if (reader == null) {
-                reader = new ImageReader(imagePath, byteOrder);
-                ImageReader existingReader = openFiles.putIfAbsent(imagePath, reader);
-                assert (existingReader == null);
-            }
-            reader.openCount++;
-        }
-        return reader;
+        return SharedImageReader.open(imagePath, byteOrder);
     }
 
-    private static HashMap<Path, ImageReader> getOpenFilesMap(ByteOrder byteOrder) {
-        return (byteOrder == ByteOrder.BIG_ENDIAN) ? OPEN_BE_FILES : OPEN_LE_FILES;
-    }
-
-    /**
-     * Opens the given file path as an image file, returning an {@code ImageReader}.
-     */
     public static ImageReader open(Path imagePath) throws IOException {
         return open(imagePath, ByteOrder.nativeOrder());
     }
 
-    private boolean canClose() {
-        HashMap<Path, ImageReader> openFiles = getOpenFilesMap(this.getByteOrder());
-        synchronized (openFiles) {
-            if (--this.openCount == 0) {
-                return openFiles.remove(this.getName(), this);
+    @Override
+    public void close() throws IOException {
+        if (reader == null) {
+            throw new IOException("image file already closed");
+        }
+
+        reader.close(this);
+        reader = null;
+    }
+
+    // directory management interface
+    public Directory getRootDirectory() throws IOException {
+        if (reader == null) {
+            throw new IOException("image file closed");
+        }
+        return reader.getRootDirectory();
+    }
+
+    public Node findNode(String name) throws IOException {
+        if (reader == null) {
+            throw new IOException("image file closed");
+        }
+        return reader.findNode(name);
+    }
+
+    public byte[] getResource(Node node) throws IOException {
+        if (reader == null) {
+            throw new IOException("image file closed");
+        }
+        return reader.getResource(node);
+    }
+
+    public byte[] getResource(Resource rs) throws IOException {
+        if (reader == null) {
+            throw new IOException("image file closed");
+        }
+        return reader.getResource(rs);
+    }
+
+    public ImageHeader getHeader() {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getHeader();
+    }
+
+    public static void releaseByteBuffer(ByteBuffer buffer) {
+        BasicImageReader.releaseByteBuffer(buffer);
+    }
+
+    public String getName() {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getName() ;
+    }
+
+    public ByteOrder getByteOrder() {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getByteOrder();
+    }
+
+    public Path getImagePath() {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getImagePath();
+    }
+
+    public ImageStringsReader getStrings() {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getStrings();
+    }
+
+    public ImageLocation findLocation(String mn, String rn) {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.findLocation(mn, rn);
+    }
+
+    public ImageLocation findLocation(String name) {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.findLocation(name);
+    }
+
+    public String[] getEntryNames() {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getEntryNames();
+    }
+
+    public long[] getAttributes(int offset) {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getAttributes(offset);
+    }
+
+    public String getString(int offset) {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getString(offset);
+    }
+
+    public byte[] getResource(String name) {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getResource(name);
+    }
+
+    public byte[] getResource(ImageLocation loc) {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getResource(loc);
+    }
+
+    public ByteBuffer getResourceBuffer(ImageLocation loc) {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getResourceBuffer(loc);
+    }
+
+    public InputStream getResourceStream(ImageLocation loc) {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getResourceStream(loc);
+    }
+
+    private final static class SharedImageReader extends BasicImageReader {
+        static final int SIZE_OF_OFFSET = Integer.BYTES;
+
+        static final Map<Path, SharedImageReader> OPEN_FILES = new HashMap<>();
+
+        // List of openers for this shared image.
+        final Set<ImageReader> openers;
+
+        // attributes of the .jimage file. jimage file does not contain
+        // attributes for the individual resources (yet). We use attributes
+        // of the jimage file itself (creation, modification, access times).
+        // Iniitalized lazily, see {@link #imageFileAttributes()}.
+        BasicFileAttributes imageFileAttributes;
+
+        // directory management implementation
+        final HashMap<String, Node> nodes;
+        volatile Directory rootDir;
+
+        Directory packagesDir;
+        Directory modulesDir;
+
+        private SharedImageReader(Path imagePath, ByteOrder byteOrder) throws IOException {
+            super(imagePath, byteOrder);
+            this.openers = new HashSet<>();
+            this.nodes = new HashMap<>();
+        }
+
+        public static ImageReader open(Path imagePath, ByteOrder byteOrder) throws IOException {
+            synchronized (OPEN_FILES) {
+                SharedImageReader reader = OPEN_FILES.get(imagePath);
+
+                if (reader == null) {
+                    // Will fail with an IOException if wrong byteOrder.
+                    reader =  new SharedImageReader(imagePath, byteOrder);
+                    OPEN_FILES.put(imagePath, reader);
+                } else if (reader.getByteOrder() != byteOrder) {
+                    throw new IOException("\"" + reader.getName() + "\" is not an image file");
+                }
+
+                ImageReader image = new ImageReader(reader);
+                reader.openers.add(image);
+
+                return image;
             }
         }
-        return false;
-    }
 
-    @Override
-    public void close() throws IOException {
-        if (canClose()) {
-            super.close();
-            clearNodes();
-       }
+        public void close(ImageReader image) throws IOException {
+            synchronized (OPEN_FILES) {
+                if (!openers.remove(image)) {
+                    throw new IOException("image file already closed");
+                }
+
+                if (openers.isEmpty()) {
+                    close();
+                    nodes.clear();
+                    rootDir = null;
+
+                    if (!OPEN_FILES.remove(this.getImagePath(), this)) {
+                        throw new IOException("image file not found in open list");
+                    }
+                }
+            }
+        }
+
+        void addOpener(ImageReader reader) {
+            synchronized (OPEN_FILES) {
+                openers.add(reader);
+            }
+        }
+
+        boolean removeOpener(ImageReader reader) {
+            synchronized (OPEN_FILES) {
+                return openers.remove(reader);
+            }
+        }
+
+        // directory management interface
+        Directory getRootDirectory() {
+            return buildRootDirectory();
+        }
+
+        /**
+         * Lazily build a node from a name.
+        */
+        synchronized Node buildNode(String name) {
+            Node n;
+            boolean isPackages = name.startsWith("/packages");
+            boolean isModules = !isPackages && name.startsWith("/modules");
+
+            if (!(isModules || isPackages)) {
+                return null;
+            }
+
+            ImageLocation loc = findLocation(name);
+
+            if (loc != null) { // A sub tree node
+                if (isPackages) {
+                    n = handlePackages(name, loc);
+                } else { // modules sub tree
+                    n = handleModulesSubTree(name, loc);
+                }
+            } else { // Asking for a resource? /modules/java.base/java/lang/Object.class
+                if (isModules) {
+                    n = handleResource(name);
+                } else {
+                    // Possibly ask for /packages/java.lang/java.base
+                    // although /packages/java.base not created
+                    n = handleModuleLink(name);
+                }
+            }
+            return n;
+        }
+
+        synchronized Directory buildRootDirectory() {
+            Directory root = rootDir; // volatile read
+            if (root != null) {
+                return root;
+            }
+
+            root = newDirectory(null, "/");
+            root.setIsRootDir();
+
+            // /packages dir
+            packagesDir = newDirectory(root, "/packages");
+            packagesDir.setIsPackagesDir();
+
+            // /modules dir
+            modulesDir = newDirectory(root, "/modules");
+            modulesDir.setIsModulesDir();
+
+            root.setCompleted(true);
+            return rootDir = root;
+        }
+
+        /**
+         * To visit sub tree resources.
+         */
+        interface LocationVisitor {
+            void visit(ImageLocation loc);
+        }
+
+        void visitLocation(ImageLocation loc, LocationVisitor visitor) {
+            byte[] offsets = getResource(loc);
+            ByteBuffer buffer = ByteBuffer.wrap(offsets);
+            buffer.order(getByteOrder());
+            IntBuffer intBuffer = buffer.asIntBuffer();
+            for (int i = 0; i < offsets.length / SIZE_OF_OFFSET; i++) {
+                int offset = intBuffer.get(i);
+                ImageLocation pkgLoc = getLocation(offset);
+                visitor.visit(pkgLoc);
+            }
+        }
+
+        void visitPackageLocation(ImageLocation loc) {
+            // Retrieve package name
+            String pkgName = getBaseExt(loc);
+            // Content is array of offsets in Strings table
+            byte[] stringsOffsets = getResource(loc);
+            ByteBuffer buffer = ByteBuffer.wrap(stringsOffsets);
+            buffer.order(getByteOrder());
+            IntBuffer intBuffer = buffer.asIntBuffer();
+            // For each module, create a link node.
+            for (int i = 0; i < stringsOffsets.length / SIZE_OF_OFFSET; i++) {
+                // skip empty state, useless.
+                intBuffer.get(i);
+                i++;
+                int offset = intBuffer.get(i);
+                String moduleName = getString(offset);
+                Node targetNode = findNode("/modules/" + moduleName);
+                if (targetNode != null) {
+                    String pkgDirName = packagesDir.getName() + "/" + pkgName;
+                    Directory pkgDir = (Directory) nodes.get(pkgDirName);
+                    newLinkNode(pkgDir, pkgDir.getName() + "/" + moduleName, targetNode);
+                }
+            }
+        }
+
+        Node handlePackages(String name, ImageLocation loc) {
+            long size = loc.getUncompressedSize();
+            Node n = null;
+            // Only possiblities are /packages, /packages/package/module
+            if (name.equals("/packages")) {
+                visitLocation(loc, (childloc) -> {
+                    findNode(childloc.getFullName());
+                });
+                packagesDir.setCompleted(true);
+                n = packagesDir;
+            } else {
+                if (size != 0) { // children are offsets to module in StringsTable
+                    String pkgName = getBaseExt(loc);
+                    Directory pkgDir = newDirectory(packagesDir, packagesDir.getName() + "/" + pkgName);
+                    visitPackageLocation(loc);
+                    pkgDir.setCompleted(true);
+                    n = pkgDir;
+                } else { // Link to module
+                    String pkgName = loc.getParent();
+                    String modName = getBaseExt(loc);
+                    Node targetNode = findNode("/modules/" + modName);
+                    if (targetNode != null) {
+                        String pkgDirName = packagesDir.getName() + "/" + pkgName;
+                        Directory pkgDir = (Directory) nodes.get(pkgDirName);
+                        Node linkNode = newLinkNode(pkgDir, pkgDir.getName() + "/" + modName, targetNode);
+                        n = linkNode;
+                    }
+                }
+            }
+            return n;
+        }
+
+        // Asking for /packages/package/module although
+        // /packages/<pkg>/ not yet created, need to create it
+        // prior to return the link to module node.
+        Node handleModuleLink(String name) {
+            // eg: unresolved /packages/package/module
+            // Build /packages/package node
+            Node ret = null;
+            String radical = "/packages/";
+            String path = name;
+            if (path.startsWith(radical)) {
+                int start = radical.length();
+                int pkgEnd = path.indexOf('/', start);
+                if (pkgEnd != -1) {
+                    String pkg = path.substring(start, pkgEnd);
+                    String pkgPath = radical + pkg;
+                    Node n = findNode(pkgPath);
+                    // If not found means that this is a symbolic link such as:
+                    // /packages/java.util/java.base/java/util/Vector.class
+                    // and will be done by a retry of the filesystem
+                    for (Node child : n.getChildren()) {
+                        if (child.name.equals(name)) {
+                            ret = child;
+                            break;
+                        }
+                    }
+                }
+            }
+            return ret;
+        }
+
+        Node handleModulesSubTree(String name, ImageLocation loc) {
+            Node n;
+            assert (name.equals(loc.getFullName()));
+            Directory dir = makeDirectories(name);
+            visitLocation(loc, (childloc) -> {
+                String path = childloc.getFullName();
+                if (path.startsWith("/modules")) { // a package
+                    makeDirectories(path);
+                } else { // a resource
+                    makeDirectories(childloc.buildName(true, true, false));
+                    newResource(dir, childloc);
+                }
+            });
+            dir.setCompleted(true);
+            n = dir;
+            return n;
+        }
+
+        Node handleResource(String name) {
+            Node n = null;
+            String locationPath = name.substring("/modules".length());
+            ImageLocation resourceLoc = findLocation(locationPath);
+            if (resourceLoc != null) {
+                Directory dir = makeDirectories(resourceLoc.buildName(true, true, false));
+                Resource res = newResource(dir, resourceLoc);
+                n = res;
+            }
+            return n;
+        }
+
+        String getBaseExt(ImageLocation loc) {
+            String base = loc.getBase();
+            String ext = loc.getExtension();
+            if (ext != null && !ext.isEmpty()) {
+                base = base + "." + ext;
+            }
+            return base;
+        }
+
+        synchronized Node findNode(String name) {
+            buildRootDirectory();
+            Node n = nodes.get(name);
+            if (n == null || !n.isCompleted()) {
+                n = buildNode(name);
+            }
+            return n;
+        }
+
+        /**
+         * Returns the file attributes of the image file.
+         */
+        BasicFileAttributes imageFileAttributes() {
+            BasicFileAttributes attrs = imageFileAttributes;
+            if (attrs == null) {
+                try {
+                    Path file = getImagePath();
+                    attrs = Files.readAttributes(file, BasicFileAttributes.class);
+                } catch (IOException ioe) {
+                    throw new UncheckedIOException(ioe);
+                }
+                imageFileAttributes = attrs;
+            }
+            return attrs;
+        }
+
+        Directory newDirectory(Directory parent, String name) {
+            Directory dir = Directory.create(parent, name, imageFileAttributes());
+            nodes.put(dir.getName(), dir);
+            return dir;
+        }
+
+        Resource newResource(Directory parent, ImageLocation loc) {
+            Resource res = Resource.create(parent, loc, imageFileAttributes());
+            nodes.put(res.getName(), res);
+            return res;
+        }
+
+        LinkNode newLinkNode(Directory dir, String name, Node link) {
+            LinkNode linkNode = LinkNode.create(dir, name, link);
+            nodes.put(linkNode.getName(), linkNode);
+            return linkNode;
+        }
+
+        Directory makeDirectories(String parent) {
+            Directory last = rootDir;
+            for (int offset = parent.indexOf('/', 1);
+                    offset != -1;
+                    offset = parent.indexOf('/', offset + 1)) {
+                String dir = parent.substring(0, offset);
+                last = makeDirectory(dir, last);
+            }
+            return makeDirectory(parent, last);
+
+        }
+
+        Directory makeDirectory(String dir, Directory last) {
+            Directory nextDir = (Directory) nodes.get(dir);
+            if (nextDir == null) {
+                nextDir = newDirectory(last, dir);
+            }
+            return nextDir;
+        }
+
+        byte[] getResource(Node node) throws IOException {
+            if (node.isResource()) {
+                return super.getResource(node.getLocation());
+            }
+            throw new IOException("Not a resource: " + node);
+        }
+
+        byte[] getResource(Resource rs) throws IOException {
+            return super.getResource(rs.getLocation());
+        }
     }
 
     // jimage file does not store directory structure. We build nodes
@@ -389,7 +799,7 @@
 
         @Override
         public Node resolveLink(boolean recursive) {
-            return recursive && (link instanceof LinkNode)? ((LinkNode)link).resolveLink(true) : link;
+            return (recursive && link instanceof LinkNode) ? ((LinkNode)link).resolveLink(true) : link;
         }
 
         @Override
@@ -397,297 +807,4 @@
             return true;
         }
     }
-
-    // directory management interface
-    public Directory getRootDirectory() {
-        return buildRootDirectory();
-    }
-
-    /**
-     * To visit sub tree resources.
-     */
-    interface LocationVisitor {
-
-        void visit(ImageLocation loc);
-    }
-
-    /**
-     * Lazily build a node from a name.
-    */
-    private Node buildNode(String name) {
-        Node n;
-        boolean isPackages = name.startsWith("/packages");
-        boolean isModules = !isPackages && name.startsWith("/modules");
-
-        if (!(isModules || isPackages)) {
-            return null;
-        }
-
-        ImageLocation loc = findLocation(name);
-
-        if (loc != null) { // A sub tree node
-            if (isPackages) {
-                n = handlePackages(name, loc);
-            } else { // modules sub tree
-                n = handleModulesSubTree(name, loc);
-            }
-        } else { // Asking for a resource? /modules/java.base/java/lang/Object.class
-            if (isModules) {
-                n = handleResource(name);
-            } else {
-                // Possibly ask for /packages/java.lang/java.base
-                // although /packages/java.base not created
-                n = handleModuleLink(name);
-            }
-        }
-        return n;
-    }
-
-    private void visitLocation(ImageLocation loc, LocationVisitor visitor) {
-        byte[] offsets = getResource(loc);
-        ByteBuffer buffer = ByteBuffer.wrap(offsets);
-        buffer.order(getByteOrder());
-        IntBuffer intBuffer = buffer.asIntBuffer();
-        for (int i = 0; i < offsets.length / SIZE_OF_OFFSET; i++) {
-            int offset = intBuffer.get(i);
-            ImageLocation pkgLoc = getLocation(offset);
-            visitor.visit(pkgLoc);
-        }
-    }
-
-    private void visitPackageLocation(ImageLocation loc) {
-        // Retrieve package name
-        String pkgName = getBaseExt(loc);
-        // Content is array of offsets in Strings table
-        byte[] stringsOffsets = getResource(loc);
-        ByteBuffer buffer = ByteBuffer.wrap(stringsOffsets);
-        buffer.order(getByteOrder());
-        IntBuffer intBuffer = buffer.asIntBuffer();
-        // For each module, create a link node.
-        for (int i = 0; i < stringsOffsets.length / SIZE_OF_OFFSET; i++) {
-            // skip empty state, useless.
-            intBuffer.get(i);
-            i++;
-            int offset = intBuffer.get(i);
-            String moduleName = getString(offset);
-            Node targetNode = findNode("/modules/" + moduleName);
-            if (targetNode != null) {
-                String pkgDirName = packagesDir.getName() + "/" + pkgName;
-                Directory pkgDir = (Directory) nodes.get(pkgDirName);
-                newLinkNode(pkgDir, pkgDir.getName() + "/" + moduleName, targetNode);
-            }
-        }
-    }
-
-    private Node handlePackages(String name, ImageLocation loc) {
-        long size = loc.getUncompressedSize();
-        Node n = null;
-        // Only possiblities are /packages, /packages/package/module
-        if (name.equals("/packages")) {
-            visitLocation(loc, (childloc) -> {
-                findNode(childloc.getFullName());
-            });
-            packagesDir.setCompleted(true);
-            n = packagesDir;
-        } else {
-            if (size != 0) { // children are offsets to module in StringsTable
-                String pkgName = getBaseExt(loc);
-                Directory pkgDir = newDirectory(packagesDir, packagesDir.getName() + "/" + pkgName);
-                visitPackageLocation(loc);
-                pkgDir.setCompleted(true);
-                n = pkgDir;
-            } else { // Link to module
-                String pkgName = loc.getParent();
-                String modName = getBaseExt(loc);
-                Node targetNode = findNode("/modules/" + modName);
-                if (targetNode != null) {
-                    String pkgDirName = packagesDir.getName() + "/" + pkgName;
-                    Directory pkgDir = (Directory) nodes.get(pkgDirName);
-                    Node linkNode = newLinkNode(pkgDir, pkgDir.getName() + "/" + modName, targetNode);
-                    n = linkNode;
-                }
-            }
-        }
-        return n;
-    }
-
-    // Asking for /packages/package/module although
-    // /packages/<pkg>/ not yet created, need to create it
-    // prior to return the link to module node.
-    private Node handleModuleLink(String name) {
-        // eg: unresolved /packages/package/module
-        // Build /packages/package node
-        Node ret = null;
-        String radical = "/packages/";
-        String path = name;
-        if (path.startsWith(radical)) {
-            int start = radical.length();
-            int pkgEnd = path.indexOf('/', start);
-            if (pkgEnd != -1) {
-                String pkg = path.substring(start, pkgEnd);
-                String pkgPath = radical + pkg;
-                Node n = findNode(pkgPath);
-                // If not found means that this is a symbolic link such as:
-                // /packages/java.util/java.base/java/util/Vector.class
-                // and will be done by a retry of the filesystem
-                for (Node child : n.getChildren()) {
-                    if (child.name.equals(name)) {
-                        ret = child;
-                        break;
-                    }
-                }
-            }
-        }
-        return ret;
-    }
-
-    private Node handleModulesSubTree(String name, ImageLocation loc) {
-        Node n;
-        assert (name.equals(loc.getFullName()));
-        Directory dir = makeDirectories(name);
-        visitLocation(loc, (childloc) -> {
-            String path = childloc.getFullName();
-            if (path.startsWith("/modules")) { // a package
-                makeDirectories(path);
-            } else { // a resource
-                makeDirectories(childloc.buildName(true, true, false));
-                newResource(dir, childloc);
-            }
-        });
-        dir.setCompleted(true);
-        n = dir;
-        return n;
-    }
-
-    private Node handleResource(String name) {
-        Node n = null;
-        String locationPath = name.substring("/modules".length());
-        ImageLocation resourceLoc = findLocation(locationPath);
-        if (resourceLoc != null) {
-            Directory dir = makeDirectories(resourceLoc.buildName(true, true, false));
-            Resource res = newResource(dir, resourceLoc);
-            n = res;
-        }
-        return n;
-    }
-
-    private String getBaseExt(ImageLocation loc) {
-        String base = loc.getBase();
-        String ext = loc.getExtension();
-        if (ext != null && !ext.isEmpty()) {
-            base = base + "." + ext;
-        }
-        return base;
-    }
-
-    public synchronized Node findNode(String name) {
-        buildRootDirectory();
-        Node n = nodes.get(name);
-        if (n == null || !n.isCompleted()) {
-            n = buildNode(name);
-        }
-        return n;
-    }
-
-    private synchronized void clearNodes() {
-        nodes.clear();
-        rootDir = null;
-    }
-
-    /**
-     * Returns the file attributes of the image file.
-     */
-    private BasicFileAttributes imageFileAttributes() {
-        BasicFileAttributes attrs = imageFileAttributes;
-        if (attrs == null) {
-            try {
-                Path file = getImagePath();
-                attrs = Files.readAttributes(file, BasicFileAttributes.class);
-            } catch (IOException ioe) {
-                throw new UncheckedIOException(ioe);
-            }
-            imageFileAttributes = attrs;
-        }
-        return attrs;
-    }
-
-    private Directory buildRootDirectory() {
-        Directory root = rootDir; // volatile read
-        if (root != null) {
-            return root;
-        }
-
-        synchronized (this) {
-            root = rootDir;
-            if (root != null) {
-                return root;
-            }
-
-            // FIXME no time information per resource in jimage file (yet?)
-            // we use file attributes of jimage itself.
-            // root directory
-            root = newDirectory(null, "/");
-            root.setIsRootDir();
-
-            // /packages dir
-            packagesDir = newDirectory(root, "/packages");
-            packagesDir.setIsPackagesDir();
-
-            // /modules dir
-            modulesDir = newDirectory(root, "/modules");
-            modulesDir.setIsModulesDir();
-
-            root.setCompleted(true);
-            return rootDir = root;
-        }
-    }
-
-    private Directory newDirectory(Directory parent, String name) {
-        Directory dir = Directory.create(parent, name, imageFileAttributes());
-        nodes.put(dir.getName(), dir);
-        return dir;
-    }
-
-    private Resource newResource(Directory parent, ImageLocation loc) {
-        Resource res = Resource.create(parent, loc, imageFileAttributes());
-        nodes.put(res.getName(), res);
-        return res;
-    }
-
-    private LinkNode newLinkNode(Directory dir, String name, Node link) {
-        LinkNode linkNode = LinkNode.create(dir, name, link);
-        nodes.put(linkNode.getName(), linkNode);
-        return linkNode;
-    }
-
-    private Directory makeDirectories(String parent) {
-        Directory last = rootDir;
-        for (int offset = parent.indexOf('/', 1);
-                offset != -1;
-                offset = parent.indexOf('/', offset + 1)) {
-            String dir = parent.substring(0, offset);
-            last = makeDirectory(dir, last);
-        }
-        return makeDirectory(parent, last);
-
-    }
-
-    private Directory makeDirectory(String dir, Directory last) {
-        Directory nextDir = (Directory) nodes.get(dir);
-        if (nextDir == null) {
-            nextDir = newDirectory(last, dir);
-        }
-        return nextDir;
-    }
-
-    public byte[] getResource(Node node) throws IOException {
-        if (node.isResource()) {
-            return super.getResource(node.getLocation());
-        }
-        throw new IOException("Not a resource: " + node);
-    }
-
-    public byte[] getResource(Resource rs) throws IOException {
-        return super.getResource(rs.getLocation());
-    }
 }
--- a/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystem.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystem.java	Sun May 08 08:25:10 2016 +0000
@@ -299,13 +299,9 @@
     }
 
     // clean up this file system - called from finalize and close
-    void cleanup() throws IOException {
-        if (!isOpen) {
-            return;
-        }
-        synchronized (this) {
+    synchronized void cleanup() throws IOException {
+        if (isOpen) {
             isOpen = false;
-            // close image reader and null out
             image.close();
             image = null;
         }
@@ -461,8 +457,8 @@
     private Node lookup(String path) {
         try {
             return image.findNode(path);
-        } catch (RuntimeException re) {
-            throw new InvalidPathException(path, re.toString());
+        } catch (RuntimeException | IOException ex) {
+            throw new InvalidPathException(path, ex.toString());
         }
     }
 
--- a/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystemProvider.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystemProvider.java	Sun May 08 08:25:10 2016 +0000
@@ -124,7 +124,9 @@
         ClassLoader cl = newJrtFsLoader(jrtfs);
         try {
             Class<?> c = Class.forName(JrtFileSystemProvider.class.getName(), false, cl);
-            return ((FileSystemProvider)c.newInstance()).newFileSystem(uri, newEnv);
+            @SuppressWarnings("deprecation")
+            Object tmp = c.newInstance();
+            return ((FileSystemProvider)tmp).newFileSystem(uri, newEnv);
         } catch (ClassNotFoundException |
                  IllegalAccessException |
                  InstantiationException e) {
--- a/src/java.base/share/classes/jdk/internal/jrtfs/SystemImage.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/jdk/internal/jrtfs/SystemImage.java	Sun May 08 08:25:10 2016 +0000
@@ -49,7 +49,7 @@
  */
 abstract class SystemImage {
 
-    abstract Node findNode(String path);
+    abstract Node findNode(String path) throws IOException;
     abstract byte[] getResource(Node node) throws IOException;
     abstract void close() throws IOException;
 
@@ -60,7 +60,7 @@
             image.getRootDirectory();
             return new SystemImage() {
                 @Override
-                Node findNode(String path) {
+                Node findNode(String path) throws IOException {
                     return image.findNode(path);
                 }
                 @Override
--- a/src/java.base/share/classes/jdk/internal/loader/BootLoader.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/jdk/internal/loader/BootLoader.java	Sun May 08 08:25:10 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -30,6 +30,7 @@
 import java.lang.reflect.Layer;
 import java.lang.reflect.Module;
 import java.net.MalformedURLException;
+import java.net.URI;
 import java.net.URL;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -67,7 +68,7 @@
     }
 
     // ServiceCatalog for the boot class loader
-    private static final ServicesCatalog SERVICES_CATALOG = new ServicesCatalog();
+    private static final ServicesCatalog SERVICES_CATALOG = ServicesCatalog.create();
 
     // ClassLoaderValue map for boot class loader
     private static final ConcurrentHashMap<?, ?> CLASS_LOADER_VALUE_MAP =
@@ -184,9 +185,9 @@
 
         /**
          * Define the {@code Package} with the given name. The specified
-         * location is a jrt URL to a named module in the run-time image, a
-         * file path to a module in an exploded run-time image, or the file
-         * path to an enty on the boot class path (java agent Boot-Class-Path
+         * location is a jrt URL to a named module in the run-time image,
+         * a file URL to a module in an exploded run-time image, or a file
+         * path to an entry on the boot class path (java agent Boot-Class-Path
          * or -Xbootclasspath/a.
          *
          * <p> If the given location is a JAR file containing a manifest,
@@ -194,7 +195,9 @@
          * the manifest, if present.
          *
          * @param name     package name
-         * @param location location where the package is (jrt URL or file path)
+         * @param location location where the package is (jrt URL or file URL
+         *                 for a named module in the run-time or exploded image;
+         *                 a file path for a package from -Xbootclasspath/a)
          */
         static Package definePackage(String name, String location) {
             Module module = findModule(location);
@@ -222,9 +225,9 @@
             if (location.startsWith("jrt:/")) {
                 // named module in runtime image ("jrt:/".length() == 5)
                 mn = location.substring(5, location.length());
-            } else {
+            } else if (location.startsWith("file:/")) {
                 // named module in exploded image
-                Path path = Paths.get(location);
+                Path path = Paths.get(URI.create(location));
                 Path modulesDir = Paths.get(JAVA_HOME, "modules");
                 if (path.startsWith(modulesDir)) {
                     mn = path.getFileName().toString();
--- a/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java	Sun May 08 08:25:10 2016 +0000
@@ -104,7 +104,7 @@
      * A module defined/loaded by a built-in class loader.
      *
      * A LoadedModule encapsulates a ModuleReference along with its CodeSource
-     * URL to avoid needing to create this URL when define classes.
+     * URL to avoid needing to create this URL when defining classes.
      */
     private static class LoadedModule {
         private final BuiltinClassLoader loader;
--- a/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java	Sun May 08 08:25:10 2016 +0000
@@ -85,7 +85,7 @@
     private static final boolean DISABLE_JAR_CHECKING;
 
     static {
-        Properties props = GetPropertyAction.getProperties();
+        Properties props = GetPropertyAction.privilegedGetProperties();
         JAVA_VERSION = props.getProperty("java.version");
         DEBUG = (props.getProperty("sun.misc.URLClassPath.debug") != null);
         String p = props.getProperty("sun.misc.URLClassPath.disableJarChecking");
@@ -372,9 +372,15 @@
             return java.security.AccessController.doPrivileged(
                 new java.security.PrivilegedExceptionAction<>() {
                 public Loader run() throws IOException {
+                    String protocol = url.getProtocol();  // lower cased in URL
                     String file = url.getFile();
-                    if (file != null && file.endsWith("/")) {
-                        if ("file".equals(url.getProtocol())) {
+                    if ("jar".equals(protocol)
+                            && file != null && (file.indexOf("!/") == file.length() - 2)) {
+                        // extract the nested URL
+                        URL nestedUrl = new URL(file.substring(0, file.length() - 2));
+                        return new JarLoader(nestedUrl, jarHandler, lmap);
+                    } else if (file != null && file.endsWith("/")) {
+                        if ("file".equals(protocol)) {
                             return new FileLoader(url);
                         } else {
                             return new Loader(url);
@@ -718,13 +724,13 @@
 
             final URL url;
             try {
+                String nm;
                 if (jar.isMultiRelease()) {
-                    // add #runtime fragment to tell JarURLConnection to use
-                    // runtime versioning if the underlying jar file is multi-release
-                    url = new URL(getBaseURL(), ParseUtil.encodePath(name, false) + "#runtime");
+                    nm = SharedSecrets.javaUtilJarAccess().getRealName(jar, entry);
                 } else {
-                    url = new URL(getBaseURL(), ParseUtil.encodePath(name, false));
+                    nm = name;
                 }
+                url = new URL(getBaseURL(), ParseUtil.encodePath(nm, false));
                 if (check) {
                     URLClassPath.check(url);
                 }
@@ -940,7 +946,8 @@
 
             ensureOpen();
 
-            if (SharedSecrets.javaUtilJarAccess().jarFileHasClassPathAttribute(jar)) { // Only get manifest when necessary
+            // Only get manifest when necessary
+            if (SharedSecrets.javaUtilJarAccess().jarFileHasClassPathAttribute(jar)) {
                 Manifest man = jar.getManifest();
                 if (man != null) {
                     Attributes attr = man.getMainAttributes();
--- a/src/java.base/share/classes/jdk/internal/logger/DefaultLoggerFinder.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/jdk/internal/logger/DefaultLoggerFinder.java	Sun May 08 08:25:10 2016 +0000
@@ -33,6 +33,9 @@
 import java.lang.System.LoggerFinder;
 import java.lang.System.Logger;
 import java.lang.ref.ReferenceQueue;
+import java.lang.reflect.Module;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.Collection;
 import java.util.ResourceBundle;
 
@@ -129,41 +132,49 @@
             return w;
         }
 
-
         final static SharedLoggers system = new SharedLoggers();
         final static SharedLoggers application = new SharedLoggers();
     }
 
+    public static boolean isSystem(Module m) {
+        ClassLoader cl = AccessController.doPrivileged(new PrivilegedAction<>() {
+            @Override
+            public ClassLoader run() {
+                return m.getClassLoader();
+            }
+        });
+        return cl == null;
+    }
+
     @Override
-    public final Logger getLogger(String name,  /* Module */ Class<?> caller) {
+    public final Logger getLogger(String name,  Module module) {
         checkPermission();
-        return demandLoggerFor(name, caller);
+        return demandLoggerFor(name, module);
     }
 
     @Override
     public final Logger getLocalizedLogger(String name, ResourceBundle bundle,
-                                           /* Module */  Class<?> caller) {
-        return super.getLocalizedLogger(name, bundle, caller);
+                                           Module module) {
+        return super.getLocalizedLogger(name, bundle, module);
     }
 
-
-
     /**
-     * Returns a {@link Logger logger} suitable for the caller usage.
+     * Returns a {@link Logger logger} suitable for use within the
+     * given {@code module}.
      *
      * @implSpec The default implementation for this method is to return a
      *    simple logger that will print all messages of INFO level and above
      *    to the console. That simple logger is not configurable.
      *
      * @param name The name of the logger.
-     * @param caller The class on behalf of which the logger is created.
+     * @param module The module on behalf of which the logger is created.
      * @return A {@link Logger logger} suitable for the application usage.
      * @throws SecurityException if the calling code does not have the
      * {@code RuntimePermission("loggerFinder")}.
      */
-    protected Logger demandLoggerFor(String name, /* Module */ Class<?> caller) {
+    protected Logger demandLoggerFor(String name, Module module) {
         checkPermission();
-        if (caller.getClassLoader() == null) {
+        if (isSystem(module)) {
             return SharedLoggers.system.get(SimpleConsoleLogger::makeSimpleLogger, name);
         } else {
             return SharedLoggers.application.get(SimpleConsoleLogger::makeSimpleLogger, name);
--- a/src/java.base/share/classes/jdk/internal/logger/LazyLoggers.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/jdk/internal/logger/LazyLoggers.java	Sun May 08 08:25:10 2016 +0000
@@ -31,6 +31,7 @@
 import java.lang.System.LoggerFinder;
 import java.lang.System.Logger;
 import java.lang.ref.WeakReference;
+import java.lang.reflect.Module;
 import java.util.Objects;
 import jdk.internal.misc.VM;
 import sun.util.logging.PlatformLogger;
@@ -59,15 +60,15 @@
          * A factory method to create an SPI logger.
          * Usually, this will be something like LazyLoggers::getSystemLogger.
          */
-        final BiFunction<String, Class<?>, L> loggerSupplier;
+        final BiFunction<String, Module, L> loggerSupplier;
 
 
-        public LazyLoggerFactories(BiFunction<String, Class<?>, L> loggerSupplier) {
+        public LazyLoggerFactories(BiFunction<String, Module, L> loggerSupplier) {
             this(Objects.requireNonNull(loggerSupplier),
                  (Void)null);
         }
 
-        private LazyLoggerFactories(BiFunction<String, Class<?>, L> loggerSupplier,
+        private LazyLoggerFactories(BiFunction<String, Module, L> loggerSupplier,
                           Void unused) {
             this.loggerSupplier = loggerSupplier;
         }
@@ -107,8 +108,8 @@
         // The factories that will be used to create the logger lazyly
         final LazyLoggerFactories<? extends Logger> factories;
 
-        // We need to pass the actual caller when creating the logger.
-        private final WeakReference<Class<?>> callerRef;
+        // We need to pass the actual caller module when creating the logger.
+        private final WeakReference<Module> moduleRef;
 
         // The name of the logger that will be created lazyly
         final String name;
@@ -121,17 +122,17 @@
 
         private LazyLoggerAccessor(String name,
                                    LazyLoggerFactories<? extends Logger> factories,
-                                   Class<?> caller) {
+                                   Module module) {
             this(Objects.requireNonNull(name), Objects.requireNonNull(factories),
-                    Objects.requireNonNull(caller), null);
+                    Objects.requireNonNull(module), null);
         }
 
         private LazyLoggerAccessor(String name,
                                    LazyLoggerFactories<? extends Logger> factories,
-                                   Class<?> caller, Void unused) {
+                                   Module module, Void unused) {
             this.name = name;
             this.factories = factories;
-            this.callerRef = new WeakReference<Class<?>>(caller);
+            this.moduleRef = new WeakReference<>(module);
         }
 
         /**
@@ -270,12 +271,12 @@
 
         // Creates the wrapped logger by invoking the SPI.
         Logger createLogger() {
-            final Class<?> caller = callerRef.get();
-            if (caller == null) {
-                throw new IllegalStateException("The class for which this logger"
+            final Module module = moduleRef.get();
+            if (module == null) {
+                throw new IllegalStateException("The module for which this logger"
                         + " was created has been garbage collected");
             }
-            return this.factories.loggerSupplier.apply(name, caller);
+            return this.factories.loggerSupplier.apply(name, module);
         }
 
         /**
@@ -289,8 +290,8 @@
          * @return A new LazyLoggerAccessor.
          */
         public static LazyLoggerAccessor makeAccessor(String name,
-                LazyLoggerFactories<? extends Logger> factories, Class<?> caller) {
-                return new LazyLoggerAccessor(name, factories, caller);
+                LazyLoggerFactories<? extends Logger> factories, Module module) {
+                return new LazyLoggerAccessor(name, factories, module);
         }
 
     }
@@ -346,11 +347,11 @@
 
     // Avoid using lambda here as lazy loggers could be created early
     // in the bootstrap sequence...
-    private static final BiFunction<String, Class<?>, Logger> loggerSupplier =
+    private static final BiFunction<String, Module, Logger> loggerSupplier =
            new BiFunction<>() {
         @Override
-        public Logger apply(String name, Class<?> caller) {
-            return LazyLoggers.getLoggerFromFinder(name, caller);
+        public Logger apply(String name, Module module) {
+            return LazyLoggers.getLoggerFromFinder(name, module);
         }
     };
 
@@ -367,8 +368,8 @@
     // logger provider until the VM has finished booting.
     //
     private static final class JdkLazyLogger extends LazyLoggerWrapper {
-        JdkLazyLogger(String name, Class<?> caller) {
-            this(LazyLoggerAccessor.makeAccessor(name, factories, caller),
+        JdkLazyLogger(String name, Module module) {
+            this(LazyLoggerAccessor.makeAccessor(name, factories, module),
                  (Void)null);
         }
         private JdkLazyLogger(LazyLoggerAccessor holder, Void unused) {
@@ -380,16 +381,16 @@
      * Gets a logger from the LoggerFinder. Creates the actual concrete
      * logger.
      * @param name    name of the logger
-     * @param caller  class on behalf of which the logger is created
+     * @param module  module on behalf of which the logger is created
      * @return  The logger returned by the LoggerFinder.
      */
-    static Logger getLoggerFromFinder(String name, Class<?> caller) {
+    static Logger getLoggerFromFinder(String name, Module module) {
         final SecurityManager sm = System.getSecurityManager();
         if (sm == null) {
-            return accessLoggerFinder().getLogger(name, caller);
+            return accessLoggerFinder().getLogger(name, module);
         } else {
             return AccessController.doPrivileged((PrivilegedAction<Logger>)
-                    () -> {return accessLoggerFinder().getLogger(name, caller);},
+                    () -> {return accessLoggerFinder().getLogger(name, module);},
                     null, LOGGERFINDER_PERMISSION);
         }
     }
@@ -398,22 +399,22 @@
      * Returns a (possibly lazy) Logger for the caller.
      *
      * @param name the logger name
-     * @param caller The class on behalf of which the logger is created.
-     *               If the caller is not loaded from the Boot ClassLoader,
+     * @param module The module on behalf of which the logger is created.
+     *               If the module is not loaded from the Boot ClassLoader,
      *               the LoggerFinder is accessed and the logger returned
-     *               by {@link LoggerFinder#getLogger(java.lang.String, java.lang.Class)}
+     *               by {@link LoggerFinder#getLogger(java.lang.String, java.lang.reflect.Module)}
      *               is returned to the caller directly.
      *               Otherwise, the logger returned by
-     *               {@link #getLazyLogger(java.lang.String, java.lang.Class)}
+     *               {@link #getLazyLogger(java.lang.String, java.lang.reflect.Module)}
      *               is returned to the caller.
      *
      * @return  a (possibly lazy) Logger instance.
      */
-    public static final Logger getLogger(String name, Class<?> caller) {
-        if (caller.getClassLoader() == null) {
-            return getLazyLogger(name, caller);
+    public static final Logger getLogger(String name, Module module) {
+        if (DefaultLoggerFinder.isSystem(module)) {
+            return getLazyLogger(name, module);
         } else {
-            return getLoggerFromFinder(name, caller);
+            return getLoggerFromFinder(name, module);
         }
     }
 
@@ -423,10 +424,10 @@
      * returned by {@link BootstrapLogger#useLazyLoggers()}.
      *
      * @param name the logger name
-     * @param caller the class on behalf of which the logger is created.
+     * @param module the module on behalf of which the logger is created.
      * @return  a (possibly lazy) Logger instance.
      */
-    public static final Logger getLazyLogger(String name, Class<?> caller) {
+    public static final Logger getLazyLogger(String name, Module module) {
 
         // BootstrapLogger has the logic to determine whether a LazyLogger
         // should be used. Usually, it is worth it only if:
@@ -438,10 +439,10 @@
         // configuration, we're not going to delay the creation of loggers...
         final boolean useLazyLogger = BootstrapLogger.useLazyLoggers();
         if (useLazyLogger) {
-            return new JdkLazyLogger(name, caller);
+            return new JdkLazyLogger(name, module);
         } else {
             // Directly invoke the LoggerFinder.
-            return getLoggerFromFinder(name, caller);
+            return getLoggerFromFinder(name, module);
         }
     }
 
--- a/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java	Sun May 08 08:25:10 2016 +0000
@@ -81,7 +81,7 @@
     // Get configuration error policy
     private static ErrorPolicy configurationErrorPolicy() {
         String errorPolicy =
-                GetPropertyAction.getProperty("jdk.logger.finder.error");
+                GetPropertyAction.privilegedGetProperty("jdk.logger.finder.error");
         if (errorPolicy == null || errorPolicy.isEmpty()) {
             return ErrorPolicy.WARNING;
         }
@@ -96,7 +96,7 @@
     // This is further submitted to the configuration error policy.
     private static boolean ensureSingletonProvider() {
         return Boolean.parseBoolean(
-                GetPropertyAction.getProperty("jdk.logger.finder.singleton"));
+                GetPropertyAction.privilegedGetProperty("jdk.logger.finder.singleton"));
     }
 
     private static Iterator<System.LoggerFinder> findLoggerFinderProviders() {
--- a/src/java.base/share/classes/jdk/internal/logger/SimpleConsoleLogger.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/jdk/internal/logger/SimpleConsoleLogger.java	Sun May 08 08:25:10 2016 +0000
@@ -56,7 +56,7 @@
 
     static Level getDefaultLevel() {
         String levelName = GetPropertyAction
-                .getProperty("jdk.system.logger.level", "INFO");
+                .privilegedGetProperty("jdk.system.logger.level", "INFO");
         try {
             return Level.valueOf(levelName);
         } catch (IllegalArgumentException iae) {
@@ -426,7 +426,7 @@
         static private final String[] skips;
         static {
             String additionalPkgs =
-                    GetPropertyAction.getProperty("jdk.logger.packages");
+                    GetPropertyAction.privilegedGetProperty("jdk.logger.packages");
             skips = additionalPkgs == null ? new String[0] : additionalPkgs.split(",");
         }
 
@@ -485,7 +485,7 @@
             //    jdk/test/java/lang/invoke/lambda/LogGeneratedClassesTest.java
             // to fail - because that test has a testcase which somehow references
             // PlatformLogger and counts the number of generated lambda classes.
-            String format = GetPropertyAction.getProperty(key);
+            String format = GetPropertyAction.privilegedGetProperty(key);
 
             if (format == null && defaultPropertyGetter != null) {
                 format = defaultPropertyGetter.apply(key);
--- a/src/java.base/share/classes/jdk/internal/misc/JavaLangModuleAccess.java	Mon Apr 25 15:32:35 2016 +0200
+++ b/src/java.base/share/classes/jdk/internal/misc/JavaLangModuleAccess.java	Sun May 08 08:25:10 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -25,13 +25,24 @@
 
 package jdk.internal.misc;
 
+import java.io.PrintStream;
+import java.lang.module.Configuration;
+import jdk.internal.module.ModuleHashes;
+
 import java.lang.module.ModuleDescriptor;
 import java.lang.module.ModuleDescriptor.Exports;
 import java.lang.module.ModuleDescriptor.Requires;
 import java.lang.module.ModuleDescriptor.Provides;
 import java.lang.module.ModuleDescriptor.Version;
+import java.lang.module.ModuleFinder;
+import java.util.Collection;
+import java.lang.module.ModuleReader;
+import java.lang.module.ModuleReference;
+import java.net.URI;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
+import java.util.function.Supplier;
 
 /**
  * Provides access to non-public methods in java.lang.module.
@@ -89,5 +100,29 @@
                                          String osArch,
                                          String osVersion,
                                          Set<String> conceals,
-                                         Set<String> packages);
+                                         Set<String> packages,
+                                         Mod