changeset 14232:a80c0f7dccb1

Merge
author prr
date Tue, 05 Apr 2016 09:17:15 -0700
parents b2244c4ecc1d e3d707ff6bfa
children bfc54d30912e
files make/src/classes/build/tools/module/Module.java make/src/classes/build/tools/module/ModuleInfoReader.java make/src/classes/build/tools/module/ModulesXmlReader.java make/src/classes/build/tools/module/ModulesXmlWriter.java src/java.base/share/classes/sun/misc/GC.java src/java.base/share/classes/sun/misc/InvalidJarIndexException.java src/java.base/share/classes/sun/misc/JarIndex.java src/java.base/share/classes/sun/misc/VMSupport.java src/java.base/share/classes/sun/misc/resources/Messages.java src/java.base/share/classes/sun/misc/resources/Messages_de.java src/java.base/share/classes/sun/misc/resources/Messages_es.java src/java.base/share/classes/sun/misc/resources/Messages_fr.java src/java.base/share/classes/sun/misc/resources/Messages_it.java src/java.base/share/classes/sun/misc/resources/Messages_ja.java src/java.base/share/classes/sun/misc/resources/Messages_ko.java src/java.base/share/classes/sun/misc/resources/Messages_pt_BR.java src/java.base/share/classes/sun/misc/resources/Messages_sv.java src/java.base/share/classes/sun/misc/resources/Messages_zh_CN.java src/java.base/share/classes/sun/misc/resources/Messages_zh_TW.java src/java.base/share/native/libjava/GC.c
diffstat 507 files changed, 87697 insertions(+), 3554 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Tue Apr 05 18:23:10 2016 +0300
+++ b/.hgignore	Tue Apr 05 09:17:15 2016 -0700
@@ -7,3 +7,5 @@
 ^make/netbeans/.*/dist/
 ^.hgtip
 .DS_Store
+.*/JTreport/.*
+.*/JTwork/.*
--- a/.hgtags	Tue Apr 05 18:23:10 2016 +0300
+++ b/.hgtags	Tue Apr 05 09:17:15 2016 -0700
@@ -354,3 +354,4 @@
 1c7bad0798900fe58f4db01ae7ffdc84f5baee8c jdk-9+109
 9417e1bcded6af5532c3b26235437ab227758877 jdk-9+110
 b2a69d66dc65ad1d3aeb3bd362cf5bb0deba040e jdk-9+111
+1565a0efe6f0ca411a6df277df1e069431c60988 jdk-9+112
--- a/make/gendata/GendataBreakIterator.gmk	Tue Apr 05 18:23:10 2016 +0300
+++ b/make/gendata/GendataBreakIterator.gmk	Tue Apr 05 09:17:15 2016 -0700
@@ -63,11 +63,9 @@
 
 ifeq ($(BOOT_JDK_MODULAR), true)
   BREAK_ITERATOR_BOOTCLASSPATH := -Xpatch:$(BREAK_ITERATOR_CLASSES) \
-      -XaddExports:$(subst $(SPACE),$(COMMA),$(strip \
-          java.base/sun.text=ALL-UNNAMED \
-          java.base/sun.text.resources=ALL-UNNAMED \
-          jdk.localedata/sun.text.resources.ext=ALL-UNNAMED \
-      ))
+        -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/gensrc/Gensrc-java.base.gmk	Tue Apr 05 18:23:10 2016 +0300
+++ b/make/gensrc/Gensrc-java.base.gmk	Tue Apr 05 09:17:15 2016 -0700
@@ -55,7 +55,6 @@
 # copied to zh_HK locale.
 $(eval $(call SetupCopy-zh_HK,COPY_ZH_HK, \
     $(addprefix $(JDK_TOPDIR)/src/java.base/share/classes/, \
-        sun/misc/resources/Messages_zh_TW.java \
         sun/security/util/AuthResources_zh_TW.java \
         sun/security/util/Resources_zh_TW.java)))
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/lib/Lib-java.rmi.gmk	Tue Apr 05 09:17:15 2016 -0700
@@ -0,0 +1,53 @@
+#
+# 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
+
+################################################################################
+
+$(eval $(call SetupNativeCompilation,BUILD_LIBRMI, \
+    LIBRARY := rmi, \
+    OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+    SRC := $(JDK_TOPDIR)/src/java.rmi/share/native/librmi, \
+    OPTIMIZATION := LOW, \
+    CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/java.rmi, \
+    MAPFILE := $(JDK_TOPDIR)/make/mapfiles/librmi/mapfile-vers, \
+    LDFLAGS := $(LDFLAGS_JDKLIB) \
+        $(call SET_SHARED_LIBRARY_ORIGIN), \
+    LIBS_unix := -ljvm, \
+    LIBS_windows := jvm.lib, \
+    VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
+    RC_FLAGS := $(RC_FLAGS) \
+         -D "JDK_FNAME=rmi.dll" \
+         -D "JDK_INTERNAL_NAME=rmi" \
+         -D "JDK_FTYPE=0x2L", \
+    OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/librmi, \
+))
+
+$(BUILD_LIBRMI): $(call FindLib, java.base, java)
+
+TARGETS += $(BUILD_LIBRMI)
+
+################################################################################
--- a/make/mapfiles/libjava/mapfile-vers	Tue Apr 05 18:23:10 2016 +0300
+++ b/make/mapfiles/libjava/mapfile-vers	Tue Apr 05 09:17:15 2016 -0700
@@ -259,7 +259,6 @@
 		Java_java_io_Console_istty;
 		Java_java_io_Console_encoding;
                 Java_java_io_Console_echo;
-		Java_sun_misc_GC_maxObjectInspectionAge;
 		Java_sun_reflect_NativeConstructorAccessorImpl_newInstance0;
 		Java_sun_reflect_NativeMethodAccessorImpl_invoke0;
 		Java_sun_reflect_Reflection_getCallerClass__;
@@ -283,8 +282,8 @@
 		Java_jdk_internal_loader_BootLoader_getSystemPackageNames;
                 Java_jdk_internal_loader_BootLoader_setBootLoaderUnnamedModule0;
 
-		Java_sun_misc_VMSupport_initAgentProperties;
-		Java_sun_misc_VMSupport_getVMTemporaryDirectory;
+		Java_jdk_internal_vm_VMSupport_initAgentProperties;
+		Java_jdk_internal_vm_VMSupport_getVMTemporaryDirectory;
 
                 # ZipFile.c needs this one
 		throwFileNotFoundException;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/mapfiles/librmi/mapfile-vers	Tue Apr 05 09:17:15 2016 -0700
@@ -0,0 +1,31 @@
+#
+# 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_sun_rmi_transport_GC_maxObjectInspectionAge;
+	local:
+	    *;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/netbeans/client_sanity/README	Tue Apr 05 09:17:15 2016 -0700
@@ -0,0 +1,15 @@
+This NetBeans project corresponds to client sanity test suite in jdk/test/sanity/client.
+
+It simplifies working on the suite in NetBeans.
+
+It also includes the following custom tasks:
+
+prepare-bundle      creates dist/sanity.zip containing standalone bundle of the suite
+
+run-jemmy-browser   runs Jemmy browser for the ButtonDemo (hardcoded in build.xml file)
+                    The tool allows to explore the UI hierarchy.
+                    
+There is no task to run tests using JTReg. Please refer to corresponding README file 
+in the client sanity test suite folder on how to run the tests.
+
+Contact alexander.kouznetsov@oracle.com in case of issues.
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/netbeans/client_sanity/build.xml	Tue Apr 05 09:17:15 2016 -0700
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See commented blocks below for -->
+<!-- some examples of how to customize the build. -->
+<!-- (If you delete it and reopen the project it will be recreated.) -->
+<!-- By default, only the Clean and Build commands use this build script. -->
+<!-- Commands such as Run, Debug, and Test only use this build script if -->
+<!-- the Compile on Save feature is turned off for the project. -->
+<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
+<!-- in the project's Project Properties dialog box.-->
+<project name="SanityTests" default="default" basedir=".">
+    <description>Builds, tests, and runs the project SanityTests.</description>
+    <import file="nbproject/build-impl.xml"/>
+    <!--
+
+    There exist several targets which are by default empty and which can be 
+    used for execution of your tasks. These targets are usually executed 
+    before and after some main targets. They are: 
+
+      -pre-init:                 called before initialization of project properties
+      -post-init:                called after initialization of project properties
+      -pre-compile:              called before javac compilation
+      -post-compile:             called after javac compilation
+      -pre-compile-single:       called before javac compilation of single file
+      -post-compile-single:      called after javac compilation of single file
+      -pre-compile-test:         called before javac compilation of JUnit tests
+      -post-compile-test:        called after javac compilation of JUnit tests
+      -pre-compile-test-single:  called before javac compilation of single JUnit test
+      -post-compile-test-single: called after javac compilation of single JUunit test
+      -pre-jar:                  called before JAR building
+      -post-jar:                 called after JAR building
+      -post-clean:               called after cleaning build products
+
+    (Targets beginning with '-' are not intended to be called on their own.)
+
+    Example of inserting an obfuscator after compilation could look like this:
+
+        <target name="-post-compile">
+            <obfuscate>
+                <fileset dir="${build.classes.dir}"/>
+            </obfuscate>
+        </target>
+
+    For list of available properties check the imported 
+    nbproject/build-impl.xml file. 
+
+
+    Another way to customize the build is by overriding existing main targets.
+    The targets of interest are: 
+
+      -init-macrodef-javac:     defines macro for javac compilation
+      -init-macrodef-junit:     defines macro for junit execution
+      -init-macrodef-debug:     defines macro for class debugging
+      -init-macrodef-java:      defines macro for class execution
+      -do-jar:                  JAR building
+      run:                      execution of project 
+      -javadoc-build:           Javadoc generation
+      test-report:              JUnit report generation
+
+    An example of overriding the target for project execution could look like this:
+
+        <target name="run" depends="SanityTests-impl.jar">
+            <exec dir="bin" executable="launcher.exe">
+                <arg file="${dist.jar}"/>
+            </exec>
+        </target>
+
+    Notice that the overridden target depends on the jar target and not only on 
+    the compile target as the regular run target does. Again, for a list of available 
+    properties which you can use, check the target you are overriding in the
+    nbproject/build-impl.xml file. 
+
+    -->
+    
+    <target name="prepare-bundle" depends="init">
+        <zip zipfile="${dist.dir}/sanity.zip">
+            <fileset dir="../../../test" includes="sanity/client/SwingSet/**"/>
+            <fileset dir="../../../test" includes="sanity/client/lib/**"/>
+            <fileset dir="../../../test" includes="sanity/client/ReadMe.txt"/>
+            <fileset dir="../../../test" includes="sanity/client/TEST.properties"/>            
+            <mappedresources>
+                <fileset dir="../../../test/sanity/client" includes="TEST.ROOT.template"/>
+                <globmapper from="TEST.ROOT.template" to="TEST.ROOT" />
+            </mappedresources>            
+        </zip>
+    </target>
+    
+    <target name="run-jemmy-browser" depends="init">
+        <java 
+            classpath="${run.classpath}"
+            classname="org.netbeans.jemmy.explorer.GUIBrowser" 
+            args="com.sun.swingset3.demos.button.ButtonDemo"/>
+    </target>
+    
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/netbeans/client_sanity/manifest.mf	Tue Apr 05 09:17:15 2016 -0700
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+X-COMMENT: Main-Class will be added automatically by build
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/netbeans/client_sanity/nbproject/build-impl.xml	Tue Apr 05 09:17:15 2016 -0700
@@ -0,0 +1,1429 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+
+For the purpose of easier reading the script
+is divided into following sections:
+
+  - initialization
+  - compilation
+  - jar
+  - execution
+  - debugging
+  - javadoc
+  - test compilation
+  - test execution
+  - test debugging
+  - applet
+  - cleanup
+
+        -->
+<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="SanityTests-impl">
+    <fail message="Please build using Ant 1.8.0 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.8.0"/>
+            </not>
+        </condition>
+    </fail>
+    <target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>
+    <!-- 
+                ======================
+                INITIALIZATION SECTION 
+                ======================
+            -->
+    <target name="-pre-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="-pre-init" name="-init-private">
+        <property file="nbproject/private/config.properties"/>
+        <property file="nbproject/private/configs/${config}.properties"/>
+        <property file="nbproject/private/private.properties"/>
+    </target>
+    <target depends="-pre-init,-init-private" name="-init-user">
+        <property file="${user.properties.file}"/>
+        <!-- The two properties below are usually overridden -->
+        <!-- by the active platform. Just a fallback. -->
+        <property name="default.javac.source" value="1.4"/>
+        <property name="default.javac.target" value="1.4"/>
+    </target>
+    <target depends="-pre-init,-init-private,-init-user" name="-init-project">
+        <property file="nbproject/configs/${config}.properties"/>
+        <property file="nbproject/project.properties"/>
+    </target>
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init">
+        <property name="platform.java" value="${java.home}/bin/java"/>
+        <available file="${manifest.file}" property="manifest.available"/>
+        <condition property="splashscreen.available">
+            <and>
+                <not>
+                    <equals arg1="${application.splash}" arg2="" trim="true"/>
+                </not>
+                <available file="${application.splash}"/>
+            </and>
+        </condition>
+        <condition property="main.class.available">
+            <and>
+                <isset property="main.class"/>
+                <not>
+                    <equals arg1="${main.class}" arg2="" trim="true"/>
+                </not>
+            </and>
+        </condition>
+        <condition property="profile.available">
+            <and>
+                <isset property="javac.profile"/>
+                <length length="0" string="${javac.profile}" when="greater"/>
+                <matches pattern="1\.[89](\..*)?" string="${javac.source}"/>
+            </and>
+        </condition>
+        <condition property="do.archive">
+            <or>
+                <not>
+                    <istrue value="${jar.archive.disabled}"/>
+                </not>
+                <istrue value="${not.archive.disabled}"/>
+            </or>
+        </condition>
+        <condition property="do.mkdist">
+            <and>
+                <isset property="do.archive"/>
+                <isset property="libs.CopyLibs.classpath"/>
+                <not>
+                    <istrue value="${mkdist.disabled}"/>
+                </not>
+            </and>
+        </condition>
+        <condition property="do.archive+manifest.available">
+            <and>
+                <isset property="manifest.available"/>
+                <istrue value="${do.archive}"/>
+            </and>
+        </condition>
+        <condition property="do.archive+main.class.available">
+            <and>
+                <isset property="main.class.available"/>
+                <istrue value="${do.archive}"/>
+            </and>
+        </condition>
+        <condition property="do.archive+splashscreen.available">
+            <and>
+                <isset property="splashscreen.available"/>
+                <istrue value="${do.archive}"/>
+            </and>
+        </condition>
+        <condition property="do.archive+profile.available">
+            <and>
+                <isset property="profile.available"/>
+                <istrue value="${do.archive}"/>
+            </and>
+        </condition>
+        <condition property="have.tests">
+            <or/>
+        </condition>
+        <condition property="have.sources">
+            <or>
+                <available file="${src.src3.dir}"/>
+                <available file="${src.src4.dir}"/>
+                <available file="${src.src2.dir}"/>
+                <available file="${src.src.dir}"/>
+            </or>
+        </condition>
+        <condition property="netbeans.home+have.tests">
+            <and>
+                <isset property="netbeans.home"/>
+                <isset property="have.tests"/>
+            </and>
+        </condition>
+        <condition property="no.javadoc.preview">
+            <and>
+                <isset property="javadoc.preview"/>
+                <isfalse value="${javadoc.preview}"/>
+            </and>
+        </condition>
+        <property name="run.jvmargs" value=""/>
+        <property name="run.jvmargs.ide" value=""/>
+        <property name="javac.compilerargs" value=""/>
+        <property name="work.dir" value="${basedir}"/>
+        <condition property="no.deps">
+            <and>
+                <istrue value="${no.dependencies}"/>
+            </and>
+        </condition>
+        <property name="javac.debug" value="true"/>
+        <property name="javadoc.preview" value="true"/>
+        <property name="application.args" value=""/>
+        <property name="source.encoding" value="${file.encoding}"/>
+        <property name="runtime.encoding" value="${source.encoding}"/>
+        <condition property="javadoc.encoding.used" value="${javadoc.encoding}">
+            <and>
+                <isset property="javadoc.encoding"/>
+                <not>
+                    <equals arg1="${javadoc.encoding}" arg2=""/>
+                </not>
+            </and>
+        </condition>
+        <property name="javadoc.encoding.used" value="${source.encoding}"/>
+        <property name="includes" value="**"/>
+        <property name="excludes" value=""/>
+        <property name="do.depend" value="false"/>
+        <condition property="do.depend.true">
+            <istrue value="${do.depend}"/>
+        </condition>
+        <path id="endorsed.classpath.path" path="${endorsed.classpath}"/>
+        <condition else="" property="endorsed.classpath.cmd.line.arg" value="-Xbootclasspath/p:'${toString:endorsed.classpath.path}'">
+            <and>
+                <isset property="endorsed.classpath"/>
+                <not>
+                    <equals arg1="${endorsed.classpath}" arg2="" trim="true"/>
+                </not>
+            </and>
+        </condition>
+        <condition else="" property="javac.profile.cmd.line.arg" value="-profile ${javac.profile}">
+            <isset property="profile.available"/>
+        </condition>
+        <condition else="false" property="jdkBug6558476">
+            <and>
+                <matches pattern="1\.[56]" string="${java.specification.version}"/>
+                <not>
+                    <os family="unix"/>
+                </not>
+            </and>
+        </condition>
+        <condition else="false" property="javac.fork">
+            <or>
+                <istrue value="${jdkBug6558476}"/>
+                <istrue value="${javac.external.vm}"/>
+            </or>
+        </condition>
+        <property name="jar.index" value="false"/>
+        <property name="jar.index.metainf" value="${jar.index}"/>
+        <property name="copylibs.rebase" value="true"/>
+        <available file="${meta.inf.dir}/persistence.xml" property="has.persistence.xml"/>
+        <condition property="junit.available">
+            <or>
+                <available classname="org.junit.Test" classpath="${run.test.classpath}"/>
+                <available classname="junit.framework.Test" classpath="${run.test.classpath}"/>
+            </or>
+        </condition>
+        <condition property="testng.available">
+            <available classname="org.testng.annotations.Test" classpath="${run.test.classpath}"/>
+        </condition>
+        <condition property="junit+testng.available">
+            <and>
+                <istrue value="${junit.available}"/>
+                <istrue value="${testng.available}"/>
+            </and>
+        </condition>
+        <condition else="testng" property="testng.mode" value="mixed">
+            <istrue value="${junit+testng.available}"/>
+        </condition>
+        <condition else="" property="testng.debug.mode" value="-mixed">
+            <istrue value="${junit+testng.available}"/>
+        </condition>
+        <property name="java.failonerror" value="true"/>
+    </target>
+    <target name="-post-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">
+        <fail unless="src.src3.dir">Must set src.src3.dir</fail>
+        <fail unless="src.src4.dir">Must set src.src4.dir</fail>
+        <fail unless="src.src2.dir">Must set src.src2.dir</fail>
+        <fail unless="src.src.dir">Must set src.src.dir</fail>
+        <fail unless="build.dir">Must set build.dir</fail>
+        <fail unless="dist.dir">Must set dist.dir</fail>
+        <fail unless="build.classes.dir">Must set build.classes.dir</fail>
+        <fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>
+        <fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail>
+        <fail unless="build.test.results.dir">Must set build.test.results.dir</fail>
+        <fail unless="build.classes.excludes">Must set build.classes.excludes</fail>
+        <fail unless="dist.jar">Must set dist.jar</fail>
+    </target>
+    <target name="-init-macrodef-property">
+        <macrodef name="property" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <attribute name="name"/>
+            <attribute name="value"/>
+            <sequential>
+                <property name="@{name}" value="${@{value}}"/>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-macrodef-javac-with-processors">
+        <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${src.src3.dir}:${src.src4.dir}:${src.src2.dir}:${src.src.dir}" name="srcdir"/>
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <attribute default="${javac.classpath}" name="classpath"/>
+            <attribute default="${javac.processorpath}" name="processorpath"/>
+            <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="${javac.debug}" name="debug"/>
+            <attribute default="${empty.dir}" name="sourcepath"/>
+            <attribute default="${empty.dir}" name="gensrcdir"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property location="${build.dir}/empty" name="empty.dir"/>
+                <mkdir dir="${empty.dir}"/>
+                <mkdir dir="@{apgeneratedsrcdir}"/>
+                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
+                    <src>
+                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">
+                            <include name="*"/>
+                        </dirset>
+                    </src>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <compilerarg line="${javac.profile.cmd.line.arg}"/>
+                    <compilerarg line="${javac.compilerargs}"/>
+                    <compilerarg value="-processorpath"/>
+                    <compilerarg path="@{processorpath}:${empty.dir}"/>
+                    <compilerarg line="${ap.processors.internal}"/>
+                    <compilerarg line="${annotation.processing.processor.options}"/>
+                    <compilerarg value="-s"/>
+                    <compilerarg path="@{apgeneratedsrcdir}"/>
+                    <compilerarg line="${ap.proc.none.internal}"/>
+                    <customize/>
+                </javac>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-ap-cmdline-properties" name="-init-macrodef-javac-without-processors" unless="ap.supported.internal">
+        <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${src.src3.dir}:${src.src4.dir}:${src.src2.dir}:${src.src.dir}" name="srcdir"/>
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <attribute default="${javac.classpath}" name="classpath"/>
+            <attribute default="${javac.processorpath}" name="processorpath"/>
+            <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="${javac.debug}" name="debug"/>
+            <attribute default="${empty.dir}" name="sourcepath"/>
+            <attribute default="${empty.dir}" name="gensrcdir"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property location="${build.dir}/empty" name="empty.dir"/>
+                <mkdir dir="${empty.dir}"/>
+                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
+                    <src>
+                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">
+                            <include name="*"/>
+                        </dirset>
+                    </src>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <compilerarg line="${javac.profile.cmd.line.arg}"/>
+                    <compilerarg line="${javac.compilerargs}"/>
+                    <customize/>
+                </javac>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-javac-with-processors,-init-macrodef-javac-without-processors" name="-init-macrodef-javac">
+        <macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${src.src3.dir}:${src.src4.dir}:${src.src2.dir}:${src.src.dir}" name="srcdir"/>
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <attribute default="${javac.classpath}" name="classpath"/>
+            <sequential>
+                <depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                </depend>
+            </sequential>
+        </macrodef>
+        <macrodef name="force-recompile" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <sequential>
+                <fail unless="javac.includes">Must set javac.includes</fail>
+                <pathconvert pathsep="${line.separator}" property="javac.includes.binary">
+                    <path>
+                        <filelist dir="@{destdir}" files="${javac.includes}"/>
+                    </path>
+                    <globmapper from="*.java" to="*.class"/>
+                </pathconvert>
+                <tempfile deleteonexit="true" property="javac.includesfile.binary"/>
+                <echo file="${javac.includesfile.binary}" message="${javac.includes.binary}"/>
+                <delete>
+                    <files includesfile="${javac.includesfile.binary}"/>
+                </delete>
+                <delete>
+                    <fileset file="${javac.includesfile.binary}"/>
+                </delete>
+            </sequential>
+        </macrodef>
+    </target>
+    <target if="${junit.available}" name="-init-macrodef-junit-init">
+        <condition else="false" property="nb.junit.batch" value="true">
+            <and>
+                <istrue value="${junit.available}"/>
+                <not>
+                    <isset property="test.method"/>
+                </not>
+            </and>
+        </condition>
+        <condition else="false" property="nb.junit.single" value="true">
+            <and>
+                <istrue value="${junit.available}"/>
+                <isset property="test.method"/>
+            </and>
+        </condition>
+    </target>
+    <target name="-init-test-properties">
+        <property name="test.binaryincludes" value="&lt;nothing&gt;"/>
+        <property name="test.binarytestincludes" value=""/>
+        <property name="test.binaryexcludes" value=""/>
+    </target>
+    <target if="${nb.junit.single}" name="-init-macrodef-junit-single" unless="${nb.junit.batch}">
+        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property name="junit.forkmode" value="perTest"/>
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
+                    <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-test-properties" if="${nb.junit.batch}" name="-init-macrodef-junit-batch" unless="${nb.junit.single}">
+        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property name="junit.forkmode" value="perTest"/>
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
+                    <batchtest todir="${build.test.results.dir}">
+                        <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">
+                            <filename name="${test.binarytestincludes}"/>
+                        </fileset>
+                    </batchtest>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit-init,-init-macrodef-junit-single, -init-macrodef-junit-batch" if="${junit.available}" name="-init-macrodef-junit"/>
+    <target if="${testng.available}" name="-init-macrodef-testng">
+        <macrodef name="testng" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <condition else="" property="testng.methods.arg" value="@{testincludes}.@{testmethods}">
+                    <isset property="test.method"/>
+                </condition>
+                <union id="test.set"/>
+                <taskdef classname="org.testng.TestNGAntTask" classpath="${run.test.classpath}" name="testng"/>
+                <testng classfilesetref="test.set" failureProperty="tests.failed" listeners="org.testng.reporters.VerboseReporter" methods="${testng.methods.arg}" mode="${testng.mode}" outputdir="${build.test.results.dir}" suitename="SanityTests" testname="TestNG tests" workingDir="${work.dir}">
+                    <xmlfileset dir="${build.test.classes.dir}" includes="@{testincludes}"/>
+                    <propertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </propertyset>
+                    <customize/>
+                </testng>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-macrodef-test-impl">
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <echo>No tests executed.</echo>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit" if="${junit.available}" name="-init-macrodef-junit-impl">
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <j2seproject3:junit excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize/>
+                </j2seproject3:junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-testng" if="${testng.available}" name="-init-macrodef-testng-impl">
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <j2seproject3:testng excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize/>
+                </j2seproject3:testng>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-test-impl,-init-macrodef-junit-impl,-init-macrodef-testng-impl" name="-init-macrodef-test">
+        <macrodef name="test" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <sequential>
+                <j2seproject3:test-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize>
+                        <classpath>
+                            <path path="${run.test.classpath}"/>
+                        </classpath>
+                        <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                        <jvmarg line="${run.jvmargs}"/>
+                        <jvmarg line="${run.jvmargs.ide}"/>
+                    </customize>
+                </j2seproject3:test-impl>
+            </sequential>
+        </macrodef>
+    </target>
+    <target if="${junit.available}" name="-init-macrodef-junit-debug" unless="${nb.junit.batch}">
+        <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property name="junit.forkmode" value="perTest"/>
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
+                    <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <jvmarg line="${debug-args-line}"/>
+                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-test-properties" if="${nb.junit.batch}" name="-init-macrodef-junit-debug-batch">
+        <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property name="junit.forkmode" value="perTest"/>
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
+                    <batchtest todir="${build.test.results.dir}">
+                        <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">
+                            <filename name="${test.binarytestincludes}"/>
+                        </fileset>
+                    </batchtest>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <jvmarg line="${debug-args-line}"/>
+                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit-debug,-init-macrodef-junit-debug-batch" if="${junit.available}" name="-init-macrodef-junit-debug-impl">
+        <macrodef name="test-debug-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <j2seproject3:junit-debug excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize/>
+                </j2seproject3:junit-debug>
+            </sequential>
+        </macrodef>
+    </target>
+    <target if="${testng.available}" name="-init-macrodef-testng-debug">
+        <macrodef name="testng-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <element name="customize2" optional="true"/>
+            <sequential>
+                <condition else="-testclass @{testClass}" property="test.class.or.method" value="-methods @{testClass}.@{testMethod}">
+                    <isset property="test.method"/>
+                </condition>
+                <condition else="-suitename SanityTests -testname @{testClass} ${test.class.or.method}" property="testng.cmd.args" value="@{testClass}">
+                    <matches pattern=".*\.xml" string="@{testClass}"/>
+                </condition>
+                <delete dir="${build.test.results.dir}" quiet="true"/>
+                <mkdir dir="${build.test.results.dir}"/>
+                <j2seproject3:debug classname="org.testng.TestNG" classpath="${debug.test.classpath}">
+                    <customize>
+                        <customize2/>
+                        <jvmarg value="-ea"/>
+                        <arg line="${testng.debug.mode}"/>
+                        <arg line="-d ${build.test.results.dir}"/>
+                        <arg line="-listener org.testng.reporters.VerboseReporter"/>
+                        <arg line="${testng.cmd.args}"/>
+                    </customize>
+                </j2seproject3:debug>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-testng-debug" if="${testng.available}" name="-init-macrodef-testng-debug-impl">
+        <macrodef name="testng-debug-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <element implicit="true" name="customize2" optional="true"/>
+            <sequential>
+                <j2seproject3:testng-debug testClass="@{testClass}" testMethod="@{testMethod}">
+                    <customize2/>
+                </j2seproject3:testng-debug>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit-debug-impl" if="${junit.available}" name="-init-macrodef-test-debug-junit">
+        <macrodef name="test-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <sequential>
+                <j2seproject3:test-debug-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize>
+                        <classpath>
+                            <path path="${run.test.classpath}"/>
+                        </classpath>
+                        <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                        <jvmarg line="${run.jvmargs}"/>
+                        <jvmarg line="${run.jvmargs.ide}"/>
+                    </customize>
+                </j2seproject3:test-debug-impl>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-testng-debug-impl" if="${testng.available}" name="-init-macrodef-test-debug-testng">
+        <macrodef name="test-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <sequential>
+                <j2seproject3:testng-debug-impl testClass="@{testClass}" testMethod="@{testMethod}">
+                    <customize2>
+                        <syspropertyset>
+                            <propertyref prefix="test-sys-prop."/>
+                            <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                        </syspropertyset>
+                    </customize2>
+                </j2seproject3:testng-debug-impl>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-test-debug-junit,-init-macrodef-test-debug-testng" name="-init-macrodef-test-debug"/>
+    <!--
+                pre NB7.2 profiling section; consider it deprecated
+            -->
+    <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile, -profile-init-check" if="profiler.info.jvmargs.agent" name="profile-init"/>
+    <target if="profiler.info.jvmargs.agent" name="-profile-pre-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target if="profiler.info.jvmargs.agent" name="-profile-post-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target if="profiler.info.jvmargs.agent" name="-profile-init-macrodef-profile">
+        <macrodef name="resolve">
+            <attribute name="name"/>
+            <attribute name="value"/>
+            <sequential>
+                <property name="@{name}" value="${env.@{value}}"/>
+            </sequential>
+        </macrodef>
+        <macrodef name="profile">
+            <attribute default="${main.class}" name="classname"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property environment="env"/>
+                <resolve name="profiler.current.path" value="${profiler.info.pathvar}"/>
+                <java classname="@{classname}" dir="${profiler.info.dir}" failonerror="${java.failonerror}" fork="true" jvm="${profiler.info.jvm}">
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <jvmarg value="${profiler.info.jvmargs.agent}"/>
+                    <jvmarg line="${profiler.info.jvmargs}"/>
+                    <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
+                    <arg line="${application.args}"/>
+                    <classpath>
+                        <path path="${run.classpath}"/>
+                    </classpath>
+                    <syspropertyset>
+                        <propertyref prefix="run-sys-prop."/>
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <customize/>
+                </java>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile" if="profiler.info.jvmargs.agent" name="-profile-init-check">
+        <fail unless="profiler.info.jvm">Must set JVM to use for profiling in profiler.info.jvm</fail>
+        <fail unless="profiler.info.jvmargs.agent">Must set profiler agent JVM arguments in profiler.info.jvmargs.agent</fail>
+    </target>
+    <!--
+                end of pre NB7.2 profiling section
+            -->
+    <target depends="-init-debug-args" name="-init-macrodef-nbjpda">
+        <macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <attribute default="${main.class}" name="name"/>
+            <attribute default="${debug.classpath}" name="classpath"/>
+            <attribute default="" name="stopclassname"/>
+            <sequential>
+                <nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="${debug-transport}">
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                </nbjpdastart>
+            </sequential>
+        </macrodef>
+        <macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <attribute default="${build.classes.dir}" name="dir"/>
+            <sequential>
+                <nbjpdareload>
+                    <fileset dir="@{dir}" includes="${fix.classes}">
+                        <include name="${fix.includes}*.class"/>
+                    </fileset>
+                </nbjpdareload>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-debug-args">
+        <property name="version-output" value="java version &quot;${ant.java.version}"/>
+        <condition property="have-jdk-older-than-1.4">
+            <or>
+                <contains string="${version-output}" substring="java version &quot;1.0"/>
+                <contains string="${version-output}" substring="java version &quot;1.1"/>
+                <contains string="${version-output}" substring="java version &quot;1.2"/>
+                <contains string="${version-output}" substring="java version &quot;1.3"/>
+            </or>
+        </condition>
+        <condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
+            <istrue value="${have-jdk-older-than-1.4}"/>
+        </condition>
+        <condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">
+            <os family="windows"/>
+        </condition>
+        <condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}">
+            <isset property="debug.transport"/>
+        </condition>
+    </target>
+    <target depends="-init-debug-args" name="-init-macrodef-debug">
+        <macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${main.class}" name="classname"/>
+            <attribute default="${debug.classpath}" name="classpath"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <java classname="@{classname}" dir="${work.dir}" failonerror="${java.failonerror}" fork="true">
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <jvmarg line="${debug-args-line}"/>
+                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+                    <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
+                    <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
+                    <jvmarg line="${run.jvmargs}"/>
+                    <jvmarg line="${run.jvmargs.ide}"/>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <syspropertyset>
+                        <propertyref prefix="run-sys-prop."/>
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <customize/>
+                </java>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-macrodef-java">
+        <macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <attribute default="${main.class}" name="classname"/>
+            <attribute default="${run.classpath}" name="classpath"/>
+            <attribute default="jvm" name="jvm"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <java classname="@{classname}" dir="${work.dir}" failonerror="${java.failonerror}" fork="true">
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
+                    <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
+                    <jvmarg line="${run.jvmargs}"/>
+                    <jvmarg line="${run.jvmargs.ide}"/>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <syspropertyset>
+                        <propertyref prefix="run-sys-prop."/>
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <customize/>
+                </java>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-macrodef-copylibs">
+        <macrodef name="copylibs" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${manifest.file}" name="manifest"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
+                <pathconvert property="run.classpath.without.build.classes.dir">
+                    <path path="${run.classpath}"/>
+                    <map from="${build.classes.dir.resolved}" to=""/>
+                </pathconvert>
+                <pathconvert pathsep=" " property="jar.classpath">
+                    <path path="${run.classpath.without.build.classes.dir}"/>
+                    <chainedmapper>
+                        <flattenmapper/>
+                        <filtermapper>
+                            <replacestring from=" " to="%20"/>
+                        </filtermapper>
+                        <globmapper from="*" to="lib/*"/>
+                    </chainedmapper>
+                </pathconvert>
+                <taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
+                <copylibs compress="${jar.compress}" excludeFromCopy="${copylibs.excludes}" index="${jar.index}" indexMetaInf="${jar.index.metainf}" jarfile="${dist.jar}" manifest="@{manifest}" rebase="${copylibs.rebase}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
+                    <fileset dir="${build.classes.dir}" excludes="${dist.archive.excludes}"/>
+                    <manifest>
+                        <attribute name="Class-Path" value="${jar.classpath}"/>
+                        <customize/>
+                    </manifest>
+                </copylibs>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-presetdef-jar">
+        <presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <jar compress="${jar.compress}" index="${jar.index}" jarfile="${dist.jar}">
+                <j2seproject1:fileset dir="${build.classes.dir}" excludes="${dist.archive.excludes}"/>
+            </jar>
+        </presetdef>
+    </target>
+    <target name="-init-ap-cmdline-properties">
+        <property name="annotation.processing.enabled" value="true"/>
+        <property name="annotation.processing.processors.list" value=""/>
+        <property name="annotation.processing.processor.options" value=""/>
+        <property name="annotation.processing.run.all.processors" value="true"/>
+        <property name="javac.processorpath" value="${javac.classpath}"/>
+        <property name="javac.test.processorpath" value="${javac.test.classpath}"/>
+        <condition property="ap.supported.internal" value="true">
+            <not>
+                <matches pattern="1\.[0-5](\..*)?" string="${javac.source}"/>
+            </not>
+        </condition>
+    </target>
+    <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-ap-cmdline-supported">
+        <condition else="" property="ap.processors.internal" value="-processor ${annotation.processing.processors.list}">
+            <isfalse value="${annotation.processing.run.all.processors}"/>
+        </condition>
+        <condition else="" property="ap.proc.none.internal" value="-proc:none">
+            <isfalse value="${annotation.processing.enabled}"/>
+        </condition>
+    </target>
+    <target depends="-init-ap-cmdline-properties,-init-ap-cmdline-supported" name="-init-ap-cmdline">
+        <property name="ap.cmd.line.internal" value=""/>
+    </target>
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-test,-init-macrodef-test-debug,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar,-init-ap-cmdline" name="init"/>
+    <!--
+                ===================
+                COMPILATION SECTION
+                ===================
+            -->
+    <target name="-deps-jar-init" unless="built-jar.properties">
+        <property location="${build.dir}/built-jar.properties" name="built-jar.properties"/>
+        <delete file="${built-jar.properties}" quiet="true"/>
+    </target>
+    <target if="already.built.jar.${basedir}" name="-warn-already-built-jar">
+        <echo level="warn" message="Cycle detected: SanityTests was already built"/>
+    </target>
+    <target depends="init,-deps-jar-init" name="deps-jar" unless="no.deps">
+        <mkdir dir="${build.dir}"/>
+        <touch file="${built-jar.properties}" verbose="false"/>
+        <property file="${built-jar.properties}" prefix="already.built.jar."/>
+        <antcall target="-warn-already-built-jar"/>
+        <propertyfile file="${built-jar.properties}">
+            <entry key="${basedir}" value=""/>
+        </propertyfile>
+    </target>
+    <target depends="init,-check-automatic-build,-clean-after-automatic-build" name="-verify-automatic-build"/>
+    <target depends="init" name="-check-automatic-build">
+        <available file="${build.classes.dir}/.netbeans_automatic_build" property="netbeans.automatic.build"/>
+    </target>
+    <target depends="init" if="netbeans.automatic.build" name="-clean-after-automatic-build">
+        <antcall target="clean"/>
+    </target>
+    <target depends="init,deps-jar" name="-pre-pre-compile">
+        <mkdir dir="${build.classes.dir}"/>
+    </target>
+    <target name="-pre-compile">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target if="do.depend.true" name="-compile-depend">
+        <pathconvert property="build.generated.subdirs">
+            <dirset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+                <include name="*"/>
+            </dirset>
+        </pathconvert>
+        <j2seproject3:depend srcdir="${src.src3.dir}:${src.src4.dir}:${src.src2.dir}:${src.src.dir}:${build.generated.subdirs}"/>
+    </target>
+    <target depends="init,deps-jar,-pre-pre-compile,-pre-compile, -copy-persistence-xml,-compile-depend" if="have.sources" name="-do-compile">
+        <j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>
+        <copy todir="${build.classes.dir}">
+            <fileset dir="${src.src3.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
+            <fileset dir="${src.src4.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
+            <fileset dir="${src.src2.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
+            <fileset dir="${src.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
+        </copy>
+    </target>
+    <target if="has.persistence.xml" name="-copy-persistence-xml">
+        <mkdir dir="${build.classes.dir}/META-INF"/>
+        <copy todir="${build.classes.dir}/META-INF">
+            <fileset dir="${meta.inf.dir}" includes="persistence.xml orm.xml"/>
+        </copy>
+    </target>
+    <target name="-post-compile">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
+    <target name="-pre-compile-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
+        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
+        <j2seproject3:force-recompile/>
+        <j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.src3.dir}:${src.src4.dir}:${src.src2.dir}:${src.src.dir}"/>
+    </target>
+    <target name="-post-compile-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
+    <!--
+                ====================
+                JAR BUILDING SECTION
+                ====================
+            -->
+    <target depends="init" name="-pre-pre-jar">
+        <dirname file="${dist.jar}" property="dist.jar.dir"/>
+        <mkdir dir="${dist.jar.dir}"/>
+    </target>
+    <target name="-pre-jar">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init" if="do.archive" name="-do-jar-create-manifest" unless="manifest.available">
+        <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/>
+        <touch file="${tmp.manifest.file}" verbose="false"/>
+    </target>
+    <target depends="init" if="do.archive+manifest.available" name="-do-jar-copy-manifest">
+        <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/>
+        <copy file="${manifest.file}" tofile="${tmp.manifest.file}"/>
+    </target>
+    <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+main.class.available" name="-do-jar-set-mainclass">
+        <manifest file="${tmp.manifest.file}" mode="update">
+            <attribute name="Main-Class" value="${main.class}"/>
+        </manifest>
+    </target>
+    <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+profile.available" name="-do-jar-set-profile">
+        <manifest file="${tmp.manifest.file}" mode="update">
+            <attribute name="Profile" value="${javac.profile}"/>
+        </manifest>
+    </target>
+    <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+splashscreen.available" name="-do-jar-set-splashscreen">
+        <basename file="${application.splash}" property="splashscreen.basename"/>
+        <mkdir dir="${build.classes.dir}/META-INF"/>
+        <copy failonerror="false" file="${application.splash}" todir="${build.classes.dir}/META-INF"/>
+        <manifest file="${tmp.manifest.file}" mode="update">
+            <attribute name="SplashScreen-Image" value="META-INF/${splashscreen.basename}"/>
+        </manifest>
+    </target>
+    <target depends="init,-init-macrodef-copylibs,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen" if="do.mkdist" name="-do-jar-copylibs">
+        <j2seproject3:copylibs manifest="${tmp.manifest.file}"/>
+        <echo level="info">To run this application from the command line without Ant, try:</echo>
+        <property location="${dist.jar}" name="dist.jar.resolved"/>
+        <echo level="info">java -jar "${dist.jar.resolved}"</echo>
+    </target>
+    <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen" if="do.archive" name="-do-jar-jar" unless="do.mkdist">
+        <j2seproject1:jar manifest="${tmp.manifest.file}"/>
+        <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
+        <property location="${dist.jar}" name="dist.jar.resolved"/>
+        <pathconvert property="run.classpath.with.dist.jar">
+            <path path="${run.classpath}"/>
+            <map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/>
+        </pathconvert>
+        <condition else="" property="jar.usage.message" value="To run this application from the command line without Ant, try:${line.separator}${platform.java} -cp ${run.classpath.with.dist.jar} ${main.class}">
+            <isset property="main.class.available"/>
+        </condition>
+        <condition else="debug" property="jar.usage.level" value="info">
+            <isset property="main.class.available"/>
+        </condition>
+        <echo level="${jar.usage.level}" message="${jar.usage.message}"/>
+    </target>
+    <target depends="-do-jar-copylibs" if="do.archive" name="-do-jar-delete-manifest">
+        <delete>
+            <fileset file="${tmp.manifest.file}"/>
+        </delete>
+    </target>
+    <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen,-do-jar-jar,-do-jar-delete-manifest" name="-do-jar-without-libraries"/>
+    <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen,-do-jar-copylibs,-do-jar-delete-manifest" name="-do-jar-with-libraries"/>
+    <target name="-post-jar">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,-pre-jar,-do-jar-without-libraries,-do-jar-with-libraries,-post-jar" name="-do-jar"/>
+    <target depends="init,compile,-pre-jar,-do-jar,-post-jar" description="Build JAR." name="jar"/>
+    <!--
+                =================
+                EXECUTION SECTION
+                =================
+            -->
+    <target depends="init,compile" description="Run a main class." name="run">
+        <j2seproject1:java>
+            <customize>
+                <arg line="${application.args}"/>
+            </customize>
+        </j2seproject1:java>
+    </target>
+    <target name="-do-not-recompile">
+        <property name="javac.includes.binary" value=""/>
+    </target>
+    <target depends="init,compile-single" name="run-single">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <j2seproject1:java classname="${run.class}"/>
+    </target>
+    <target depends="init,compile-test-single" name="run-test-with-main">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <j2seproject1:java classname="${run.class}" classpath="${run.test.classpath}"/>
+    </target>
+    <!--
+                =================
+                DEBUGGING SECTION
+                =================
+            -->
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger">
+        <j2seproject1:nbjpdastart name="${debug.class}"/>
+    </target>
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger-main-test">
+        <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${debug.class}"/>
+    </target>
+    <target depends="init,compile" name="-debug-start-debuggee">
+        <j2seproject3:debug>
+            <customize>
+                <arg line="${application.args}"/>
+            </customize>
+        </j2seproject3:debug>
+    </target>
+    <target depends="init,compile,-debug-start-debugger,-debug-start-debuggee" description="Debug project in IDE." if="netbeans.home" name="debug"/>
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger-stepinto">
+        <j2seproject1:nbjpdastart stopclassname="${main.class}"/>
+    </target>
+    <target depends="init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee" if="netbeans.home" name="debug-stepinto"/>
+    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single">
+        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
+        <j2seproject3:debug classname="${debug.class}"/>
+    </target>
+    <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>
+    <target depends="init,compile-test-single" if="netbeans.home" name="-debug-start-debuggee-main-test">
+        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
+        <j2seproject3:debug classname="${debug.class}" classpath="${debug.test.classpath}"/>
+    </target>
+    <target depends="init,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test" if="netbeans.home" name="debug-test-with-main"/>
+    <target depends="init" name="-pre-debug-fix">
+        <fail unless="fix.includes">Must set fix.includes</fail>
+        <property name="javac.includes" value="${fix.includes}.java"/>
+    </target>
+    <target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix">
+        <j2seproject1:nbjpdareload/>
+    </target>
+    <target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/>
+    <!--
+                =================
+                PROFILING SECTION
+                =================
+            -->
+    <!--
+                pre NB7.2 profiler integration
+            -->
+    <target depends="profile-init,compile" description="Profile a project in the IDE." if="profiler.info.jvmargs.agent" name="-profile-pre72">
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
+        <nbprofiledirect>
+            <classpath>
+                <path path="${run.classpath}"/>
+            </classpath>
+        </nbprofiledirect>
+        <profile/>
+    </target>
+    <target depends="profile-init,compile-single" description="Profile a selected class in the IDE." if="profiler.info.jvmargs.agent" name="-profile-single-pre72">
+        <fail unless="profile.class">Must select one file in the IDE or set profile.class</fail>
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
+        <nbprofiledirect>
+            <classpath>
+                <path path="${run.classpath}"/>
+            </classpath>
+        </nbprofiledirect>
+        <profile classname="${profile.class}"/>
+    </target>
+    <target depends="profile-init,compile-single" if="profiler.info.jvmargs.agent" name="-profile-applet-pre72">
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
+        <nbprofiledirect>
+            <classpath>
+                <path path="${run.classpath}"/>
+            </classpath>
+        </nbprofiledirect>
+        <profile classname="sun.applet.AppletViewer">
+            <customize>
+                <arg value="${applet.url}"/>
+            </customize>
+        </profile>
+    </target>
+    <target depends="profile-init,compile-test-single" if="profiler.info.jvmargs.agent" name="-profile-test-single-pre72">
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
+        <nbprofiledirect>
+            <classpath>
+                <path path="${run.test.classpath}"/>
+            </classpath>
+        </nbprofiledirect>
+        <junit dir="${profiler.info.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" jvm="${profiler.info.jvm}" showoutput="true">
+            <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
+            <jvmarg value="${profiler.info.jvmargs.agent}"/>
+            <jvmarg line="${profiler.info.jvmargs}"/>
+            <test name="${profile.class}"/>
+            <classpath>
+                <path path="${run.test.classpath}"/>
+            </classpath>
+            <syspropertyset>
+                <propertyref prefix="test-sys-prop."/>
+                <mapper from="test-sys-prop.*" to="*" type="glob"/>
+            </syspropertyset>
+            <formatter type="brief" usefile="false"/>
+            <formatter type="xml"/>
+        </junit>
+    </target>
+    <!--
+                end of pre NB72 profiling section
+            -->
+    <target if="netbeans.home" name="-profile-check">
+        <condition property="profiler.configured">
+            <or>
+                <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-agentpath:"/>
+                <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-javaagent:"/>
+            </or>
+        </condition>
+    </target>
+    <target depends="-profile-check,-profile-pre72" description="Profile a project in the IDE." if="profiler.configured" name="profile" unless="profiler.info.jvmargs.agent">
+        <startprofiler/>
+        <antcall target="run"/>
+    </target>
+    <target depends="-profile-check,-profile-single-pre72" description="Profile a selected class in the IDE." if="profiler.configured" name="profile-single" unless="profiler.info.jvmargs.agent">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <startprofiler/>
+        <antcall target="run-single"/>
+    </target>
+    <target depends="-profile-test-single-pre72" description="Profile a selected test in the IDE." name="profile-test-single"/>
+    <target depends="-profile-check" description="Profile a selected test in the IDE." if="profiler.configured" name="profile-test" unless="profiler.info.jvmargs">
+        <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
+        <startprofiler/>
+        <antcall target="test-single"/>
+    </target>
+    <target depends="-profile-check" description="Profile a selected class in the IDE." if="profiler.configured" name="profile-test-with-main">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <startprofiler/>
+        <antcal target="run-test-with-main"/>
+    </target>
+    <target depends="-profile-check,-profile-applet-pre72" if="profiler.configured" name="profile-applet" unless="profiler.info.jvmargs.agent">
+        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
+        <startprofiler/>
+        <antcall target="run-applet"/>
+    </target>
+    <!--
+                ===============
+                JAVADOC SECTION
+                ===============
+            -->
+    <target depends="init" if="have.sources" name="-javadoc-build">
+        <mkdir dir="${dist.javadoc.dir}"/>
+        <condition else="" property="javadoc.endorsed.classpath.cmd.line.arg" value="-J${endorsed.classpath.cmd.line.arg}">
+            <and>
+                <isset property="endorsed.classpath.cmd.line.arg"/>
+                <not>
+                    <equals arg1="${endorsed.classpath.cmd.line.arg}" arg2=""/>
+                </not>
+            </and>
+        </condition>
+        <condition else="" property="bug5101868workaround" value="*.java">
+            <matches pattern="1\.[56](\..*)?" string="${java.version}"/>
+        </condition>
+        <javadoc additionalparam="-J-Dfile.encoding=${file.encoding} ${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
+            <classpath>
+                <path path="${javac.classpath}"/>
+            </classpath>
+            <fileset dir="${src.src3.dir}" excludes="${bug5101868workaround},${excludes}" includes="${includes}">
+                <filename name="**/*.java"/>
+            </fileset>
+            <fileset dir="${src.src4.dir}" excludes="${bug5101868workaround},${excludes}" includes="${includes}">
+                <filename name="**/*.java"/>
+            </fileset>
+            <fileset dir="${src.src2.dir}" excludes="${bug5101868workaround},${excludes}" includes="${includes}">
+                <filename name="**/*.java"/>
+            </fileset>
+            <fileset dir="${src.src.dir}" excludes="${bug5101868workaround},${excludes}" includes="${includes}">
+                <filename name="**/*.java"/>
+            </fileset>
+            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+                <include name="**/*.java"/>
+                <exclude name="*.java"/>
+            </fileset>
+            <arg line="${javadoc.endorsed.classpath.cmd.line.arg}"/>
+        </javadoc>
+        <copy todir="${dist.javadoc.dir}">
+            <fileset dir="${src.src3.dir}" excludes="${excludes}" includes="${includes}">
+                <filename name="**/doc-files/**"/>
+            </fileset>
+            <fileset dir="${src.src4.dir}" excludes="${excludes}" includes="${includes}">
+                <filename name="**/doc-files/**"/>
+            </fileset>
+            <fileset dir="${src.src2.dir}" excludes="${excludes}" includes="${includes}">
+                <filename name="**/doc-files/**"/>
+            </fileset>
+            <fileset dir="${src.src.dir}" excludes="${excludes}" includes="${includes}">
+                <filename name="**/doc-files/**"/>
+            </fileset>
+            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+                <include name="**/doc-files/**"/>
+            </fileset>
+        </copy>
+    </target>
+    <target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">
+        <nbbrowse file="${dist.javadoc.dir}/index.html"/>
+    </target>
+    <target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/>
+    <!--
+                =========================
+                TEST COMPILATION SECTION
+                =========================
+            -->
+    <target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">
+        <mkdir dir="${build.test.classes.dir}"/>
+    </target>
+    <target name="-pre-compile-test">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target if="do.depend.true" name="-compile-test-depend">
+        <j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir=""/>
+    </target>
+    <target depends="init,deps-jar,compile,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">
+        <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" processorpath="${javac.test.processorpath}" srcdir=""/>
+        <copy todir="${build.test.classes.dir}"/>
+    </target>
+    <target name="-post-compile-test">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/>
+    <target name="-pre-compile-test-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-jar,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
+        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
+        <j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>
+        <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" processorpath="${javac.test.processorpath}" sourcepath="" srcdir=""/>
+        <copy todir="${build.test.classes.dir}"/>
+    </target>
+    <target name="-post-compile-test-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>
+    <!--
+                =======================
+                TEST EXECUTION SECTION
+                =======================
+            -->
+    <target depends="init" if="have.tests" name="-pre-test-run">
+        <mkdir dir="${build.test.results.dir}"/>
+    </target>
+    <target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
+        <j2seproject3:test includes="${includes}" testincludes="**/*Test.java"/>
+    </target>
+    <target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+    </target>
+    <target depends="init" if="have.tests" name="test-report"/>
+    <target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
+    <target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/>
+    <target depends="init" if="have.tests" name="-pre-test-run-single">
+        <mkdir dir="${build.test.results.dir}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
+        <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
+        <j2seproject3:test excludes="" includes="${test.includes}" testincludes="${test.includes}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single-method">
+        <fail unless="test.class">Must select some files in the IDE or set test.class</fail>
+        <fail unless="test.method">Must select some method in the IDE or set test.method</fail>
+        <j2seproject3:test excludes="" includes="${javac.includes}" testincludes="${test.class}" testmethods="${test.method}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method" if="have.tests" name="-post-test-run-single-method">
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method,-post-test-run-single-method" description="Run single unit test." name="test-single-method"/>
+    <!--
+                =======================
+                TEST DEBUGGING SECTION
+                =======================
+            -->
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test">
+        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
+        <j2seproject3:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testincludes="${javac.includes}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test-method">
+        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
+        <fail unless="test.method">Must select some method in the IDE or set test.method</fail>
+        <j2seproject3:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testMethod="${test.method}" testincludes="${test.class}" testmethods="${test.method}"/>
+    </target>
+    <target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">
+        <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>
+    </target>
+    <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
+    <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test-method" name="debug-test-method"/>
+    <target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
+        <j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>
+    </target>
+    <target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/>
+    <!--
+                =========================
+                APPLET EXECUTION SECTION
+                =========================
+            -->
+    <target depends="init,compile-single" name="run-applet">
+        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
+        <j2seproject1:java classname="sun.applet.AppletViewer">
+            <customize>
+                <arg value="${applet.url}"/>
+            </customize>
+        </j2seproject1:java>
+    </target>
+    <!--
+                =========================
+                APPLET DEBUGGING  SECTION
+                =========================
+            -->
+    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-applet">
+        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
+        <j2seproject3:debug classname="sun.applet.AppletViewer">
+            <customize>
+                <arg value="${applet.url}"/>
+            </customize>
+        </j2seproject3:debug>
+    </target>
+    <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet" if="netbeans.home" name="debug-applet"/>
+    <!--
+                ===============
+                CLEANUP SECTION
+                ===============
+            -->
+    <target name="-deps-clean-init" unless="built-clean.properties">
+        <property location="${build.dir}/built-clean.properties" name="built-clean.properties"/>
+        <delete file="${built-clean.properties}" quiet="true"/>
+    </target>
+    <target if="already.built.clean.${basedir}" name="-warn-already-built-clean">
+        <echo level="warn" message="Cycle detected: SanityTests was already built"/>
+    </target>
+    <target depends="init,-deps-clean-init" name="deps-clean" unless="no.deps">
+        <mkdir dir="${build.dir}"/>
+        <touch file="${built-clean.properties}" verbose="false"/>
+        <property file="${built-clean.properties}" prefix="already.built.clean."/>
+        <antcall target="-warn-already-built-clean"/>
+        <propertyfile file="${built-clean.properties}">
+            <entry key="${basedir}" value=""/>
+        </propertyfile>
+    </target>
+    <target depends="init" name="-do-clean">
+        <delete dir="${build.dir}"/>
+        <delete dir="${dist.dir}" followsymlinks="false" includeemptydirs="true"/>
+    </target>
+    <target name="-post-clean">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/>
+    <target name="-check-call-dep">
+        <property file="${call.built.properties}" prefix="already.built."/>
+        <condition property="should.call.dep">
+            <and>
+                <not>
+                    <isset property="already.built.${call.subproject}"/>
+                </not>
+                <available file="${call.script}"/>
+            </and>
+        </condition>
+    </target>
+    <target depends="-check-call-dep" if="should.call.dep" name="-maybe-call-dep">
+        <ant antfile="${call.script}" inheritall="false" target="${call.target}">
+            <propertyset>
+                <propertyref prefix="transfer."/>
+                <mapper from="transfer.*" to="*" type="glob"/>
+            </propertyset>
+        </ant>
+    </target>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/netbeans/client_sanity/nbproject/genfiles.properties	Tue Apr 05 09:17:15 2016 -0700
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=0f9d9977
+build.xml.script.CRC32=f902e8b8
+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.script.CRC32=c12f9d04
+nbproject/build-impl.xml.stylesheet.CRC32=05530350@1.79.1.48
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/netbeans/client_sanity/nbproject/project.properties	Tue Apr 05 09:17:15 2016 -0700
@@ -0,0 +1,79 @@
+annotation.processing.enabled=true
+annotation.processing.enabled.in.editor=false
+annotation.processing.processors.list=
+annotation.processing.run.all.processors=true
+annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
+application.title=SanityTests
+application.vendor=akouznet
+build.classes.dir=${build.dir}/classes
+build.classes.excludes=**/*.java,**/*.form
+# This directory is removed when the project is cleaned:
+build.dir=build
+build.generated.dir=${build.dir}/generated
+build.generated.sources.dir=${build.dir}/generated-sources
+# Only compile against the classpath explicitly listed here:
+build.sysclasspath=ignore
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
+# Uncomment to specify the preferred debugger connection transport:
+#debug.transport=dt_socket
+debug.classpath=\
+    ${run.classpath}
+debug.test.classpath=\
+    ${run.test.classpath}
+# Files in build.classes.dir which should be excluded from distribution jar
+dist.archive.excludes=
+# This directory is removed when the project is cleaned:
+dist.dir=dist
+dist.jar=${dist.dir}/SanityTests.jar
+dist.javadoc.dir=${dist.dir}/javadoc
+endorsed.classpath=
+excludes=*.cfg
+includes=**
+jar.compress=false
+javac.classpath=\
+    ${libs.testng.classpath}
+# Space-separated list of extra javac options
+javac.compilerargs=-Xmaxwarns 9999 -Xlint:all -Xlint:-serial
+javac.deprecation=false
+javac.external.vm=false
+javac.processorpath=\
+    ${javac.classpath}
+javac.source=1.8
+javac.target=1.8
+javac.test.classpath=\
+    ${javac.classpath}:\
+    ${build.classes.dir}
+javac.test.processorpath=\
+    ${javac.test.classpath}
+javadoc.additionalparam=
+javadoc.author=false
+javadoc.encoding=${source.encoding}
+javadoc.noindex=false
+javadoc.nonavbar=false
+javadoc.notree=false
+javadoc.private=false
+javadoc.splitindex=true
+javadoc.use=true
+javadoc.version=false
+javadoc.windowtitle=
+main.class=
+manifest.file=manifest.mf
+meta.inf.dir=${src.dir}/META-INF
+mkdist.disabled=false
+platform.active=default_platform
+run.classpath=\
+    ${javac.classpath}:\
+    ${build.classes.dir}
+# Space-separated list of JVM arguments used when running the project.
+# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
+# To set system properties for unit tests define test-sys-prop.name=value:
+run.jvmargs=-ea
+run.test.classpath=\
+    ${javac.test.classpath}:\
+    ${build.test.classes.dir}
+source.encoding=UTF-8
+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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/netbeans/client_sanity/nbproject/project.xml	Tue Apr 05 09:17:15 2016 -0700
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.java.j2seproject</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/j2se-project/3">
+            <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.src2.dir" name="lib\SwingSet3\src"/>
+                <root id="src.src.dir" name="SwingSet\src"/>
+            </source-roots>
+            <test-roots/>
+        </data>
+        <references xmlns="http://www.netbeans.org/ns/ant-project-references/2"/>
+    </configuration>
+</project>
--- a/make/rmic/RmicCommon.gmk	Tue Apr 05 18:23:10 2016 +0300
+++ b/make/rmic/RmicCommon.gmk	Tue Apr 05 09:17:15 2016 -0700
@@ -31,7 +31,13 @@
 
 ##########################################################################################
 
-RMIC := $(JAVA) $(INTERIM_OVERRIDE_MODULES_ARGS) sun.rmi.rmic.Main
+ifeq ($(BOOT_JDK_MODULAR), true)
+  RMIC_MAIN_CLASS := -m jdk.rmic/sun.rmi.rmic.Main
+else
+  RMIC_MAIN_CLASS := sun.rmi.rmic.Main
+endif
+
+RMIC := $(JAVA) $(INTERIM_OVERRIDE_MODULES_ARGS) $(RMIC_MAIN_CLASS)
 
 CLASSES_DIR := $(JDK_OUTPUTDIR)/modules
 # NOTE: If the smart javac dependency management is reintroduced, these classes risk
--- a/make/src/classes/build/tools/cldrconverter/LDMLParseHandler.java	Tue Apr 05 18:23:10 2016 +0300
+++ b/make/src/classes/build/tools/cldrconverter/LDMLParseHandler.java	Tue Apr 05 09:17:15 2016 -0700
@@ -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
@@ -786,10 +786,10 @@
         return keyName;
     }
 
-    private String getTarget(String qName, String path, String calType, String context, String width) {
-        // qName
+    private String getTarget(String path, String calType, String context, String width) {
+        // Target qName
         int lastSlash = path.lastIndexOf('/');
-        qName = path.substring(lastSlash+1);
+        String qName = path.substring(lastSlash+1);
         int bracket = qName.indexOf('[');
         if (bracket != -1) {
             qName = qName.substring(0, bracket);
@@ -885,7 +885,7 @@
                     String[] tmp = keyName.split(",", 3);
                     String calType = currentCalendarType.lname();
                     String src = calType+"."+tmp[0];
-                    String target = getTarget(containerqName,
+                    String target = getTarget(
                                 entry.getKey(),
                                 calType,
                                 tmp[1].length()>0 ? tmp[1] : currentContext,
--- a/make/src/classes/build/tools/module/GenModuleInfoSource.java	Tue Apr 05 18:23:10 2016 +0300
+++ b/make/src/classes/build/tools/module/GenModuleInfoSource.java	Tue Apr 05 09:17:15 2016 -0700
@@ -25,25 +25,27 @@
 package build.tools.module;
 
 import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 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.stream.Collectors;
 
 /**
- * A build tool to extend the module-info.java in the source tree
- * for platform-specific exports, uses, and provides and write
- * to the specified output file.
+ * A build tool to extend the module-info.java in the source tree for
+ * platform-specific exports, uses, and provides and write to the specified
+ * output file. Injecting platform-specific requires is not supported.
  *
- * GenModulesList build tool currently generates the modules.list from
- * the module-info.java from the source tree that will be used for
- * the make target and dependences.
- *
- * The build currently invokes gensrc-$MODULE.gmk after modules.list
- * is generated.  Hence, platform-specific requires is not supported.
+ * The extra exports, uses, provides can be specified in module-info.java.extra
+ * files and GenModuleInfoSource will be invoked for each module that has
+ * module-info.java.extra in the source directory.
  */
 public class GenModuleInfoSource {
     private final static String USAGE =
@@ -57,17 +59,32 @@
     public static void main(String... args) throws Exception {
         Path outfile = null;
         Path moduleInfoJava = null;
-        Map<String, Set<String>> options = new HashMap<>();
+        GenModuleInfoSource genModuleInfo = new GenModuleInfoSource();
 
         // validate input arguments
         for (int i = 0; i < args.length; i++){
             String option = args[i];
             if (option.startsWith("-")) {
                 String arg = args[++i];
-                if (option.equals("-exports") ||
-                        option.equals("-uses") ||
-                        option.equals("-provides")) {
-                    options.computeIfAbsent(option, _k -> new HashSet<>()).add(arg);
+                if (option.equals("-exports")) {
+                    int index = arg.indexOf('/');
+                        if (index > 0) {
+                            String pn = arg.substring(0, index);
+                            String mn = arg.substring(index + 1, arg.length());
+                            genModuleInfo.exportTo(pn, mn);
+                        } else {
+                            genModuleInfo.export(arg);
+                        }
+                } else if (option.equals("-uses")) {
+                    genModuleInfo.use(arg);
+                } else if (option.equals("-provides")) {
+                        int index = arg.indexOf('/');
+                        if (index <= 0) {
+                            throw new IllegalArgumentException("invalid -provide argument: " + arg);
+                        }
+                        String service = arg.substring(0, index);
+                        String impl = arg.substring(index + 1, arg.length());
+                        genModuleInfo.provide(service, impl);
                 } else if (option.equals("-o")) {
                     outfile = Paths.get(arg);
                 } else {
@@ -87,48 +104,145 @@
             System.err.println(USAGE);
             System.exit(-1);
         }
-        // read module-info.java
-        Module.Builder builder = ModuleInfoReader.builder(moduleInfoJava);
-        augment(builder, options);
 
         // generate new module-info.java
-        Module module = builder.build();
+        genModuleInfo.generate(moduleInfoJava, outfile);
+    }
+
+    private final Set<String> exports = new HashSet<>();
+    private final Map<String, Set<String>> exportsTo = new HashMap<>();
+    private final Set<String> uses = new HashSet<>();
+    private final Map<String, Set<String>> provides = new HashMap<>();
+    GenModuleInfoSource() {
+    }
+
+    private void export(String p) {
+        Objects.requireNonNull(p);
+        if (exports.contains(p) || exportsTo.containsKey(p)) {
+            throw new RuntimeException("duplicated exports: " + p);
+        }
+        exports.add(p);
+    }
+    private void exportTo(String p, String mn) {
+        Objects.requireNonNull(p);
+        Objects.requireNonNull(mn);
+        if (exports.contains(p)) {
+            throw new RuntimeException("unqualified exports already exists: " + p);
+        }
+        exportsTo.computeIfAbsent(p, _k -> new HashSet<>()).add(mn);
+    }
+
+    private void use(String service) {
+        uses.add(service);
+    }
+
+    private void provide(String s, String impl) {
+        provides.computeIfAbsent(s, _k -> new HashSet<>()).add(impl);
+    }
+
+    private void generate(Path sourcefile, Path outfile) throws IOException {
         Path parent = outfile.getParent();
         if (parent != null)
             Files.createDirectories(parent);
 
-        try (BufferedWriter writer = Files.newBufferedWriter(outfile)) {
-            writer.write(module.toString());
-        }
-    }
+        List<String> lines = Files.readAllLines(sourcefile);
+        try (BufferedWriter bw = Files.newBufferedWriter(outfile);
+             PrintWriter writer = new PrintWriter(bw)) {
+            int lineNumber = 0;
+            for (String l : lines) {
+                lineNumber++;
+                String[] s = l.trim().split("\\s+");
+                String keyword = s[0].trim();
+                int nextIndex = keyword.length();
+                String exp = null;
+                int n = l.length();
+                switch (keyword) {
+                    case "exports":
+                        boolean inExportsTo = false;
+                        // assume package name immediately after exports
+                        exp = s[1].trim();
+                        if (s.length >= 3) {
+                            nextIndex = l.indexOf(exp, nextIndex) + exp.length();
+                            if (s[2].trim().equals("to")) {
+                                inExportsTo = true;
+                                n = l.indexOf("to", nextIndex) + "to".length();
+                            } else {
+                                throw new RuntimeException(sourcefile + ", line " +
+                                    lineNumber + ", is malformed: " + s[2]);
+                            }
+                        }
 
-    private static void augment(Module.Builder builder, Map<String, Set<String>> options) {
-        for (String opt : options.keySet()) {
-            if (opt.equals("-exports")) {
-                for (String arg : options.get(opt)) {
-                    int index = arg.indexOf('/');
-                    if (index > 0) {
-                        String pn = arg.substring(0, index);
-                        String mn = arg.substring(index + 1, arg.length());
-                        builder.exportTo(pn, mn);
-                    } else {
-                        builder.export(arg);
-                    }
-                }
-            } else if (opt.equals("-uses")) {
-                options.get(opt).stream()
-                        .forEach(builder::use);
-            } else if (opt.equals("-provides")) {
-                for (String arg : options.get(opt)) {
-                    int index = arg.indexOf('/');
-                    if (index <= 0) {
-                        throw new IllegalArgumentException("invalid -provide argument: " + arg);
-                    }
-                    String service = arg.substring(0, index);
-                    String impl = arg.substring(index + 1, arg.length());
-                    builder.provide(service, impl);
+                        // inject the extra targets after "to"
+                        if (inExportsTo) {
+                            writer.println(injectExportTargets(exp, l, n));
+                        } else {
+                            writer.println(l);
+                        }
+                        break;
+                    case "to":
+                        if (exp == null) {
+                            throw new RuntimeException(sourcefile + ", line " +
+                                lineNumber + ", is malformed");
+                        }
+                        n = l.indexOf("to", nextIndex) + "to".length();
+                        writer.println(injectExportTargets(exp, l, n));
+                        break;
+                    case "}":
+                        doAugments(writer);
+                        // fall through
+                    default:
+                        writer.println(l);
+                        // reset exports
+                        exp = null;
                 }
             }
         }
     }
+
+    private String injectExportTargets(String pn, String exp, int pos) {
+        Set<String> targets = exportsTo.remove(pn);
+        if (targets != null) {
+            StringBuilder sb = new StringBuilder();
+            // inject the extra targets after the given pos
+            sb.append(exp.substring(0, pos))
+              .append("\n\t")
+              .append(targets.stream()
+                             .collect(Collectors.joining(",", "", ",")))
+              .append(" /* injected */");
+            if (pos < exp.length()) {
+                // print the remaining statement followed "to"
+                sb.append("\n\t")
+                  .append(exp.substring(pos+1, exp.length()));
+            }
+            return sb.toString();
+        } else {
+            return exp;
+        }
+    }
+
+    private void doAugments(PrintWriter writer) {
+        if ((exports.size() + exportsTo.size() + uses.size() + provides.size()) == 0)
+            return;
+
+        writer.println("    // augmented from module-info.java.extra");
+        exports.stream()
+            .sorted()
+            .forEach(e -> writer.format("    exports %s;%n", e));
+        // remaining injected qualified exports
+        exportsTo.entrySet().stream()
+            .sorted(Map.Entry.comparingByKey())
+            .map(e -> String.format("    exports %s to%n%s;", e.getKey(),
+                                    e.getValue().stream().sorted()
+                                        .map(mn -> String.format("        %s", mn))
+                                        .collect(Collectors.joining(",\n"))))
+            .forEach(writer::println);
+        uses.stream().sorted()
+            .forEach(s -> writer.format("    uses %s;%n", s));
+        provides.entrySet().stream()
+            .sorted(Map.Entry.comparingByKey())
+            .flatMap(e -> e.getValue().stream().sorted()
+                           .map(impl -> String.format("    provides %s with %s;",
+                                                      e.getKey(), impl)))
+            .forEach(writer::println);
+    }
 }
--- a/make/src/classes/build/tools/module/Module.java	Tue Apr 05 18:23:10 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,280 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package build.tools.module;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-public class Module {
-    public static class Dependence implements Comparable<Dependence> {
-        final String name;
-        final boolean reexport;
-        Dependence(String name) {
-            this(name, false);
-        }
-        Dependence(String name, boolean reexport) {
-            this.name = name;
-            this.reexport = reexport;
-        }
-
-        public String name() {
-            return name;
-        }
-
-        public boolean reexport(){
-            return reexport;
-        }
-
-        @Override
-        public int hashCode() {
-            int hash = 5;
-            hash = 11 * hash + Objects.hashCode(this.name);
-            hash = 11 * hash + (this.reexport ? 1 : 0);
-            return hash;
-        }
-
-        public boolean equals(Object o) {
-            Dependence d = (Dependence)o;
-            return this.name.equals(d.name) && this.reexport == d.reexport;
-        }
-
-        @Override
-        public int compareTo(Dependence o) {
-            int rc = this.name.compareTo(o.name);
-            return rc != 0 ? rc : Boolean.compare(this.reexport, o.reexport);
-        }
-
-        @Override
-        public String toString() {
-            return String.format("requires %s%s;",
-                                 reexport ? "public " : "", name);
-        }
-    }
-    private final String moduleName;
-    private final Set<Dependence> requires;
-    private final Map<String, Set<String>> exports;
-    private final Set<String> uses;
-    private final Map<String, Set<String>> provides;
-
-    private Module(String name,
-                   Set<Dependence> requires,
-                   Map<String, Set<String>> exports,
-                   Set<String> uses,
-                   Map<String, Set<String>> provides) {
-        this.moduleName = name;
-        this.requires = Collections.unmodifiableSet(requires);
-        this.exports = Collections.unmodifiableMap(exports);
-        this.uses  = Collections.unmodifiableSet(uses);
-        this.provides = Collections.unmodifiableMap(provides);
-    }
-
-    public String name() {
-        return moduleName;
-    }
-
-    public Set<Dependence> requires() {
-        return requires;
-    }
-
-    public Map<String, Set<String>> exports() {
-        return exports;
-    }
-
-    public Set<String> uses() {
-        return uses;
-    }
-
-    public Map<String, Set<String>> provides() {
-        return provides;
-    }
-
-    @Override
-    public boolean equals(Object ob) {
-        if (!(ob instanceof Module)) {
-            return false;
-        }
-        Module that = (Module) ob;
-        return (moduleName.equals(that.moduleName)
-                && requires.equals(that.requires)
-                && exports.equals(that.exports));
-    }
-
-    @Override
-    public int hashCode() {
-        int hc = moduleName.hashCode();
-        hc = hc * 43 + requires.hashCode();
-        hc = hc * 43 + exports.hashCode();
-        return hc;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append(String.format("module %s {%n", moduleName));
-        requires.stream()
-                .sorted()
-                .map(d -> String.format("    requires %s%s;%n", d.reexport ? "public " : "", d.name))
-                .forEach(sb::append);
-        exports.entrySet().stream()
-                .filter(e -> e.getValue().isEmpty())
-                .sorted(Map.Entry.comparingByKey())
-                .map(e -> String.format("    exports %s;%n", e.getKey()))
-                .forEach(sb::append);
-        exports.entrySet().stream()
-                .filter(e -> !e.getValue().isEmpty())
-                .sorted(Map.Entry.comparingByKey())
-                .map(e -> String.format("    exports %s to%n%s;%n", e.getKey(),
-                        e.getValue().stream().sorted()
-                                .map(mn -> String.format("        %s", mn))
-                                .collect(Collectors.joining(",\n"))))
-                .forEach(sb::append);
-        uses.stream().sorted()
-                .map(s -> String.format("    uses %s;%n", s))
-                .forEach(sb::append);
-        provides.entrySet().stream()
-                .sorted(Map.Entry.comparingByKey())
-                .flatMap(e -> e.getValue().stream().sorted()
-                        .map(impl -> String.format("    provides %s with %s;%n", e.getKey(), impl)))
-                .forEach(sb::append);
-        sb.append("}").append("\n");
-        return sb.toString();
-    }
-
-    /**
-     * Module Builder
-     */
-    static class Builder {
-        private String name;
-        final Set<Dependence> requires = new HashSet<>();
-        final Map<String, Set<String>> exports = new HashMap<>();
-        final Set<String> uses = new HashSet<>();
-        final Map<String, Set<String>> provides = new HashMap<>();
-
-        public Builder() {
-        }
-
-        public Builder name(String n) {
-            name = n;
-            return this;
-        }
-
-        public Builder require(String d, boolean reexport) {
-            requires.add(new Dependence(d, reexport));
-            return this;
-        }
-
-        public Builder export(String p) {
-            Objects.requireNonNull(p);
-            if (exports.containsKey(p)) {
-                throw new RuntimeException(name + " already exports " + p +
-                        " " + exports.get(p));
-            }
-            return exportTo(p, Collections.emptySet());
-        }
-
-        public Builder exportTo(String p, String mn) {
-            Objects.requireNonNull(p);
-            Objects.requireNonNull(mn);
-            Set<String> ms = exports.get(p);
-            if (ms != null && ms.isEmpty()) {
-                throw new RuntimeException(name + " already has unqualified exports " + p);
-            }
-            exports.computeIfAbsent(p, _k -> new HashSet<>()).add(mn);
-            return this;
-        }
-
-        public Builder exportTo(String p, Set<String> ms) {
-            Objects.requireNonNull(p);
-            Objects.requireNonNull(ms);
-            if (exports.containsKey(p)) {
-                throw new RuntimeException(name + " already exports " + p +
-                        " " + exports.get(p));
-            }
-            exports.put(p, new HashSet<>(ms));
-            return this;
-        }
-
-        public Builder use(String cn) {
-            uses.add(cn);
-            return this;
-        }
-
-        public Builder provide(String s, String impl) {
-            provides.computeIfAbsent(s, _k -> new HashSet<>()).add(impl);
-            return this;
-        }
-
-        public Builder merge(Module m1, Module m2) {
-            if (!m1.name().equals(m2.name())) {
-                throw new IllegalArgumentException(m1.name() + " != " + m2.name());
-            }
-            name = m1.name();
-            // ## reexports
-            requires.addAll(m1.requires());
-            requires.addAll(m2.requires());
-            Stream.concat(m1.exports().keySet().stream(), m2.exports().keySet().stream())
-                    .distinct()
-                    .forEach(pn -> {
-                        Set<String> s1 = m2.exports().get(pn);
-                        Set<String> s2 = m2.exports().get(pn);
-                        if (s1 == null || s2 == null) {
-                            exportTo(pn, s1 != null ? s1 : s2);
-                        } else if (s1.isEmpty() || s2.isEmpty()) {
-                            // unqualified exports
-                            export(pn);
-                        } else {
-                            exportTo(pn, Stream.concat(s1.stream(), s2.stream())
-                                               .collect(Collectors.toSet()));
-                        }
-                    });
-            uses.addAll(m1.uses());
-            uses.addAll(m2.uses());
-            m1.provides().keySet().stream()
-                    .forEach(s -> m1.provides().get(s).stream()
-                            .forEach(impl -> provide(s, impl)));
-            m2.provides().keySet().stream()
-                    .forEach(s -> m2.provides().get(s).stream()
-                            .forEach(impl -> provide(s, impl)));
-            return this;
-        }
-
-        public Module build() {
-            Module m = new Module(name, requires, exports, uses, provides);
-            return m;
-        }
-
-        @Override
-        public String toString() {
-            return name != null ? name : "Unknown";
-        }
-    }
-}
--- a/make/src/classes/build/tools/module/ModuleInfoReader.java	Tue Apr 05 18:23:10 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,357 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package build.tools.module;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.List;
-import java.util.function.Supplier;
-import java.util.regex.Pattern;
-import java.util.stream.Stream;
-
-import build.tools.module.Module.Builder;
-
-/**
- * Source reader of module-info.java
- */
-public class ModuleInfoReader {
-    private final Path sourcefile;
-    private final Builder builder;
-    private ModuleInfoReader(Path file) {
-        this.sourcefile = file;
-        this.builder = new Builder();
-    }
-
-    public static Builder builder(Path file) throws IOException {
-        ModuleInfoReader reader = new ModuleInfoReader(file);
-        reader.readFile();
-        return reader.builder;
-    }
-
-    /**
-     * Reads the source file.
-     */
-    void readFile() throws IOException {
-        List<String> lines = Files.readAllLines(sourcefile);
-        boolean done = false;
-        int lineNumber = 0;
-        boolean inBlockComment = false;
-        boolean inRequires = false;
-        boolean reexports = false;
-        boolean inProvides = false;
-        boolean inWith = false;
-        String serviceIntf = null;
-        String providerClass = null;
-        boolean inUses = false;
-        boolean inExports = false;
-        boolean inExportsTo = false;
-        String qualifiedExports = null;
-        Counter counter = new Counter();
-
-        for (String line : lines) {
-            lineNumber++;
-            if (inBlockComment) {
-                int c = line.indexOf("*/");
-                if (c >= 0) {
-                    line = line.substring(c + 2, line.length());
-                    inBlockComment = false;
-                } else {
-                    // skip lines until end of comment block
-                    continue;
-                }
-            }
-            inBlockComment = beginBlockComment(line);
-
-            line = trimComment(line).trim();
-            // ignore empty lines
-            if (line.length() == 0) {
-                continue;
-            }
-            String values;
-            if (inRequires || inExports | inUses | (inWith && providerClass == null)) {
-                values = line;
-            } else {
-                String[] s = line.split("\\s+");
-                String keyword = s[0].trim();
-                int nextIndex = keyword.length();
-                switch (keyword) {
-                    case "module":
-                        if (s.length != 3 || !s[2].trim().equals("{")) {
-                            throw new RuntimeException(sourcefile + ", line " +
-                                    lineNumber + ", is malformed");
-                        }
-                        builder.name(s[1].trim());
-                        continue;  // next line
-                    case "requires":
-                        inRequires = true;
-                        counter.numRequires++;
-                        if (s.length >= 2) {
-                            String ss = s[1].trim();
-                            if (ss.equals("public")) {
-                                nextIndex = line.indexOf(ss) + ss.length();
-                                reexports = true;
-                            }
-                        }
-                        break;
-                    case "exports":
-                        inExports = true;
-                        inExportsTo = false;
-                        counter.numExports++;
-                        qualifiedExports = null;
-                        if (s.length >= 3) {
-                            qualifiedExports = s[1].trim();
-                            nextIndex = line.indexOf(qualifiedExports, nextIndex)
-                                            + qualifiedExports.length();
-                            if (s[2].trim().equals("to")) {
-                                inExportsTo = true;
-                                nextIndex = line.indexOf("to", nextIndex) + "to".length();
-                            } else {
-                                throw new RuntimeException(sourcefile + ", line " +
-                                        lineNumber + ", is malformed: " + s[2]);
-                            }
-                        }
-                        break;
-                    case "to":
-                        if (!inExports || qualifiedExports == null) {
-                            throw new RuntimeException(sourcefile + ", line " +
-                                    lineNumber + ", is malformed");
-                        }
-                        inExportsTo = true;
-                        break;
-                    case "uses":
-                        inUses = true;
-                        counter.numUses++;
-                        break;
-                    case "provides":
-                        inProvides = true;
-                        inWith = false;
-                        counter.numProvides++;
-                        serviceIntf = null;
-                        providerClass = null;
-                        if (s.length >= 2) {
-                            serviceIntf = s[1].trim();
-                            nextIndex = line.indexOf(serviceIntf) + serviceIntf.length();
-                        }
-                        if (s.length >= 3) {
-                            if (s[2].trim().equals("with")) {
-                                inWith = true;
-                                nextIndex = line.indexOf("with") + "with".length();
-                            } else {
-                                throw new RuntimeException(sourcefile + ", line " +
-                                        lineNumber + ", is malformed: " + s[2]);
-                            }
-                        }
-                        break;
-                    case "with":
-                        if (!inProvides || serviceIntf == null) {
-                            throw new RuntimeException(sourcefile + ", line " +
-                                    lineNumber + ", is malformed");
-                        }
-                        inWith = true;
-                        nextIndex = line.indexOf("with") + "with".length();
-                        break;
-                    case "}":
-                        counter.validate(builder);
-                        done = true;
-                        continue;  // next line
-                    default:
-                        throw new RuntimeException(sourcefile + ", \"" +
-                                keyword + "\" on line " +
-                                lineNumber + ", is not recognized");
-                }
-                values = line.substring(nextIndex, line.length()).trim();
-            }
-
-            int len = values.length();
-            if (len == 0) {
-                continue;  // next line
-            }
-            char lastchar = values.charAt(len - 1);
-            if (lastchar != ',' && lastchar != ';') {
-                throw new RuntimeException(sourcefile + ", line " +
-                        lineNumber + ", is malformed:" +
-                        " ',' or ';' is missing.");
-            }
-
-            values = values.substring(0, len - 1).trim();
-            // parse the values specified for a keyword specified
-            for (String s : values.split(",")) {
-                s = s.trim();
-                if (s.length() > 0) {
-                    if (inRequires) {
-                        if (builder.requires.contains(s)) {
-                            throw new RuntimeException(sourcefile + ", line "
-                                    + lineNumber + " duplicated requires: \"" + s + "\"");
-                        }
-                        builder.require(s, reexports);
-                    } else if (inExports) {
-                        if (!inExportsTo && qualifiedExports == null) {
-                            builder.export(s);
-                        } else {
-                            builder.exportTo(qualifiedExports, s);
-                        }
-                    } else if (inUses) {
-                        builder.use(s);
-                    } else if (inProvides) {
-                        if (!inWith) {
-                            serviceIntf = s;
-                        } else {
-                            providerClass = s;
-                            builder.provide(serviceIntf, providerClass);
-                        }
-                    }
-                }
-            }
-            if (lastchar == ';') {
-                inRequires = false;
-                reexports = false;
-                inExports = false;
-                inExportsTo = false;
-                inProvides = false;
-                inWith = false;
-                inUses = false;
-            }
-        }
-
-        if (inBlockComment) {
-            throw new RuntimeException(sourcefile + ", line " +
-                    lineNumber + ", missing \"*/\" to end a block comment");
-        }
-        if (!done) {
-            throw new RuntimeException(sourcefile + ", line " +
-                    lineNumber + ", missing \"}\" to end module definition" +
-                    " for \"" + builder + "\"");
-        }
-        return;
-    }
-
-    // the naming convention for the module names without dashes
-    private static final Pattern CLASS_NAME_PATTERN = Pattern.compile("[\\w\\.\\*_$/]+");
-    private static boolean beginBlockComment(String line) {
-        int pos = 0;
-        while (pos >= 0 && pos < line.length()) {
-            int c = line.indexOf("/*", pos);
-            if (c < 0) {
-                return false;
-            }
-
-            if (c > 0 && !Character.isWhitespace(line.charAt(c - 1))) {
-                return false;
-            }
-
-            int c1 = line.indexOf("//", pos);
-            if (c1 >= 0 && c1 < c) {
-                return false;
-            }
-
-            int c2 = line.indexOf("*/", c + 2);
-            if (c2 < 0) {
-                return true;
-            }
-            pos = c + 2;
-        }
-        return false;
-    }
-    private static String trimComment(String line) {
-        StringBuilder sb = new StringBuilder();
-
-        int pos = 0;
-        while (pos >= 0 && pos < line.length()) {
-            int c1 = line.indexOf("//", pos);
-            if (c1 > 0 && !Character.isWhitespace(line.charAt(c1 - 1))) {
-                // not a comment
-                c1 = -1;
-            }
-
-            int c2 = line.indexOf("/*", pos);
-            if (c2 > 0 && !Character.isWhitespace(line.charAt(c2 - 1))) {
-                // not a comment
-                c2 = -1;
-            }
-
-            int c = line.length();
-            int n = line.length();
-            if (c1 >= 0 || c2 >= 0) {
-                if (c1 >= 0) {
-                    c = c1;
-                }
-                if (c2 >= 0 && c2 < c) {
-                    c = c2;
-                }
-                int c3 = line.indexOf("*/", c2 + 2);
-                if (c == c2 && c3 > c2) {
-                    n = c3 + 2;
-                }
-            }
-            if (c > 0) {
-                if (sb.length() > 0) {
-                    // add a whitespace if multiple comments on one line
-                    sb.append(" ");
-                }
-                sb.append(line.substring(pos, c));
-            }
-            pos = n;
-        }
-        return sb.toString();
-    }
-
-
-    static class Counter {
-        int numRequires;
-        int numExports;
-        int numUses;
-        int numProvides;
-
-        void validate(Builder builder) {
-            assertEquals("requires", numRequires, builder.requires.size(),
-                         () -> builder.requires.stream()
-                                      .map(Module.Dependence::toString));
-            assertEquals("exports", numExports, builder.exports.size(),
-                         () -> builder.exports.entrySet().stream()
-                                      .map(e -> "exports " + e.getKey() + " to " + e.getValue()));
-            assertEquals("uses", numUses, builder.uses.size(),
-                         () -> builder.uses.stream());
-            assertEquals("provides", numProvides,
-                         (int)builder.provides.values().stream()
-                                     .flatMap(s -> s.stream())
-                                     .count(),
-                         () -> builder.provides.entrySet().stream()
-                                      .map(e -> "provides " + e.getKey() + " with " + e.getValue()));
-        }
-
-        private static void assertEquals(String msg, int expected, int got,
-                                         Supplier<Stream<String>> supplier) {
-            if (expected != got){
-                System.err.println("ERROR: mismatched " + msg +
-                        " expected: " + expected + " got: " + got );
-                supplier.get().sorted()
-                        .forEach(System.err::println);
-                throw new AssertionError("mismatched " + msg +
-                        " expected: " + expected + " got: " + got + " ");
-            }
-        }
-    }
-}
--- a/make/src/classes/build/tools/module/ModulesXmlReader.java	Tue Apr 05 18:23:10 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,162 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package build.tools.module;
-
-import javax.xml.namespace.QName;
-import javax.xml.stream.XMLEventReader;
-import javax.xml.stream.XMLInputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.events.Attribute;
-import javax.xml.stream.events.XMLEvent;
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.HashSet;
-import java.util.Set;
-
-public class ModulesXmlReader {
-
-    private ModulesXmlReader() {}
-
-    public static Set<Module> readModules(Path modulesXml)
-        throws XMLStreamException, IOException
-    {
-        Set<Module> modules = new HashSet<>();
-        try (InputStream in = new BufferedInputStream(Files.newInputStream(modulesXml))) {
-            Set<Module> mods = ModulesXmlReader.load(in);
-            modules.addAll(mods);
-        }
-        return modules;
-    }
-
-    private static final String MODULES   = "modules";
-    private static final String MODULE    = "module";
-    private static final String NAME      = "name";
-    private static final String DEPEND    = "depend";
-    private static final String EXPORT    = "export";
-    private static final String TO        = "to";
-    private static final QName  REEXPORTS = new QName("re-exports");
-    private static Set<Module> load(InputStream in)
-        throws XMLStreamException, IOException
-    {
-        Set<Module> modules = new HashSet<>();
-        XMLInputFactory factory = XMLInputFactory.newInstance();
-        XMLEventReader stream = factory.createXMLEventReader(in);
-        Module.Builder mb = null;
-        String modulename = null;
-        String pkg = null;
-        Set<String> permits = new HashSet<>();
-        while (stream.hasNext()) {
-            XMLEvent event = stream.nextEvent();
-            if (event.isStartElement()) {
-                String startTag = event.asStartElement().getName().getLocalPart();
-                switch (startTag) {
-                    case MODULES:
-                        break;
-                    case MODULE:
-                        if (mb != null) {
-                            throw new RuntimeException("end tag for module is missing");
-                        }
-                        modulename = getNextTag(stream, NAME);
-                        mb = new Module.Builder();
-                        mb.name(modulename);
-                        break;
-                    case NAME:
-                        throw new RuntimeException(event.toString());
-                    case DEPEND:
-                        boolean reexports = false;
-                        Attribute attr = event.asStartElement().getAttributeByName(REEXPORTS);
-                        if (attr != null) {
-                            String value = attr.getValue();
-                            if (value.equals("true") || value.equals("false")) {
-                                reexports = Boolean.parseBoolean(value);
-                            } else {
-                                throw new RuntimeException("unexpected attribute " + attr.toString());
-                            }
-                        }
-                        mb.require(getData(stream), reexports);
-                        break;
-                    case EXPORT:
-                        pkg = getNextTag(stream, NAME);
-                        break;
-                    case TO:
-                        permits.add(getData(stream));
-                        break;
-                    default:
-                }
-            } else if (event.isEndElement()) {
-                String endTag = event.asEndElement().getName().getLocalPart();
-                switch (endTag) {
-                    case MODULE:
-                        modules.add(mb.build());
-                        mb = null;
-                        break;
-                    case EXPORT:
-                        if (pkg == null) {
-                            throw new RuntimeException("export-to is malformed");
-                        }
-                        mb.exportTo(pkg, permits);
-                        pkg = null;
-                        permits.clear();
-                        break;
-                    default:
-                }
-            } else if (event.isCharacters()) {
-                String s = event.asCharacters().getData();
-                if (!s.trim().isEmpty()) {
-                    throw new RuntimeException("export-to is malformed");
-                }
-            }
-        }
-        return modules;
-    }
-
-    private static String getData(XMLEventReader reader)
-        throws XMLStreamException
-    {
-        XMLEvent e = reader.nextEvent();
-        if (e.isCharacters())
-            return e.asCharacters().getData();
-
-        throw new RuntimeException(e.toString());
-    }
-
-    private static String getNextTag(XMLEventReader reader, String tag)
-        throws XMLStreamException
-    {
-        XMLEvent e = reader.nextTag();
-        if (e.isStartElement()) {
-            String t = e.asStartElement().getName().getLocalPart();
-            if (!tag.equals(t)) {
-                throw new RuntimeException(e + " expected: " + tag);
-            }
-            return getData(reader);
-        }
-        throw new RuntimeException("export-to name is missing:" + e);
-    }
-}
--- a/make/src/classes/build/tools/module/ModulesXmlWriter.java	Tue Apr 05 18:23:10 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,176 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package build.tools.module;
-
-import javax.xml.namespace.QName;
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Map;
-import java.util.Set;
-
-public final class ModulesXmlWriter {
-
-    private ModulesXmlWriter() {}
-
-    public static void writeModules(Set<Module> modules, Path path)
-        throws IOException, XMLStreamException
-    {
-        writeXML(modules, path);
-    }
-
-    private static final String MODULES   = "modules";
-    private static final String MODULE    = "module";
-    private static final String NAME      = "name";
-    private static final String DEPEND    = "depend";
-    private static final String EXPORT    = "export";
-    private static final String TO        = "to";
-    private static final QName  REEXPORTS = new QName("re-exports");
-
-    private static void writeXML(Set<Module> modules, Path path)
-        throws IOException, XMLStreamException
-    {
-        XMLOutputFactory xof = XMLOutputFactory.newInstance();
-        try (OutputStream out = Files.newOutputStream(path)) {
-            int depth = 0;
-            XMLStreamWriter xtw = xof.createXMLStreamWriter(out, "UTF-8");
-            xtw.writeStartDocument("utf-8","1.0");
-            writeStartElement(xtw, MODULES, depth);
-            modules.stream()
-                   .sorted(Comparator.comparing(Module::name))
-                   .forEach(m -> writeModuleElement(xtw, m, depth+1));
-            writeEndElement(xtw, depth);
-            xtw.writeCharacters("\n");
-            xtw.writeEndDocument();
-            xtw.flush();
-            xtw.close();
-        }
-    }
-
-    private static void writeElement(XMLStreamWriter xtw,
-                                     String element,
-                                     String value,
-                                     int depth) {
-        try {
-            writeStartElement(xtw, element, depth);
-            xtw.writeCharacters(value);
-            xtw.writeEndElement();
-        } catch (XMLStreamException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private static void writeDependElement(XMLStreamWriter xtw,
-                                           Module.Dependence d,
-                                           int depth) {
-        try {
-            writeStartElement(xtw, DEPEND, depth);
-            if (d.reexport) {
-                xtw.writeAttribute("re-exports", "true");
-            }
-            xtw.writeCharacters(d.name);
-            xtw.writeEndElement();
-        } catch (XMLStreamException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private static void writeExportElement(XMLStreamWriter xtw,
-                                           String pkg,
-                                           int depth) {
-        writeExportElement(xtw, pkg, Collections.emptySet(), depth);
-    }
-
-    private static void writeExportElement(XMLStreamWriter xtw,
-                                           String pkg,
-                                           Set<String> permits,
-                                           int depth) {
-        try {
-            writeStartElement(xtw, EXPORT, depth);
-            writeElement(xtw, NAME, pkg, depth+1);
-            if (!permits.isEmpty()) {
-                permits.stream().sorted()
-                       .forEach(m -> writeElement(xtw, TO, m, depth + 1));
-            }
-            writeEndElement(xtw, depth);
-        } catch (XMLStreamException e) {
-            throw new RuntimeException(e);
-        }
-    }
-    private static void writeModuleElement(XMLStreamWriter xtw,
-                                           Module m,
-                                           int depth) {
-        try {
-            writeStartElement(xtw, MODULE, depth);
-            writeElement(xtw, NAME, m.name(), depth+1);
-            m.requires().stream().sorted(Comparator.comparing(d -> d.name))
-                        .forEach(d -> writeDependElement(xtw, d, depth+1));
-            m.exports().keySet().stream()
-                       .filter(pn -> m.exports().get(pn).isEmpty())
-                       .sorted()
-                       .forEach(pn -> writeExportElement(xtw, pn, depth+1));
-            m.exports().entrySet().stream()
-                       .filter(e -> !e.getValue().isEmpty())
-                       .sorted(Map.Entry.comparingByKey())
-                       .forEach(e -> writeExportElement(xtw, e.getKey(), e.getValue(), depth+1));
-            writeEndElement(xtw, depth);
-        } catch (XMLStreamException e) {
-            throw new RuntimeException(e);
-
-        }
-    }
-
-    /** Two spaces; the default indentation. */
-    public static final String DEFAULT_INDENT = "  ";
-
-    /** stack[depth] indicates what's been written into the current scope. */
-    private static String[] stack = new String[] { "\n",
-        "\n" + DEFAULT_INDENT,
-        "\n" + DEFAULT_INDENT + DEFAULT_INDENT,
-        "\n" + DEFAULT_INDENT + DEFAULT_INDENT + DEFAULT_INDENT};
-
-    private static void writeStartElement(XMLStreamWriter xtw,
-                                          String name,
-                                          int depth)
-        throws XMLStreamException
-    {
-        xtw.writeCharacters(stack[depth]);
-        xtw.writeStartElement(name);
-    }
-
-    private static void writeEndElement(XMLStreamWriter xtw, int depth)
-        throws XMLStreamException
-    {
-        xtw.writeCharacters(stack[depth]);
-        xtw.writeEndElement();
-    }
-}
--- a/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java	Tue Apr 05 18:23:10 2016 +0300
+++ b/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java	Tue Apr 05 09:17:15 2016 -0700
@@ -25,6 +25,7 @@
 
 package java.lang.invoke;
 
+import jdk.internal.loader.BootLoader;
 import jdk.internal.vm.annotation.Stable;
 import jdk.internal.org.objectweb.asm.ClassWriter;
 import jdk.internal.org.objectweb.asm.FieldVisitor;
@@ -36,6 +37,7 @@
 import java.lang.invoke.MethodHandles.Lookup;
 import java.lang.reflect.Field;
 import java.util.Arrays;
+import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.function.Function;
@@ -463,6 +465,7 @@
 
         static final String SPECIES_PREFIX_NAME = "Species_";
         static final String SPECIES_PREFIX_PATH = BMH + "$" + SPECIES_PREFIX_NAME;
+        static final String SPECIES_CLASS_PREFIX = SPECIES_PREFIX_PATH.replace('/', '.');
 
         static final String BMHSPECIES_DATA_EWI_SIG = "(B)" + SPECIES_DATA_SIG;
         static final String BMHSPECIES_DATA_GFC_SIG = "(" + JLS_SIG + JLC_SIG + ")" + SPECIES_DATA_SIG;
@@ -489,7 +492,15 @@
                 types, new Function<String, Class<? extends BoundMethodHandle>>() {
                     @Override
                     public Class<? extends BoundMethodHandle> apply(String types) {
-                        return generateConcreteBMHClass(types);
+                        String shortTypes = LambdaForm.shortenSignature(types);
+                        String className = SPECIES_CLASS_PREFIX + shortTypes;
+                        Class<?> c = BootLoader.loadClassOrNull(className);
+                        if (c != null) {
+                            return c.asSubclass(BoundMethodHandle.class);
+                        } else {
+                            // Not pregenerated, generate the class
+                            return generateConcreteBMHClass(shortTypes, types);
+                        }
                     }
                 });
         }
@@ -558,12 +569,49 @@
          * @param types the type signature, wherein reference types are erased to 'L'
          * @return the generated concrete BMH class
          */
-        static Class<? extends BoundMethodHandle> generateConcreteBMHClass(String types) {
+        static Class<? extends BoundMethodHandle> generateConcreteBMHClass(String shortTypes,
+                String types) {
+            final String className  = speciesInternalClassName(shortTypes);
+            byte[] classFile = generateConcreteBMHClassBytes(shortTypes, types, className);
+
+            // load class
+            InvokerBytecodeGenerator.maybeDump(className, classFile);
+            Class<? extends BoundMethodHandle> bmhClass =
+                UNSAFE.defineClass(className, classFile, 0, classFile.length,
+                                   BoundMethodHandle.class.getClassLoader(), null)
+                    .asSubclass(BoundMethodHandle.class);
+
+            return bmhClass;
+        }
+
+        /**
+         * @implNote this method is used by GenerateBMHClassesPlugin to enable
+         * ahead-of-time generation of BMH classes at link time. It does
+         * added validation since this string may be user provided.
+         */
+        static Map.Entry<String, byte[]> generateConcreteBMHClassBytes(
+                final String types) {
+            for (char c : types.toCharArray()) {
+                if ("LIJFD".indexOf(c) < 0) {
+                    throw new IllegalArgumentException("All characters must "
+                            + "correspond to a basic field type: LIJFD");
+                }
+            }
+            String shortTypes = LambdaForm.shortenSignature(types);
+            final String className  = speciesInternalClassName(shortTypes);
+            return Map.entry(className,
+                    generateConcreteBMHClassBytes(shortTypes, types, className));
+        }
+
+        private static String speciesInternalClassName(String shortTypes) {
+            return SPECIES_PREFIX_PATH + shortTypes;
+        }
+
+        static byte[] generateConcreteBMHClassBytes(final String shortTypes,
+                final String types, final String className) {
+            final String sourceFile = SPECIES_PREFIX_NAME + shortTypes;
+
             final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
-
-            String shortTypes = LambdaForm.shortenSignature(types);
-            final String className  = SPECIES_PREFIX_PATH + shortTypes;
-            final String sourceFile = SPECIES_PREFIX_NAME + shortTypes;
             final int NOT_ACC_PUBLIC = 0;  // not ACC_PUBLIC
             cw.visit(V1_6, NOT_ACC_PUBLIC + ACC_FINAL + ACC_SUPER, className, null, BMH, null);
             cw.visitSource(sourceFile, null);
@@ -699,16 +747,7 @@
 
             cw.visitEnd();
 
-            // load class
-            final byte[] classFile = cw.toByteArray();
-            InvokerBytecodeGenerator.maybeDump(className, classFile);
-            Class<? extends BoundMethodHandle> bmhClass =
-                //UNSAFE.defineAnonymousClass(BoundMethodHandle.class, classFile, null).asSubclass(BoundMethodHandle.class);
-                UNSAFE.defineClass(className, classFile, 0, classFile.length,
-                                   BoundMethodHandle.class.getClassLoader(), null)
-                    .asSubclass(BoundMethodHandle.class);
-
-            return bmhClass;
+            return cw.toByteArray();
         }
 
         private static int typeLoadOp(char t) {
--- a/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Tue Apr 05 18:23:10 2016 +0300
+++ b/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Tue Apr 05 09:17:15 2016 -0700
@@ -255,7 +255,6 @@
      */
     private static final class Recipe {
         private final List<RecipeElement> elements;
-        private final List<RecipeElement> elementsRev;
 
         public Recipe(String src, Object[] constants) {
             List<RecipeElement> el = new ArrayList<>();
@@ -294,19 +293,13 @@
                 el.add(new RecipeElement(acc.toString()));
             }
 
-            elements = new ArrayList<>(el);
-            Collections.reverse(el);
-            elementsRev = el;
+            elements = el;
         }
 
-        public Collection<RecipeElement> getElements() {
+        public List<RecipeElement> getElements() {
             return elements;
         }
 
-        public Collection<RecipeElement> getElementsReversed() {
-            return elementsRev;
-        }
-
         @Override
         public boolean equals(Object o) {
             if (this == o) return true;
@@ -1310,7 +1303,9 @@
 
             // Compose append calls. This is done in reverse because the application order is
             // reverse as well.
-            for (RecipeElement el : recipe.getElementsReversed()) {
+            List<RecipeElement> elements = recipe.getElements();
+            for (int i = elements.size() - 1; i >= 0; i--) {
+                RecipeElement el = elements.get(i);
                 MethodHandle appender;
                 switch (el.getTag()) {
                     case CONST: {
--- a/src/java.base/share/classes/java/util/AbstractList.java	Tue Apr 05 18:23:10 2016 +0300
+++ b/src/java.base/share/classes/java/util/AbstractList.java	Tue Apr 05 09:17:15 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, 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
@@ -462,10 +462,9 @@
      * @implSpec
      * This implementation returns a list that subclasses
      * {@code AbstractList}.  The subclass stores, in private fields, the
-     * offset of the subList within the backing list, the size of the subList
-     * (which can change over its lifetime), and the expected
-     * {@code modCount} value of the backing list.  There are two variants
-     * of the subclass, one of which implements {@code RandomAccess}.
+     * size of the subList (which can change over its lifetime), and the
+     * expected {@code modCount} value of the backing list.  There are two
+     * variants of the subclass, one of which implements {@code RandomAccess}.
      * If this list implements {@code RandomAccess} the returned list will
      * be an instance of the subclass that implements {@code RandomAccess}.
      *
@@ -493,11 +492,22 @@
      *         {@code (fromIndex > toIndex)}
      */
     public List<E> subList(int fromIndex, int toIndex) {
+        subListRangeCheck(fromIndex, toIndex, size());
         return (this instanceof RandomAccess ?
                 new RandomAccessSubList<>(this, fromIndex, toIndex) :
                 new SubList<>(this, fromIndex, toIndex));
     }
 
+    static void subListRangeCheck(int fromIndex, int toIndex, int size) {
+        if (fromIndex < 0)
+            throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
+        if (toIndex > size)
+            throw new IndexOutOfBoundsException("toIndex = " + toIndex);
+        if (fromIndex > toIndex)
+            throw new IllegalArgumentException("fromIndex(" + fromIndex +
+                                               ") > toIndex(" + toIndex + ")");
+    }
+
     // Comparison and hashing
 
     /**
@@ -623,174 +633,199 @@
     private String outOfBoundsMsg(int index) {
         return "Index: "+index+", Size: "+size();
     }
-}
 
-class SubList<E> extends AbstractList<E> {
-    private final AbstractList<E> l;
-    private final int offset;
-    private int size;
+    private static class SubList<E> extends AbstractList<E> {
+        private final AbstractList<E> root;
+        private final SubList<E> parent;
+        private final int offset;
+        protected int size;
 
-    SubList(AbstractList<E> list, int fromIndex, int toIndex) {
-        if (fromIndex < 0)
-            throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
-        if (toIndex > list.size())
-            throw new IndexOutOfBoundsException("toIndex = " + toIndex);
-        if (fromIndex > toIndex)
-            throw new IllegalArgumentException("fromIndex(" + fromIndex +
-                                               ") > toIndex(" + toIndex + ")");
-        l = list;
-        offset = fromIndex;
-        size = toIndex - fromIndex;
-        this.modCount = l.modCount;
+        /**
+         * Constructs a sublist of an arbitrary AbstractList, which is
+         * not a SubList itself.
+         */
+        public SubList(AbstractList<E> root, int fromIndex, int toIndex) {
+            this.root = root;
+            this.parent = null;
+            this.offset = fromIndex;
+            this.size = toIndex - fromIndex;
+            this.modCount = root.modCount;
+        }
+
+        /**
+         * Constructs a sublist of another SubList.
+         */
+        protected SubList(SubList<E> parent, int fromIndex, int toIndex) {
+            this.root = parent.root;
+            this.parent = parent;
+            this.offset = parent.offset + fromIndex;
+            this.size = toIndex - fromIndex;
+            this.modCount = root.modCount;
+        }
+
+        public E set(int index, E element) {
+            Objects.checkIndex(index, size);
+            checkForComodification();
+            return root.set(offset + index, element);
+        }
+
+        public E get(int index) {
+            Objects.checkIndex(index, size);
+            checkForComodification();
+            return root.get(offset + index);
+        }
+
+        public int size() {
+            checkForComodification();
+            return size;
+        }
+
+        public void add(int index, E element) {
+            rangeCheckForAdd(index);
+            checkForComodification();
+            root.add(offset + index, element);
+            updateSizeAndModCount(1);
+        }
+
+        public E remove(int index) {
+            Objects.checkIndex(index, size);
+            checkForComodification();
+            E result = root.remove(offset + index);
+            updateSizeAndModCount(-1);
+            return result;
+        }
+
+        protected void removeRange(int fromIndex, int toIndex) {
+            checkForComodification();
+            root.removeRange(offset + fromIndex, offset + toIndex);
+            updateSizeAndModCount(fromIndex - toIndex);
+        }
+
+        public boolean addAll(Collection<? extends E> c) {
+            return addAll(size, c);
+        }
+
+        public boolean addAll(int index, Collection<? extends E> c) {
+            rangeCheckForAdd(index);
+            int cSize = c.size();
+            if (cSize==0)
+                return false;
+            checkForComodification();
+            root.addAll(offset + index, c);
+            updateSizeAndModCount(cSize);
+            return true;
+        }
+
+        public Iterator<E> iterator() {
+            return listIterator();
+        }
+
+        public ListIterator<E> listIterator(int index) {
+            checkForComodification();
+            rangeCheckForAdd(index);
+
+            return new ListIterator<E>() {
+                private final ListIterator<E> i =
+                        root.listIterator(offset + index);
+
+                public boolean hasNext() {
+                    return nextIndex() < size;
+                }
+
+                public E next() {
+                    if (hasNext())
+                        return i.next();
+                    else
+                        throw new NoSuchElementException();
+                }
+
+                public boolean hasPrevious() {
+                    return previousIndex() >= 0;
+                }
+
+                public E previous() {
+                    if (hasPrevious())
+                        return i.previous();
+                    else
+                        throw new NoSuchElementException();
+                }
+
+                public int nextIndex() {
+                    return i.nextIndex() - offset;
+                }
+
+                public int previousIndex() {
+                    return i.previousIndex() - offset;
+                }
+
+                public void remove() {
+                    i.remove();
+                    updateSizeAndModCount(-1);
+                }
+
+                public void set(E e) {
+                    i.set(e);
+                }
+
+                public void add(E e) {
+                    i.add(e);
+                    updateSizeAndModCount(1);
+                }
+            };
+        }
+
+        public List<E> subList(int fromIndex, int toIndex) {
+            subListRangeCheck(fromIndex, toIndex, size);
+            return new SubList<>(this, fromIndex, toIndex);
+        }
+
+        private void rangeCheckForAdd(int index) {
+            if (index < 0 || index > size)
+                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+        }
+
+        private String outOfBoundsMsg(int index) {
+            return "Index: "+index+", Size: "+size;
+        }
+
+        private void checkForComodification() {
+            if (root.modCount != this.modCount)
+                throw new ConcurrentModificationException();
+        }
+
+        private void updateSizeAndModCount(int sizeChange) {
+            SubList<E> slist = this;
+            do {
+                slist.size += sizeChange;
+                slist.modCount = root.modCount;
+                slist = slist.parent;
+            } while (slist != null);
+        }
     }
 
-    public E set(int index, E element) {
-        rangeCheck(index);
-        checkForComodification();
-        return l.set(index+offset, element);
-    }
+    private static class RandomAccessSubList<E>
+            extends SubList<E> implements RandomAccess {
 
-    public E get(int index) {
-        rangeCheck(index);
-        checkForComodification();
-        return l.get(index+offset);
-    }
+        /**
+         * Constructs a sublist of an arbitrary AbstractList, which is
+         * not a RandomAccessSubList itself.
+         */
+        RandomAccessSubList(AbstractList<E> root,
+                int fromIndex, int toIndex) {
+            super(root, fromIndex, toIndex);
+        }
 
-    public int size() {
-        checkForComodification();
-        return size;
-    }
+        /**
+         * Constructs a sublist of another RandomAccessSubList.
+         */
+        RandomAccessSubList(RandomAccessSubList<E> parent,
+                int fromIndex, int toIndex) {
+            super(parent, fromIndex, toIndex);
+        }
 
-    public void add(int index, E element) {
-        rangeCheckForAdd(index);
-        checkForComodification();
-        l.add(index+offset, element);
-        this.modCount = l.modCount;
-        size++;
-    }
-
-    public E remove(int index) {
-        rangeCheck(index);
-        checkForComodification();
-        E result = l.remove(index+offset);
-        this.modCount = l.modCount;
-        size--;
-        return result;
-    }
-
-    protected void removeRange(int fromIndex, int toIndex) {
-        checkForComodification();
-        l.removeRange(fromIndex+offset, toIndex+offset);
-        this.modCount = l.modCount;
-        size -= (toIndex-fromIndex);
-    }
-
-    public boolean addAll(Collection<? extends E> c) {
-        return addAll(size, c);
-    }
-
-    public boolean addAll(int index, Collection<? extends E> c) {
-        rangeCheckForAdd(index);
-        int cSize = c.size();
-        if (cSize==0)
-            return false;
-
-        checkForComodification();
-        l.addAll(offset+index, c);
-        this.modCount = l.modCount;
-        size += cSize;
-        return true;
-    }
-
-    public Iterator<E> iterator() {
-        return listIterator();
-    }
-
-    public ListIterator<E> listIterator(final int index) {
-        checkForComodification();
-        rangeCheckForAdd(index);
-
-        return new ListIterator<E>() {
-            private final ListIterator<E> i = l.listIterator(index+offset);
-
-            public boolean hasNext() {
-                return nextIndex() < size;
-            }
-
-            public E next() {
-                if (hasNext())
-                    return i.next();
-                else
-                    throw new NoSuchElementException();
-            }
-
-            public boolean hasPrevious() {
-                return previousIndex() >= 0;
-            }
-
-            public E previous() {
-                if (hasPrevious())
-                    return i.previous();
-                else
-                    throw new NoSuchElementException();
-            }
-
-            public int nextIndex() {
-                return i.nextIndex() - offset;
-            }
-
-            public int previousIndex() {
-                return i.previousIndex() - offset;
-            }
-
-            public void remove() {
-                i.remove();
-                SubList.this.modCount = l.modCount;
-                size--;
-            }
-
-            public void set(E e) {
-                i.set(e);
-            }
-
-            public void add(E e) {
-                i.add(e);
-                SubList.this.modCount = l.modCount;
-                size++;
-            }
-        };
-    }
-
-    public List<E> subList(int fromIndex, int toIndex) {
-        return new SubList<>(this, fromIndex, toIndex);
-    }
-
-    private void rangeCheck(int index) {
-        if (index < 0 || index >= size)
-            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
-    }
-
-    private void rangeCheckForAdd(int index) {
-        if (index < 0 || index > size)
-            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
-    }
-
-    private String outOfBoundsMsg(int index) {
-        return "Index: "+index+", Size: "+size;
-    }
-
-    private void checkForComodification() {
-        if (this.modCount != l.modCount)
-            throw new ConcurrentModificationException();
+        public List<E> subList(int fromIndex, int toIndex) {
+            subListRangeCheck(fromIndex, toIndex, size);
+            return new RandomAccessSubList<>(this, fromIndex, toIndex);
+        }
     }
 }
-
-class RandomAccessSubList<E> extends SubList<E> implements RandomAccess {
-    RandomAccessSubList(AbstractList<E> list, int fromIndex, int toIndex) {
-        super(list, fromIndex, toIndex);
-    }
-
-    public List<E> subList(int fromIndex, int toIndex) {
-        return new RandomAccessSubList<>(this, fromIndex, toIndex);
-    }
-}
--- a/src/java.base/share/classes/java/util/ArrayList.java	Tue Apr 05 18:23:10 2016 +0300
+++ b/src/java.base/share/classes/java/util/ArrayList.java	Tue Apr 05 09:17:15 2016 -0700
@@ -432,8 +432,7 @@
      * @throws IndexOutOfBoundsException {@inheritDoc}
      */
     public E get(int index) {
-        rangeCheck(index);
-
+        Objects.checkIndex(index, size);
         return elementData(index);
     }
 
@@ -447,8 +446,7 @@
      * @throws IndexOutOfBoundsException {@inheritDoc}
      */
     public E set(int index, E element) {
-        rangeCheck(index);
-
+        Objects.checkIndex(index, size);
         E oldValue = elementData(index);
         elementData[index] = element;
         return oldValue;
@@ -511,7 +509,7 @@
      * @throws IndexOutOfBoundsException {@inheritDoc}
      */
     public E remove(int index) {
-        rangeCheck(index);
+        Objects.checkIndex(index, size);
 
         modCount++;
         E oldValue = elementData(index);
@@ -680,17 +678,6 @@
     }
 
     /**
-     * Checks if the given index is in range.  If not, throws an appropriate
-     * runtime exception.  This method does *not* check if the index is
-     * negative: It is always used immediately prior to an array access,
-     * which throws an ArrayIndexOutOfBoundsException if index is negative.
-     */
-    private void rangeCheck(int index) {
-        if (index >= size)
-            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
-    }
-
-    /**
      * A version of rangeCheck used by add and addAll.
      */
     private void rangeCheckForAdd(int index) {
@@ -854,8 +841,7 @@
      * @throws IndexOutOfBoundsException {@inheritDoc}
      */
     public ListIterator<E> listIterator(int index) {
-        if (index < 0 || index > size)
-            throw new IndexOutOfBoundsException("Index: "+index);
+        rangeCheckForAdd(index);
         return new ListItr(index);
     }
 
@@ -1042,76 +1028,75 @@
      */
     public List<E> subList(int fromIndex, int toIndex) {
         subListRangeCheck(fromIndex, toIndex, size);
-        return new SubList(this, 0, fromIndex, toIndex);
+        return new SubList<>(this, fromIndex, toIndex);
     }
 
-    static void subListRangeCheck(int fromIndex, int toIndex, int size) {
-        if (fromIndex < 0)
-            throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
-        if (toIndex > size)
-            throw new IndexOutOfBoundsException("toIndex = " + toIndex);
-        if (fromIndex > toIndex)
-            throw new IllegalArgumentException("fromIndex(" + fromIndex +
-                                               ") > toIndex(" + toIndex + ")");
-    }
+    private static class SubList<E> extends AbstractList<E> implements RandomAccess {
+        private final ArrayList<E> root;
+        private final SubList<E> parent;
+        private final int offset;
+        private int size;
 
-    private class SubList extends AbstractList<E> implements RandomAccess {
-        private final AbstractList<E> parent;
-        private final int parentOffset;
-        private final int offset;
-        int size;
-
-        SubList(AbstractList<E> parent,
-                int offset, int fromIndex, int toIndex) {
-            this.parent = parent;
-            this.parentOffset = fromIndex;
-            this.offset = offset + fromIndex;
+        /**
+         * Constructs a sublist of an arbitrary ArrayList.
+         */
+        public SubList(ArrayList<E> root, int fromIndex, int toIndex) {
+            this.root = root;
+            this.parent = null;
+            this.offset = fromIndex;
             this.size = toIndex - fromIndex;
-            this.modCount = ArrayList.this.modCount;
+            this.modCount = root.modCount;
         }
 
-        public E set(int index, E e) {
-            rangeCheck(index);
+        /**
+         * Constructs a sublist of another SubList.
+         */
+        private SubList(SubList<E> parent, int fromIndex, int toIndex) {
+            this.root = parent.root;
+            this.parent = parent;
+            this.offset = parent.offset + fromIndex;
+            this.size = toIndex - fromIndex;
+            this.modCount = root.modCount;
+        }
+
+        public E set(int index, E element) {
+            Objects.checkIndex(index, size);
             checkForComodification();
-            E oldValue = ArrayList.this.elementData(offset + index);
-            ArrayList.this.elementData[offset + index] = e;
+            E oldValue = root.elementData(offset + index);
+            root.elementData[offset + index] = element;
             return oldValue;
         }
 
         public E get(int index) {
-            rangeCheck(index);
+            Objects.checkIndex(index, size);
             checkForComodification();
-            return ArrayList.this.elementData(offset + index);
+            return root.elementData(offset + index);
         }
 
         public int size() {
             checkForComodification();
-            return this.size;
+            return size;
         }
 
-        public void add(int index, E e) {
+        public void add(int index, E element) {
             rangeCheckForAdd(index);
             checkForComodification();
-            parent.add(parentOffset + index, e);
-            this.modCount = parent.modCount;
-            this.size++;
+            root.add(offset + index, element);
+            updateSizeAndModCount(1);
         }
 
         public E remove(int index) {
-            rangeCheck(index);
+            Objects.checkIndex(index, size);
             checkForComodification();
-            E result = parent.remove(parentOffset + index);
-            this.modCount = parent.modCount;
-            this.size--;
+            E result = root.remove(offset + index);
+            updateSizeAndModCount(-1);
             return result;
         }
 
         protected void removeRange(int fromIndex, int toIndex) {
             checkForComodification();
-            parent.removeRange(parentOffset + fromIndex,
-                               parentOffset + toIndex);
-            this.modCount = parent.modCount;
-            this.size -= toIndex - fromIndex;
+            root.removeRange(offset + fromIndex, offset + toIndex);
+            updateSizeAndModCount(fromIndex - toIndex);
         }
 
         public boolean addAll(Collection<? extends E> c) {
@@ -1123,11 +1108,9 @@
             int cSize = c.size();
             if (cSize==0)
                 return false;
-
             checkForComodification();
-            parent.addAll(parentOffset + index, c);
-            this.modCount = parent.modCount;
-            this.size += cSize;
+            root.addAll(offset + index, c);
+            updateSizeAndModCount(cSize);
             return true;
         }
 
@@ -1135,15 +1118,14 @@
             return listIterator();
         }
 
-        public ListIterator<E> listIterator(final int index) {
+        public ListIterator<E> listIterator(int index) {
             checkForComodification();
             rangeCheckForAdd(index);
-            final int offset = this.offset;
 
             return new ListIterator<E>() {
                 int cursor = index;
                 int lastRet = -1;
-                int expectedModCount = ArrayList.this.modCount;
+                int expectedModCount = root.modCount;
 
                 public boolean hasNext() {
                     return cursor != SubList.this.size;
@@ -1155,7 +1137,7 @@
                     int i = cursor;
                     if (i >= SubList.this.size)
                         throw new NoSuchElementException();
-                    Object[] elementData = ArrayList.this.elementData;
+                    Object[] elementData = root.elementData;
                     if (offset + i >= elementData.length)
                         throw new ConcurrentModificationException();
                     cursor = i + 1;
@@ -1172,7 +1154,7 @@
                     int i = cursor - 1;
                     if (i < 0)
                         throw new NoSuchElementException();
-                    Object[] elementData = ArrayList.this.elementData;
+                    Object[] elementData = root.elementData;
                     if (offset + i >= elementData.length)
                         throw new ConcurrentModificationException();
                     cursor = i;
@@ -1187,7 +1169,7 @@
                     if (i >= size) {
                         return;
                     }
-                    final Object[] elementData = ArrayList.this.elementData;
+                    final Object[] elementData = root.elementData;
                     if (offset + i >= elementData.length) {
                         throw new ConcurrentModificationException();
                     }
@@ -1216,7 +1198,7 @@
                         SubList.this.remove(lastRet);
                         cursor = lastRet;
                         lastRet = -1;
-                        expectedModCount = ArrayList.this.modCount;
+                        expectedModCount = root.modCount;
                     } catch (IndexOutOfBoundsException ex) {
                         throw new ConcurrentModificationException();
                     }
@@ -1228,7 +1210,7 @@
                     checkForComodification();
 
                     try {
-                        ArrayList.this.set(offset + lastRet, e);
+                        root.set(offset + lastRet, e);
                     } catch (IndexOutOfBoundsException ex) {
                         throw new ConcurrentModificationException();
                     }
@@ -1242,14 +1224,14 @@
                         SubList.this.add(i, e);
                         cursor = i + 1;
                         lastRet = -1;
-                        expectedModCount = ArrayList.this.modCount;
+                        expectedModCount = root.modCount;
                     } catch (IndexOutOfBoundsException ex) {
                         throw new ConcurrentModificationException();
                     }
                 }
 
                 final void checkForComodification() {
-                    if (expectedModCount != ArrayList.this.modCount)
+                    if (root.modCount != expectedModCount)
                         throw new ConcurrentModificationException();
                 }
             };
@@ -1257,12 +1239,7 @@
 
         public List<E> subList(int fromIndex, int toIndex) {
             subListRangeCheck(fromIndex, toIndex, size);
-            return new SubList(this, offset, fromIndex, toIndex);
-        }
-
-        private void rangeCheck(int index) {
-            if (index < 0 || index >= this.size)
-                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+            return new SubList<>(this, fromIndex, toIndex);
         }
 
         private void rangeCheckForAdd(int index) {
@@ -1275,13 +1252,24 @@
         }
 
         private void checkForComodification() {
-            if (ArrayList.this.modCount != this.modCount)
+            if (root.modCount != modCount)
                 throw new ConcurrentModificationException();
         }
 
+        private void updateSizeAndModCount(int sizeChange) {
+            SubList<E> slist = this;
+            do {
+                slist.size += sizeChange;
+                slist.modCount = root.modCount;
+                slist = slist.parent;
+            } while (slist != null);
+        }
+
         public Spliterator<E> spliterator() {
             checkForComodification();
 
+            // ArrayListSpliterator is not used because late-binding logic
+            // is different here
             return new Spliterator<>() {
                 private int index = offset; // current index, modified on advance/split
                 private int fence = -1; // -1 until used; then one past last index
@@ -1298,8 +1286,9 @@
 
                 public ArrayListSpliterator<E> trySplit() {
                     int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
+                    // ArrayListSpliterator could be used here as the source is already bound
                     return (lo >= mid) ? null : // divide range in half unless too small
-                        new ArrayListSpliterator<>(ArrayList.this, lo, index = mid,
+                        new ArrayListSpliterator<>(root, lo, index = mid,
                                                    expectedModCount);
                 }
 
@@ -1308,9 +1297,9 @@
                     int hi = getFence(), i = index;
                     if (i < hi) {
                         index = i + 1;
-                        @SuppressWarnings("unchecked") E e = (E)elementData[i];
+                        @SuppressWarnings("unchecked") E e = (E)root.elementData[i];
                         action.accept(e);
-                        if (ArrayList.this.modCount != expectedModCount)
+                        if (root.modCount != expectedModCount)
                             throw new ConcurrentModificationException();
                         return true;
                     }
@@ -1320,7 +1309,7 @@
                 public void forEachRemaining(Consumer<? super E> action) {
                     Objects.requireNonNull(action);
                     int i, hi, mc; // hoist accesses and checks from loop
-                    ArrayList<E> lst = ArrayList.this;
+                    ArrayList<E> lst = root;
                     Object[] a;
                     if ((a = lst.elementData) != null) {
                         if ((hi = fence) < 0) {
--- a/src/java.base/share/classes/java/util/GregorianCalendar.java	Tue Apr 05 18:23:10 2016 +0300
+++ b/src/java.base/share/classes/java/util/GregorianCalendar.java	Tue Apr 05 09:17:15 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -1189,37 +1189,33 @@
         case HOUR:
         case HOUR_OF_DAY:
             {
-                int unit = max + 1; // 12 or 24 hours
-                int h = internalGet(field);
-                int nh = (h + amount) % unit;
-                if (nh < 0) {
-                    nh += unit;
+                int rolledValue = getRolledValue(internalGet(field), amount, min, max);
+                int hourOfDay = rolledValue;
+                if (field == HOUR && internalGet(AM_PM) == PM) {
+                    hourOfDay += 12;
                 }
-                time += ONE_HOUR * (nh - h);
 
-                // The day might have changed, which could happen if
-                // the daylight saving time transition brings it to
-                // the next day, although it's very unlikely. But we
-                // have to make sure not to change the larger fields.
+                // Create the current date/time value to perform wall-clock-based
+                // roll.
                 CalendarDate d = calsys.getCalendarDate(time, getZone());
-                if (internalGet(DAY_OF_MONTH) != d.getDayOfMonth()) {
-                    d.setDate(internalGet(YEAR),
-                              internalGet(MONTH) + 1,
-                              internalGet(DAY_OF_MONTH));
-                    if (field == HOUR) {
-                        assert (internalGet(AM_PM) == PM);
-                        d.addHours(+12); // restore PM
+                d.setHours(hourOfDay);
+                time = calsys.getTime(d);
+
+                // If we stay on the same wall-clock time, try the next or previous hour.
+                if (internalGet(HOUR_OF_DAY) == d.getHours()) {
+                    hourOfDay = getRolledValue(rolledValue, amount > 0 ? +1 : -1, min, max);
+                    if (field == HOUR && internalGet(AM_PM) == PM) {
+                        hourOfDay += 12;
                     }
+                    d.setHours(hourOfDay);
                     time = calsys.getTime(d);
                 }
-                int hourOfDay = d.getHours();
-                internalSet(field, hourOfDay % unit);
-                if (field == HOUR) {
-                    internalSet(HOUR_OF_DAY, hourOfDay);
-                } else {
-                    internalSet(AM_PM, hourOfDay / 12);
-                    internalSet(HOUR, hourOfDay % 12);
-                }
+                // Get the new hourOfDay value which might have changed due to a DST transition.
+                hourOfDay = d.getHours();
+                // Update the hour related fields
+                internalSet(HOUR_OF_DAY, hourOfDay);
+                internalSet(AM_PM, hourOfDay / 12);
+                internalSet(HOUR, hourOfDay % 12);
 
                 // Time zone offset and/or daylight saving might have changed.
                 int zoneOffset = d.getZoneOffset();
--- a/src/java.base/share/classes/java/util/concurrent/TimeUnit.java	Tue Apr 05 18:23:10 2016 +0300
+++ b/src/java.base/share/classes/java/util/concurrent/TimeUnit.java	Tue Apr 05 09:17:15 2016 -0700
@@ -75,137 +75,94 @@
     /**
      * Time unit representing one thousandth of a microsecond.
      */
-    NANOSECONDS {
-        public long toNanos(long d)   { return d; }
-        public long toMicros(long d)  { return d/(C1/C0); }
-        public long toMillis(long d)  { return d/(C2/C0); }
-        public long toSeconds(long d) { return d/(C3/C0); }
-        public long toMinutes(long d) { return d/(C4/C0); }
-        public long toHours(long d)   { return d/(C5/C0); }
-        public long toDays(long d)    { return d/(C6/C0); }
-        public long convert(long d, TimeUnit u) { return u.toNanos(d); }
-        int excessNanos(long d, long m) { return (int)(d - (m*C2)); }
-    },
-
+    NANOSECONDS(TimeUnit.NANO_SCALE),
     /**
      * Time unit representing one thousandth of a millisecond.
      */
-    MICROSECONDS {
-        public long toNanos(long d)   { return x(d, C1/C0, MAX/(C1/C0)); }
-        public long toMicros(long d)  { return d; }
-        public long toMillis(long d)  { return d/(C2/C1); }
-        public long toSeconds(long d) { return d/(C3/C1); }
-        public long toMinutes(long d) { return d/(C4/C1); }
-        public long toHours(long d)   { return d/(C5/C1); }
-        public long toDays(long d)    { return d/(C6/C1); }
-        public long convert(long d, TimeUnit u) { return u.toMicros(d); }
-        int excessNanos(long d, long m) { return (int)((d*C1) - (m*C2)); }
-    },
-
+    MICROSECONDS(TimeUnit.MICRO_SCALE),
     /**
      * Time unit representing one thousandth of a second.
      */
-    MILLISECONDS {
-        public long toNanos(long d)   { return x(d, C2/C0, MAX/(C2/C0)); }
-        public long toMicros(long d)  { return x(d, C2/C1, MAX/(C2/C1)); }
-        public long toMillis(long d)  { return d; }
-        public long toSeconds(long d) { return d/(C3/C2); }
-        public long toMinutes(long d) { return d/(C4/C2); }
-        public long toHours(long d)   { return d/(C5/C2); }
-        public long toDays(long d)    { return d/(C6/C2); }
-        public long convert(long d, TimeUnit u) { return u.toMillis(d); }
-        int excessNanos(long d, long m) { return 0; }
-    },
-
+    MILLISECONDS(TimeUnit.MILLI_SCALE),
     /**
      * Time unit representing one second.
      */
-    SECONDS {
-        public long toNanos(long d)   { return x(d, C3/C0, MAX/(C3/C0)); }
-        public long toMicros(long d)  { return x(d, C3/C1, MAX/(C3/C1)); }
-        public long toMillis(long d)  { return x(d, C3/C2, MAX/(C3/C2)); }
-        public long toSeconds(long d) { return d; }
-        public long toMinutes(long d) { return d/(C4/C3); }
-        public long toHours(long d)   { return d/(C5/C3); }
-        public long toDays(long d)    { return d/(C6/C3); }
-        public long convert(long d, TimeUnit u) { return u.toSeconds(d); }
-        int excessNanos(long d, long m) { return 0; }
-    },
-
+    SECONDS(TimeUnit.SECOND_SCALE),
     /**
      * Time unit representing sixty seconds.
      * @since 1.6
      */
-    MINUTES {
-        public long toNanos(long d)   { return x(d, C4/C0, MAX/(C4/C0)); }
-        public long toMicros(long d)  { return x(d, C4/C1, MAX/(C4/C1)); }
-        public long toMillis(long d)  { return x(d, C4/C2, MAX/(C4/C2)); }
-        public long toSeconds(long d) { return x(d, C4/C3, MAX/(C4/C3)); }
-        public long toMinutes(long d) { return d; }
-        public long toHours(long d)   { return d/(C5/C4); }
-        public long toDays(long d)    { return d/(C6/C4); }
-        public long convert(long d, TimeUnit u) { return u.toMinutes(d); }
-        int excessNanos(long d, long m) { return 0; }
-    },
-
+    MINUTES(TimeUnit.MINUTE_SCALE),
     /**
      * Time unit representing sixty minutes.
      * @since 1.6
      */
-    HOURS {
-        public long toNanos(long d)   { return x(d, C5/C0, MAX/(C5/C0)); }
-        public long toMicros(long d)  { return x(d, C5/C1, MAX/(C5/C1)); }
-        public long toMillis(long d)  { return x(d, C5/C2, MAX/(C5/C2)); }
-        public long toSeconds(long d) { return x(d, C5/C3, MAX/(C5/C3)); }
-        public long toMinutes(long d) { return x(d, C5/C4, MAX/(C5/C4)); }
-        public long toHours(long d)   { return d; }
-        public long toDays(long d)    { return d/(C6/C5); }
-        public long convert(long d, TimeUnit u) { return u.toHours(d); }
-        int excessNanos(long d, long m) { return 0; }
-    },
-
+    HOURS(TimeUnit.HOUR_SCALE),
     /**
      * Time unit representing twenty four hours.
      * @since 1.6
      */
-    DAYS {
-        public long toNanos(long d)   { return x(d, C6/C0, MAX/(C6/C0)); }
-        public long toMicros(long d)  { return x(d, C6/C1, MAX/(C6/C1)); }
-        public long toMillis(long d)  { return x(d, C6/C2, MAX/(C6/C2)); }
-        public long toSeconds(long d) { return x(d, C6/C3, MAX/(C6/C3)); }
-        public long toMinutes(long d) { return x(d, C6/C4, MAX/(C6/C4)); }
-        public long toHours(long d)   { return x(d, C6/C5, MAX/(C6/C5)); }
-        public long toDays(long d)    { return d; }
-        public long convert(long d, TimeUnit u) { return u.toDays(d); }
-        int excessNanos(long d, long m) { return 0; }
-    };
+    DAYS(TimeUnit.DAY_SCALE);
 
-    // Handy constants for conversion methods
-    static final long C0 = 1L;
-    static final long C1 = C0 * 1000L;
-    static final long C2 = C1 * 1000L;
-    static final long C3 = C2 * 1000L;
-    static final long C4 = C3 * 60L;
-    static final long C5 = C4 * 60L;
-    static final long C6 = C5 * 24L;
+    // Scales as constants
+    private static final long NANO_SCALE   = 1L;
+    private static final long MICRO_SCALE  = 1000L * NANO_SCALE;
+    private static final long MILLI_SCALE  = 1000L * MICRO_SCALE;
+    private static final long SECOND_SCALE = 1000L * MILLI_SCALE;
+    private static final long MINUTE_SCALE = 60L * SECOND_SCALE;
+    private static final long HOUR_SCALE   = 60L * MINUTE_SCALE;
+    private static final long DAY_SCALE    = 24L * HOUR_SCALE;
 
-    static final long MAX = Long.MAX_VALUE;
+    /*
+     * Instances cache conversion ratios and saturation cutoffs for
+     * the units up through SECONDS. Other cases compute them, in
+     * method cvt.
+     */
+
+    private final long scale;
+    private final long maxNanos;
+    private final long maxMicros;
+    private final long maxMillis;
+    private final long maxSecs;
+    private final long microRatio;
+    private final int milliRatio;   // fits in 32 bits
+    private final int secRatio;     // fits in 32 bits
+
+    private TimeUnit(long s) {
+        this.scale = s;
+        this.maxNanos = Long.MAX_VALUE / s;
+        long ur = (s >= MICRO_SCALE) ? (s / MICRO_SCALE) : (MICRO_SCALE / s);
+        this.microRatio = ur;
+        this.maxMicros = Long.MAX_VALUE / ur;
+        long mr = (s >= MILLI_SCALE) ? (s / MILLI_SCALE) : (MILLI_SCALE / s);
+        this.milliRatio = (int)mr;
+        this.maxMillis = Long.MAX_VALUE / mr;
+        long sr = (s >= SECOND_SCALE) ? (s / SECOND_SCALE) : (SECOND_SCALE / s);
+        this.secRatio = (int)sr;
+        this.maxSecs = Long.MAX_VALUE / sr;
+    }
 
     /**
-     * Scale d by m, checking for overflow.
-     * This has a short name to make above code more readable.
+     * General conversion utility.
+     *
+     * @param d duration
+     * @param dst result unit scale
+     * @param src source unit scale
      */
-    static long x(long d, long m, long over) {
-        if (d > +over) return Long.MAX_VALUE;
-        if (d < -over) return Long.MIN_VALUE;
-        return d * m;
+    private static long cvt(long d, long dst, long src) {
+        long r, m;
+        if (src == dst)
+            return d;
+        else if (src < dst)
+            return d / (dst / src);
+        else if (d > (m = Long.MAX_VALUE / (r = src / dst)))
+            return Long.MAX_VALUE;
+        else if (d < -m)
+            return Long.MIN_VALUE;
+        else
+            return d * r;
     }
 
-    // To maintain full signature compatibility with 1.5, and to improve the
-    // clarity of the generated javadoc (see 6287639: Abstract methods in
-    // enum classes should not be listed as abstract), method convert
-    // etc. are not declared abstract but otherwise act as abstract methods.
-
     /**
      * Converts the given time duration in the given unit to this unit.
      * Conversions from finer to coarser granularities truncate, so
@@ -221,11 +178,17 @@
      * @param sourceDuration the time duration in the given {@code sourceUnit}
      * @param sourceUnit the unit of the {@code sourceDuration} argument
      * @return the converted duration in this unit,
-     * or {@code Long.MIN_VALUE} if conversion would negatively
-     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
+     * or {@code Long.MIN_VALUE} if conversion would negatively overflow,
+     * or {@code Long.MAX_VALUE} if it would positively overflow.
      */
     public long convert(long sourceDuration, TimeUnit sourceUnit) {
-        throw new AbstractMethodError();
+        switch (this) {
+        case NANOSECONDS:  return sourceUnit.toNanos(sourceDuration);
+        case MICROSECONDS: return sourceUnit.toMicros(sourceDuration);
+        case MILLISECONDS: return sourceUnit.toMillis(sourceDuration);
+        case SECONDS:      return sourceUnit.toSeconds(sourceDuration);
+        default: return cvt(sourceDuration, scale, sourceUnit.scale);
+        }
     }
 
     /**
@@ -233,11 +196,19 @@
      * {@link #convert(long, TimeUnit) NANOSECONDS.convert(duration, this)}.
      * @param duration the duration
      * @return the converted duration,
-     * or {@code Long.MIN_VALUE} if conversion would negatively
-     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
+     * or {@code Long.MIN_VALUE} if conversion would negatively overflow,
+     * or {@code Long.MAX_VALUE} if it would positively overflow.
      */
     public long toNanos(long duration) {
-        throw new AbstractMethodError();
+        long s, m;
+        if ((s = scale) == NANO_SCALE)
+            return duration;
+        else if (duration > (m = maxNanos))
+            return Long.MAX_VALUE;
+        else if (duration < -m)
+            return Long.MIN_VALUE;
+        else
+            return duration * s;
     }
 
     /**
@@ -245,11 +216,21 @@
      * {@link #convert(long, TimeUnit) MICROSECONDS.convert(duration, this)}.
      * @param duration the duration
      * @return the converted duration,
-     * or {@code Long.MIN_VALUE} if conversion would negatively
-     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
+     * or {@code Long.MIN_VALUE} if conversion would negatively overflow,
+     * or {@code Long.MAX_VALUE} if it would positively overflow.
      */
     public long toMicros(long duration) {
-        throw new AbstractMethodError();
+        long s, m;
+        if ((s = scale) == MICRO_SCALE)
+            return duration;
+        else if (s < MICRO_SCALE)
+            return duration / microRatio;
+        else if (duration > (m = maxMicros))
+            return Long.MAX_VALUE;
+        else if (duration < -m)
+            return Long.MIN_VALUE;
+        else
+            return duration * microRatio;
     }
 
     /**
@@ -257,11 +238,21 @@
      * {@link #convert(long, TimeUnit) MILLISECONDS.convert(duration, this)}.
      * @param duration the duration
      * @return the converted duration,
-     * or {@code Long.MIN_VALUE} if conversion would negatively
-     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
+     * or {@code Long.MIN_VALUE} if conversion would negatively overflow,
+     * or {@code Long.MAX_VALUE} if it would positively overflow.
      */
     public long toMillis(long duration) {
-        throw new AbstractMethodError();
+        long s, m;
+        if ((s = scale) == MILLI_SCALE)
+            return duration;
+        else if (s < MILLI_SCALE)
+            return duration / milliRatio;
+        else if (duration > (m = maxMillis))
+            return Long.MAX_VALUE;
+        else if (duration < -m)
+            return Long.MIN_VALUE;
+        else
+            return duration * milliRatio;
     }
 
     /**
@@ -269,11 +260,21 @@
      * {@link #convert(long, TimeUnit) SECONDS.convert(duration, this)}.
      * @param duration the duration
      * @return the converted duration,
-     * or {@code Long.MIN_VALUE} if conversion would negatively
-     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
+     * or {@code Long.MIN_VALUE} if conversion would negatively overflow,
+     * or {@code Long.MAX_VALUE} if it would positively overflow.
      */
     public long toSeconds(long duration) {
-        throw new AbstractMethodError();
+        long s, m;
+        if ((s = scale) == SECOND_SCALE)
+            return duration;
+        else if (s < SECOND_SCALE)
+            return duration / secRatio;
+        else if (duration > (m = maxSecs))
+            return Long.MAX_VALUE;
+        else if (duration < -m)
+            return Long.MIN_VALUE;
+        else
+            return duration * secRatio;
     }
 
     /**
@@ -281,12 +282,12 @@
      * {@link #convert(long, TimeUnit) MINUTES.convert(duration, this)}.
      * @param duration the duration
      * @return the converted duration,
-     * or {@code Long.MIN_VALUE} if conversion would negatively
-     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
+     * or {@code Long.MIN_VALUE} if conversion would negatively overflow,
+     * or {@code Long.MAX_VALUE} if it would positively overflow.
      * @since 1.6
      */
     public long toMinutes(long duration) {
-        throw new AbstractMethodError();
+        return cvt(duration, MINUTE_SCALE, scale);
     }
 
     /**
@@ -294,12 +295,12 @@
      * {@link #convert(long, TimeUnit) HOURS.convert(duration, this)}.
      * @param duration the duration
      * @return the converted duration,
-     * or {@code Long.MIN_VALUE} if conversion would negatively
-     * overflow, or {@code Long.MAX_VALUE} if it would positively overflow.
+     * or {@code Long.MIN_VALUE} if conversion would negatively overflow,
+     * or {@code Long.MAX_VALUE} if it would positively overflow.
      * @since 1.6
      */
     public long toHours(long duration) {
-        throw new AbstractMethodError();
+        return cvt(duration, HOUR_SCALE, scale);
     }
 
     /**
@@ -310,7 +311,7 @@
      * @since 1.6
      */
     public long toDays(long duration) {
-        throw new AbstractMethodError();
+        return cvt(duration, DAY_SCALE, scale);
     }
 
     /**
@@ -320,7 +321,15 @@
      * @param m the number of milliseconds
      * @return the number of nanoseconds
      */
-    abstract int excessNanos(long d, long m);
+    private int excessNanos(long d, long m) {
+        long s;
+        if ((s = scale) == NANO_SCALE)
+            return (int)(d - (m * MILLI_SCALE));
+        else if (s == MICRO_SCALE)
+            return (int)((d * 1000L) - (m * MILLI_SCALE));
+        else
+            return 0;
+    }
 
     /**
      * Performs a timed {@link Object#wait(long, int) Object.wait}
--- a/src/java.base/share/classes/java/util/jar/JarFile.java	Tue Apr 05 18:23:10 2016 +0300
+++ b/src/java.base/share/classes/java/util/jar/JarFile.java	Tue Apr 05 09:17:15 2016 -0700
@@ -28,7 +28,6 @@
 import java.io.*;
 import java.lang.ref.SoftReference;
 import java.net.URL;
-import java.security.PrivilegedAction;
 import java.util.*;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
@@ -38,11 +37,10 @@
 import java.security.AccessController;
 import java.security.CodeSource;
 import jdk.internal.misc.SharedSecrets;
+import sun.security.action.GetPropertyAction;
 import sun.security.util.ManifestEntryVerifier;
 import sun.security.util.SignatureFileVerifier;
 
-import static java.util.jar.Attributes.Name.MULTI_RELEASE;
-
 /**
  * The {@code JarFile} class is used to read the contents of a jar file
  * from any file that can be opened with {@code java.io.RandomAccessFile}.
@@ -144,8 +142,9 @@
     private final int version;
     private boolean notVersioned;
     private final boolean runtimeVersioned;
+    private boolean isMultiRelease;    // is jar multi-release?
 
-    // indicates if Class-Path attribute present (only valid if hasCheckedSpecialAttributes true)
+    // indicates if Class-Path attribute present
     private boolean hasClassPathAttribute;
     // true if manifest checked for special attributes
     private volatile boolean hasCheckedSpecialAttributes;
@@ -155,24 +154,18 @@
         SharedSecrets.setJavaUtilJarAccess(new JavaUtilJarAccessImpl());
 
         BASE_VERSION = 8;  // one less than lowest version for versioned entries
-        RUNTIME_VERSION = AccessController.doPrivileged(
-                new PrivilegedAction<Integer>() {
-                    public Integer run() {
-                        Integer v = jdk.Version.current().major();
-                        Integer i = Integer.getInteger("jdk.util.jar.version", v);
-                        i = i < 0 ? 0 : i;
-                        return i > v ? v : i;
-                    }
-                }
-        );
-        String multi_release = AccessController.doPrivileged(
-                new PrivilegedAction<String>() {
-                    public String run() {
-                        return System.getProperty("jdk.util.jar.enableMultiRelease", "true");
-                    }
-                }
-        );
-        switch (multi_release) {
+        int runtimeVersion = jdk.Version.current().major();
+        String jarVersion = AccessController.doPrivileged(
+                new GetPropertyAction("jdk.util.jar.version"));
+        if (jarVersion != null) {
+            int jarVer = Integer.parseInt(jarVersion);
+            runtimeVersion = (jarVer > runtimeVersion)
+                    ? runtimeVersion : Math.max(jarVer, 0);
+        }
+        RUNTIME_VERSION = runtimeVersion;
+        String enableMultiRelease = AccessController.doPrivileged(
+                new GetPropertyAction("jdk.util.jar.enableMultiRelease", "true"));
+        switch (enableMultiRelease) {
             case "true":
             default:
                 MULTI_RELEASE_ENABLED = true;
@@ -353,8 +346,14 @@
         Objects.requireNonNull(version);
         this.verify = verify;
         // version applies to multi-release jar files, ignored for regular jar files
-        this.version = MULTI_RELEASE_FORCED ? RUNTIME_VERSION : version.value();
+        if (MULTI_RELEASE_FORCED) {
+            this.version = RUNTIME_VERSION;
+            version = Release.RUNTIME;
+        } else {
+            this.version = version.value();
+        }
         this.runtimeVersioned = version == Release.RUNTIME;
+
         assert runtimeVersionExists();
     }
 
@@ -392,35 +391,18 @@
      * @since 9
      */
     public final boolean isMultiRelease() {
-        // do not call this code in a constructor because some subclasses use
-        // lazy loading of manifest so it won't be available at construction time
-        if (MULTI_RELEASE_ENABLED) {
-            // Doubled-checked locking pattern
-            Boolean result = isMultiRelease;
-            if (result == null) {
-                synchronized (this) {
-                    result = isMultiRelease;
-                    if (result == null) {
-                        Manifest man = null;
-                        try {
-                            man = getManifest();
-                        } catch (IOException e) {
-                            //Ignored, manifest cannot be read
-                        }
-                        isMultiRelease = result = (man != null)
-                                && man.getMainAttributes().containsKey(MULTI_RELEASE)
-                                ? Boolean.TRUE : Boolean.FALSE;
-                    }
-                }
+        if (isMultiRelease) {
+            return true;
+        }
+        if (MULTI_RELEASE_ENABLED && version != BASE_VERSION) {
+            try {
+                checkForSpecialAttributes();
+            } catch (IOException io) {
+                isMultiRelease = false;
             }
-            return result == Boolean.TRUE;
-        } else {
-            return false;
         }
+        return isMultiRelease;
     }
-    // the following field, isMultiRelease, should only be used in the method
-    // isMultiRelease(), like a static local
-    private volatile Boolean isMultiRelease;    // is jar multi-release?
 
     /**
      * Returns the jar file manifest, or {@code null} if none.
@@ -905,26 +887,44 @@
     }
 
     // Statics for hand-coded Boyer-Moore search
-    private static final char[] CLASSPATH_CHARS = {'c','l','a','s','s','-','p','a','t','h'};
-    // The bad character shift for "class-path"
-    private static final int[] CLASSPATH_LASTOCC;
-    // The good suffix shift for "class-path"
-    private static final int[] CLASSPATH_OPTOSFT;
+    private static final byte[] CLASSPATH_CHARS =
+            {'C','L','A','S','S','-','P','A','T','H', ':', ' '};
+
+    // The bad character shift for "class-path:"
+    private static final byte[] CLASSPATH_LASTOCC;
+
+    private static final byte[] MULTIRELEASE_CHARS =
+            {'M','U','L','T','I','-','R','E','L','E', 'A', 'S', 'E', ':', ' '};
+
+    // The bad character shift for "multi-release: "
+    private static final byte[] MULTIRELEASE_LASTOCC;
 
     static {
-        CLASSPATH_LASTOCC = new int[128];
-        CLASSPATH_OPTOSFT = new int[10];
-        CLASSPATH_LASTOCC[(int)'c'] = 1;
-        CLASSPATH_LASTOCC[(int)'l'] = 2;
-        CLASSPATH_LASTOCC[(int)'s'] = 5;
-        CLASSPATH_LASTOCC[(int)'-'] = 6;
-        CLASSPATH_LASTOCC[(int)'p'] = 7;
-        CLASSPATH_LASTOCC[(int)'a'] = 8;
-        CLASSPATH_LASTOCC[(int)'t'] = 9;
-        CLASSPATH_LASTOCC[(int)'h'] = 10;
-        for (int i=0; i<9; i++)
-            CLASSPATH_OPTOSFT[i] = 10;
-        CLASSPATH_OPTOSFT[9]=1;
+        CLASSPATH_LASTOCC = new byte[64];
+        CLASSPATH_LASTOCC[(int)'C' - 32] = 1;
+        CLASSPATH_LASTOCC[(int)'L' - 32] = 2;
+        CLASSPATH_LASTOCC[(int)'S' - 32] = 5;
+        CLASSPATH_LASTOCC[(int)'-' - 32] = 6;
+        CLASSPATH_LASTOCC[(int)'P' - 32] = 7;
+        CLASSPATH_LASTOCC[(int)'A' - 32] = 8;
+        CLASSPATH_LASTOCC[(int)'T' - 32] = 9;
+        CLASSPATH_LASTOCC[(int)'H' - 32] = 10;
+        CLASSPATH_LASTOCC[(int)':' - 32] = 11;
+        CLASSPATH_LASTOCC[(int)' ' - 32] = 12;
+
+        MULTIRELEASE_LASTOCC = new byte[64];
+        MULTIRELEASE_LASTOCC[(int)'M' - 32] = 1;
+        MULTIRELEASE_LASTOCC[(int)'U' - 32] = 2;
+        MULTIRELEASE_LASTOCC[(int)'T' - 32] = 4;
+        MULTIRELEASE_LASTOCC[(int)'I' - 32] = 5;
+        MULTIRELEASE_LASTOCC[(int)'-' - 32] = 6;
+        MULTIRELEASE_LASTOCC[(int)'R' - 32] = 7;
+        MULTIRELEASE_LASTOCC[(int)'L' - 32] = 9;
+        MULTIRELEASE_LASTOCC[(int)'A' - 32] = 11;
+        MULTIRELEASE_LASTOCC[(int)'S' - 32] = 12;
+        MULTIRELEASE_LASTOCC[(int)'E' - 32] = 13;
+        MULTIRELEASE_LASTOCC[(int)':' - 32] = 14;
+        MULTIRELEASE_LASTOCC[(int)' ' - 32] = 15;
     }
 
     private JarEntry getManEntry() {
@@ -962,22 +962,33 @@
 
     /**
      * Returns true if the pattern {@code src} is found in {@code b}.
-     * The {@code lastOcc} and {@code optoSft} arrays are the precomputed
-     * bad character and good suffix shifts.
+     * The {@code lastOcc} array is the precomputed bad character shifts.
+     * Since there are no repeated substring in our search strings,
+     * the good suffix shifts can be replaced with a comparison.
      */
-    private boolean match(char[] src, byte[] b, int[] lastOcc, int[] optoSft) {
+    private boolean match(byte[] src, byte[] b, byte[] lastOcc) {
         int len = src.length;
         int last = b.length - len;
         int i = 0;
         next:
-        while (i<=last) {
-            for (int j=(len-1); j>=0; j--) {
-                char c = (char) b[i+j];
-                c = (((c-'A')|('Z'-c)) >= 0) ? (char)(c + 32) : c;
-                if (c != src[j]) {
-                    i += Math.max(j + 1 - lastOcc[c&0x7F], optoSft[j]);
+        while (i <= last) {
+            for (int j = (len - 1); j >= 0; j--) {
+                byte c = b[i + j];
+                if (c >= ' ' && c <= 'z') {
+                    if (c >= 'a') c -= 32; // Canonicalize
+
+                    if (c != src[j]) {
+                        // no match
+                        int goodShift = (j < len - 1) ? len : 1;
+                        int badShift = lastOcc[c - 32];
+                        i += Math.max(j + 1 - badShift, goodShift);
+                        continue next;
+                    }
+                } else {
+                    // no match, character not valid for name
+                    i += len;
                     continue next;
-                 }
+                }
             }
             return true;
         }
@@ -986,17 +997,29 @@
 
     /**
      * On first invocation, check if the JAR file has the Class-Path
-     * attribute. A no-op on subsequent calls.
+     * and the Multi-Release attribute. A no-op on subsequent calls.
      */
     private void checkForSpecialAttributes() throws IOException {
-        if (hasCheckedSpecialAttributes) return;
-        JarEntry manEntry = getManEntry();
-        if (manEntry != null) {
-            byte[] b = getBytes(manEntry);
-            if (match(CLASSPATH_CHARS, b, CLASSPATH_LASTOCC, CLASSPATH_OPTOSFT))
-                hasClassPathAttribute = true;
+        if (hasCheckedSpecialAttributes) {
+            return;
         }
-        hasCheckedSpecialAttributes = true;
+        synchronized (this) {
+            if (hasCheckedSpecialAttributes) {
+                return;
+            }
+            JarEntry manEntry = getManEntry();
+            if (manEntry != null) {
+                byte[] b = getBytes(manEntry);
+                hasClassPathAttribute = match(CLASSPATH_CHARS, b,
+                        CLASSPATH_LASTOCC);
+                // is this a multi-release jar file
+                if (MULTI_RELEASE_ENABLED && version != BASE_VERSION) {
+                    isMultiRelease = match(MULTIRELEASE_CHARS, b,
+                            MULTIRELEASE_LASTOCC);
+                }
+            }
+            hasCheckedSpecialAttributes = true;
+        }
     }
 
     private synchronized void ensureInitialization() {
--- a/src/java.base/share/classes/java/util/jar/JarInputStream.java	Tue Apr 05 18:23:10 2016 +0300
+++ b/src/java.base/share/classes/java/util/jar/JarInputStream.java	Tue Apr 05 09:17:15 2016 -0700
@@ -28,7 +28,7 @@
 import java.util.zip.*;
 import java.io.*;
 import sun.security.util.ManifestEntryVerifier;
-import sun.misc.JarIndex;
+import jdk.internal.util.jar.JarIndex;
 
 /**
  * The <code>JarInputStream</code> class is used to read the contents of
--- a/src/java.base/share/classes/java/util/jar/JarVerifier.java	Tue Apr 05 18:23:10 2016 +0300
+++ b/src/java.base/share/classes/java/util/jar/JarVerifier.java	Tue Apr 05 09:17:15 2016 -0700
@@ -32,7 +32,7 @@
 import java.security.cert.CertificateException;
 import java.util.zip.ZipEntry;
 
-import sun.misc.JarIndex;
+import jdk.internal.util.jar.JarIndex;
 import sun.security.util.ManifestDigester;
 import sun.security.util.ManifestEntryVerifier;
 import sun.security.util.SignatureFileVerifier;
--- a/src/java.base/share/classes/jdk/internal/jimage/decompressor/CompressIndexes.java	Tue Apr 05 18:23:10 2016 +0300
+++ b/src/java.base/share/classes/jdk/internal/jimage/decompressor/CompressIndexes.java	Tue Apr 05 09:17:15 2016 -0700
@@ -42,107 +42,95 @@
  * to the jimage file provided by the shipped JDK by tools running on JDK 8.
  */
 public class CompressIndexes {
-    private static final int INTEGER_SIZE = 4;
+    private static final int COMPRESSED_FLAG = 1 << (Byte.SIZE - 1);
+    private static final int HEADER_WIDTH = 3;
+    private static final int HEADER_SHIFT = Byte.SIZE - HEADER_WIDTH;
 
     public static List<Integer> decompressFlow(byte[] values) {
         List<Integer> lst = new ArrayList<>();
-        for (int i = 0; i < values.length;) {
-            byte b = values[i];
-            int length = isCompressed(b) ? getLength(b) : INTEGER_SIZE;
+
+        for (int i = 0; i < values.length; i += getHeaderLength(values[i])) {
             int decompressed = decompress(values, i);
             lst.add(decompressed);
-            i += length;
         }
+
         return lst;
     }
 
     public static int readInt(DataInputStream cr) throws IOException {
-        byte[] b = new byte[1];
-        cr.readFully(b);
-        byte firstByte = b[0];
-        boolean compressed = CompressIndexes.isCompressed(firstByte);
-        int toRead = 4;
-        if(compressed) {
-            toRead = CompressIndexes.getLength(firstByte);
+        // Get header byte.
+        byte header = cr.readByte();
+        // Determine size.
+        int size = getHeaderLength(header);
+        // Prepare result.
+        int result = getHeaderValue(header);
+
+        // For each value byte
+        for (int i = 1; i < size; i++) {
+            // Merge byte value.
+            result <<= Byte.SIZE;
+            result |= cr.readByte() & 0xFF;
         }
-        byte[] content = new byte[toRead-1];
-        cr.readFully(content);
-        ByteBuffer bb = ByteBuffer.allocate(content.length+1);
-        bb.put(firstByte);
-        bb.put(content);
-        int index = CompressIndexes.decompress(bb.array(), 0);
-        return index;
+
+        return result;
     }
 
-    public static int getLength(byte b) {
-        return ((byte) (b & 0x60) >> 5);
+    private static boolean isCompressed(byte b) {
+        return (b & COMPRESSED_FLAG) != 0;
     }
 
-    public static boolean isCompressed(byte b) {
-        return b < 0;
+    private static int getHeaderLength(byte b) {
+        return isCompressed(b) ? (b >> HEADER_SHIFT) & 3 : Integer.BYTES;
+    }
+
+    private static int getHeaderValue(byte b) {
+        return isCompressed(b) ? b & (1 << HEADER_SHIFT) - 1 : b;
     }
 
     public static int decompress(byte[] value, int offset) {
-        byte b1 = value[offset];
-        ByteBuffer buffer = ByteBuffer.allocate(INTEGER_SIZE);
-        if (isCompressed(b1)) { // compressed
-            int length = getLength(b1);
-            byte clearedValue = (byte) (b1 & 0x1F);
+        // Get header byte.
+        byte header = value[offset];
+        // Determine size.
+        int size = getHeaderLength(header);
+        // Prepare result.
+        int result = getHeaderValue(header);
 
-            int start = INTEGER_SIZE - length;
-            buffer.put(start, clearedValue);
-            for (int i = offset + 1; i < offset + length; i++) {
-                buffer.put(++start, value[i]);
-            }
-        } else {
-            buffer.put(value, offset, INTEGER_SIZE);
+        // For each value byte
+        for (int i = 1; i < size; i++) {
+            // Merge byte value.
+            result <<= Byte.SIZE;
+            result |= value[offset + i] & 0xFF;
         }
-        return buffer.getInt(0);
+
+        return result;
     }
 
-    public static byte[] compress(int val) {
-        ByteBuffer result = ByteBuffer.allocate(4).putInt(val);
-        byte[] array = result.array();
+    public static byte[] compress(int value) {
+        // Only positive values are supported.
+        if (value < 0) {
+            throw new  IllegalArgumentException("value < 0");
+        }
 
-        if ((val & 0xFF000000) == 0) { // nothing on 4th
-            if ((val & 0x00FF0000) == 0) { // nothing on 3rd
-                if ((val & 0x0000FF00) == 0) { // nothing on 2nd
-                    if ((val & 0x000000E0) == 0) { // only in 1st, encode length in the byte.
-                        //sign bit and size 1 ==> 101X
-                        result = ByteBuffer.allocate(1);
-                        result.put((byte) (0xA0 | array[3]));
-                    } else { // add a byte for size
-                        //sign bit and size 2 ==> 110X
-                        result = ByteBuffer.allocate(2);
-                        result.put((byte) 0xC0);
-                        result.put(array[3]);
-                    }
-                } else { // content in 2nd
-                    if ((val & 0x0000E000) == 0) {// encode length in the byte.
-                        //sign bit and size 2 ==> 110X
-                        result = ByteBuffer.allocate(2);
-                        result.put((byte) (0xC0 | array[2]));
-                        result.put(array[3]);
-                    } else { // add a byte for size
-                        //sign bit and size 3 ==> 111X
-                        result = ByteBuffer.allocate(3);
-                        result.put((byte) 0xE0);
-                        result.put(array[2]);
-                        result.put(array[3]);
-                    }
-                }
-            } else {// content in 3rd
-                if ((val & 0x00E00000) == 0) {// encode length in the byte.
-                    //sign bit and size 3 ==> 111X
-                    result = ByteBuffer.allocate(3);
-                    result.put((byte) (0xE0 | array[1]));
-                    result.put(array[2]);
-                    result.put(array[3]);
-                } else { // add a byte, useless
-                    //
-                }
-            }
+        // Determine number of significant digits.
+        int width = 32 - Integer.numberOfLeadingZeros(value);
+        // Determine number of byte to represent.  Allow for header if
+        // compressed.
+        int size = Math.min(((width + HEADER_WIDTH - 1) >> 3) + 1, Integer.BYTES);
+
+        // Allocate result buffer.
+        byte[] result = new byte[size];
+
+        // Insert significant bytes in result.
+        for (int i = 0; i < size; i++) {
+            result[i] = (byte)(value >> ((size - i - 1) * Byte.SIZE));
         }
-        return result.array();
+
+        // If compressed, mark and insert size.
+        if (size < Integer.BYTES) {
+            result[0] |= (byte)(COMPRESSED_FLAG | (size << HEADER_SHIFT));
+        }
+
+        return result;
     }
+
 }
--- a/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java	Tue Apr 05 18:23:10 2016 +0300
+++ b/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java	Tue Apr 05 09:17:15 2016 -0700
@@ -65,8 +65,8 @@
 
 import jdk.internal.misc.JavaUtilZipFileAccess;
 import jdk.internal.misc.SharedSecrets;
-import sun.misc.InvalidJarIndexException;
-import sun.misc.JarIndex;
+import jdk.internal.util.jar.InvalidJarIndexError;
+import jdk.internal.util.jar.JarIndex;
 import sun.net.util.URLUtil;
 import sun.net.www.ParseUtil;
 
@@ -902,7 +902,7 @@
                          */
                         if (!newLoader.validIndex(name)) {
                             /* the mapping is wrong */
-                            throw new InvalidJarIndexException("Invalid index");
+                            throw new InvalidJarIndexError("Invalid index");
                         }
                     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/util/jar/InvalidJarIndexError.java	Tue Apr 05 09:17:15 2016 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.jar;
+
+/**
+ * Thrown if the URLClassLoader finds the INDEX.LIST file of
+ * a jar file contains incorrect information.
+ *
+ * @since 9
+ */
+
+public class InvalidJarIndexError extends Error {
+
+    static final long serialVersionUID = 0L;
+
+    /**
+     * Constructs an {@code InvalidJarIndexError} with no detail message.
+     */
+    public InvalidJarIndexError() {
+        super();
+    }
+
+    /**
+     * Constructs an {@code InvalidJarIndexError} with the specified detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public InvalidJarIndexError(String s) {
+        super(s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/util/jar/JarIndex.java	Tue Apr 05 09:17:15 2016 -0700
@@ -0,0 +1,333 @@
+/*
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.util.jar;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+import java.util.zip.*;
+
+/**
+ * This class is used to maintain mappings from packages, classes
+ * and resources to their enclosing JAR files. Mappings are kept
+ * at the package level except for class or resource files that
+ * are located at the root directory. URLClassLoader uses the mapping
+ * information to determine where to fetch an extension class or
+ * resource from.
+ *
+ * @author  Zhenghua Li
+ * @since   1.3
+ */
+
+public class JarIndex {
+
+    /**
+     * The hash map that maintains mappings from
+     * package/classe/resource to jar file list(s)
+     */
+    private HashMap<String,LinkedList<String>> indexMap;
+
+    /**
+     * The hash map that maintains mappings from
+     * jar file to package/class/resource lists
+     */
+    private HashMap<String,LinkedList<String>> jarMap;
+
+    /*
+     * An ordered list of jar file names.
+     */
+    private String[] jarFiles;
+
+    /**
+     * The index file name.
+     */
+    public static final String INDEX_NAME = "META-INF/INDEX.LIST";
+
+    /**
+     * true if, and only if, sun.misc.JarIndex.metaInfFilenames is set to true.
+     * If true, the names of the files in META-INF, and its subdirectories, will
+     * be added to the index. Otherwise, just the directory names are added.
+     */
+    private static final boolean metaInfFilenames =
+        "true".equals(System.getProperty("sun.misc.JarIndex.metaInfFilenames"));
+
+    /**
+     * Constructs a new, empty jar index.
+     */
+    public JarIndex() {
+        indexMap = new HashMap<>();
+        jarMap = new HashMap<>();
+    }
+
+    /**
+     * Constructs a new index from the specified input stream.
+     *
+     * @param is the input stream containing the index data
+     */
+    public JarIndex(InputStream is) throws IOException {
+        this();
+        read(is);
+    }
+
+    /**
+     * Constructs a new index for the specified list of jar files.
+     *
+     * @param files the list of jar files to construct the index from.
+     */
+    public JarIndex(String[] files) throws IOException {
+        this();
+        this.jarFiles = files;
+        parseJars(files);
+    }
+
+    /**
+     * Returns the jar index, or <code>null</code> if none.
+     *
+     * @param jar the JAR file to get the index from.
+     * @exception IOException if an I/O error has occurred.
+     */
+    public static JarIndex getJarIndex(JarFile jar) throws IOException {
+        JarIndex index = null;
+        JarEntry e = jar.getJarEntry(INDEX_NAME);
+        // if found, then load the index
+        if (e != null) {
+            index = new JarIndex(jar.getInputStream(e));
+        }
+        return index;
+    }
+
+    /**
+     * Returns the jar files that are defined in this index.
+     */
+    public String[] getJarFiles() {
+        return jarFiles;
+    }
+
+    /*
+     * Add the key, value pair to the hashmap, the value will
+     * be put in a linked list which is created if necessary.
+     */
+    private void addToList(String key, String value,
+                           HashMap<String,LinkedList<String>> t) {
+        LinkedList<String> list = t.get(key);
+        if (list == null) {
+            list = new LinkedList<>();
+            list.add(value);
+            t.put(key, list);
+        } else if (!list.contains(value)) {
+            list.add(value);
+        }
+    }
+
+    /**
+     * Returns the list of jar files that are mapped to the file.
+     *
+     * @param fileName the key of the mapping
+     */
+    public LinkedList<String> get(String fileName) {
+        LinkedList<String> jarFiles = null;
+        if ((jarFiles = indexMap.get(fileName)) == null) {
+            /* try the package name again */
+            int pos;
+            if((pos = fileName.lastIndexOf('/')) != -1) {
+                jarFiles = indexMap.get(fileName.substring(0, pos));
+            }
+        }
+        return jarFiles;
+    }
+
+    /**
+     * Add the mapping from the specified file to the specified
+     * jar file. If there were no mapping for the package of the
+     * specified file before, a new linked list will be created,
+     * the jar file is added to the list and a new mapping from
+     * the package to the jar file list is added to the hashmap.
+     * Otherwise, the jar file will be added to the end of the
+     * existing list.
+     *
+     * @param fileName the file name
+     * @param jarName the jar file that the file is mapped to
+     *
+     */
+    public void add(String fileName, String jarName) {
+        String packageName;
+        int pos;
+        if((pos = fileName.lastIndexOf('/')) != -1) {
+            packageName = fileName.substring(0, pos);
+        } else {
+            packageName = fileName;
+        }
+
+        addMapping(packageName, jarName);
+    }
+
+    /**
+     * Same as add(String,String) except that it doesn't strip off from the
+     * last index of '/'. It just adds the jarItem (filename or package)
+     * as it is received.
+     */
+    private void addMapping(String jarItem, String jarName) {
+        // add the mapping to indexMap
+        addToList(jarItem, jarName, indexMap);
+
+        // add the mapping to jarMap
+        addToList(jarName, jarItem, jarMap);
+     }
+
+    /**
+     * Go through all the jar files and construct the
+     * index table.
+     */
+    private void parseJars(String[] files) throws IOException {
+        if (files == null) {
+            return;
+        }
+
+        String currentJar = null;
+
+        for (int i = 0; i < files.length; i++) {
+            currentJar = files[i];
+            ZipFile zrf = new ZipFile(currentJar.replace
+                                      ('/', File.separatorChar));
+
+            Enumeration<? extends ZipEntry> entries = zrf.entries();
+            while(entries.hasMoreElements()) {
+                ZipEntry entry = entries.nextElement();
+                String fileName = entry.getName();
+
+                // Skip the META-INF directory, the index, and manifest.
+                // Any files in META-INF/ will be indexed explicitly
+                if (fileName.equals("META-INF/") ||
+                    fileName.equals(INDEX_NAME) ||
+                    fileName.equals(JarFile.MANIFEST_NAME))
+                    continue;
+
+                if (!metaInfFilenames || !fileName.startsWith("META-INF/")) {
+                    add(fileName, currentJar);
+                } else if (!entry.isDirectory()) {
+                        // Add files under META-INF explicitly so that certain
+                        // services, like ServiceLoader, etc, can be located
+                        // with greater accuracy. Directories can be skipped
+                        // since each file will be added explicitly.
+                        addMapping(fileName, currentJar);
+                }
+            }
+
+            zrf.close();
+        }
+    }
+
+    /**
+     * Writes the index to the specified OutputStream
+     *
+     * @param out the output stream
+     * @exception IOException if an I/O error has occurred
+     */
+    public void write(OutputStream out) throws IOException {
+        BufferedWriter bw = new BufferedWriter
+            (new OutputStreamWriter(out, "UTF8"));
+        bw.write("JarIndex-Version: 1.0\n\n");
+
+        if (jarFiles != null) {
+            for (int i = 0; i < jarFiles.length; i++) {
+                /* print out the jar file name */
+                String jar = jarFiles[i];
+                bw.write(jar + "\n");
+                LinkedList<String> jarlist = jarMap.get(jar);
+                if (jarlist != null) {
+                    Iterator<String> listitr = jarlist.iterator();
+                    while(listitr.hasNext()) {
+                        bw.write(listitr.next() + "\n");
+                    }
+                }
+                bw.write("\n");
+            }
+            bw.flush();
+        }
+    }
+
+
+    /**
+     * Reads the index from the specified InputStream.
+     *
+     * @param is the input stream
+     * @exception IOException if an I/O error has occurred
+     */
+    public void read(InputStream is) throws IOException {
+        BufferedReader br = new BufferedReader
+            (new InputStreamReader(is, "UTF8"));
+        String line = null;
+        String currentJar = null;
+
+        /* an ordered list of jar file names */
+        Vector<String> jars = new Vector<>();
+
+        /* read until we see a .jar line */
+        while((line = br.readLine()) != null && !line.endsWith(".jar"));
+
+        for(;line != null; line = br.readLine()) {
+            if (line.length() == 0)
+                continue;
+
+            if (line.endsWith(".jar")) {
+                currentJar = line;
+                jars.add(currentJar);
+            } else {
+                String name = line;
+                addMapping(name, currentJar);
+            }
+        }
+
+        jarFiles = jars.toArray(new String[jars.size()]);
+    }
+
+    /**
+     * Merges the current index into another index, taking into account
+     * the relative path of the current index.
+     *
+     * @param toIndex The destination index which the current index will
+     *                merge into.
+     * @param path    The relative path of the this index to the destination
+     *                index.
+     *
+     */
+    public void merge(JarIndex toIndex, String path) {
+        Iterator<Map.Entry<String,LinkedList<String>>> itr = indexMap.entrySet().iterator();
+        while(itr.hasNext()) {
+            Map.Entry<String,LinkedList<String>> e = itr.next();
+            String packageName = e.getKey();
+            LinkedList<String> from_list = e.getValue();
+            Iterator<String> listItr = from_list.iterator();
+            while(listItr.hasNext()) {
+                String jarName = listItr.next();
+                if (path != null) {
+                    jarName = path.concat(jarName);
+                }
+                toIndex.addMapping(packageName, jarName);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/vm/VMSupport.java	Tue Apr 05 09:17:15 2016 -0700
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.internal.vm;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Properties;
+import java.util.Set;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+import java.util.jar.Attributes;
+
+/*
+ * Support class used by JVMTI and VM attach mechanism.
+ */
+public class VMSupport {
+
+    private static Properties agentProps = null;
+    /**
+     * Returns the agent properties.
+     */
+    public static synchronized Properties getAgentProperties() {
+        if (agentProps == null) {
+            agentProps = new Properties();
+            initAgentProperties(agentProps);
+        }
+        return agentProps;
+    }
+    private static native Properties initAgentProperties(Properties props);
+
+    /**
+     * Write the given properties list to a byte array and return it. Properties with
+     * a key or value that is not a String is filtered out. The stream written to the byte
+     * array is ISO 8859-1 encoded.
+     */
+    private static byte[] serializePropertiesToByteArray(Properties p) throws IOException {
+        ByteArrayOutputStream out = new ByteArrayOutputStream(4096);
+
+        Properties props = new Properties();
+
+        // stringPropertyNames() returns a snapshot of the property keys
+        Set<String> keyset = p.stringPropertyNames();
+        for (String key : keyset) {
+            String value = p.getProperty(key);
+            props.put(key, value);
+        }
+
+        props.store(out, null);
+        return out.toByteArray();
+    }
+
+    public static byte[] serializePropertiesToByteArray() throws IOException {
+        return serializePropertiesToByteArray(System.getProperties());
+    }
+
+    public static byte[] serializeAgentPropertiesToByteArray() throws IOException {
+        return serializePropertiesToByteArray(getAgentProperties());
+    }
+
+    /*
+     * Returns true if the given JAR file has the Class-Path attribute in the
+     * main section of the JAR manifest. Throws RuntimeException if the given
+     * path is not a JAR file or some other error occurs.
+     */
+    public static boolean isClassPathAttributePresent(String path) {
+        try {
+            Manifest man = (new JarFile(path)).getManifest();
+            if (man != null) {
+                if (man.getMainAttributes().getValue(Attributes.Name.CLASS_PATH) != null) {
+                    return true;
+                }
+            }
+            return false;
+        } catch (IOException ioe) {
+            throw new RuntimeException(ioe.getMessage());
+        }
+    }
+
+    /*
+     * Return the temporary directory that the VM uses for the attach
+     * and perf data files.
+     *
+     * It is important that this directory is well-known and the
+     * same for all VM instances. It cannot be affected by configuration
+     * variables such as java.io.tmpdir.
+     */
+    public static native String getVMTemporaryDirectory();
+}
--- a/src/java.base/share/classes/module-info.java	Tue Apr 05 18:23:10 2016 +0300
+++ b/src/java.base/share/classes/module-info.java	Tue Apr 05 09:17:15 2016 -0700
@@ -180,6 +180,11 @@
         jdk.jvmstat;
     exports jdk.internal.ref to
         java.desktop;
+    exports jdk.internal.util.jar to
+        jdk.jartool;
+    exports jdk.internal.vm to
+        java.management,
+        jdk.jvmstat;
     exports sun.net to
         java.httpclient;
     exports sun.net.dns to
--- a/src/java.base/share/classes/sun/misc/GC.java	Tue Apr 05 18:23:10 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,283 +0,0 @@
-/*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc;
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-
-/**
- * Support for garbage-collection latency requests.
- *
- * @author   Mark Reinhold
- * @since    1.2
- */
-
-public class GC {
-
-    private GC() { }            /* To prevent instantiation */
-
-
-    /* Latency-target value indicating that there's no active target
-     */
-    private static final long NO_TARGET = Long.MAX_VALUE;
-
-    /* The current latency target, or NO_TARGET if there is no target
-     */
-    private static long latencyTarget = NO_TARGET;
-
-    /* The daemon thread that implements the latency-target mechanism,
-     * or null if there is presently no daemon thread
-     */
-    private static Thread daemon = null;
-
-    /* The lock object for the latencyTarget and daemon fields.  The daemon
-     * thread, if it exists, waits on this lock for notification that the
-     * latency target has changed.
-     */
-    private static class LatencyLock extends Object { };
-    private static Object lock = new LatencyLock();
-
-
-    /**
-     * Returns the maximum <em>object-inspection age</em>, which is the number
-     * of real-time milliseconds that have elapsed since the
-     * least-recently-inspected heap object was last inspected by the garbage
-     * collector.
-     *
-     * <p> For simple stop-the-world collectors this value is just the time
-     * since the most recent collection.  For generational collectors it is the
-     * time since the oldest generation was most recently collected.  Other
-     * collectors are free to return a pessimistic estimate of the elapsed
-     * time, or simply the time since the last full collection was performed.
-     *
-     * <p> Note that in the presence of reference objects, a given object that
-     * is no longer strongly reachable may have to be inspected multiple times
-     * before it can be reclaimed.
-     */
-    public static native long maxObjectInspectionAge();
-
-    private static class Daemon extends Thread {
-
-        public void run() {
-            for (;;) {
-                long l;
-                synchronized (lock) {
-
-                    l = latencyTarget;
-                    if (l == NO_TARGET) {
-                        /* No latency target, so exit */
-                        GC.daemon = null;
-                        return;
-                    }
-
-                    long d = maxObjectInspectionAge();
-                    if (d >= l) {
-                        /* Do a full collection.  There is a remote possibility
-                         * that a full collection will occurr between the time
-                         * we sample the inspection age and the time the GC
-                         * actually starts, but this is sufficiently unlikely
-                         * that it doesn't seem worth the more expensive JVM
-                         * interface that would be required.
-                         */
-                        System.gc();
-                        d = 0;
-                    }
-
-                    /* Wait for the latency period to expire,
-                     * or for notification that the period has changed
-                     */
-                    try {
-                        lock.wait(l - d);
-                    } catch (InterruptedException x) {
-                        continue;
-                    }
-                }
-            }
-        }
-
-        private Daemon(ThreadGroup tg) {
-            super(tg, null, "GC Daemon", 0L, false);
-        }
-
-        /* Create a new daemon thread in the root thread group */
-        public static void create() {
-            PrivilegedAction<Void> pa = new PrivilegedAction<Void>() {
-                public Void run() {
-                    ThreadGroup tg = Thread.currentThread().getThreadGroup();
-                    for (ThreadGroup tgn = tg;
-                         tgn != null;
-                         tg = tgn, tgn = tg.getParent());
-                    Daemon d = new Daemon(tg);
-                    d.setDaemon(true);
-                    d.setPriority(Thread.MIN_PRIORITY + 1);
-                    d.start();
-                    GC.daemon = d;
-                    return null;
-                }};
-            AccessController.doPrivileged(pa);
-        }
-
-    }
-
-
-    /* Sets the latency target to the given value.
-     * Must be invoked while holding the lock.
-     */
-    private static void setLatencyTarget(long ms) {
-        latencyTarget = ms;
-        if (daemon == null) {
-            /* Create a new daemon thread */
-            Daemon.create();
-        } else {
-            /* Notify the existing daemon thread
-             * that the lateency target has changed
-             */
-            lock.notify();
-        }
-    }
-
-
-    /**
-     * Represents an active garbage-collection latency request.  Instances of
-     * this class are created by the <code>{@link #requestLatency}</code>
-     * method.  Given a request, the only interesting operation is that of
-     * cancellation.
-     */
-    public static class LatencyRequest
-        implements Comparable<LatencyRequest> {
-
-        /* Instance counter, used to generate unique identifers */
-        private static long counter = 0;
-
-        /* Sorted set of active latency requests */
-        private static SortedSet<LatencyRequest> requests = null;
-
-        /* Examine the request set and reset the latency target if necessary.
-         * Must be invoked while holding the lock.
-         */
-        private static void adjustLatencyIfNeeded() {
-            if ((requests == null) || requests.isEmpty()) {
-                if (latencyTarget != NO_TARGET) {
-                    setLatencyTarget(NO_TARGET);
-                }
-            } else {
-                LatencyRequest r = requests.first();
-                if (r.latency != latencyTarget) {
-                    setLatencyTarget(r.latency);
-                }
-            }
-        }
-
-        /* The requested latency, or NO_TARGET
-         * if this request has been cancelled
-         */
-        private long latency;
-
-        /* Unique identifier for this request */
-        private long id;
-
-        private LatencyRequest(long ms) {
-            if (ms <= 0) {
-                throw new IllegalArgumentException("Non-positive latency: "
-                                                   + ms);
-            }
-            this.latency = ms;
-            synchronized (lock) {
-                this.id = ++counter;
-                if (requests == null) {
-                    requests = new TreeSet<LatencyRequest>();
-                }
-                requests.add(this);
-                adjustLatencyIfNeeded();
-            }
-        }
-
-        /**
-         * Cancels this latency request.
-         *
-         * @throws  IllegalStateException
-         *          If this request has already been cancelled
-         */
-        public void cancel() {
-            synchronized (lock) {
-                if (this.latency == NO_TARGET) {
-                    throw new IllegalStateException("Request already"
-                                                    + " cancelled");
-                }
-                if (!requests.remove(this)) {
-                    throw new InternalError("Latency request "
-                                            + this + " not found");
-                }
-                if (requests.isEmpty()) requests = null;
-                this.latency = NO_TARGET;
-                adjustLatencyIfNeeded();
-            }
-        }
-
-        public int compareTo(LatencyRequest r) {
-            long d = this.latency - r.latency;
-            if (d == 0) d = this.id - r.id;
-            return (d < 0) ? -1 : ((d > 0) ? +1 : 0);
-        }
-
-        public String toString() {
-            return (LatencyRequest.class.getName()
-                    + "[" + latency + "," + id + "]");
-        }
-
-    }
-
-
-    /**
-     * Makes a new request for a garbage-collection latency of the given
-     * number of real-time milliseconds.  A low-priority daemon thread makes a
-     * best effort to ensure that the maximum object-inspection age never
-     * exceeds the smallest of the currently active requests.
-     *
-     * @param   latency
-     *          The requested latency
-     *
-     * @throws  IllegalArgumentException
-     *          If the given <code>latency</code> is non-positive
-     */
-    public static LatencyRequest requestLatency(long latency) {
-        return new LatencyRequest(latency);
-    }
-
-
-    /**
-     * Returns the current smallest garbage-collection latency request, or zero
-     * if there are no active requests.
-     */
-    public static long currentLatencyTarget() {
-        long t = latencyTarget;
-        return (t == NO_TARGET) ? 0 : t;
-    }
-
-}
--- a/src/java.base/share/classes/sun/misc/InvalidJarIndexException.java	Tue Apr 05 18:23:10 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc;
-
-import java.lang.LinkageError;
-
-/**
- * Thrown if the URLClassLoader finds the INDEX.LIST file of
- * a jar file contains incorrect information.
- *
- * @author   Zhenghua Li
- * @since   1.3
- */
-
-public
-class InvalidJarIndexException extends RuntimeException {
-
-    static final long serialVersionUID = -6159797516569680148L;
-
-    /**
-     * Constructs an <code>InvalidJarIndexException</code> with no
-     * detail message.
-     */
-    public InvalidJarIndexException() {
-        super();
-    }
-
-    /**
-     * Constructs an <code>InvalidJarIndexException</code> with the
-     * specified detail message.
-     *
-     * @param   s   the detail message.
-     */
-    public InvalidJarIndexException(String s) {
-        super(s);
-    }
-}
--- a/src/java.base/share/classes/sun/misc/JarIndex.java	Tue Apr 05 18:23:10 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,333 +0,0 @@
-/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc;
-
-import java.io.*;
-import java.util.*;
-import java.util.jar.*;
-import java.util.zip.*;
-
-/**
- * This class is used to maintain mappings from packages, classes
- * and resources to their enclosing JAR files. Mappings are kept
- * at the package level except for class or resource files that
- * are located at the root directory. URLClassLoader uses the mapping
- * information to determine where to fetch an extension class or
- * resource from.
- *
- * @author  Zhenghua Li
- * @since   1.3
- */
-
-public class JarIndex {
-
-    /**
-     * The hash map that maintains mappings from
-     * package/classe/resource to jar file list(s)
-     */
-    private HashMap<String,LinkedList<String>> indexMap;
-
-    /**
-     * The hash map that maintains mappings from
-     * jar file to package/class/resource lists
-     */
-    private HashMap<String,LinkedList<String>> jarMap;
-
-    /*
-     * An ordered list of jar file names.
-     */
-    private String[] jarFiles;
-
-    /**
-     * The index file name.
-     */
-    public static final String INDEX_NAME = "META-INF/INDEX.LIST";
-
-    /**
-     * true if, and only if, sun.misc.JarIndex.metaInfFilenames is set to true.
-     * If true, the names of the files in META-INF, and its subdirectories, will
-     * be added to the index. Otherwise, just the directory names are added.
-     */
-    private static final boolean metaInfFilenames =
-        "true".equals(System.getProperty("sun.misc.JarIndex.metaInfFilenames"));
-
-    /**
-     * Constructs a new, empty jar index.
-     */
-    public JarIndex() {
-        indexMap = new HashMap<>();
-        jarMap = new HashMap<>();
-    }
-
-    /**
-     * Constructs a new index from the specified input stream.
-     *
-     * @param is the input stream containing the index data
-     */
-    public JarIndex(InputStream is) throws IOException {
-        this();
-        read(is);
-    }
-
-    /**
-     * Constructs a new index for the specified list of jar files.
-     *
-     * @param files the list of jar files to construct the index from.
-     */
-    public JarIndex(String[] files) throws IOException {
-        this();
-        this.jarFiles = files;
-        parseJars(files);
-    }
-
-    /**
-     * Returns the jar index, or <code>null</code> if none.
-     *
-     * @param jar the JAR file to get the index from.
-     * @exception IOException if an I/O error has occurred.
-     */
-    public static JarIndex getJarIndex(JarFile jar) throws IOException {
-        JarIndex index = null;
-        JarEntry e = jar.getJarEntry(INDEX_NAME);
-        // if found, then load the index
-        if (e != null) {
-            index = new JarIndex(jar.getInputStream(e));
-        }
-        return index;
-    }
-
-    /**
-     * Returns the jar files that are defined in this index.
-     */
-    public String[] getJarFiles() {
-        return jarFiles;
-    }
-
-    /*
-     * Add the key, value pair to the hashmap, the value will
-     * be put in a linked list which is created if necessary.
-     */
-    private void addToList(String key, String value,
-                           HashMap<String,LinkedList<String>> t) {
-        LinkedList<String> list = t.get(key);
-        if (list == null) {
-            list = new LinkedList<>();
-            list.add(value);
-            t.put(key, list);
-        } else if (!list.contains(value)) {
-            list.add(value);
-        }
-    }
-
-    /**
-     * Returns the list of jar files that are mapped to the file.
-     *
-     * @param fileName the key of the mapping
-     */
-    public LinkedList<String> get(String fileName) {
-        LinkedList<String> jarFiles = null;
-        if ((jarFiles = indexMap.get(fileName)) == null) {
-            /* try the package name again */
-            int pos;
-            if((pos = fileName.lastIndexOf('/')) != -1) {
-                jarFiles = indexMap.get(fileName.substring(0, pos));
-            }
-        }
-        return jarFiles;
-    }
-
-    /**
-     * Add the mapping from the specified file to the specified
-     * jar file. If there were no mapping for the package of the
-     * specified file before, a new linked list will be created,
-     * the jar file is added to the list and a new mapping from
-     * the package to the jar file list is added to the hashmap.
-     * Otherwise, the jar file will be added to the end of the
-     * existing list.
-     *
-     * @param fileName the file name
-     * @param jarName the jar file that the file is mapped to
-     *
-     */
-    public void add(String fileName, String jarName) {
-        String packageName;
-        int pos;
-        if((pos = fileName.lastIndexOf('/')) != -1) {
-            packageName = fileName.substring(0, pos);
-        } else {
-            packageName = fileName;
-        }
-
-        addMapping(packageName, jarName);
-    }
-
-    /**
-     * Same as add(String,String) except that it doesn't strip off from the
-     * last index of '/'. It just adds the jarItem (filename or package)
-     * as it is received.
-     */
-    private void addMapping(String jarItem, String jarName) {
-        // add the mapping to indexMap
-        addToList(jarItem, jarName, indexMap);
-
-        // add the mapping to jarMap
-        addToList(jarName, jarItem, jarMap);
-     }
-
-    /**
-     * Go through all the jar files and construct the
-     * index table.
-     */
-    private void parseJars(String[] files) throws IOException {
-        if (files == null) {
-            return;
-        }
-
-        String currentJar = null;
-
-        for (int i = 0; i < files.length; i++) {
-            currentJar = files[i];
-            ZipFile zrf = new ZipFile(currentJar.replace
-                                      ('/', File.separatorChar));
-
-            Enumeration<? extends ZipEntry> entries = zrf.entries();
-            while(entries.hasMoreElements()) {
-                ZipEntry entry = entries.nextElement();
-                String fileName = entry.getName();
-
-                // Skip the META-INF directory, the index, and manifest.
-                // Any files in META-INF/ will be indexed explicitly
-                if (fileName.equals("META-INF/") ||
-                    fileName.equals(INDEX_NAME) ||
-                    fileName.equals(JarFile.MANIFEST_NAME))
-                    continue;
-
-                if (!metaInfFilenames || !fileName.startsWith("META-INF/")) {
-                    add(fileName, currentJar);
-                } else if (!entry.isDirectory()) {
-                        // Add files under META-INF explicitly so that certain
-                        // services, like ServiceLoader, etc, can be located
-                        // with greater accuracy. Directories can be skipped
-                        // since each file will be added explicitly.
-                        addMapping(fileName, currentJar);
-                }
-            }
-
-            zrf.close();
-        }
-    }
-
-    /**
-     * Writes the index to the specified OutputStream
-     *
-     * @param out the output stream
-     * @exception IOException if an I/O error has occurred
-     */
-    public void write(OutputStream out) throws IOException {
-        BufferedWriter bw = new BufferedWriter
-            (new OutputStreamWriter(out, "UTF8"));
-        bw.write("JarIndex-Version: 1.0\n\n");
-
-        if (jarFiles != null) {
-            for (int i = 0; i < jarFiles.length; i++) {
-                /* print out the jar file name */
-                String jar = jarFiles[i];
-                bw.write(jar + "\n");
-                LinkedList<String> jarlist = jarMap.get(jar);
-                if (jarlist != null) {
-                    Iterator<String> listitr = jarlist.iterator();
-                    while(listitr.hasNext()) {
-                        bw.write(listitr.next() + "\n");
-                    }
-                }
-                bw.write("\n");
-            }
-            bw.flush();
-        }
-    }
-
-
-    /**
-     * Reads the index from the specified InputStream.
-     *
-     * @param is the input stream
-     * @exception IOException if an I/O error has occurred
-     */
-    public void read(InputStream is) throws IOException {
-        BufferedReader br = new BufferedReader
-            (new InputStreamReader(is, "UTF8"));
-        String line = null;
-        String currentJar = null;
-
-        /* an ordered list of jar file names */
-        Vector<String> jars = new Vector<>();
-
-        /* read until we see a .jar line */
-        while((line = br.readLine()) != null && !line.endsWith(".jar"));
-
-        for(;line != null; line = br.readLine()) {
-            if (line.length() == 0)
-                continue;
-
-            if (line.endsWith(".jar")) {
-                currentJar = line;
-                jars.add(currentJar);
-            } else {
-                String name = line;
-                addMapping(name, currentJar);
-            }
-        }
-
-        jarFiles = jars.toArray(new String[jars.size()]);
-    }
-
-    /**
-     * Merges the current index into another index, taking into account
-     * the relative path of the current index.
-     *
-     * @param toIndex The destination index which the current index will
-     *                merge into.
-     * @param path    The relative path of the this index to the destination
-     *                index.
-     *
-     */
-    public void merge(JarIndex toIndex, String path) {
-        Iterator<Map.Entry<String,LinkedList<String>>> itr = indexMap.entrySet().iterator();
-        while(itr.hasNext()) {
-            Map.Entry<String,LinkedList<String>> e = itr.next();
-            String packageName = e.getKey();
-            LinkedList<String> from_list = e.getValue();
-            Iterator<String> listItr = from_list.iterator();
-            while(listItr.hasNext()) {
-                String jarName = listItr.next();
-                if (path != null) {
-                    jarName = path.concat(jarName);
-                }
-                toIndex.addMapping(packageName, jarName);
-            }
-        }
-    }
-}
--- a/src/java.base/share/classes/sun/misc/VMSupport.java	Tue Apr 05 18:23:10 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.misc;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.Properties;
-import java.util.Set;
-import java.util.jar.JarFile;
-import java.util.jar.Manifest;
-import java.util.jar.Attributes;
-
-/*
- * Support class used by JVMTI and VM attach mechanism.
- */
-public class VMSupport {
-
-    private static Properties agentProps = null;
-    /**
-     * Returns the agent properties.
-     */
-    public static synchronized Properties getAgentProperties() {
-        if (agentProps == null) {
-            agentProps = new Properties();
-            initAgentProperties(agentProps);
-        }
-        return agentProps;
-    }
-    private static native Properties initAgentProperties(Properties props);
-
-    /**
-     * Write the given properties list to a byte array and return it. Properties with
-     * a key or value that is not a String is filtered out. The stream written to the byte
-     * array is ISO 8859-1 encoded.
-     */
-    private static byte[] serializePropertiesToByteArray(Properties p) throws IOException {
-        ByteArrayOutputStream out = new ByteArrayOutputStream(4096);
-
-        Properties props = new Properties();
-
-        // stringPropertyNames() returns a snapshot of the property keys
-        Set<String> keyset = p.stringPropertyNames();
-        for (String key : keyset) {
-            String value = p.getProperty(key);
-            props.put(key, value);
-        }
-
-        props.store(out, null);
-        return out.toByteArray();
-    }
-
-    public static byte[] serializePropertiesToByteArray() throws IOException {
-        return serializePropertiesToByteArray(System.getProperties());
-    }
-
-    public static byte[] serializeAgentPropertiesToByteArray() throws IOException {
-        return serializePropertiesToByteArray(getAgentProperties());
-    }
-
-    /*
-     * Returns true if the given JAR file has the Class-Path attribute in the
-     * main section of the JAR manifest. Throws RuntimeException if the given
-     * path is not a JAR file or some other error occurs.
-     */
-    public static boolean isClassPathAttributePresent(String path) {
-        try {
-            Manifest man = (new JarFile(path)).getManifest();
-            if (man != null) {
-                if (man.getMainAttributes().getValue(Attributes.Name.CLASS_PATH) != null) {
-                    return true;
-                }
-            }
-            return false;
-        } catch (IOException ioe) {
-            throw new RuntimeException(ioe.getMessage());
-        }
-    }
-
-    /*
-     * Return the temporary directory that the VM uses for the attach
-     * and perf data files.
-     *
-     * It is important that this directory is well-known and the
-     * same for all VM instances. It cannot be affected by configuration
-     * variables such as java.io.tmpdir.
-     */
-    public static native String getVMTemporaryDirectory();
-}
--- a/src/java.base/share/classes/sun/misc/resources/Messages.java	Tue Apr 05 18:23:10 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2002, 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc.resources;
-
-/**
- * This class represents the {@code ResourceBundle}
- * for sun.misc.
- *
- * @author Michael Colburn
- */
-
-public class Messages extends java.util.ListResourceBundle {
-
-    /**
-     * Returns the contents of this {@code ResourceBundle}.
-     *
-     * @return the contents of this {@code ResourceBundle}.
-     */
-    public Object[][] getContents() {
-        return contents;
-    }
-
-    private static final Object[][] contents = {
-        { "optpkg.versionerror", "ERROR: Invalid version format used in {0} JAR file. Check the documentation for the supported version format." },
-        { "optpkg.attributeerror", "ERROR: The required {0} JAR manifest attribute is not set in {1} JAR file." },
-        { "optpkg.attributeserror", "ERROR: Some required JAR manifest attributes are not set in {0} JAR file." }
-    };
-
-}
--- a/src/java.base/share/classes/sun/misc/resources/Messages_de.java	Tue Apr 05 18:23:10 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc.resources;
-
-/**
- * This class represents the {@code ResourceBundle}
- * for sun.misc.
- *
- * @author Michael Colburn
- */
-
-public class Messages_de extends java.util.ListResourceBundle {
-
-    /**
-     * Returns the contents of this {@code ResourceBundle}.
-     *
-     * @return the contents of this {@code ResourceBundle}.
-     */
-    public Object[][] getContents() {
-        return contents;
-    }
-
-    private static final Object[][] contents = {
-        { "optpkg.versionerror", "ERROR: In JAR-Datei {0} wurde ein ung\u00FCltiges Versionsformat verwendet. Pr\u00FCfen Sie in der Dokumentation, welches Versionsformat unterst\u00FCtzt wird." },
-        { "optpkg.attributeerror", "ERROR: In JAR-Datei {1} ist das erforderliche JAR-Manifestattribut {0} nicht festgelegt." },
-        { "optpkg.attributeserror", "ERROR: In JAR-Datei {0} sind einige erforderliche JAR-Manifestattribute nicht festgelegt." }
-    };
-
-}
--- a/src/java.base/share/classes/sun/misc/resources/Messages_es.java	Tue Apr 05 18:23:10 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc.resources;
-
-/**
- * This class represents the {@code ResourceBundle}
- * for sun.misc.
- *
- * @author Michael Colburn
- */
-
-public class Messages_es extends java.util.ListResourceBundle {
-
-    /**
-     * Returns the contents of this {@code ResourceBundle}.
-     *
-     * @return the contents of this {@code ResourceBundle}.
-     */
-    public Object[][] getContents() {
-        return contents;
-    }
-
-    private static final Object[][] contents = {
-        { "optpkg.versionerror", "ERROR: el formato del archivo JAR {0} pertenece a una versi\u00F3n no v\u00E1lida. Busque en la documentaci\u00F3n el formato de una versi\u00F3n soportada." },
-        { "optpkg.attributeerror", "ERROR: el atributo obligatorio JAR manifest {0} no est\u00E1 definido en el archivo JAR {1}." },
-        { "optpkg.attributeserror", "ERROR: algunos atributos obligatorios JAR manifest no est\u00E1n definidos en el archivo JAR {0}." }
-    };
-
-}
--- a/src/java.base/share/classes/sun/misc/resources/Messages_fr.java	Tue Apr 05 18:23:10 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc.resources;
-
-/**
- * This class represents the {@code ResourceBundle}
- * for sun.misc.
- *
- * @author Michael Colburn
- */
-
-public class Messages_fr extends java.util.ListResourceBundle {
-
-    /**
-     * Returns the contents of this {@code ResourceBundle}.
-     *
-     * @return the contents of this {@code ResourceBundle}.
-     */
-    public Object[][] getContents() {
-        return contents;
-    }
-
-    private static final Object[][] contents = {
-        { "optpkg.versionerror", "ERREUR\u00A0: le format de version utilis\u00E9 pour le fichier JAR {0} n''est pas valide. Pour conna\u00EEtre le format de version pris en charge, consultez la documentation." },
-        { "optpkg.attributeerror", "ERREUR\u00A0: l''attribut manifest JAR {0} obligatoire n''est pas d\u00E9fini dans le fichier JAR {1}." },
-        { "optpkg.attributeserror", "ERREUR\u00A0: certains attributs manifest JAR obligatoires ne sont pas d\u00E9finis dans le fichier JAR {0}." }
-    };
-
-}
--- a/src/java.base/share/classes/sun/misc/resources/Messages_it.java	Tue Apr 05 18:23:10 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc.resources;
-
-/**
- * This class represents the {@code ResourceBundle}
- * for sun.misc.
- *
- * @author Michael Colburn
- */
-
-public class Messages_it extends java.util.ListResourceBundle {
-
-    /**
-     * Returns the contents of this {@code ResourceBundle}.
-     *
-     * @return the contents of this {@code ResourceBundle}.
-     */
-    public Object[][] getContents() {
-        return contents;
-    }
-
-    private static final Object[][] contents = {
-        { "optpkg.versionerror", "ERRORE: Formato versione non valido nel file JAR {0}. Verificare nella documentazione il formato della versione supportato." },
-        { "optpkg.attributeerror", "ERRORE: L''attributo manifest JAR {0} richiesto non \u00E8 impostato nel file JAR {1}." },
-        { "optpkg.attributeserror", "ERRORE: Alcuni attributi manifesti JAR obbligatori non sono impostati nel file JAR {0}." }
-    };
-
-}
--- a/src/java.base/share/classes/sun/misc/resources/Messages_ja.java	Tue Apr 05 18:23:10 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc.resources;
-
-/**
- * This class represents the {@code ResourceBundle}
- * for sun.misc.
- *
- * @author Michael Colburn
- */
-
-public class Messages_ja extends java.util.ListResourceBundle {
-
-    /**
-     * Returns the contents of this {@code ResourceBundle}.
-     *
-     * @return the contents of this {@code ResourceBundle}.
-     */
-    public Object[][] getContents() {
-        return contents;
-    }
-
-    private static final Object[][] contents = {
-        { "optpkg.versionerror", "\u30A8\u30E9\u30FC: JAR\u30D5\u30A1\u30A4\u30EB{0}\u3067\u7121\u52B9\u306A\u30D0\u30FC\u30B8\u30E7\u30F3\u5F62\u5F0F\u304C\u4F7F\u7528\u3055\u308C\u3066\u3044\u307E\u3059\u3002\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u308B\u30D0\u30FC\u30B8\u30E7\u30F3\u5F62\u5F0F\u306B\u3064\u3044\u3066\u306E\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002" },
-        { "optpkg.attributeerror", "\u30A8\u30E9\u30FC: \u5FC5\u8981\u306AJAR\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u5C5E\u6027{0}\u304CJAR\u30D5\u30A1\u30A4\u30EB{1}\u306B\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002" },
-        { "optpkg.attributeserror", "\u30A8\u30E9\u30FC: \u8907\u6570\u306E\u5FC5\u8981\u306AJAR\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u5C5E\u6027\u304CJAR\u30D5\u30A1\u30A4\u30EB{0}\u306B\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002" }
-    };
-
-}
--- a/src/java.base/share/classes/sun/misc/resources/Messages_ko.java	Tue Apr 05 18:23:10 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc.resources;
-
-/**
- * This class represents the {@code ResourceBundle}
- * for sun.misc.
- *
- * @author Michael Colburn
- */
-
-public class Messages_ko extends java.util.ListResourceBundle {
-
-    /**
-     * Returns the contents of this {@code ResourceBundle}.
-     *
-     * @return the contents of this {@code ResourceBundle}.
-     */
-    public Object[][] getContents() {
-        return contents;
-    }
-
-    private static final Object[][] contents = {
-        { "optpkg.versionerror", "\uC624\uB958: {0} JAR \uD30C\uC77C\uC5D0 \uBD80\uC801\uD569\uD55C \uBC84\uC804 \uD615\uC2DD\uC774 \uC0AC\uC6A9\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uC124\uBA85\uC11C\uC5D0\uC11C \uC9C0\uC6D0\uB418\uB294 \uBC84\uC804 \uD615\uC2DD\uC744 \uD655\uC778\uD558\uC2ED\uC2DC\uC624." },
-        { "optpkg.attributeerror", "\uC624\uB958: \uD544\uC694\uD55C {0} JAR manifest \uC18D\uC131\uC774 {1} JAR \uD30C\uC77C\uC5D0 \uC124\uC815\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4." },
-        { "optpkg.attributeserror", "\uC624\uB958: \uD544\uC694\uD55C \uC77C\uBD80 JAR manifest \uC18D\uC131\uC774 {0} JAR \uD30C\uC77C\uC5D0 \uC124\uC815\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4." }
-    };
-
-}
--- a/src/java.base/share/classes/sun/misc/resources/Messages_pt_BR.java	Tue Apr 05 18:23:10 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc.resources;
-
-/**
- * This class represents the {@code ResourceBundle}
- * for sun.misc.
- *
- * @author Michael Colburn
- */
-
-public class Messages_pt_BR extends java.util.ListResourceBundle {
-
-    /**
-     * Returns the contents of this {@code ResourceBundle}.
-     *
-     * @return the contents of this {@code ResourceBundle}.
-     */
-    public Object[][] getContents() {
-        return contents;
-    }
-
-    private static final Object[][] contents = {
-        { "optpkg.versionerror", "ERRO: formato de vers\u00E3o inv\u00E1lido usado no arquivo JAR {0}. Verifique a documenta\u00E7\u00E3o para obter o formato de vers\u00E3o suportado." },
-        { "optpkg.attributeerror", "ERRO: o atributo de manifesto JAR {0} necess\u00E1rio n\u00E3o est\u00E1 definido no arquivo JAR {1}." },
-        { "optpkg.attributeserror", "ERRO: alguns atributos de manifesto JAR necess\u00E1rios n\u00E3o est\u00E3o definidos no arquivo JAR {0}." }
-    };
-
-}
--- a/src/java.base/share/classes/sun/misc/resources/Messages_sv.java	Tue Apr 05 18:23:10 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc.resources;
-
-/**
- * This class represents the {@code ResourceBundle}
- * for sun.misc.
- *
- * @author Michael Colburn
- */
-
-public class Messages_sv extends java.util.ListResourceBundle {
-
-    /**
-     * Returns the contents of this {@code ResourceBundle}.
-     *
-     * @return the contents of this {@code ResourceBundle}.
-     */
-    public Object[][] getContents() {
-        return contents;
-    }
-
-    private static final Object[][] contents = {
-        { "optpkg.versionerror", "FEL: Ogiltigt versionsformat i {0} JAR-fil. Kontrollera i dokumentationen vilket versionsformat som st\u00F6ds." },
-        { "optpkg.attributeerror", "FEL: Obligatoriskt JAR manifest-attribut {0} \u00E4r inte inst\u00E4llt i {1} JAR-filen." },
-        { "optpkg.attributeserror", "FEL: Vissa obligatoriska JAR manifest-attribut \u00E4r inte inst\u00E4llda i {0} JAR-filen." }
-    };
-
-}
--- a/src/java.base/share/classes/sun/misc/resources/Messages_zh_CN.java	Tue Apr 05 18:23:10 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc.resources;
-
-/**
- * This class represents the {@code ResourceBundle}
- * for sun.misc.
- *
- * @author Michael Colburn
- */
-
-public class Messages_zh_CN extends java.util.ListResourceBundle {
-
-    /**
-     * Returns the contents of this {@code ResourceBundle}.
-     *
-     * @return the contents of this {@code ResourceBundle}.
-     */
-    public Object[][] getContents() {
-        return contents;
-    }
-
-    private static final Object[][] contents = {
-        { "optpkg.versionerror", "\u9519\u8BEF: {0} JAR \u6587\u4EF6\u4E2D\u4F7F\u7528\u7684\u7248\u672C\u683C\u5F0F\u65E0\u6548\u3002\u8BF7\u68C0\u67E5\u6587\u6863\u4EE5\u4E86\u89E3\u652F\u6301\u7684\u7248\u672C\u683C\u5F0F\u3002" },
-        { "optpkg.attributeerror", "\u9519\u8BEF: \u5FC5\u8981\u7684{0} JAR \u6E05\u5355\u5C5E\u6027\u672A\u5728{1} JAR \u6587\u4EF6\u4E2D\u8BBE\u7F6E\u3002" },
-        { "optpkg.attributeserror", "\u9519\u8BEF: \u67D0\u4E9B\u5FC5\u8981\u7684 JAR \u6E05\u5355\u5C5E\u6027\u672A\u5728{0} JAR \u6587\u4EF6\u4E2D\u8BBE\u7F6E\u3002" }
-    };
-
-}
--- a/src/java.base/share/classes/sun/misc/resources/Messages_zh_TW.java	Tue Apr 05 18:23:10 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc.resources;
-
-/**
- * This class represents the {@code ResourceBundle}
- * for sun.misc.
- *
- * @author Michael Colburn
- */
-
-public class Messages_zh_TW extends java.util.ListResourceBundle {
-
-    /**
-     * Returns the contents of this {@code ResourceBundle}.
-     *
-     * @return the contents of this {@code ResourceBundle}.
-     */
-    public Object[][] getContents() {
-        return contents;
-    }
-
-    private static final Object[][] contents = {
-        { "optpkg.versionerror", "\u932F\u8AA4: {0} JAR \u6A94\u4F7F\u7528\u4E86\u7121\u6548\u7684\u7248\u672C\u683C\u5F0F\u3002\u8ACB\u6AA2\u67E5\u6587\u4EF6\uFF0C\u4EE5\u7372\u5F97\u652F\u63F4\u7684\u7248\u672C\u683C\u5F0F\u3002" },
-        { "optpkg.attributeerror", "\u932F\u8AA4: {1} JAR \u6A94\u4E2D\u672A\u8A2D\u5B9A\u5FC5\u8981\u7684 {0} JAR \u8CC7\u8A0A\u6E05\u55AE\u5C6C\u6027\u3002" },
-        { "optpkg.attributeserror", "\u932F\u8AA4: {0} JAR \u6A94\u4E2D\u672A\u8A2D\u5B9A\u67D0\u4E9B\u5FC5\u8981\u7684 JAR \u8CC7\u8A0A\u6E05\u55AE\u5C6C\u6027\u3002" }
-    };
-
-}
--- a/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java	Tue Apr 05 18:23:10 2016 +0300
+++ b/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java	Tue Apr 05 09:17:15 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2010, 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
@@ -299,6 +299,13 @@
             // Just keep throwing for now.
             throw e;
         } catch (FtpProtocolException fe) {
+            if (ftp != null) {
+                try {
+                    ftp.close();
+                } catch (IOException ioe) {
+                    fe.addSuppressed(ioe);
+                }
+            }
             throw new IOException(fe);
         }
         try {
@@ -481,11 +488,34 @@
                 msgh.add("content-type", "text/plain");
                 msgh.add("access-type", "directory");
             } catch (IOException ex) {
-                throw new FileNotFoundException(fullpath);
+                FileNotFoundException fnfe = new FileNotFoundException(fullpath);
+                if (ftp != null) {
+                    try {
+                        ftp.close();
+                    } catch (IOException ioe) {
+                        fnfe.addSuppressed(ioe);
+                    }
+                }
+                throw fnfe;
             } catch (FtpProtocolException ex2) {
-                throw new FileNotFoundException(fullpath);
+                FileNotFoundException fnfe = new FileNotFoundException(fullpath);
+                if (ftp != null) {
+                    try {
+                        ftp.close();
+                    } catch (IOException ioe) {
+                        fnfe.addSuppressed(ioe);
+                    }
+                }
+                throw fnfe;
             }
         } catch (FtpProtocolException ftpe) {
+            if (ftp != null) {
+                try {
+                    ftp.close();
+                } catch (IOException ioe) {
+                    ftpe.addSuppressed(ioe);
+                }
+            }
             throw new IOException(ftpe);
         }
         setProperties(msgh);
--- a/src/java.base/share/classes/sun/util/resources/LocaleData.java	Tue Apr 05 18:23:10 2016 +0300
+++ b/src/java.base/share/classes/sun/util/resources/LocaleData.java	Tue Apr 05 09:17:15 2016 -0700
@@ -197,8 +197,6 @@
 
     private static abstract class LocaleDataResourceBundleProvider
                                             implements ResourceBundleProvider {
-        abstract protected boolean isSupportedInModule(String baseName, Locale locale);
-
         /**
          * Changes baseName to its module dependent package name and
          * calls the super class implementation. For example,
@@ -217,10 +215,6 @@
      * resource bundles except for the java.time supplementary data.
      */
     public static abstract class CommonResourceBundleProvider extends LocaleDataResourceBundleProvider {
-        @Override
-        protected boolean isSupportedInModule(String baseName, Locale locale) {
-            return LocaleDataStrategy.INSTANCE.inJavaBaseModule(baseName, locale);
-        }
     }
 
     /**
@@ -228,10 +222,6 @@
      * resource bundles for java.time.
      */
     public static abstract class SupplementaryResourceBundleProvider extends LocaleDataResourceBundleProvider {
-        @Override
-        protected boolean isSupportedInModule(String baseName, Locale locale) {
-            return SupplementaryStrategy.INSTANCE.inJavaBaseModule(baseName, locale);
-        }
     }
 
     // Bundles.Strategy implementations
--- a/src/java.base/share/native/libjava/GC.c	Tue Apr 05 18:23:10 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <jni.h>
-#include <jvm.h>
-#include "sun_misc_GC.h"
-
-
-JNIEXPORT jlong JNICALL
-Java_sun_misc_GC_maxObjectInspectionAge(JNIEnv *env, jclass cls)
-{
-    return JVM_MaxObjectInspectionAge();
-}
--- a/src/java.base/share/native/libjava/VMSupport.c	Tue Apr 05 18:23:10 2016 +0300
+++ b/src/java.base/share/native/libjava/VMSupport.c	Tue Apr 05 09:17:15 2016 -0700
@@ -27,36 +27,17 @@
 #include "jni_util.h"
 #include "jlong.h"
 #include "jvm.h"
-#include "jdk_util.h"
 
-#include "sun_misc_VMSupport.h"
-
-typedef jobject (JNICALL *INIT_AGENT_PROPERTIES_FN)(JNIEnv *, jobject);
-
-static INIT_AGENT_PROPERTIES_FN InitAgentProperties_fp = NULL;
+#include "jdk_internal_vm_VMSupport.h"
 
 JNIEXPORT jobject JNICALL
-Java_sun_misc_VMSupport_initAgentProperties(JNIEnv *env, jclass cls, jobject props)
+Java_jdk_internal_vm_VMSupport_initAgentProperties(JNIEnv *env, jclass cls, jobject props)
 {
-    if (InitAgentProperties_fp == NULL) {
-        if (!JDK_InitJvmHandle()) {
-            JNU_ThrowInternalError(env,
-                 "Handle for JVM not found for symbol lookup");
-            return NULL;
-        }
-        InitAgentProperties_fp = (INIT_AGENT_PROPERTIES_FN)
-            JDK_FindJvmEntry("JVM_InitAgentProperties");
-        if (InitAgentProperties_fp == NULL) {
-            JNU_ThrowInternalError(env,
-                 "Mismatched VM version: JVM_InitAgentProperties not found");
-            return NULL;
-        }
-    }
-    return (*InitAgentProperties_fp)(env, props);
+    return JVM_InitAgentProperties(env, props);
 }
 
 JNIEXPORT jstring JNICALL
-Java_sun_misc_VMSupport_getVMTemporaryDirectory(JNIEnv *env, jclass cls)
+Java_jdk_internal_vm_VMSupport_getVMTemporaryDirectory(JNIEnv *env, jclass cls)
 {
     return JVM_GetTemporaryDirectory(env);
 }
--- a/src/java.management/share/classes/sun/management/Agent.java	Tue Apr 05 18:23:10 2016 +0300
+++ b/src/java.management/share/classes/sun/management/Agent.java	Tue Apr 05 09:17:15 2016 -0700
@@ -52,7 +52,7 @@
 import sun.management.jmxremote.ConnectorBootstrap;
 import sun.management.jdp.JdpController;
 import sun.management.jdp.JdpException;
-import sun.misc.VMSupport;
+import jdk.internal.vm.VMSupport;
 
 /**
  * This Agent is started by the VM when -Dcom.sun.management.snmp or
--- a/src/java.rmi/share/classes/sun/rmi/transport/DGCClient.java	Tue Apr 05 18:23:10 2016 +0300
+++ b/src/java.rmi/share/classes/sun/rmi/transport/DGCClient.java	Tue Apr 05 09:17:15 2016 -0700
@@ -41,7 +41,6 @@
 import java.rmi.dgc.Lease;
 import java.rmi.dgc.VMID;
 import java.rmi.server.ObjID;
-import sun.misc.GC;
 import sun.rmi.runtime.NewThreadAction;
 import sun.rmi.server.UnicastRef;
 import sun.rmi.server.Util;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.rmi/share/classes/sun/rmi/transport/GC.java	Tue Apr 05 09:17:15 2016 -0700
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.rmi.transport;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+
+/**
+ * Support for garbage-collection latency requests.
+ *
+ * @author   Mark Reinhold
+ * @since    1.2
+ */
+
+class GC {
+
+    private GC() { }            /* To prevent instantiation */
+
+
+    /* Latency-target value indicating that there's no active target
+     */
+    private static final long NO_TARGET = Long.MAX_VALUE;
+
+    /* The current latency target, or NO_TARGET if there is no target
+     */
+    private static long latencyTarget = NO_TARGET;
+
+    /* The daemon thread that implements the latency-target mechanism,
+     * or null if there is presently no daemon thread
+     */
+    private static Thread daemon = null;
+
+    /* The lock object for the latencyTarget and daemon fields.  The daemon
+     * thread, if it exists, waits on this lock for notification that the
+     * latency target has changed.
+     */
+    private static class LatencyLock extends Object { };
+    private static Object lock = new LatencyLock();
+
+
+    /**
+     * Returns the maximum <em>object-inspection age</em>, which is the number
+     * of real-time milliseconds that have elapsed since the
+     * least-recently-inspected heap object was last inspected by the garbage
+     * collector.
+     *
+     * <p> For simple stop-the-world collectors this value is just the time
+     * since the most recent collection.  For generational collectors it is the
+     * time since the oldest generation was most recently collected.  Other
+     * collectors are free to return a pessimistic estimate of the elapsed
+     * time, or simply the time since the last full collection was performed.
+     *
+     * <p> Note that in the presence of reference objects, a given object that
+     * is no longer strongly reachable may have to be inspected multiple times
+     * before it can be reclaimed.
+     */
+    public static native long maxObjectInspectionAge();
+
+    static {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
+                System.loadLibrary("rmi");
+                return null;
+            }});
+    }
+
+    private static class Daemon extends Thread {
+
+        public void run() {
+            for (;;) {
+                long l;
+                synchronized (lock) {
+
+                    l = latencyTarget;
+                    if (l == NO_TARGET) {
+                        /* No latency target, so exit */
+                        GC.daemon = null;
+                        return;
+                    }
+
+                    long d = maxObjectInspectionAge();
+                    if (d >= l) {
+                        /* Do a full collection.  There is a remote possibility
+                         * that a full collection will occurr between the time
+                         * we sample the inspection age and the time the GC
+                         * actually starts, but this is sufficiently unlikely
+                         * that it doesn't seem worth the more expensive JVM
+                         * interface that would be required.
+                         */
+                        System.gc();
+                        d = 0;
+                    }
+
+                    /* Wait for the latency period to expire,
+                     * or for notification that the period has changed
+                     */
+                    try {
+                        lock.wait(l - d);
+                    } catch (InterruptedException x) {
+                        continue;
+                    }
+                }
+            }
+        }
+
+        private Daemon(ThreadGroup tg) {
+            super(tg, null, "GC Daemon", 0L, false);
+        }
+
+        /* Create a new daemon thread in the root thread group */
+        public static void create() {
+            PrivilegedAction<Void> pa = new PrivilegedAction<Void>() {
+                public Void run() {
+                    ThreadGroup tg = Thread.currentThread().getThreadGroup();
+                    for (ThreadGroup tgn = tg;
+                         tgn != null;
+                         tg = tgn, tgn = tg.getParent());
+                    Daemon d = new Daemon(tg);
+                    d.setDaemon(true);
+                    d.setPriority(Thread.MIN_PRIORITY + 1);
+                    d.start();
+                    GC.daemon = d;
+                    return null;
+                }};
+            AccessController.doPrivileged(pa);
+        }
+
+    }
+
+
+    /* Sets the latency target to the given value.
+     * Must be invoked while holding the lock.
+     */
+    private static void setLatencyTarget(long ms) {
+        latencyTarget = ms;
+        if (daemon == null) {
+            /* Create a new daemon thread */
+            Daemon.create();
+        } else {
+            /* Notify the existing daemon thread
+             * that the lateency target has changed
+             */
+            lock.notify();
+        }
+    }
+
+
+    /**
+     * Represents an active garbage-collection latency request.  Instances of
+     * this class are created by the <code>{@link #requestLatency}</code>
+     * method.  Given a request, the only interesting operation is that of
+     * cancellation.
+     */
+    public static class LatencyRequest
+        implements Comparable<LatencyRequest> {
+
+        /* Instance counter, used to generate unique identifers */
+        private static long counter = 0;
+
+        /* Sorted set of active latency requests */
+        private static SortedSet<LatencyRequest> requests = null;
+
+        /* Examine the request set and reset the latency target if necessary.
+         * Must be invoked while holding the lock.
+         */
+        private static void adjustLatencyIfNeeded() {
+            if ((requests == null) || requests.isEmpty()) {
+                if (latencyTarget != NO_TARGET) {
+                    setLatencyTarget(NO_TARGET);
+                }
+            } else {
+                LatencyRequest r = requests.first();
+                if (r.latency != latencyTarget) {
+                    setLatencyTarget(r.latency);
+                }
+            }
+        }
+
+        /* The requested latency, or NO_TARGET
+         * if this request has been cancelled
+         */
+        private long latency;
+
+        /* Unique identifier for this request */
+        private long id;
+
+        private LatencyRequest(long ms) {
+            if (ms <= 0) {
+                throw new IllegalArgumentException("Non-positive latency: "
+                                                   + ms);
+            }
+            this.latency = ms;
+            synchronized (lock) {
+                this.id = ++counter;
+                if (requests == null) {
+                    requests = new TreeSet<LatencyRequest>();
+                }
+                requests.add(this);
+                adjustLatencyIfNeeded();
+            }
+        }
+
+        /**
+         * Cancels this latency request.
+         *
+         * @throws  IllegalStateException
+         *          If this request has already been cancelled
+         */
+        public void cancel() {
+            synchronized (lock) {
+                if (this.latency == NO_TARGET) {
+                    throw new IllegalStateException("Request already"
+                                                    + " cancelled");
+                }
+                if (!requests.remove(this)) {
+                    throw new InternalError("Latency request "
+                                            + this + " not found");
+                }
+                if (requests.isEmpty()) requests = null;
+                this.latency = NO_TARGET;
+                adjustLatencyIfNeeded();
+            }
+        }
+
+        public int compareTo(LatencyRequest r) {
+            long d = this.latency - r.latency;
+            if (d == 0) d = this.id - r.id;
+            return (d < 0) ? -1 : ((d > 0) ? +1 : 0);
+        }
+
+        public String toString() {
+            return (LatencyRequest.class.getName()
+                    + "[" + latency + "," + id + "]");
+        }
+
+    }
+
+
+    /**
+     * Makes a new request for a garbage-collection latency of the given
+     * number of real-time milliseconds.  A low-priority daemon thread makes a
+     * best effort to ensure that the maximum object-inspection age never
+     * exceeds the smallest of the currently active requests.
+     *
+     * @param   latency
+     *          The requested latency
+     *
+     * @throws  IllegalArgumentException
+     *          If the given <code>latency</code> is non-positive
+     */
+    public static LatencyRequest requestLatency(long latency) {
+        return new LatencyRequest(latency);
+    }
+
+
+    /**
+     * Returns the current smallest garbage-collection latency request, or zero
+     * if there are no active requests.
+     */
+    public static long currentLatencyTarget() {
+        long t = latencyTarget;
+        return (t == NO_TARGET) ? 0 : t;
+    }
+
+}
--- a/src/java.rmi/share/classes/sun/rmi/transport/ObjectTable.java	Tue Apr 05 18:23:10 2016 +0300
+++ b/src/java.rmi/share/classes/sun/rmi/transport/ObjectTable.java	Tue Apr 05 09:17:15 2016 -0700
@@ -34,7 +34,6 @@
 import java.security.PrivilegedAction;
 import java.util.HashMap;
 import java.util.Map;
-import sun.misc.GC;
 import sun.rmi.runtime.Log;
 import sun.rmi.runtime.NewThreadAction;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.rmi/share/native/librmi/GC.c	Tue Apr 05 09:17:15 2016 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <jni.h>
+#include <jvm.h>
+#include "sun_rmi_transport_GC.h"
+
+
+JNIEXPORT jlong JNICALL
+Java_sun_rmi_transport_GC_maxObjectInspectionAge(JNIEnv *env, jclass cls)
+{
+    return JVM_MaxObjectInspectionAge();
+}
--- a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/KeyStore.java	Tue Apr 05 18:23:10 2016 +0300
+++ b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/KeyStore.java	Tue Apr 05 09:17:15 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, 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
@@ -188,8 +188,10 @@
 
     /*
      * The keystore entries.
+     * Keys in the map are unique aliases (thus can differ from
+     * KeyEntry.getAlias())
      */
-    private Collection<KeyEntry> entries = new ArrayList<KeyEntry>();
+    private Map<String,KeyEntry> entries = new HashMap<>();
 
     /*
      * The keystore name.
@@ -248,13 +250,10 @@
         if (engineIsKeyEntry(alias) == false)
             return null;
 
-        for (KeyEntry entry : entries) {
-            if (alias.equals(entry.getAlias())) {
-                return entry.getPrivateKey();
-            }
-        }
-
-        return null;
+        KeyEntry entry = entries.get(alias);
+        return (entry == null)
+                ? null
+                : entry.getPrivateKey();
     }
 
     /**
@@ -274,15 +273,13 @@
             return null;
         }
 
-        for (KeyEntry entry : entries) {
-            if (alias.equals(entry.getAlias())) {
-                X509Certificate[] certChain = entry.getCertificateChain();
-
-                return certChain.clone();
-            }
-        }
-
-        return null;
+        KeyEntry entry = entries.get(alias);
+        X509Certificate[] certChain = (entry == null)
+                ? null
+                : entry.getCertificateChain();
+        return (certChain == null)
+                ? null
+                : certChain.clone();
     }
 
     /**
@@ -306,15 +303,13 @@
             return null;
         }
 
-        for (KeyEntry entry : entries) {
-            if (alias.equals(entry.getAlias()))
-            {
-                X509Certificate[] certChain = entry.getCertificateChain();
-                return certChain.length == 0 ? null : certChain[0];
-            }
-        }
-
-        return null;
+        KeyEntry entry = entries.get(alias);
+        X509Certificate[] certChain = (entry == null)
+                ? null
+                : entry.getCertificateChain();
+        return (certChain == null || certChain.length == 0)
+                ? null
+                : certChain[0];
     }
 
     /**
@@ -378,16 +373,7 @@
 
         if (key instanceof RSAPrivateCrtKey) {
 
-            KeyEntry entry = null;
-            boolean found = false;
-
-            for (KeyEntry e : entries) {
-                if (alias.equals(e.getAlias())) {
-                    found = true;
-                    entry = e;
-                    break;
-                }
-            }
+            KeyEntry entry = entries.get(alias);
 
             X509Certificate[] xchain;
             if (chain != null) {
@@ -401,11 +387,11 @@
                 xchain = null;
             }
 
-            if (! found) {
+            if (entry == null) {
                 entry =
                     //TODO new KeyEntry(alias, key, (X509Certificate[]) chain);
                     new KeyEntry(alias, null, xchain);
-                entries.add(entry);
+                storeWithUniqueAlias(alias, entry);
             }
 
             entry.setAlias(alias);
@@ -484,23 +470,14 @@
             // TODO - build CryptoAPI chain?
             X509Certificate[] chain =
                 new X509Certificate[]{ (X509Certificate) cert };
-            KeyEntry entry = null;
-            boolean found = false;
+            KeyEntry entry = entries.get(alias);
 
-            for (KeyEntry e : entries) {
-                if (alias.equals(e.getAlias())) {
-                    found = true;
-                    entry = e;
-                    break;
-                }
+            if (entry == null) {
+                entry =
+                    new KeyEntry(alias, null, chain);
+                storeWithUniqueAlias(alias, entry);
             }
 
-            if (! found) {
-                entry =
-                    new KeyEntry(alias, null, chain);
-                entries.add(entry);
-
-            }
             if (entry.getPrivateKey() == null) { // trusted-cert entry
                 entry.setAlias(alias);
 
@@ -532,32 +509,26 @@
             throw new KeyStoreException("alias must not be null");
         }
 
-        for (KeyEntry entry : entries) {
-            if (alias.equals(entry.getAlias())) {
+        KeyEntry entry = entries.remove(alias);
+        if (entry != null) {
+            // Get end-entity certificate and remove from system cert store
+            X509Certificate[] certChain = entry.getCertificateChain();
+            if (certChain != null) {
 
-                // Get end-entity certificate and remove from system cert store
-                X509Certificate[] certChain = entry.getCertificateChain();
-                if (certChain != null) {
+                try {
 
-                    try {
-
-                        byte[] encoding = certChain[0].getEncoded();
-                        removeCertificate(getName(), alias, encoding,
+                    byte[] encoding = certChain[0].getEncoded();
+                    removeCertificate(getName(), entry.getAlias(), encoding,
                             encoding.length);
 
-                    } catch (CertificateException e) {
-                        throw new KeyStoreException("Cannot remove entry: " +
-                            e);
-                    }
+                } catch (CertificateException e) {
+                    throw new KeyStoreException("Cannot remove entry: ", e);
                 }
-                Key privateKey = entry.getPrivateKey();
-                if (privateKey != null) {
-                    destroyKeyContainer(
-                        Key.getContainerName(privateKey.getHCryptProvider()));
-                }
-
-                entries.remove(entry);
-                break;
+            }
+            Key privateKey = entry.getPrivateKey();
+            if (privateKey != null) {
+                destroyKeyContainer(
+                    Key.getContainerName(privateKey.getHCryptProvider()));
             }
         }
     }