changeset 12529:e8fbe86a8ca7

Merge
author mchung
date Tue, 21 Apr 2015 16:49:28 -0700
parents 80dd13a0b46c 15191ebbe2ab
children 89eaf42779b6
files make/CompileDemos.gmk make/Tools.gmk make/copy/Copy-java.base.gmk make/gensrc/Gensrc-jdk.dev.gmk make/gensrc/GensrcMisc.gmk make/gensrc/GensrcModuleInfo.gmk make/gensrc/GensrcModuleLoaderMap.gmk make/lib/Awt2dLibraries.gmk make/lib/CoreLibraries.gmk make/lib/NetworkingLibraries.gmk make/lib/NioLibraries.gmk make/lib/PlatformLibraries.gmk make/lib/SoundLibraries.gmk make/src/classes/build/tools/module/ImageBuilder.java make/src/classes/build/tools/module/ModuleArchive.java make/src/classes/build/tools/module/boot.modules make/src/classes/build/tools/module/ext.modules src/java.base/share/classes/java/lang/ref/Finalizer.java src/java.base/share/classes/jdk/internal/jimage/ImageFile.java src/java.base/share/classes/jdk/internal/jimage/ImageModules.java src/java.base/share/classes/jdk/internal/jimage/PReader.java src/java.base/share/classes/jdk/internal/jimage/PackageModuleMap.java src/java.base/share/classes/jdk/internal/jimage/Resource.java src/java.base/share/classes/jdk/internal/jimage/concurrent/ConcurrentPReader.java src/java.base/share/classes/module-info.java src/java.base/share/classes/sun/misc/Launcher.java src/java.base/share/conf/security/java.security src/java.base/share/native/libjava/Package.c src/java.base/unix/native/libjava/ConcurrentPReader_md.c src/java.base/windows/conf/security/java.policy src/java.base/windows/native/libjava/ConcurrentPReader_md.c src/java.logging/share/classes/java/util/logging/LogManager.java src/jdk.crypto.ec/share/classes/sun/security/ec/SunECEntries.java src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/SunPKCS11.java src/jdk.dev/share/classes/jdk/tools/jimage/JImageTask.java src/jdk.dev/share/classes/jdk/tools/jimage/Main.java src/jdk.dev/share/classes/jdk/tools/jimage/resources/jimage.properties test/TEST.groups test/javax/management/remote/mandatory/notif/NotSerializableNotifTest.java test/sun/management/jmxremote/bootstrap/RmiSslBootstrapTest.sh test/sun/security/krb5/auto/SSL.java
diffstat 1746 files changed, 53545 insertions(+), 7417 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Tue Apr 21 13:21:40 2015 -0700
+++ b/.hgignore	Tue Apr 21 16:49:28 2015 -0700
@@ -7,3 +7,4 @@
 ^make/netbeans/.*/dist/
 ^.hgtip
 .DS_Store
+^src_shuffled/
--- a/.jcheck/conf	Tue Apr 21 13:21:40 2015 -0700
+++ b/.jcheck/conf	Tue Apr 21 16:49:28 2015 -0700
@@ -1,1 +1,4 @@
 project=jdk9
+comments=lax
+tags=lax
+bugids=dup
--- a/make/CompileInterimRmic.gmk	Tue Apr 21 13:21:40 2015 -0700
+++ b/make/CompileInterimRmic.gmk	Tue Apr 21 16:49:28 2015 -0700
@@ -45,6 +45,7 @@
     SETUP := GENERATE_OLDBYTECODE, \
     SRC := $(JDK_TOPDIR)/src/jdk.rmic/share/classes, \
     INCLUDES := $(RMIC_PKGS), \
+    EXCLUDE_FILES := module-info.java, \
     BIN := $(BUILDTOOLS_OUTPUTDIR)/interim_rmic_classes, \
     COPY := .properties))
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/GenerateModuleSummary.gmk	Tue Apr 21 16:49:28 2015 -0700
@@ -0,0 +1,47 @@
+#
+# 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.
+#
+
+# Default target declared first
+default: all
+
+include $(SPEC)
+include MakeBase.gmk
+include ModuleTools.gmk
+
+GENGRAPHS_DIR := $(IMAGES_OUTPUTDIR)/gengraphs
+TOOLS_MODULE_SRCDIR := $(JDK_TOPDIR)/make/src/classes/build/tools/jigsaw
+
+$(GENGRAPHS_DIR)/jdk.dot: $(BUILD_JIGSAW_TOOLS)
+	$(MKDIR) -p $(@D)
+	$(TOOL_GENGRAPHS) $(GENGRAPHS_DIR)
+
+$(GENGRAPHS_DIR)/technology-summary.html: $(TOOLS_MODULE_SRCDIR)/technology-summary.html
+	$(install-file)
+
+$(GENGRAPHS_DIR)/module-summary.html: $(BUILD_JIGSAW_TOOLS) $(GENGRAPHS_DIR)/technology-summary.html
+	$(MKDIR) -p $(@D)
+	$(TOOL_MODULESUMMARY) -o $@ -mp $(IMAGES_OUTPUTDIR)/jmods
+
+all: $(GENGRAPHS_DIR)/jdk.dot $(GENGRAPHS_DIR)/module-summary.html
--- a/make/Import.gmk	Tue Apr 21 13:21:40 2015 -0700
+++ b/make/Import.gmk	Tue Apr 21 16:49:28 2015 -0700
@@ -203,29 +203,17 @@
 
 ################################################################################
 
-$(JDK_OUTPUTDIR)/modules/jdk.hotspot.agent/_the.sa.jar.unpacked: $(HOTSPOT_DIST)/lib/sa-jdi.jar \
-    $(SUPPORT_OUTPUTDIR)/gensrc/jdk.hotspot.agent/_the.sa.services
+$(JDK_OUTPUTDIR)/modules/jdk.hotspot.agent/_the.sa.jar.unpacked: $(HOTSPOT_DIST)/lib/sa-jdi.jar
 	$(ECHO) $(LOG_INFO) Unzipping $(<F)
 	$(RM) -r $(@D)
 	$(MKDIR) -p $(@D)
 	$(CD) $(@D) && $(UNZIP) $< -x META-INF/MANIFEST.MF $(LOG_DEBUG)
-        # We must move the service provider file out of the way so that
-        # Gensrc-jdk.jdi.gmk can combine them.
-	$(MKDIR) -p $(SUPPORT_OUTPUTDIR)/gensrc/jdk.hotspot.agent
-	$(MV) $(JDK_OUTPUTDIR)/modules/jdk.hotspot.agent/META-INF/services/com.sun.jdi.connect.Connector \
-	    $(SUPPORT_OUTPUTDIR)/gensrc/jdk.hotspot.agent/_the.sa.services
-	$(TOUCH) $(SUPPORT_OUTPUTDIR)/gensrc/jdk.hotspot.agent/_the.sa.services
 	$(TOUCH) $@
 
-# Declaring this dependency guarantees that _the.sa.services will be rebuilt
-# even if zip is already unpacked.
-$(SUPPORT_OUTPUTDIR)/gensrc/jdk.hotspot.agent/_the.sa.services: $(HOTSPOT_DIST)/lib/sa-jdi.jar
-
 # Some platforms don't have the serviceability agent
 ifeq (, $(filter $(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU), aix-ppc64))
   ifneq ($(JVM_VARIANT_ZERO), true)
-    SA_TARGETS += $(JDK_OUTPUTDIR)/modules/jdk.hotspot.agent/_the.sa.jar.unpacked \
-        $(SUPPORT_OUTPUTDIR)/gensrc/jdk.hotspot.agent/_the.sa.services
+    SA_TARGETS += $(JDK_OUTPUTDIR)/modules/jdk.hotspot.agent/_the.sa.jar.unpacked
   endif
 endif
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/ModuleTools.gmk	Tue Apr 21 16:49:28 2015 -0700
@@ -0,0 +1,47 @@
+#
+# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  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 $(SPEC)
+include MakeBase.gmk
+include JavaCompilation.gmk
+include SetupJavaCompilers.gmk
+
+TOOLS_CLASSES_DIR := $(BUILDTOOLS_OUTPUTDIR)/tools_jigsaw_classes
+
+$(eval $(call SetupJavaCompilation,BUILD_JIGSAW_TOOLS, \
+    SETUP := GENERATE_USINGJDKBYTECODE, \
+    SRC := $(JDK_TOPDIR)/make/src/classes, \
+    INCLUDES := build/tools/deps \
+                build/tools/jigsaw, \
+    BIN := $(TOOLS_CLASSES_DIR), \
+    ADD_JAVAC_FLAGS := -XX:AddModuleExports=jdk.compiler/com.sun.tools.classfile ))
+
+
+TOOL_GENGRAPHS := $(BUILD_JAVA) -esa -ea -cp $(TOOLS_CLASSES_DIR) \
+    build.tools.jigsaw.GenGraphs
+
+TOOL_MODULESUMMARY := $(BUILD_JAVA) -esa -ea -cp $(TOOLS_CLASSES_DIR) \
+    -XX:AddModuleExports=jdk.compiler/com.sun.tools.classfile \
+    build.tools.jigsaw.ModuleSummary
--- a/make/Tools.gmk	Tue Apr 21 13:21:40 2015 -0700
+++ b/make/Tools.gmk	Tue Apr 21 16:49:28 2015 -0700
@@ -38,10 +38,10 @@
 
 $(eval $(call SetupJavaCompilation,BUILD_TOOLS_JDK, \
     SETUP := GENERATE_OLDBYTECODE, \
-    ADD_JAVAC_FLAGS := "-Xbootclasspath/p:$(BUILDTOOLS_OUTPUTDIR)/interim_jimage_classes", \
     SRC := $(JDK_TOPDIR)/make/src/classes, \
-    BIN := $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes, \
-    COPY := boot.modules ext.modules))
+    EXCLUDES := build/tools/deps \
+                build/tools/jigsaw, \
+    BIN := $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes))
 
 $(eval $(call SetupCopyFiles,COPY_NIMBUS_TEMPLATES, \
     SRC := $(JDK_TOPDIR)/src/java.desktop/share/classes/javax/swing/plaf/nimbus, \
@@ -126,35 +126,16 @@
     build.tools.cldrconverter.CLDRConverter
 
 TOOL_GENMODULESXML = $(JAVA_SMALL) -Xbootclasspath/p:$(INTERIM_LANGTOOLS_JAR) \
-    -cp "$(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes$(PATH_SEP)$(JDK_OUTPUTDIR)" \
+    -cp "$(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes" \
     build.tools.module.GenJdepsModulesXml
 
-TOOL_IMAGEBUILDER = $(JAVA_SMALL) -Xbootclasspath/p:$(BUILDTOOLS_OUTPUTDIR)/interim_jimage_classes \
-    -cp "$(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes$(PATH_SEP)$(JDK_OUTPUTDIR)" \
-    build.tools.module.ImageBuilder
+TOOL_GENMODULEINFOSOURCE = $(JAVA_SMALL) -Xbootclasspath/p:$(INTERIM_LANGTOOLS_JAR) \
+    -cp "$(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes" \
+    build.tools.module.GenModuleInfoSource
 
-##########################################################################################
-
-JIMAGE_PKGS := \
-    jdk/internal/jimage \
-    jdk/internal/jrtfs \
-    #
-
-$(eval $(call SetupJavaCompilation,BUILD_INTERIM_JIMAGE, \
-    SETUP := GENERATE_OLDBYTECODE, \
-    SRC := $(JDK_TOPDIR)/src/java.base/share/classes, \
-    INCLUDES := $(JIMAGE_PKGS), \
-    EXCLUDES := jdk/internal/jimage/concurrent, \
-    BIN := $(BUILDTOOLS_OUTPUTDIR)/interim_jimage_classes))
-
-# Because of the explicit INCLUDES in the compilation setup above, the service provider
-# file will not be copied unless META-INF/services would also be added to the INCLUDES.
-# Adding META-INF/services would include all files in that directory when only the one
-# is needed, which is why this explicit copy is defined instead.
-$(eval $(call SetupCopyFiles,COPY_JIMAGE_SERVICE_PROVIDER, \
-    SRC := $(JDK_TOPDIR)/src/java.base/share/classes, \
-    DEST := $(BUILDTOOLS_OUTPUTDIR)/interim_jimage_classes, \
-    FILES := META-INF/services/java.nio.file.spi.FileSystemProvider))
+TOOL_GENCLASSLOADERMAP = $(JAVA_SMALL) -Xbootclasspath/p:$(INTERIM_LANGTOOLS_JAR) \
+    -cp "$(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes" \
+    build.tools.module.GenModuleLoaderMap
 
 ##########################################################################################
 
@@ -180,8 +161,6 @@
   BUILD_TOOLS_JDK += $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS)
 endif
 
-$(BUILD_TOOLS_JDK): $(BUILD_INTERIM_JIMAGE) $(COPY_JIMAGE_SERVICE_PROVIDER)
-
 java-tools: $(BUILD_TOOLS_JDK)
 
 all: java-tools
--- a/make/copy/Copy-java.base.gmk	Tue Apr 21 13:21:40 2015 -0700
+++ b/make/copy/Copy-java.base.gmk	Tue Apr 21 16:49:28 2015 -0700
@@ -210,4 +210,4 @@
   TARGETS += $(CONF_DST_DIR)/sdp/sdp.conf.template
 endif
 
-################################################################################
+##########################################################################################
--- a/make/gendata/Gendata-jdk.dev.gmk	Tue Apr 21 13:21:40 2015 -0700
+++ b/make/gendata/Gendata-jdk.dev.gmk	Tue Apr 21 16:49:28 2015 -0700
@@ -37,6 +37,6 @@
 $(JDEPS_MODULES_XML): $(BUILD_TOOLS_JDK) $(MODULES_XML)
 	$(MKDIR) -p $(@D)
 	$(RM) $@
-	$(TOOL_GENMODULESXML) -o $@ -mp $(JDK_OUTPUTDIR)/modules $(MODULES_XML)
+	$(TOOL_GENMODULESXML) -o $@ $(MODULES_XML)
 
 TARGETS += $(JDEPS_MODULES_XML)
--- a/make/gensrc/Gensrc-java.base.gmk	Tue Apr 21 13:21:40 2015 -0700
+++ b/make/gensrc/Gensrc-java.base.gmk	Tue Apr 21 16:49:28 2015 -0700
@@ -32,6 +32,8 @@
 include GensrcCharsetCoder.gmk
 include GensrcBuffer.gmk
 include GensrcExceptions.gmk
+include GensrcModuleLoaderMap.gmk
+include GensrcModuleInfo.gmk
 
 ################################################################################
 
--- a/make/gensrc/Gensrc-java.desktop.gmk	Tue Apr 21 13:21:40 2015 -0700
+++ b/make/gensrc/Gensrc-java.desktop.gmk	Tue Apr 21 16:49:28 2015 -0700
@@ -24,6 +24,7 @@
 #
 
 include GensrcCommon.gmk
+include GensrcModuleInfo.gmk
 
 # Hook to include the corresponding custom file, if present.
 $(eval $(call IncludeCustomExtension, jdk, gensrc/Gensrc-java.desktop.gmk))
--- a/make/gensrc/Gensrc-java.management.gmk	Tue Apr 21 13:21:40 2015 -0700
+++ b/make/gensrc/Gensrc-java.management.gmk	Tue Apr 21 16:49:28 2015 -0700
@@ -24,10 +24,13 @@
 #
 
 include GensrcCommon.gmk
+include GensrcModuleInfo.gmk
 
 # Hook to include the corresponding custom file, if present.
 $(eval $(call IncludeCustomExtension, jdk, gensrc/Gensrc-java.management.gmk))
 
+TARGETS += $(GENSRC_JAVA_MANAGEMENT)
+
 ################################################################################
 
 include GensrcProperties.gmk
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/gensrc/Gensrc-java.rmi.gmk	Tue Apr 21 16:49:28 2015 -0700
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+include GensrcCommon.gmk
+
+include GensrcModuleInfo.gmk
+
+java.rmi: $(GENSRC_JAVA_RMI)
+
+all: java.rmi
+
+.PHONY: all
--- a/make/gensrc/Gensrc-jdk.dev.gmk	Tue Apr 21 13:21:40 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-#
-# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.  Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-include GensrcCommon.gmk
-
-################################################################################
-
-include GensrcProperties.gmk
-
-$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \
-    $(filter %.properties, \
-        $(call CacheFind, \
-            $(JDK_TOPDIR)/src/jdk.dev/share/classes/jdk/tools/jimage/resources)), \
-    ListResourceBundle))
-
-TARGETS += $(COMPILE_PROPERTIES)
-
-################################################################################
-
-all: $(TARGETS)
-
-.PHONY: all
--- a/make/gensrc/Gensrc-jdk.jdi.gmk	Tue Apr 21 13:21:40 2015 -0700
+++ b/make/gensrc/Gensrc-jdk.jdi.gmk	Tue Apr 21 16:49:28 2015 -0700
@@ -24,6 +24,24 @@
 #
 
 include GensrcCommon.gmk
+include GensrcModuleInfo.gmk
+
+################################################################################
+ifeq ($(OPENJDK_TARGET_OS), windows)
+  # Add shared memory connector provider
+  JDK_JDI_MODULEINFO_EXTRAS = \
+    -provide com.sun.jdi.connect.Connector/com.sun.tools.jdi.SharedMemoryAttachingConnector \
+    -provide com.sun.jdi.connect.Connector/com.sun.tools.jdi.SharedMemoryListeningConnector
+endif
+
+$(SUPPORT_OUTPUTDIR)/gensrc/jdk.jdi/module-info.java: $(BUILD_TOOLS_JDK) \
+    $(JDK_TOPDIR)/src/jdk.jdi/share/classes/module-info.java
+	$(MKDIR) -p $(@D)
+	$(RM) $@ $@.tmp
+	$(TOOL_GENMODULEINFOSOURCE) $(JDK_JDI_MODULEINFO_EXTRAS) -o $@.tmp $(filter %.java, $^)
+	$(MV) $@.tmp $@
+
+GENSRC_JDK_JDI += $(SUPPORT_OUTPUTDIR)/gensrc/jdk.jdi/module-info.java
 
 ################################################################################
 # Translate the Java debugger wire protocol (jdwp.spec) file into a JDWP.java file
@@ -69,22 +87,10 @@
 
 # Filter com.sun.jdi.connect.Connector
 $(SUPPORT_OUTPUTDIR)/gensrc/jdk.jdi/META-INF/services/com.sun.jdi.connect.Connector: \
-    $(JDK_TOPDIR)/src/jdk.jdi/share/classes/META-INF/services/com.sun.jdi.connect.Connector \
-    $(SUPPORT_OUTPUTDIR)/gensrc/jdk.hotspot.agent/_the.sa.services
+    $(JDK_TOPDIR)/src/jdk.jdi/share/classes/META-INF/services/com.sun.jdi.connect.Connector
 	$(process-provider)
 
-# Copy the same service file into jdk.hotspot.agent so that they are kept the same.
-$(JDK_OUTPUTDIR)/modules/jdk.hotspot.agent/META-INF/services/com.sun.jdi.connect.Connector: \
-    $(SUPPORT_OUTPUTDIR)/gensrc/jdk.jdi/META-INF/services/com.sun.jdi.connect.Connector
-	$(install-file)
-
-# Some platforms don't have the serviceability agent
-ifeq (, $(filter $(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU), aix-ppc64))
-  ifneq ($(JVM_VARIANT_ZERO), true)
-    GENSRC_JDK_JDI += $(SUPPORT_OUTPUTDIR)/gensrc/jdk.jdi/META-INF/services/com.sun.jdi.connect.Connector \
-        $(JDK_OUTPUTDIR)/modules/jdk.hotspot.agent/META-INF/services/com.sun.jdi.connect.Connector
-  endif
-endif
+GENSRC_JDK_JDI += $(SUPPORT_OUTPUTDIR)/gensrc/jdk.jdi/META-INF/services/com.sun.jdi.connect.Connector
 
 ################################################################################
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/gensrc/Gensrc-jdk.jlink.gmk	Tue Apr 21 16:49:28 2015 -0700
@@ -0,0 +1,46 @@
+#
+# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+include GensrcCommon.gmk
+
+################################################################################
+
+include GensrcProperties.gmk
+
+$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \
+    $(filter %.properties, \
+        $(call CacheFind, \
+            $(JDK_TOPDIR)/src/jdk.jlink/share/classes/jdk/jigsaw/tools/jlink/resources \
+            $(JDK_TOPDIR)/src/jdk.jlink/share/classes/jdk/jigsaw/tools/jmod/resources \
+            $(JDK_TOPDIR)/src/jdk.jlink/share/classes/jdk/tools/jimage/resources)), \
+    ListResourceBundle))
+
+TARGETS += $(COMPILE_PROPERTIES)
+
+################################################################################
+
+all: $(TARGETS)
+
+.PHONY: all
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/gensrc/GensrcModuleInfo.gmk	Tue Apr 21 16:49:28 2015 -0700
@@ -0,0 +1,96 @@
+#
+# 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.
+#
+
+$(eval $(call IncludeCustomExtension, jdk, gensrc/GensrcModuleInfo.gmk))
+
+##########################################################################################
+
+ifeq ($(OPENJDK_TARGET_OS), windows)
+  JAVA_BASE_MODULEINFO_EXTRAS += \
+    -export sun.security.rsa/jdk.crypto.mscapi \
+    -export sun.security.internal.spec/jdk.crypto.mscapi \
+    -export sun.security.util/jdk.crypto.mscapi
+
+  JAVA_DESKTOP_MODULEINFO_EXTRAS += -export sun.awt/jdk.accessibility
+endif
+
+ifeq ($(OPENJDK_TARGET_OS), solaris)
+  JAVA_BASE_MODULEINFO_EXTRAS += -export sun.nio.ch/jdk.crypto.ucrypto
+  JAVA_BASE_MODULEINFO_EXTRAS += -export sun.security.action/jdk.crypto.ucrypto
+  JAVA_BASE_MODULEINFO_EXTRAS += -export sun.security.internal.spec/jdk.crypto.ucrypto
+  JAVA_BASE_MODULEINFO_EXTRAS += -export sun.security.jca/jdk.crypto.ucrypto
+  JAVA_BASE_MODULEINFO_EXTRAS += -export sun.security.rsa/jdk.crypto.ucrypto 
+  JAVA_BASE_MODULEINFO_EXTRAS += -export sun.security.util/jdk.crypto.ucrypto
+endif
+
+ifeq ($(OPENJDK_TARGET_OS), macosx)
+  JAVA_BASE_MODULEINFO_EXTRAS += -export sun.misc/jdk.deploy.osx
+  JAVA_BASE_MODULEINFO_EXTRAS += -export sun.security.pkcs/jdk.deploy.osx
+  JAVA_BASE_MODULEINFO_EXTRAS += -export sun.security.util/jdk.deploy.osx
+  JAVA_BASE_MODULEINFO_EXTRAS += -export sun.security.x509/jdk.deploy.osx
+endif
+
+$(SUPPORT_OUTPUTDIR)/gensrc/java.base/module-info.java: $(BUILD_TOOLS_JDK) \
+    $(JDK_TOPDIR)/src/java.base/share/classes/module-info.java
+	$(MKDIR) -p $(@D)
+	$(RM) $@ $@.tmp
+	$(TOOL_GENMODULEINFOSOURCE) $(JAVA_BASE_MODULEINFO_EXTRAS) -o $@.tmp $(filter %.java, $^)
+	$(MV) $@.tmp $@
+
+GENSRC_JAVA_BASE += $(SUPPORT_OUTPUTDIR)/gensrc/java.base/module-info.java
+
+##########################################################################################
+
+$(SUPPORT_OUTPUTDIR)/gensrc/java.desktop/module-info.java: $(BUILD_TOOLS_JDK) \
+    $(JDK_TOPDIR)/src/java.desktop/share/classes/module-info.java
+	$(MKDIR) -p $(@D)
+	$(RM) $@ $@.tmp
+	$(TOOL_GENMODULEINFOSOURCE) $(JAVA_DESKTOP_MODULEINFO_EXTRAS) -o $@.tmp $(filter %.java, $^)
+	$(MV) $@.tmp $@
+
+GENSRC_JAVA_DESKTOP += $(SUPPORT_OUTPUTDIR)/gensrc/java.desktop/module-info.java
+
+
+##########################################################################################
+
+$(SUPPORT_OUTPUTDIR)/gensrc/java.management/module-info.java: $(BUILD_TOOLS_JDK) \
+    $(JDK_TOPDIR)/src/java.management/share/classes/module-info.java
+	$(MKDIR) -p $(@D)
+	$(RM) $@ $@.tmp
+	$(TOOL_GENMODULEINFOSOURCE) $(JAVA_MANAGEMENT_MODULEINFO_EXTRAS) -o $@.tmp $(filter %.java, $^)
+	$(MV) $@.tmp $@
+
+GENSRC_JAVA_MANAGEMENT += $(SUPPORT_OUTPUTDIR)/gensrc/java.management/module-info.java
+
+################################################################################
+
+$(SUPPORT_OUTPUTDIR)/gensrc/java.rmi/module-info.java: $(BUILD_TOOLS_JDK) \
+    $(JDK_TOPDIR)/src/java.rmi/share/classes/module-info.java
+	$(MKDIR) -p $(@D)
+	$(RM) $@ $@.tmp
+	$(TOOL_GENMODULEINFOSOURCE) $(JAVA_RMI_MODULEINFO_EXTRAS) -o $@.tmp $(filter %.java, $^)
+	$(MV) $@.tmp $@
+
+GENSRC_JAVA_RMI += $(SUPPORT_OUTPUTDIR)/gensrc/java.rmi/module-info.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/gensrc/GensrcModuleLoaderMap.gmk	Tue Apr 21 16:49:28 2015 -0700
@@ -0,0 +1,113 @@
+#
+# 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.
+#
+
+BOOT_MODULES :=
+UPGRADEABLE_MDOULES :=
+EXT_MODULES :=
+
+# Hook to include the corresponding custom file, if present.
+$(eval $(call IncludeCustomExtension, jdk, gensrc/GensrcModuleLoaderMap.gmk))
+
+BOOT_MODULES += \
+    java.base \
+    java.datatransfer \
+    java.desktop \
+    java.instrument \
+    java.logging \
+    java.management \
+    java.naming \
+    java.prefs \
+    java.rmi \
+    java.security.jgss \
+    java.security.sasl \
+    java.sql \
+    java.xml \
+    java.xml.crypto \
+    jdk.hprof.agent \
+    jdk.httpserver \
+    jdk.sctp \
+    jdk.security.auth \
+    jdk.security.jgss \
+    #
+
+# to be deprivileged
+BOOT_MODULES += \
+    java.compiler \
+    java.scripting \
+    java.sql.rowset \
+    java.smartcardio \
+    jdk.charsets \
+    jdk.naming.rmi \
+    #
+
+UPGRADEABLE_MODULES += \
+    java.activation \
+    java.annotations.common \
+    java.corba \
+    java.transaction \
+    java.xml.bind \
+    java.xml.ws \
+    #
+
+EXT_MODULES += \
+    jdk.crypto.ec \
+    jdk.crypto.pkcs11 \
+    jdk.localedata \
+    jdk.naming.dns \
+    jdk.scripting.nashorn \
+    jdk.zipfs \
+    #
+
+ifeq ($(OPENJDK_TARGET_OS), macsox)
+  BOOT_MODULES += jdk.deploy.osx 
+endif
+ifeq ($(OPENJDK_TARGET_OS), windows)
+  EXT_MODULES += jdk.accessibility jdk.crypto.mscapi
+endif
+ifeq ($(OPENJDK_TARGET_OS), solaris)
+  EXT_MODULES += jdk.crypto.ucrypto
+endif
+
+# Replacing double-comma with a single comma is to workaround the issue
+# with some version of make on windows that doesn't substitute spaces
+# with one comma properly as with make 4.0
+define SubstComma
+$(strip \
+  $(subst $(COMMA)$(COMMA),$(COMMA),$(subst $(SPACE),$(COMMA),$(strip $1))) \
+)
+endef
+BOOT_MODULES_LIST := $(call SubstComma, $(BOOT_MODULES))
+EXT_MODULES_LIST := $(call SubstComma, $(UPGRADEABLE_MODULES) $(EXT_MODULES))
+
+############################################################################
+
+$(SUPPORT_OUTPUTDIR)/gensrc/java.base/jdk/jigsaw/module/runtime/ModuleLoaderMap.java: $(BUILD_TOOLS_JDK) \
+    $(JDK_TOPDIR)/src/java.base/share/classes/jdk/jigsaw/module/runtime/ModuleLoaderMap.java
+	$(MKDIR) -p $(@D)
+	$(RM) $@ $@.tmp
+	$(TOOL_GENCLASSLOADERMAP) -boot $(BOOT_MODULES_LIST) -ext $(EXT_MODULES_LIST) -o $@.tmp $(filter %.java, $^)
+	$(MV) $@.tmp $@
+
+GENSRC_JAVA_BASE += $(SUPPORT_OUTPUTDIR)/gensrc/java.base/jdk/jigsaw/module/runtime/ModuleLoaderMap.java
--- a/make/gensrc/GensrcSwing.gmk	Tue Apr 21 13:21:40 2015 -0700
+++ b/make/gensrc/GensrcSwing.gmk	Tue Apr 21 16:49:28 2015 -0700
@@ -85,6 +85,7 @@
 	    -t $(DOCLET_DATA_DIR)/SwingBeanInfo.template \
 	    -docletpath $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
 	    -XDignore.symbol.file=true \
+	    -XDnoModules=true \
 	    -classpath $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes $(BEANS_SRC) $(LOG_INFO)
         # Move the JTextComponent into its proper package directory.
 	$(MKDIR) -p $(BEANINFO_OUTPUTDIR)/javax/swing/text
--- a/make/launcher/Launcher-jdk.dev.gmk	Tue Apr 21 13:21:40 2015 -0700
+++ b/make/launcher/Launcher-jdk.dev.gmk	Tue Apr 21 16:49:28 2015 -0700
@@ -30,9 +30,6 @@
     -DNEVER_ACT_AS_SERVER_CLASS_MACHINE \
     -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.jdeps.Main"$(COMMA) }'))
 
-$(eval $(call SetupLauncher,jimage,\
-    -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "jdk.tools.jimage.Main"$(COMMA) }'))
-
 $(eval $(call SetupLauncher,jhat, \
     -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.hat.Main"$(COMMA) }'))
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/launcher/Launcher-jdk.jlink.gmk	Tue Apr 21 16:49:28 2015 -0700
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+include LauncherCommon.gmk
+
+$(eval $(call SetupLauncher,jimage,\
+    -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "jdk.tools.jimage.Main"$(COMMA) }'))
+
+$(eval $(call SetupLauncher,jlink,\
+    -DEXPAND_CLASSPATH_WILDCARDS \
+    -DNEVER_ACT_AS_SERVER_CLASS_MACHINE \
+    -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "jdk.jigsaw.tools.jlink.Main"$(COMMA) }'))
+
+$(eval $(call SetupLauncher,jmod,\
+    -DEXPAND_CLASSPATH_WILDCARDS \
+    -DNEVER_ACT_AS_SERVER_CLASS_MACHINE \
+    -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "jdk.jigsaw.tools.jmod.Main"$(COMMA) }'))
--- a/make/mapfiles/libjava/mapfile-vers	Tue Apr 21 13:21:40 2015 -0700
+++ b/make/mapfiles/libjava/mapfile-vers	Tue Apr 21 16:49:28 2015 -0700
@@ -163,8 +163,6 @@
 		Java_java_lang_StrictMath_expm1;
 		Java_java_lang_Object_getClass;
 		Java_java_lang_Object_registerNatives;
-		Java_java_lang_Package_getSystemPackage0;
-		Java_java_lang_Package_getSystemPackages0;
 		Java_java_lang_ProcessEnvironment_environ;
 		Java_java_lang_reflect_Array_get;
 		Java_java_lang_reflect_Array_getBoolean;
@@ -191,11 +189,11 @@
 		Java_java_lang_reflect_Executable_getTypeAnnotationBytes0;
 		Java_java_lang_reflect_Field_getTypeAnnotationBytes0;
 		Java_java_lang_Runtime_freeMemory;
-                Java_java_lang_Runtime_maxMemory;
+		Java_java_lang_Runtime_maxMemory;
 		Java_java_lang_Runtime_gc;
 		Java_java_lang_Runtime_runFinalization0;
 		Java_java_lang_Runtime_totalMemory;
-                Java_java_lang_Runtime_availableProcessors;
+		Java_java_lang_Runtime_availableProcessors;
 		Java_java_lang_SecurityManager_classDepth;
 		Java_java_lang_SecurityManager_classLoaderDepth0;
 		Java_java_lang_SecurityManager_currentClassLoader0;
@@ -212,18 +210,18 @@
 		Java_java_lang_System_setOut0;
 		Java_java_lang_Thread_registerNatives;
 		Java_java_lang_Throwable_fillInStackTrace;
-                Java_java_lang_Throwable_getStackTraceDepth;
-                Java_java_lang_Throwable_getStackTraceElement;
+		Java_java_lang_Throwable_getStackTraceDepth;
+		Java_java_lang_Throwable_getStackTraceElement;
 		Java_java_lang_ProcessImpl_init;
 		Java_java_lang_ProcessImpl_waitForProcessExit;
 		Java_java_lang_ProcessImpl_forkAndExec;
 		Java_java_lang_ProcessImpl_destroyProcess;
-                Java_java_nio_Bits_copyFromShortArray;
-                Java_java_nio_Bits_copyToShortArray;
-                Java_java_nio_Bits_copyFromIntArray;
-                Java_java_nio_Bits_copyToIntArray;
-                Java_java_nio_Bits_copyFromLongArray;
-                Java_java_nio_Bits_copyToLongArray;
+		Java_java_nio_Bits_copyFromShortArray;
+		Java_java_nio_Bits_copyToShortArray;
+		Java_java_nio_Bits_copyFromIntArray;
+		Java_java_nio_Bits_copyToIntArray;
+		Java_java_nio_Bits_copyFromLongArray;
+		Java_java_nio_Bits_copyToLongArray;
 		Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2;
 		Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2;
 		Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedExceptionAction_2;
@@ -239,20 +237,20 @@
 		Java_sun_misc_Signal_findSignal;
 		Java_sun_misc_Signal_handle0;
 		Java_sun_misc_Signal_raise0;
-              Java_sun_reflect_ConstantPool_getClassAt0;
-              Java_sun_reflect_ConstantPool_getClassAtIfLoaded0;
-              Java_sun_reflect_ConstantPool_getDoubleAt0;
-              Java_sun_reflect_ConstantPool_getFieldAt0;
-              Java_sun_reflect_ConstantPool_getFieldAtIfLoaded0;
-              Java_sun_reflect_ConstantPool_getFloatAt0;
-              Java_sun_reflect_ConstantPool_getIntAt0;
-              Java_sun_reflect_ConstantPool_getLongAt0;
-              Java_sun_reflect_ConstantPool_getMemberRefInfoAt0;
-              Java_sun_reflect_ConstantPool_getMethodAt0;
-              Java_sun_reflect_ConstantPool_getMethodAtIfLoaded0;
-              Java_sun_reflect_ConstantPool_getSize0;
-              Java_sun_reflect_ConstantPool_getStringAt0;
-              Java_sun_reflect_ConstantPool_getUTF8At0;
+                Java_sun_reflect_ConstantPool_getClassAt0;
+                Java_sun_reflect_ConstantPool_getClassAtIfLoaded0;
+                Java_sun_reflect_ConstantPool_getDoubleAt0;
+                Java_sun_reflect_ConstantPool_getFieldAt0;
+                Java_sun_reflect_ConstantPool_getFieldAtIfLoaded0;
+                Java_sun_reflect_ConstantPool_getFloatAt0;
+                Java_sun_reflect_ConstantPool_getIntAt0;
+                Java_sun_reflect_ConstantPool_getLongAt0;
+                Java_sun_reflect_ConstantPool_getMemberRefInfoAt0;
+                Java_sun_reflect_ConstantPool_getMethodAt0;
+                Java_sun_reflect_ConstantPool_getMethodAtIfLoaded0;
+                Java_sun_reflect_ConstantPool_getSize0;
+                Java_sun_reflect_ConstantPool_getStringAt0;
+                Java_sun_reflect_ConstantPool_getUTF8At0;
 		Java_java_io_Console_istty;
 		Java_java_io_Console_encoding;
                 Java_java_io_Console_echo;
@@ -272,12 +270,33 @@
                 Java_sun_misc_VM_getgid;
                 Java_sun_misc_VM_getegid;
                 Java_sun_misc_VM_initialize;
+
+                Java_java_lang_reflect_Module_jvmDefineModule;
+                Java_java_lang_reflect_Module_jvmAddReadsModule;
+                Java_java_lang_reflect_Module_jvmAddModuleExports;
+                Java_java_lang_reflect_Module_jvmAddModulePackage;
+
+                Java_jdk_internal_jimage_ImageNativeSubstrate_openImage;
+                Java_jdk_internal_jimage_ImageNativeSubstrate_closeImage;
+                Java_jdk_internal_jimage_ImageNativeSubstrate_getIndexAddress;
+                Java_jdk_internal_jimage_ImageNativeSubstrate_getDataAddress;
+                Java_jdk_internal_jimage_ImageNativeSubstrate_read;
+                Java_jdk_internal_jimage_ImageNativeSubstrate_readCompressed;
+                Java_jdk_internal_jimage_ImageNativeSubstrate_getStringBytes;
+                Java_jdk_internal_jimage_ImageNativeSubstrate_getAttributes;
+                Java_jdk_internal_jimage_ImageNativeSubstrate_findAttributes;
+                Java_jdk_internal_jimage_ImageNativeSubstrate_attributeOffsets;
+
+                # for testing performance of access checks in VM
+                Java_sun_reflect_Reflection_jvmCanReadModule;
+                Java_sun_reflect_Reflection_jvmIsExportedToModule;
+
+		Java_sun_misc_BootLoader_getSystemPackageLocation;
+		Java_sun_misc_BootLoader_getSystemPackageNames;
+
 		Java_sun_misc_VMSupport_initAgentProperties;
 		Java_sun_misc_VMSupport_getVMTemporaryDirectory;
 
-                Java_jdk_internal_jimage_concurrent_ConcurrentPReader_initIDs;
-                Java_jdk_internal_jimage_concurrent_ConcurrentPReader_pread;
-		
                 # ZipFile.c needs this one
 		throwFileNotFoundException;
                 # zip_util.c needs this one
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/src/classes/build/tools/jigsaw/GenGraphs.java	Tue Apr 21 16:49:28 2015 -0700
@@ -0,0 +1,234 @@
+/*
+ * 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.jigsaw;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import java.lang.module.Configuration;
+import java.lang.module.Layer;
+import java.lang.module.ModuleArtifact;
+import java.lang.module.ModuleArtifactFinder;
+import java.lang.module.ModuleDescriptor;
+import static java.lang.module.ModuleDependence.Modifier.PUBLIC;
+
+/**
+ * Generate the DOT file for a module graph for each module in the JDK
+ * after transitive reduction.
+ */
+public class GenGraphs {
+
+    public static void main(String[] args) throws Exception {
+
+        if (args.length != 1) {
+            System.err.println("ERROR: specify the output directory");
+            System.exit(1);
+        }
+        Path dir = Paths.get(args[0]);
+        Files.createDirectories(dir);
+
+        ModuleArtifactFinder finder = ModuleArtifactFinder.installedModules();
+
+        Set<ModuleDescriptor> javaSEModules
+            = new TreeSet<>(finder.allModules().stream()
+                                  .map(ModuleArtifact::descriptor)
+                                  .filter(m -> (m.name().startsWith("java.") &&
+                                               !m.name().equals("java.smartcardio")))
+                                  .collect(Collectors.toSet()));
+        Set<ModuleDescriptor> jdkModules
+            = new TreeSet<>(finder.allModules().stream()
+                                  .map(ModuleArtifact::descriptor)
+                                  .filter(m -> !javaSEModules.contains(m))
+                                  .collect(Collectors.toSet()));
+
+        GenGraphs genGraphs = new GenGraphs(javaSEModules, jdkModules);
+        Set<String> mods = new HashSet<>();
+        for (ModuleArtifact artifact: finder.allModules()) {
+            ModuleDescriptor descriptor = artifact.descriptor();
+            String name = descriptor.name();
+            switch (name) {
+            case "jdk.dev":
+            case "jdk.runtime":
+            case "jdk.deploy":
+                continue;
+            }
+            mods.add(name);
+            Configuration cf = Configuration.resolve(finder,
+                    Layer.emptyLayer(),
+                    ModuleArtifactFinder.nullFinder(),
+                    name);
+            genGraphs.genDotFile(dir, name, cf);
+        }
+
+        Configuration cf = Configuration.resolve(finder,
+                Layer.emptyLayer(),
+                ModuleArtifactFinder.nullFinder(),
+                mods);
+        genGraphs.genDotFile(dir, "jdk", cf);
+
+    }
+
+    private final Set<ModuleDescriptor> javaGroup;
+    private final Set<ModuleDescriptor> jdkGroup;
+
+    GenGraphs(Set<ModuleDescriptor> javaGroup, Set<ModuleDescriptor> jdkGroup) {
+        this.javaGroup = Collections.unmodifiableSet(javaGroup);
+        this.jdkGroup = Collections.unmodifiableSet(jdkGroup);
+    }
+
+    private static final String ORANGE = "#e76f00";
+    private static final String BLUE = "#437291";
+    private static final String GRAY = "#dddddd";
+
+    private static final String REEXPORTS = "";
+    private static final String REQUIRES = "style=\"dashed\"";
+    private static final String REQUIRES_BASE = "color=\"" + GRAY + "\"";
+
+    private static final Map<String,Integer> weights = new HashMap<>();
+
+    private static void weight(String s, String t, int w) {
+        weights.put(s + ":" + t, w);
+    }
+
+    private static int weightOf(String s, String t) {
+        int w = weights.getOrDefault(s + ":" + t, 1);
+        if (w != 1)
+            return w;
+        if (s.startsWith("java.") && t.startsWith("java."))
+            return 10;
+        return 1;
+    }
+
+    static {
+        int h = 1000;
+        weight("java.se", "java.compact3", h * 10);
+        weight("jdk.compact3", "java.compact3", h * 10);
+        weight("java.compact3", "java.compact2", h * 10);
+        weight("java.compact2", "java.compact1", h * 10);
+        weight("java.compact1", "java.logging", h * 10);
+        weight("java.logging", "java.base", h * 10);
+    }
+
+    private void genDotFile(Path dir, String name, Configuration cf) throws IOException {
+        try (PrintStream out
+                 = new PrintStream(Files.newOutputStream(dir.resolve(name + ".dot")))) {
+
+            Map<String,ModuleDescriptor> nameToModule = cf.descriptors().stream()
+                    .collect(Collectors.toMap(ModuleDescriptor::name, Function.identity()));
+
+            out.format("digraph \"%s\" {%n", name);
+            out.format("size=\"25,25\";");
+            out.format("nodesep=.5;%n");
+            out.format("ranksep=1.5;%n");
+            out.format("node [shape=plaintext, fontname=\"DejaVuSans\", fontsize=36, margin=\".2,.2\"];");
+            out.format("edge [penwidth=4, color=\"#999999\", arrowhead=open, arrowsize=2];");
+
+            out.format("subgraph se {%n");
+            cf.descriptors().stream()
+                .filter(javaGroup::contains)
+                .map(ModuleDescriptor::name)
+                .forEach(mn -> out.format("  \"%s\" [fontcolor=\"%s\", group=%s];%n",
+                                          mn, ORANGE, "java"));
+            out.format("}%n");
+            cf.descriptors().stream()
+                .filter(jdkGroup::contains)
+                .map(ModuleDescriptor::name)
+                .forEach(mn -> out.format("  \"%s\" [fontcolor=\"%s\", group=%s];%n",
+                                          mn, BLUE, "jdk"));
+
+            // transitive reduction
+            Graph<String> graph = gengraph(cf);
+            cf.descriptors().forEach(md -> {
+                String mn = md.name();
+                Set<String> requiresPublic = md.moduleDependences().stream()
+                        .filter(d -> d.modifiers().contains(PUBLIC))
+                        .map(d -> d.name())
+                        .collect(Collectors.toSet());
+
+                graph.adjacentNodes(mn).forEach(dn -> {
+                    String attr = dn.equals("java.base") ? REQUIRES_BASE
+                            : (requiresPublic.contains(dn) ? REEXPORTS : REQUIRES);
+                    int w = weightOf(mn, dn);
+                    if (w > 1)
+                        attr += "weight=" + w;
+                    out.format("  \"%s\" -> \"%s\" [%s];%n", mn, dn, attr);
+                });
+            });
+
+            out.println("}");
+        }
+    }
+
+    /**
+     * Returns a Graph of the given Configuration after transitive reduction.
+     *
+     * Transitive reduction of requires public edge and requires edge have
+     * to be applied separately to prevent the requires public edges
+     * (e.g. U -> V) from being reduced by a path (U -> X -> Y -> V)
+     * in which  V would not be re-exported from U.
+     */
+    private Graph<String> gengraph(Configuration cf) {
+        Graph.Builder<String> builder = new Graph.Builder<>();
+        cf.descriptors().forEach(md -> {
+            String mn = md.name();
+            builder.addNode(mn);
+            cf.readDependences(md).stream()
+                    .map(d -> d.name())
+                    .forEach(d -> builder.addEdge(mn, d));
+        });
+
+        Graph<String> rpg = requiresPublicGraph(cf);
+        return builder.build().reduce(rpg);
+    }
+
+    /**
+     * Returns a Graph containing only requires public edges
+     * with transitive reduction.
+     */
+    private Graph<String> requiresPublicGraph(Configuration cf) {
+        Graph.Builder<String> builder = new Graph.Builder<>();
+        cf.descriptors().forEach(md -> {
+            String mn = md.name();
+            md.moduleDependences().stream()
+                    .filter(d -> d.modifiers().contains(PUBLIC))
+                    .map(d -> d.name())
+                    .forEach(d -> builder.addEdge(mn, d));
+        });
+
+        return builder.build().reduce();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/src/classes/build/tools/jigsaw/Graph.java	Tue Apr 21 16:49:28 2015 -0700
@@ -0,0 +1,171 @@
+/*
+ * 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.jigsaw;
+
+import java.io.PrintStream;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+
+public class Graph<T> {
+    private static boolean traceOn = Boolean.getBoolean("build.tools.module.trace");
+    private final Set<T> nodes;
+    private final Map<T, Set<T>> edges;
+    private Graph(Set<T> nodes, Map<T, Set<T>> edges) {
+        this.nodes = nodes;
+        this.edges = edges;
+    }
+
+    public Set<T> nodes() {
+        return nodes;
+    }
+
+    public Map<T, Set<T>> edges() {
+        return edges;
+    }
+
+    public Set<T> adjacentNodes(T u) {
+        return edges.get(u);
+    }
+
+    /**
+     * Returns a new Graph after transitive reduction
+     */
+    public Graph<T> reduce() {
+        Graph.Builder<T> builder = new Builder<>();
+        nodes.stream()
+             .forEach(u -> {
+                 builder.addNode(u);
+                 edges.get(u).stream()
+                         .filter(v -> !pathExists(u, v, false))
+                         .forEach(v -> builder.addEdge(u, v));
+             });
+        return builder.build();
+    }
+
+    /**
+     * Returns a new Graph after transitive reduction.  All edges in
+     * the given g takes precedence over this graph.
+     *
+     * @throw IllegalArgumentException g must be a subgraph this graph
+     */
+    public Graph<T> reduce(Graph<T> g) {
+        boolean subgraph = nodes.containsAll(g.nodes) && g.edges.keySet().stream()
+               .allMatch(u -> adjacentNodes(u).containsAll(g.adjacentNodes(u)));
+        if (!subgraph) {
+            throw new IllegalArgumentException("the given argument is not a subgraph of this graph");
+        }
+
+        Graph.Builder<T> builder = new Builder<>();
+        nodes.stream()
+             .forEach(u -> {
+                 builder.addNode(u);
+                 // filter the edge if there exists a path from u to v in the given g
+                 // or there exists another path from u to v in this graph
+                 edges.get(u).stream()
+                      .filter(v -> !g.pathExists(u, v) && !pathExists(u, v, false))
+                      .forEach(v -> builder.addEdge(u, v));
+             });
+
+        // add the overlapped edges from this graph and the given g
+        g.edges().keySet().stream()
+                 .forEach(u -> g.adjacentNodes(u).stream()
+                         .filter(v -> isAdjacent(u, v))
+                         .forEach(v -> builder.addEdge(u, v)));
+        return builder.build();
+    }
+
+    private boolean isAdjacent(T u, T v) {
+        return edges.containsKey(u) && edges.get(u).contains(v);
+    }
+
+    private boolean pathExists(T u, T v) {
+        return pathExists(u, v, true);
+    }
+
+    /**
+     * Returns true if there exists a path from u to v in this graph.
+     * If includeAdjacent is false, it returns true if there exists
+     * another path from u to v of distance > 1
+     */
+    private boolean pathExists(T u, T v, boolean includeAdjacent) {
+        if (!nodes.contains(u) || !nodes.contains(v)) {
+            return false;
+        }
+        if (includeAdjacent && isAdjacent(u, v)) {
+            return true;
+        }
+        Deque<T> stack = new LinkedList<>();
+        Set<T> visited = new HashSet<>();
+        stack.push(u);
+        while (!stack.isEmpty()) {
+            T node = stack.pop();
+            if (node.equals(v)) {
+                if (traceOn) {
+                    System.out.format("Edge %s -> %s removed%n", u, v);
+                }
+                return true;
+            }
+            if (!visited.contains(node)) {
+                visited.add(node);
+                edges.get(node).stream()
+                     .filter(e -> includeAdjacent || !node.equals(u) || !e.equals(v))
+                     .forEach(e -> stack.push(e));
+            }
+        }
+        assert !visited.contains(v);
+        return false;
+    }
+
+    void printGraph(PrintStream out) {
+        nodes.stream()
+             .forEach(u -> adjacentNodes(u).stream()
+                     .forEach(v -> out.format("%s -> %s%n", u, v)));
+    }
+
+    public static class Builder<T> {
+        final Set<T> nodes = new HashSet<>();
+        final Map<T, Set<T>> edges = new HashMap<>();
+        public void addNode(T node) {
+            if (nodes.contains(node)) {
+                return;
+            }
+            nodes.add(node);
+            edges.computeIfAbsent(node, _e -> new HashSet<>());
+        }
+        public void addEdge(T u, T v) {
+            addNode(u);
+            addNode(v);
+            edges.get(u).add(v);
+        }
+        public Graph<T> build() {
+            return new Graph<>(nodes, edges);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/src/classes/build/tools/jigsaw/ModuleSummary.java	Tue Apr 21 16:49:28 2015 -0700
@@ -0,0 +1,483 @@
+/*
+ * 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.jigsaw;
+
+import com.sun.tools.classfile.AccessFlags;
+import static com.sun.tools.classfile.AccessFlags.ACC_PROTECTED;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.Dependencies;
+import com.sun.tools.classfile.Dependency;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import java.lang.module.Configuration;
+import java.lang.module.Layer;
+import java.lang.module.ModuleArtifact;
+import java.lang.module.ModuleArtifactFinder;
+import java.lang.module.ModuleDependence;
+import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleExport;
+
+public class ModuleSummary {
+    private static final String USAGE = "Usage: ModuleSummary -mp <dir> -o <outfile>";
+
+    public static void main(String[] args) throws Exception {
+        int i=0;
+        Path modpath = null;
+        Path outfile = null;
+        while (i < args.length && args[i].startsWith("-")) {
+            String arg = args[i++];
+            switch (arg) {
+                case "-mp":
+                    modpath = Paths.get(args[i++]);
+                    break;
+                case "-o":
+                    outfile = Paths.get(args[i++]);
+                    break;
+                default:
+                    System.err.println(USAGE);
+                    System.exit(-1);
+            }
+        }
+        if (outfile == null || modpath == null) {
+            System.err.println(USAGE);
+            System.exit(1);
+        }
+        Path dir = outfile.getParent() != null ? outfile.getParent() : Paths.get(".");
+        Files.createDirectories(dir);
+        ModuleSummary ms = new ModuleSummary(modpath);
+        ms.genReport(outfile, ms.modules(), "JDK Module Summary");
+        ms.genReport(dir.resolve("java.se.html"),
+                     Collections.singleton("java.se"), "Java SE Modules");
+        ms.genCSV(dir.resolve("jdk.csv"), ms.modules());
+    }
+
+    private final Map<String, ModuleArtifact> nameToArtifact = new HashMap<>();
+    private final Map<String, JmodInfo> jmods = new HashMap<>();
+    private final Map<String, Set<String>> deps = new HashMap<>();
+    private final Map<String, ModuleDescriptor> packageMap = new HashMap<>();
+    private final Path modpath;
+
+    ModuleSummary(Path modpath) throws IOException, ConstantPoolException {
+        this.modpath = modpath;
+
+        Set<ModuleArtifact> artifacts = ModuleArtifactFinder.installedModules().allModules();
+        artifacts.forEach(m -> nameToArtifact.put(m.descriptor().name(), m));
+
+        // build package map for all modules for API dependency analysis
+        artifacts.forEach(m -> m.packages().stream()
+                 .forEach(p -> packageMap.put(p, m.descriptor())));
+
+        for (ModuleArtifact artifact : artifacts) {
+            String name = artifact.descriptor().name();
+            Path jmod = modpath.resolve(name + ".jmod");
+            jmods.put(name, new JmodInfo(jmod));
+            deps.put(name, getAPIDependences(artifact, jmod));
+        }
+    }
+
+    Set<String> modules() {
+        return nameToArtifact.keySet();
+    }
+
+    public void genCSV(Path outfile, Set<String> roots) throws IOException {
+        Configuration cf  = resolve(roots);
+        Set<ModuleDescriptor> selectedModules = cf.descriptors();
+        try (PrintStream out = new PrintStream(Files.newOutputStream(outfile))) {
+            out.format("module,size,\"direct deps\",\"indirect deps\",total," +
+                       "\"compressed size\",\"compressed direct deps\",\"compressed indirect deps\",total%n");
+            selectedModules.stream()
+                   .sorted(Comparator.comparing(ModuleDescriptor::name))
+                   .forEach(m -> {
+                        Set<ModuleDescriptor> deps = resolve(Collections.singleton(m.name())).descriptors();
+                        long reqBytes = 0;
+                        long reqJmodSize = 0;
+                        long otherBytes = 0;
+                        long otherJmodSize = 0;
+                        Set<String> reqs = m.moduleDependences().stream()
+                                                .map(d -> d.name())
+                                                .collect(Collectors.toSet());
+                        reqBytes = deps.stream()
+                                        .filter(d -> reqs.contains(d.name()))
+                                        .mapToLong(d -> jmods.get(d.name()).size).sum();
+                        reqJmodSize = deps.stream()
+                                        .filter(d -> reqs.contains(d.name()))
+                                        .mapToLong(d -> jmods.get(d.name()).filesize).sum();
+                        otherBytes = deps.stream()
+                                        .filter(d -> !reqs.contains(d.name()))
+                                        .mapToLong(d -> jmods.get(d.name()).size).sum();
+                        otherJmodSize = deps.stream()
+                                        .filter(d -> !reqs.contains(d.name()))
+                                        .mapToLong(d -> jmods.get(d.name()).filesize).sum();
+
+                        String name = m.name();
+                        out.format("%s,%d,%d,%d,%d,%d,%d,%d,%d%n", name,
+                                   jmods.get(name).size, reqBytes, otherBytes,
+                                   jmods.get(name).size + reqBytes + otherBytes,
+                                   jmods.get(name).filesize, reqJmodSize, otherJmodSize,
+                                   jmods.get(name).filesize + reqJmodSize + otherJmodSize);
+                   });
+        }
+    }
+
+    public void genReport(Path outfile, Set<String> roots, String title) throws IOException {
+        Configuration cf = resolve(roots);
+        Set<ModuleDescriptor> selectedModules = cf.descriptors();
+        try (PrintStream out = new PrintStream(Files.newOutputStream(outfile))) {
+            long totalBytes = selectedModules.stream()
+                                  .mapToLong(m -> jmods.get(m.name()).size).sum();
+            writeHeader(out, title, selectedModules.size(), totalBytes);
+            selectedModules.stream()
+                   .sorted(Comparator.comparing(ModuleDescriptor::name))
+                   .forEach(m -> {
+                        try {
+                            String name = m.name();
+                            Set<ModuleDescriptor> deps =
+                                resolve(Collections.singleton(name)).descriptors();
+                            long reqBytes = jmods.get(name).size;
+                            long reqJmodSize = jmods.get(name).filesize;
+                            int reqCount = deps.size();
+                            reqBytes += deps.stream()
+                                        .mapToLong(d -> jmods.get(d.name()).size).sum();
+                            reqJmodSize += deps.stream()
+                                    .mapToLong(d -> jmods.get(d.name()).filesize).sum();
+                            genSummary(out, m, jmods.get(name), reqCount, reqBytes, reqJmodSize);
+                        } catch (IOException e) {
+                            throw new UncheckedIOException(e);
+                        }
+                    });
+            out.format("</table>");
+            out.format("</body></html>%n");
+        }
+    }
+
+    private String toRequires(String from, ModuleDependence d) {
+        String name = d.name();
+        String ref = String.format("<a href=\"#%s\">%s</a>",
+                                   name, name);
+        Stream<String> mods = d.modifiers().stream().map(e -> e.toString().toLowerCase());
+        String result = (Stream.concat(Stream.of("requires"),
+                                       Stream.concat(mods, Stream.of(ref)))
+                .collect(Collectors.joining(" ")));
+        if (name.equals("java.base")) {
+            return result;
+        }
+
+        // API dependency: bold
+        // aggregator module's require: italic
+        ModuleArtifact artifact = nameToArtifact.get(from);
+        boolean reexport = d.modifiers().contains(ModuleDependence.Modifier.PUBLIC);
+        if (deps.containsKey(from) && deps.get(from).contains(name)) {
+            // has API dependency
+            return reexport ? String.format("<b>%s</b>", result)
+                            : String.format("<b><font color=\"red\">%s</font></b>", result);
+        } else if (artifact.packages().size() == 0) {
+            // aggregator module
+            return String.format("<em>%s</em>", result);
+        } else {
+            // "requires public" whose types are not referenced from exported APIs
+            return reexport ? String.format("<font color=\"brown\">%s</font>", result) : result;
+        }
+    }
+
+    private void genSummary(PrintStream out, ModuleDescriptor descriptor, JmodInfo jm,
+                            int requireModules, long requireUncompressed, long requireJmodFileSize)
+            throws IOException
+    {
+        String name = descriptor.name();
+        out.format("<tr>%n");
+        out.format("<td class=\"name\"><b><a name=\"%s\">%s</a></b><br><br>%n",
+                   name, name);
+        // statistic about module content
+        out.format("jmod file<br>%n");
+        out.format("uncompressed<br>%n");
+        out.format("%8d %s<br>%n", jm.classCount, "classes");
+        out.format("%8d %s<br>%n", jm.resourceCount, "resources");
+        out.format("%8d %s<br>%n", jm.configCount, "config");
+        out.format("%8d %s<br>%n", jm.nativeLibs.size() - jm.debugInfoLibCount, "native libs");
+        out.format("%8d %s<br>%n", jm.debugInfoLibCount, "debugInfo libs");
+        out.format("%8d %s<br>%n", jm.nativeCmds.size() - jm.debugInfoCmdCount, "launchers");
+        out.format("%8d %s<br>%n", jm.debugInfoCmdCount, "debugInfo");
+        out.format("<br>Transitive dependences<br>%n");
+        out.format("Total uncompressed<br>%n");
+        out.format("Approx compressed<br>%n");
+
+        out.format("</td>%n");
+        out.format("<td class=\"num\"><br><br>%n");
+        out.format("%12d<br>%n", jm.filesize);
+        out.format("%12d<br>%n", jm.size);
+        out.format("%10d<br>%n", jm.classBytes);
+        out.format("%10d<br>%n", jm.resourceBytes);
+        out.format("%10d<br>%n", jm.configBytes);
+        out.format("%10d<br>%n", jm.nativeLibs.values().stream()
+                                   .mapToLong(l -> l.longValue()).sum() - jm.debugInfoLibBytes);
+        out.format("%10d<br>%n", jm.debugInfoLibBytes);
+        out.format("%10d<br>%n", jm.nativeCmds.values().stream()
+                                   .mapToLong(l -> l.longValue()).sum());
+        out.format("%10d<br>%n", jm.debugInfoCmdBytes);
+        // total size due to the transitive dependences
+        out.format("<br>%10d<br>%n", requireModules);
+        out.format("%10d<br>%n", requireUncompressed);
+        out.format("%10d<br>%n", requireJmodFileSize);
+
+        out.format("</td>%n");
+
+        out.format("<td>%n");
+        jm.nativeCmds.entrySet().stream()
+                .sorted(Map.Entry.comparingByKey())
+                .forEach(e -> out.format("%s <br>%n", e.getKey()));
+        out.format("</td>%n");
+        String requires = descriptor.moduleDependences().stream()
+            .map(md -> toRequires(name, md))
+            .sorted()
+            .collect(Collectors.joining("<br>\n"));
+        out.format("<td>%s</td>%n", requires);
+        String exports = descriptor.exports().stream()
+            .filter(e -> e.permit() == null)
+            .map(e -> e.pkg())
+            .sorted()
+            .collect(Collectors.joining("<br>\n"));
+        out.format("<td>%s</td>%n", exports);
+        Stream<String> uses = descriptor.serviceDependences().stream()
+            .map(s -> "uses " + s)
+            .sorted();
+        Stream<String> providers = descriptor.services().entrySet().stream()
+            .sorted(Map.Entry.comparingByKey())
+            .flatMap(e -> e.getValue().stream().map(p ->
+                String.format("provides %s<br>&nbsp; <em>with %s</em>", e.getKey(), p)));
+        out.format("<td>%s</td>%n", Stream.concat(uses, providers)
+                                          .collect(Collectors.joining("<br>\n")));
+        if (jm.nativeLibs.size() > 0) {
+            String nativeLibs = jm.nativeLibs.keySet().stream()
+                .sorted()
+                .collect(Collectors.joining("<br>\n"));
+            out.format("<td class=\"name\">%s</td>%n", nativeLibs);
+            String sizes = jm.nativeLibs.entrySet().stream()
+                .sorted(Map.Entry.comparingByKey())
+                .map(e -> e.getValue().toString())
+                .collect(Collectors.joining("<br>\n"));
+            out.format("<td class=\"num\">%s</td>%n", sizes);
+        }
+        out.format("</td>%n");
+        out.format("</tr>%n");
+    }
+
+    private void writeHeader(PrintStream out, String title, int numModules, long size) {
+        out.format("<html>%n");
+        out.format("<head>%n");
+        out.format("<title>%s</title>%n", title);
+        out.format("<style type=\"text/css\">%n");
+        out.format("table {border: 1px solid black; border-collapse: collapse;}%n");
+        out.format("td { font-family: monospace; padding: 3px 6px}%n");
+        out.format("td {vertical-align:text-top; border: 1px solid;}%n");
+        out.format("td.name {border-right: none;}");
+        out.format("td.num {border-left: none; text-align:right;}");
+        out.format("th {border: 1px solid black;}%n");
+        out.format("th.name {border-right: none;}");
+        out.format("th.num {border-left: none; text-align:right;}");
+        out.format("</style>%n</head>%n");
+        out.format("<h1>%s</h1>%n", title);
+        out.format("<h3>Number of Modules = %d<br>%n", numModules);
+        out.format("Total Uncompressed Size = %,d bytes</h3>%n", size);
+        out.format("(*) <b>bold</b> indicates a dependence due to an exported API's signature. ");
+        out.format("<em>italic</em> indicates a dependence from an aggregator module<p>%n");
+        out.format("<table>");
+        out.format("<tr>%n");
+        out.format("<th class=\"name\">Module</th>%n");
+        out.format("<th class=\"num\">Bytes</th>%n");
+        out.format("<th>Launchers</th>%n");
+        out.format("<th>Dependences (*)</th>%n");
+        out.format("<th>Exports</th>%n");
+        out.format("<th>Services</th>%n");
+        out.format("<th class=\"name\">Native libs</th>%n");
+        out.format("<th class=\"num\">Bytes</th>%n");
+        out.format("</tr>%n");
+    }
+
+    static class JmodInfo {
+        final long size;
+        final long filesize;
+        final int  classCount;
+        final long classBytes;
+        final int  resourceCount;
+        final long resourceBytes;
+        final int  configCount;
+        final long configBytes;
+        final int debugInfoLibCount;
+        final long debugInfoLibBytes;
+        final int debugInfoCmdCount;
+        final long debugInfoCmdBytes;
+        final Map<String,Long> nativeCmds = new HashMap<>();
+        final Map<String,Long> nativeLibs = new HashMap<>();
+
+        JmodInfo(Path jmod) throws IOException {
+            this.filesize = jmod.toFile().length();
+            long total = 0;
+            int cCount = 0;
+            long cBytes = 0;
+            int rCount = 0;
+            long rBytes = 0;
+            int cfCount = 0;
+            long cfBytes = 0;
+            int dizLibCount = 0;
+            long dizLibBytes = 0;
+            int dizCmdCount = 0;
+            long dizCmdBytes = 0;
+            try (ZipFile zf = new ZipFile(jmod.toFile())) {
+                for (Enumeration<? extends ZipEntry> e = zf.entries(); e.hasMoreElements();) {
+                    ZipEntry ze = e.nextElement();
+                    String fn = ze.getName();
+                    String dir = fn.substring(0, fn.indexOf('/'));
+                    String filename = fn.substring(fn.lastIndexOf('/') + 1);
+                    long len = ze.getSize();
+                    total += len;
+                    switch (dir) {
+                        case NATIVE_LIBS:
+                            nativeLibs.put(filename, len);
+                            if (filename.endsWith(".diz")) {
+                                dizLibCount++;
+                                dizLibBytes += len;
+                            }
+                            break;
+                        case NATIVE_CMDS:
+                            nativeCmds.put(filename, len);
+                            if (filename.endsWith(".diz")) {
+                                dizCmdCount++;
+                                dizCmdBytes += len;
+                            }
+                            break;
+                        case CLASSES:
+                            if (filename.endsWith(".class")) {
+                                cCount++;
+                                cBytes += len;
+                            } else {
+                                rCount++;
+                                rBytes += len;
+                            }
+                            break;
+                        case CONFIG:
+                            cfCount++;
+                            cfBytes += len;
+                            break;
+                        default:
+                            break;
+                    }
+                }
+                this.classCount = cCount;
+                this.classBytes = cBytes;
+                this.resourceCount = rCount;
+                this.resourceBytes = rBytes;
+                this.configCount = cfCount;
+                this.configBytes = cfBytes;
+                this.size = total;
+                this.debugInfoLibCount = dizLibCount;
+                this.debugInfoLibBytes = dizLibBytes;
+                this.debugInfoCmdCount = dizCmdCount;
+                this.debugInfoCmdBytes = dizCmdBytes;
+            }
+        }
+
+        static final String NATIVE_LIBS = "native";
+        static final String NATIVE_CMDS = "bin";
+        static final String CLASSES = "classes";
+        static final String CONFIG = "conf";
+
+        static final String MODULE_ID = "module/id";
+        static final String MODULE_MAIN_CLASS = "module/main-class";
+    }
+
+    Set<String> getAPIDependences(ModuleArtifact artifact, Path jmod)
+        throws IOException, ConstantPoolException
+    {
+        ModuleDescriptor descriptor = artifact.descriptor();
+        Dependency.Finder finder = Dependencies.getAPIFinder(ACC_PROTECTED);
+        Dependency.Filter filter =
+            (Dependency d) -> !artifact.packages().contains(d.getTarget().getPackageName());
+        Set<String> exports = descriptor.exports().stream()
+                    .map(ModuleExport::pkg)
+                    .sorted()
+                    .collect(Collectors.toSet());
+        Set<String> deps = new HashSet<>();
+        try (ZipFile zf = new ZipFile(jmod.toFile())) {
+            for (Enumeration<? extends ZipEntry> e = zf.entries(); e.hasMoreElements();) {
+                ZipEntry ze = e.nextElement();
+                String fn = ze.getName();
+                String dir = fn.substring(0, fn.indexOf('/'));
+                if (JmodInfo.CLASSES.equals(dir) && fn.endsWith(".class")) {
+                    if (fn.equals("classes/module-info.class"))
+                        continue;   // skip module-info.class
+                    String pn = fn.substring(fn.indexOf('/')+1, fn.lastIndexOf('/')).replace('/', '.');
+                    if (exports.contains(pn)) {
+                        // analyze only exported APIs
+                        try (InputStream in = zf.getInputStream(ze)) {
+                            ClassFile cf = ClassFile.read(in);
+                            if (cf.access_flags.is(AccessFlags.ACC_PUBLIC)) {
+                                for (Dependency d : finder.findDependencies(cf)) {
+                                    if (filter.accepts(d)) {
+                                       ModuleDescriptor a = packageMap.get(d.getTarget().getPackageName());
+                                       if (a == null) {
+                                           throw new Error(d.getOrigin() + " -> " +
+                                                           d.getTarget() + " not found");
+                                       }
+                                       deps.add(a.name());
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return deps;
+    }
+
+    static Configuration resolve(Collection<String> roots) {
+        return Configuration.resolve(ModuleArtifactFinder.installedModules(),
+                                     Layer.emptyLayer(),
+                                     ModuleArtifactFinder.nullFinder(),
+                                     roots);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/src/classes/build/tools/jigsaw/technology-summary.html	Tue Apr 21 16:49:28 2015 -0700
@@ -0,0 +1,596 @@
+<html>
+<head>
+<title>JDK Technology Summary</title>
+<style type="text/css">
+table { border: 1px solid black; border-collapse: collapse; }
+tr.se-base { background-color: bisque; }
+tr.se-misc { background-color: lavender; }
+tr.ee-misc { background-color: lightgreen; }
+td { font-family: monospace; padding: 4px; border: 1px solid; }
+</style>
+</head>
+
+<h1>Technologies in the Modular JDK</h1>
+
+<p><em>Last updated 2015-02-18 (Removed java.security.acl and moved java.{transaction,corba} to ext loader. Assumes StAX joins the Java SE Platform.)</em></p>
+
+<p><a href="module-summary.html">JDK Module Summary</a> | Technologies in the <a href="https://docs.oracle.com/javase/8/docs/">Java SE Documentation</a></p>
+
+<table>
+<tr><th>Family</th><th>Color</th></tr>
+<tr><td><a href="https://jcp.org/en/jsr/platform?listBy=2&listByType=platform">Technologies in the Java SE Platform</a></td><td>Pink inside java.base - Blue outside java.base</td></tr>
+<tr><td><a href="https://jcp.org/en/jsr/platform?listBy=3&listByType=platform">Technologies in the Java EE Platform</a></td><td>Green</td></tr>
+<tr><td>JCP technologies not in the Java SE or EE Platforms</td><td>White</td></tr>
+</table>
+
+<br/>
+
+<table>
+<tr>
+<th>Technology</th>
+<th>Original JSR</th>
+<th><a href="https://jcp.org/en/procedures/jcp2#DEF">Original Target</a></th>
+<th>Module</th>
+<th><a href="https://jcp.org/en/procedures/jcp2#2.1.2">Evolved By</a></th>
+<th>History</th>
+<th>Profile/SE</th>
+<th>Loader</th>
+<th>Upg?</th>
+</tr>
+
+<tr class="se-misc">
+<td>JMX</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=3">3</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.management">java.management</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>3</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-misc">
+<td>Print Service</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=6">6</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.desktop">java.desktop</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>SE</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-misc">
+<td>Preferences</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=10">10</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.prefs">java.prefs</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>3</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-misc">
+<td>Image I/O</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=15">15</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.desktop">java.desktop</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>SE</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-misc">
+<td>SASL</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=28">28</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.security.sasl"/>java.security.sasl</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>3</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-misc">
+<td>Logging</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=47">47</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.logging">java.logging</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>1</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-misc">
+<td>Beans Persistence</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=57">57</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.desktop">java.desktop</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>SE</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-misc">
+<td>GSS</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=72">72</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.security.jgss">java.security.jgss</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>3</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-misc">
+<td>XML Digital Signature</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=105">105</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.xml.crypto">java.xml.crypto</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>3</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-misc">
+<td>JDBC Rowset</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=114">114</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.sql.rowset">java.sql.rowset</a></td>
+<td>Original JSR</td>
+<td>Co-evolved with JDBC</td>
+<td>3</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-misc">
+<td>JMX Remote</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=160">160</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.management">java.management</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>3</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-misc">
+<td>Profiling (Agent)</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=163">163</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.instrument">java.instrument</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>3</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-misc">
+<td>Profiling (JMX)</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=163">163</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.management">java.management</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>3</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<!-- Alex: Always targeted SE. Was not part of SE Platform; was part of EE Platform, and evolved through its own MRs. -->
+<tr class="se-misc">
+<td>StAX</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=173">173</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.xml">java.xml</a></td>
+<td>UJSR for Java SE</td>
+<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a></td>
+<td>2</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-misc">
+<td>Compiler</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=199">199</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.compiler">java.compiler</a></td>
+<td>Original JSR</td>
+<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a></td>
+<td>3</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-misc">
+<td>JAXP</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=206">206</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.xml">java.xml</a></td>
+<td>UJSR for Java SE</td>
+<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a></td>
+<td>2</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-misc">
+<td>JDBC</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=221">221</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.sql">java.sql</a></td>
+<td>Original JSR</td>
+<td>Co-evolved with JDBC Rowset</td>
+<td>2</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-misc">
+<td>Scripting</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=223">223</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.scripting">java.scripting</a></td>
+<td>Original JSR</td>
+<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a></td>
+<td>1</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr>
+<td>Smart Card I/O</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=268">268</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.smartcardio">java.smartcardio</a></td>
+<td>Original JSR</td>
+<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a> (unlisted)</td>
+<td>N/A</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-misc">
+<td>Annotation Processing</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=269">269</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.compiler">java.compiler</a></td>
+<td>Original JSR</td>
+<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a></td>
+<td>3</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-base">
+<td>NIO</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=51">51</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.base"/>java.base</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>1</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-base">
+<td>Concurrency Utilities</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=166">166</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.base"/>java.base</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>1</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-base">
+<td>Annotations</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=175">175</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.base"/>java.base</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>1</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-misc">
+<td>Annotations (Language Model)</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=175">175</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.compiler"/>java.compiler</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>3</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-base">
+<td>Pack200</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=200">200</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.base"/>java.base</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>1</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-base">
+<td>NIO.2</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=203">203</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.base"/>java.base</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>1</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-base">
+<td>InvokeDynamic</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=292">292</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.base"/>java.base</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>1</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-base">
+<td>Type Annotations</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=308">308</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.base"/>java.base</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>1</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-misc">
+<td>Type Annotations (Language Model)</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=308">308</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.compiler"/>java.compiler</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>3</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-base">
+<td>Date and Time</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=310">310</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.base"/>java.base</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>1</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-base">
+<td>Streams</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=335">335</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.base"/>java.base</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>1</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-base">
+<td>Collections, Math, I18N, I/O, Net, Reflection</td>
+<td>---</td>
+<td>---</td>
+<td><a href="module-summary.html#java.base"/>java.base</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>1</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-base">
+<td>JCA, JAAS, JSSE</td>
+<td>---</td>
+<td>---</td>
+<td><a href="module-summary.html#java.base"/>java.base</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>1</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-misc">
+<td>Applet, AWT, Swing, Java 2D, Beans, A11Y, Sound</td>
+<td>---</td>
+<td>---</td>
+<td><a href="module-summary.html#java.desktop"/>java.desktop</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>SE</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-misc">
+<td>JNDI</td>
+<td>---</td>
+<td>---</td>
+<td><a href="module-summary.html#java.naming"/>java.naming</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>3</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-misc">
+<td>RMI</td>
+<td>---</td>
+<td>---</td>
+<td><a href="module-summary.html#java.rmi"/>java.rmi</a></td>
+<td>UJSR for Java SE</td>
+<td></td>
+<td>2</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="se-misc">
+<td>RMI-IIOP, IDL</td>
+<td>(OMG)</td>
+<td>---</td>
+<td><a href="module-summary.html#java.corba"/>java.corba</a></td>
+<td>UJSR for Java SE</td>
+<td>Formerly an <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#endorsed-standards-apis">Endorsed Standard</a></td>
+<td>SE</td>
+<td>ext</td>
+<td>No</td>
+</tr>
+
+<tr class="se-misc">
+<td>DOM, SAX</td>
+<td>(W3C)</td>
+<td>---</td>
+<td><a href="module-summary.html#java.xml">java.xml</a></td>
+<td>UJSR for Java SE</td>
+<td>Formerly an <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#endorsed-standards-apis">Endorsed Standard</a></td>
+<td>2</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="ee-misc">
+<td>SAAJ</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=67">67</a></td>
+<td>Java EE</td>
+<td><a href="module-summary.html#java.xml.ws">java.xml.ws</a></td>
+<td>Original JSR</td>
+<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a> (f.k.a. JAXM)</td>
+<td>SE</td>
+<td>ext</td>
+<td>Yes</td>
+</tr>
+
+<tr class="ee-misc">
+<td>Web Services Metadata</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=181">181</a></td>
+<td>Java EE</td>
+<td><a href="module-summary.html#java.xml.ws">java.xml.ws</a></td>
+<td>Original JSR</td>
+<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a> (unlisted)</td>
+<td>SE</td>
+<td>ext</td>
+<td>Yes</td>
+</tr>
+
+<tr class="ee-misc">
+<td>JAXB</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=222">222</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.xml.bind">java.xml.bind</a></td>
+<td>Original JSR</td>
+<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a></td>
+<td>SE</td>
+<td>ext</td>
+<td>Yes</td>
+</tr>
+
+<tr class="ee-misc">
+<td>JAXWS</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=224">224</a></td>
+<td>Java SE</td>
+<td><a href="module-summary.html#java.xml.ws">java.xml.ws</a></td>
+<td>Original JSR</td>
+<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a></td>
+<td>SE</td>
+<td>ext</td>
+<td>Yes</td>
+</tr>
+
+<tr class="ee-misc">
+<td>Common Annotations</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=250">250</a></td>
+<td>Java SE,EE</td>
+<td><a href="module-summary.html#java.annotations.common">java.annotations.common</a></td>
+<td>Original JSR</td>
+<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a> (unlisted)</td>
+<td>SE</td>
+<td>ext</td>
+<td>Yes</td>
+</tr>
+
+<tr class="ee-misc">
+<td>JTA (non-XA)</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=907">907</a></td>
+<td>---</td>
+<td><a href="module-summary.html#java.transaction">java.transaction</a></td>
+<td>Original JSR</td>
+<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a> (unlisted)</td>
+<td>SE</td>
+<td>ext</td>
+<td>Yes</td>
+</tr>
+
+<tr class="se-misc">
+<td>JTA (XA)</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=907">907</a></td>
+<td>---</td>
+<td><a href="module-summary.html#java.sql"/>java.sql</a></td>
+<td>Original JSR</td>
+<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a> (unlisted)</td>
+<td>2</td>
+<td>boot</td>
+<td>No</td>
+</tr>
+
+<tr class="ee-misc">
+<td>JAF</td>
+<td><a href="https://jcp.org/en/jsr/detail?id=925">925</a></td>
+<td>---</td>
+<td><a href="module-summary.html#java.activation">java.activation</a></a></td>
+<td>Original JSR</td>
+<td>Formerly a <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/standards/#standalone-technologies">Standalone Technology</a> (unlisted)</td>
+<td>SE</td>
+<td>ext</td>
+<td>Yes</td>
+</tr>
+
+</table>
+
+</html>
--- a/make/src/classes/build/tools/module/GenJdepsModulesXml.java	Tue Apr 21 13:21:40 2015 -0700
+++ b/make/src/classes/build/tools/module/GenJdepsModulesXml.java	Tue Apr 21 16:49:28 2015 -0700
@@ -54,77 +54,32 @@
  */
 public final class GenJdepsModulesXml {
     private final static String USAGE =
-        "Usage: GenJdepsModulesXml -o <output file> -mp build/modules path-to-modules-xml";
+        "Usage: GenJdepsModulesXml -o <output file> path-to-modules-xml";
 
     public static void main(String[] args) throws Exception {
         Path outfile = null;
-        Path modulepath = null;
         int i = 0;
         while (i < args.length) {
             String arg = args[i];
             if (arg.equals("-o")) {
-                outfile = Paths.get(args[i+1]);
-                i = i+2;
-            } else if (arg.equals("-mp")) {
-                modulepath = Paths.get(args[i+1]);
-                i = i+2;
-                if (!Files.isDirectory(modulepath)) {
-                    System.err.println(modulepath + " is not a directory");
-                    System.exit(1);
-                }
+                outfile = Paths.get(args[i + 1]);
+                i = i + 2;
             } else {
                 break;
             }
         }
-        if (outfile == null || modulepath == null || i >= args.length) {
+        if (outfile == null || i >= args.length) {
             System.err.println(USAGE);
             System.exit(-1);
         }
 
-        GenJdepsModulesXml gentool = new GenJdepsModulesXml(modulepath);
         Set<Module> modules = new HashSet<>();
         for (; i < args.length; i++) {
             Path p = Paths.get(args[i]);
-            modules.addAll(ModulesXmlReader.readModules(p)
-                    .stream()
-                    .map(gentool::buildIncludes)
-                    .collect(Collectors.toSet()));
+            modules.addAll(ModulesXmlReader.readModules(p));
         }
 
         Files.createDirectories(outfile.getParent());
         ModulesXmlWriter.writeModules(modules, outfile);
     }
-
-    final Path modulepath;
-    public GenJdepsModulesXml(Path modulepath) {
-        this.modulepath = modulepath;
-    }
-
-    private static String packageName(Path p) {
-        return packageName(p.toString().replace(File.separatorChar, '/'));
-    }
-    private static String packageName(String name) {
-        int i = name.lastIndexOf('/');
-        return (i > 0) ? name.substring(0, i).replace('/', '.') : "";
-    }
-
-    private static boolean includes(String name) {
-        return name.endsWith(".class");
-    }
-
-    public Module buildIncludes(Module module) {
-        Module.Builder mb = new Module.Builder(module);
-        Path mclasses = modulepath.resolve(module.name());
-        try {
-            Files.find(mclasses, Integer.MAX_VALUE, (Path p, BasicFileAttributes attr)
-                         -> includes(p.getFileName().toString()))
-                 .map(p -> packageName(mclasses.relativize(p)))
-                 .forEach(mb::include);
-        } catch (NoSuchFileException e) {
-            // aggregate module may not have class
-        } catch (IOException ioe) {
-            throw new UncheckedIOException(ioe);
-        }
-        return mb.build();
-    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/src/classes/build/tools/module/GenModuleInfo.java	Tue Apr 21 16:49:28 2015 -0700
@@ -0,0 +1,519 @@
+/*
+ * 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 build.tools.module.Module.Dependence;
+import com.sun.tools.classfile.*;
+import com.sun.tools.classfile.Attribute;
+import static com.sun.tools.classfile.Module_attribute.RequiresEntry;
+import static com.sun.tools.classfile.Module_attribute.ExportsEntry;
+import static com.sun.tools.classfile.Module_attribute.ProvidesEntry;
+
+import static com.sun.tools.classfile.ConstantPool.*;
+
+import javax.xml.stream.XMLStreamException;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.*;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * GenModuleInfo build tool will generate module-info.java of JDK modules.
+ *
+ * $ java build.tools.module.GenModuleInfo \
+ *        -mp $JDK_OUTPUTDIR/modules \
+ *        -o $TOP_REPO \
+ *        top/modules.xml
+ *
+ * This will generate module-info.java of the JDK modules listed in
+ * the given modules.xml merged with the module definition,
+ * i.e. module-info.class, in the given modulepath.
+ *
+ */
+public final class GenModuleInfo {
+    private final static String USAGE =
+        "Usage: GenModuleInfo [-diff] [-o <top-repo-path>] -mp <modulepath> <path-to-modules-xml>";
+
+    public static void main(String[] args) throws Exception {
+        Path outputdir = null;
+        Path moduleinfos = null;
+        boolean diff = false;
+        boolean verbose = false;
+        Stream<String> xmlfiles = null;
+        int i = 0;
+        while (i < args.length) {
+            String arg = args[i++];
+            switch (arg) {
+                case "-o":
+                    outputdir = Paths.get(args[i++]);
+                    break;
+                case "-mp":
+                    moduleinfos = Paths.get(args[i++]);
+                    if (!Files.isDirectory(moduleinfos)) {
+                        System.err.println(moduleinfos + " is not a directory");
+                        System.exit(1);
+                    }
+                    break;
+                case "-diff":
+                    diff = true;
+                    break;
+                case "-v":
+                    verbose = true;
+                    break;
+                default:
+                    xmlfiles = Arrays.stream(args, i-1, args.length);
+                    i = args.length;
+            }
+        }
+        if ((outputdir == null && !diff) || moduleinfos == null || xmlfiles == null) {
+            System.err.println(USAGE);
+            System.exit(-1);
+        }
+        GenModuleInfo tool = new GenModuleInfo(moduleinfos, outputdir, xmlfiles, verbose);
+        if (diff) {
+            tool.diffs();
+        }
+        if (outputdir != null) {
+            tool.genModuleInfos();
+        }
+    }
+
+    private static Set<Module> readModules(String xmlfile) {
+        try {
+            return ModulesXmlReader.readModules(Paths.get(xmlfile));
+        } catch (XMLStreamException | IOException e) {
+            throw new InternalError(e);
+        }
+    }
+
+    private final Path modulepath;
+    private final SourceLocation sourceLocation;
+    private final Map<String, Module> modules;
+    private final Map<String, Module> moduleInfoClasses;
+    private final boolean verbose;
+    private int modified = 0;
+    private int created = 0;
+    private int unchanged = 0;
+    public GenModuleInfo(Path modulepath, Path sourceDir, Stream<String> xmls, boolean verbose)
+            throws IOException
+    {
+        this.modulepath = modulepath;
+        this.sourceLocation = new SourceLocation(sourceDir);
+        this.modules = xmls.flatMap(f -> readModules(f).stream())
+                           .collect(Collectors.toMap(Module::name, Function.identity()));
+        this.moduleInfoClasses = readModuleInfos();
+        this.verbose = verbose;
+    }
+
+    void genModuleInfos() {
+        Stream.concat(modules.keySet().stream(), moduleInfoClasses.keySet().stream())
+                .distinct().sorted()
+                .forEach(this::genModuleInfo);
+        System.out.format("%d module-info.java modified %d created %d unchanged%n",
+                          modified, created, unchanged);
+    }
+
+    void diffs() {
+        Stream.concat(modules.keySet().stream(), moduleInfoClasses.keySet().stream())
+                .distinct().sorted()
+                .filter(mn -> !DiffUtil.equals(modules.get(mn), moduleInfoClasses.get(mn)))
+                .forEach(mn -> DiffUtil.diff(header(mn), modules.get(mn), moduleInfoClasses.get(mn)));
+    }
+
+    private void genModuleInfo(String mn) {
+        Module m = modules.get(mn);
+        Module minfo = moduleInfoClasses.get(mn);
+        assert m != null || minfo != null;
+        if (m != null && minfo != null && DiffUtil.equals(m, minfo)) {
+            unchanged++;
+            return;
+        }
+        Module module = (m != null && minfo != null)
+                                ? new Module.Builder().merge(m, minfo).build()
+                                : (m != null ? m : minfo);
+
+        List<Path> paths = sourceLocation.findSourceLocation(mn);
+        if (m == null) {
+            paths.stream().forEach(p ->
+                    System.err.format("Warning: module %s not in modules.xml source %s%n", mn, p));
+            unchanged++;
+            return;
+        } else if (minfo == null) {
+            System.err.format("Warning: module %s not found from %s%n", mn, modulepath);
+            unchanged++;
+            return;
+        }
+        if (verbose) {
+            DiffUtil.diff(header(mn), m, minfo);
+        }
+        if (paths.isEmpty()) {
+            Path p = sourceLocation.getSourcePath("jdk", mn);
+            if (Files.notExists(p)) {
+                try {
+                    Files.createDirectories(p);
+                } catch (IOException e) {
+                    throw new UncheckedIOException(e);
+                }
+            }
+            Path newModuleInfoJava = p.resolve("module-info.java");
+            System.err.format("Warning: module %s not found in the source under %s%n",
+                               mn, sourceLocation);
+            writeModuleInfo(module, newModuleInfoJava);
+        } else {
+            paths.stream().forEach(p -> writeModuleInfo(module, p));
+        }
+    }
+
+    private void writeModuleInfo(Module m, Path p) {
+        if (Files.exists(p)) {
+            modified++;
+        } else {
+            created++;
+        }
+        if (verbose) {
+            System.out.format("%s %s%n", p, Files.exists(p) ? "modified" : "created");
+        }
+        try (PrintWriter writer = new PrintWriter(p.toFile())) {
+            writeCopyrightHeader(writer);
+            writer.println(m.toString());
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    private Map<String,Module> readModuleInfos() throws IOException {
+         return Files.find(modulepath, 2, (Path p, BasicFileAttributes attr)
+                      -> p.getFileName().toString().equals("module-info.class"))
+                     .map(this::parseModuleInfo)
+                     .collect(Collectors.toMap(Module::name, Function.identity()));
+    }
+
+    private Module parseModuleInfo(Path p) {
+        try {
+            ClassFile cf = ClassFile.read(p);
+            int i = cf.getName().indexOf("/module-info");
+            if (i <= 0) {
+                throw new RuntimeException("Not module-info: " + cf.getName());
+            }
+            String mn = cf.getName().substring(0, i).replace('/', '.');
+            ModuleInfoBuilder builder = new ModuleInfoBuilder(mn, cf);
+            return builder.build();
+        } catch (IOException | ConstantPoolException e) {
+            throw new InternalError(e);
+        }
+    }
+
+    private String header(String mn) {
+        return String.format("--- %s %s%n", mn,
+                moduleInfoClasses.containsKey(mn)
+                        ? modulepath.resolve(mn).resolve("module-info.class")
+                        : "");
+    }
+
+    class ModuleInfoBuilder extends AttributeVisitor<Void, Void> {
+        private final Module.Builder builder;
+        private final ClassFile cf;
+        ModuleInfoBuilder(String mn, ClassFile cf) {
+            this.builder = new Module.Builder();
+            this.builder.name(mn);
+            this.cf = cf;
+        }
+
+        public Module build() {
+            Module_attribute attr = (Module_attribute) cf.getAttribute(Attribute.Module);
+            attr.accept(this, null);
+            return builder.build();
+        }
+
+        public Void visitModule(Module_attribute attr, Void p) {
+            if (attr.requires_count > 0) {
+                Arrays.stream(attr.requires)
+                        .forEach(this::addRequire);
+            }
+            if (attr.exports_count > 0) {
+                Arrays.stream(attr.exports)
+                        .forEach(this::addExport);
+            }
+            if (attr.uses_count > 0) {
+                Arrays.stream(attr.uses_index)
+                        .mapToObj(this::getClassName)
+                        .forEach(builder::use);
+            }
+            if (attr.provides_count > 0) {
+                Arrays.stream(attr.provides)
+                        .forEach(this::addProvide);
+            }
+            return null;
+        }
+
+        void addRequire(RequiresEntry r) {
+            boolean reexport = r.requires_flags == Module_attribute.ACC_PUBLIC;
+            builder.require(getString(r.requires_index), reexport);
+        }
+
+        void addExport(ExportsEntry e) {
+            String pn = getString(e.exports_index).replace('/', '.');
+            if (e.exports_to_count == 0) {
+                builder.export(pn);
+            } else {
+                Set<String> permits = Arrays.stream(e.exports_to_index)
+                        .mapToObj(this::getString)
+                        .collect(Collectors.toSet());
+                builder.exportTo(pn, permits);
+            }
+        }
+
+        void addProvide(ProvidesEntry p) {
+            String s = getClassName(p.provides_index);
+            String impl = getClassName(p.with_index);
+            builder.provide(s, impl);
+        }
+
+
+        private String getString(int index) {
+            try {
+                return cf.constant_pool.getUTF8Value(index);
+            } catch (InvalidIndex | UnexpectedEntry e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        private String getClassName(int index) {
+            try {
+                return cf.constant_pool.getClassInfo(index).getName().replace('/', '.');
+            } catch (ConstantPoolException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    class AttributeVisitor<R, P> implements Attribute.Visitor<R, P> {
+        public R visitBootstrapMethods(BootstrapMethods_attribute attr, P p) { return null; }
+        public R visitDefault(DefaultAttribute attr, P p) { return null; }
+        public R visitAnnotationDefault(AnnotationDefault_attribute attr, P p) { return null; }
+        public R visitCharacterRangeTable(CharacterRangeTable_attribute attr, P p) { return null; }
+        public R visitCode(Code_attribute attr, P p) { return null; }
+        public R visitCompilationID(CompilationID_attribute attr, P p) { return null; }
+        public R visitConstantValue(ConstantValue_attribute attr, P p) { return null; }
+        public R visitDeprecated(Deprecated_attribute attr, P p) { return null; }
+        public R visitEnclosingMethod(EnclosingMethod_attribute attr, P p) { return null; }
+        public R visitExceptions(Exceptions_attribute attr, P p) { return null; }
+        public R visitHashes(Hashes_attribute attr, P p) { return null; }
+        public R visitInnerClasses(InnerClasses_attribute attr, P p) { return null; }
+        public R visitLineNumberTable(LineNumberTable_attribute attr, P p) { return null; }
+        public R visitLocalVariableTable(LocalVariableTable_attribute attr, P p) { return null; }
+        public R visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr, P p) { return null; }
+        public R visitMethodParameters(MethodParameters_attribute attr, P p) { return null; }
+        public R visitMainClass(MainClass_attribute attr, P p) { return null; }
+        public R visitModule(Module_attribute attr, P p) {
+            return null;
+        }
+        public R visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, P p) { return null; }
+        public R visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, P p) { return null; }
+        public R visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, P p) { return null; }
+        public R visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, P p) { return null; }
+        public R visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, P p) { return null; }
+        public R visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, P p) { return null; }
+        public R visitSignature(Signature_attribute attr, P p) { return null; }
+        public R visitSourceDebugExtension(SourceDebugExtension_attribute attr, P p) { return null; }
+        public R visitSourceFile(SourceFile_attribute attr, P p) { return null; }
+        public R visitSourceID(SourceID_attribute attr, P p) { return null; }
+        public R visitStackMap(StackMap_attribute attr, P p) { return null; }
+        public R visitStackMapTable(StackMapTable_attribute attr, P p) { return null; }
+        public R visitSynthetic(Synthetic_attribute attr, P p) { return null; }
+        public R visitVersion(Version_attribute attr, P p) { return null; }
+    }
+
+    static class DiffUtil {
+        private static final String LEFT = "< ";
+        private static final String RIGHT = "> ";
+        static <T extends Comparable> void diff(Set<T> o1, Set<T> o2) {
+            Stream.concat(o1.stream(), o2.stream())
+                    .distinct()
+                    .sorted()
+                    .filter(e -> (!o1.contains(e) || !o2.contains(e)))
+                    .forEach(e -> {
+                        String diff = o1.contains(e) ? LEFT : RIGHT;
+                        System.err.format("%s    %s%n", diff, e.toString());
+                    });
+        }
+
+        static <K extends Comparable, V extends Comparable>
+            void diff(Map<K, Set<V>> m1, Map<K, Set<V>> m2, BiFunction<K, V, String> mapper)
+        {
+            Stream.concat(m1.keySet().stream(), m2.keySet().stream())
+                    .distinct()
+                    .sorted()
+                    .forEach(k -> {
+                        if (m1.containsKey(k) && m2.containsKey(k)) {
+                            Set<V> v1 = m1.get(k);
+                            Set<V> v2 = m2.get(k);
+                            Stream.concat(v1.stream(), v2.stream())
+                                    .distinct().sorted()
+                                    .filter(v -> (!v1.contains(v) || !v2.contains(v)))
+                                    .forEach(v -> {
+                                        String diff = v1.contains(v) ? LEFT : RIGHT;
+                                        System.err.format("%s    %s%n", diff, mapper.apply(k, v));
+                                    });
+                        } else {
+                            String diff = m1.containsKey(k) ? LEFT : RIGHT;
+                            Set<V> values = m1.containsKey(k) ? m1.get(k) : m2.get(k);
+                            values.stream().sorted()
+                                    .forEach(v -> System.err.format("%s    %s%n", diff, mapper.apply(k, v)));
+                        }
+                    });
+        }
+
+        static String exports(String k, String v) {
+            return String.format("exports %s to %s;", k, v);
+        }
+
+        static void diff(String header, Module original, Module module) {
+            assert original != null || module != null;
+            if (original == null || module == null) {
+                Module m = original != null ? original : module;
+                System.err.print(header);
+                String[] lines = original.toString().split("\n");
+                String diff = original == m ? LEFT : RIGHT;
+                Arrays.stream(lines).forEach(l -> System.err.println(diff + l));
+            } else if (!equals(original, module)) {
+                // uses and provides are not diff
+                System.err.print(header);
+                DiffUtil.diff(original.requires(), module.requires());
+                DiffUtil.diff(original.exports(), module.exports(), DiffUtil::exports);
+            }
+        }
+
+        static boolean equals(Module m1, Module m2) {
+            if (m1 != null && m2 != null) {
+                // filter requires java.base as it may be synthesized
+                Set<Dependence> requires1 = m1.requires().stream()
+                                              .filter(d -> !d.name().equals("java.base") || d.reexport())
+                                              .collect(Collectors.toSet());
+                Set<Dependence> requires2 = m2.requires().stream()
+                                              .filter(d -> !d.name().equals("java.base") || d.reexport())
+                                              .collect(Collectors.toSet());
+                return requires2.equals(requires2) && m1.exports().equals(m2.exports());
+            } else {
+                return false;
+            }
+        }
+    }
+
+    static class SourceLocation {
+        static final List<Path> repos = new ArrayList<>();
+        static final List<String> dirs = Arrays.asList("share", "unix", "windows",
+                                                       "macosx", "linux", "solaris");
+
+        static {
+            addRepo("jdk", "src");
+            addRepo("langtools", "src");
+            addRepo("jaxp", "src");
+            addRepo("jaxws", "src");
+            addRepo("corba", "src");
+            addRepo("nashorn", "src");
+            addRepo("hotspot", "agent", "src");
+            addRepo(Paths.get("jdk", "src", "closed"));
+        }
+
+        private static void addRepo(String repo, String... paths) {
+            addRepo(Paths.get(repo, paths));
+        }
+        private static void addRepo(Path repo) {
+            repos.add(repo);
+        }
+
+        private final Path srcDir;
+        SourceLocation(Path dir) {
+            this.srcDir = dir;
+        }
+
+        private Stream<Path> expand(Path moduleSourcePath) {
+            return dirs.stream()
+                       .map(os -> moduleSourcePath.resolve(os)
+                                                  .resolve("classes")
+                                                  .resolve("module-info.java"));
+        }
+        private List<Path> findSourceLocation(String mn) {
+            List<Path> minfos = repos.stream()
+                    .map(srcDir::resolve)
+                    .flatMap(p -> expand(p.resolve(mn)))
+                    .filter(Files::exists)
+                    .collect(Collectors.toList());
+            return minfos;
+        }
+
+        private Path getSourcePath(String repo, String mn) {
+            return srcDir.resolve(repo).resolve("src").resolve(mn)
+                         .resolve("share").resolve("classes");
+        }
+
+        @Override
+        public String toString() {
+            return srcDir.toString();
+        }
+    }
+
+    private static final String[] COPYRIGHT_HEADER = new String[]{
+        "/*",
+        " * 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.",
+        " */",
+        ""
+    };
+
+    private static void writeCopyrightHeader(PrintWriter writer) {
+        Arrays.stream(COPYRIGHT_HEADER).forEach(writer::println);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/src/classes/build/tools/module/GenModuleInfoSource.java	Tue Apr 21 16:49:28 2015 -0700
@@ -0,0 +1,112 @@
+/*
+ * 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.BufferedWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+/**
+ * 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.
+ *
+ * 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.
+ */
+public class GenModuleInfoSource {
+    private final static String USAGE =
+        "Usage: GenModuleInfoSource [option] -o <output file> <module-info-java>\n" +
+        "Options are:\n" +
+        "  -export  <package-name>\n" +
+        "  -export  <package-name>/<module-name>\n" +
+        "  -use     <service>\n" +
+        "  -provide <service>/<provider-impl-classname>\n";
+
+    public static void main(String... args) throws Exception {
+        Path outfile = null;
+        Path moduleInfoJava = null;
+
+        Module.Builder builder = new Module.Builder();
+        int i = 0;
+        for (; i < args.length; i++) {
+            String option = args[i];
+            if (option.startsWith("-")) {
+                String arg = args[++i];
+                if (option.equals("-export")) {
+                    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 (option.equals("-use")) {
+                    builder.use(arg);
+                } else if (option.equals("-provide")) {
+                    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);
+                } else if (option.equals("-o")) {
+                    outfile = Paths.get(arg);
+                } else {
+                    throw new IllegalArgumentException("invalid option: " + option);
+                }
+            } else if (moduleInfoJava != null) {
+                throw new IllegalArgumentException("more than one module-info.java");
+            } else {
+                moduleInfoJava = Paths.get(option);
+                if (Files.notExists(moduleInfoJava)) {
+                    throw new IllegalArgumentException(option + " not exist");
+                }
+            }
+        }
+
+        if (moduleInfoJava == null || outfile == null) {
+            System.err.println(USAGE);
+            System.exit(-1);
+        }
+
+        ModuleInfoReader reader = new ModuleInfoReader(moduleInfoJava, builder);
+        Module module = reader.get();
+        Path parent = outfile.getParent();
+        if (parent != null)
+            Files.createDirectories(parent);
+
+        try (BufferedWriter writer = Files.newBufferedWriter(outfile)) {
+            writer.write(module.toString());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/src/classes/build/tools/module/GenModuleLoaderMap.java	Tue Apr 21 16:49:28 2015 -0700
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class GenModuleLoaderMap {
+    private static final String USAGE =
+        "GenModuleLoaderMap -o <output-file> -boot m1[,m2]* -ext m3[,m4]* <original-source>";
+
+    public static void main(String... args) throws Exception {
+        // default set of boot modules and ext modules
+        Stream<String> bootModules = Stream.empty();
+        Stream<String> extModules = Stream.empty();
+        Path outfile = null;
+        Path source = null;
+        for (int i=0; i < args.length; i++) {
+            String option = args[i];
+            if (option.startsWith("-")) {
+                String arg = args[++i];
+                if (option.equals("-boot")) {
+                    String[] mns = arg.split(",");
+                    bootModules = Stream.concat(bootModules, Arrays.stream(mns));
+                } else if (option.equals("-ext")) {
+                    String[] mns = arg.split(",");
+                    extModules = Stream.concat(extModules, Arrays.stream(mns));
+                } else if (option.equals("-o")) {
+                    outfile = Paths.get(arg);
+                } else {
+                    throw new IllegalArgumentException("invalid option: " + option);
+                }
+            } else {
+                source = Paths.get(option);
+            }
+        }
+
+        if (outfile == null) {
+            throw new IllegalArgumentException("-o must be specified");
+        }
+        if (Files.notExists(source)) {
+            throw new IllegalArgumentException(source + " not exist");
+        }
+
+        try (BufferedWriter bw = Files.newBufferedWriter(outfile, StandardCharsets.UTF_8);
+             PrintWriter writer = new PrintWriter(bw)) {
+            for (String line : Files.readAllLines(source)) {
+                if (line.contains("@@BOOT_MODULE_NAMES@@")) {
+                    line = patch(line, "@@BOOT_MODULE_NAMES@@", bootModules);
+                } else if (line.contains("@@EXT_MODULE_NAMES@@")) {
+                    line = patch(line, "@@EXT_MODULE_NAMES@@", extModules);
+                }
+                writer.println(line);
+            }
+        }
+    }
+
+    private static String patch(String s, String tag, Stream<String> stream) {
+        String mns = stream.sorted()
+            .collect(Collectors.joining("\",\n            \""));
+        return s.replace(tag, mns);
+    }
+
+    /**
+     * Reads the contents of the given modules file.
+     */
+    private static Set<String> readModuleSet(String name) throws IOException {
+        try (InputStream is = GenModuleLoaderMap.class.getResourceAsStream(name);
+             BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
+            return reader.lines().collect(Collectors.toSet());
+        }
+    }
+}
--- a/make/src/classes/build/tools/module/ImageBuilder.java	Tue Apr 21 13:21:40 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,499 +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 jdk.internal.jimage.Archive;
-import jdk.internal.jimage.ImageFile;
-import jdk.internal.jimage.ImageModules;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.PrintWriter;
-import java.io.UncheckedIOException;
-import java.nio.ByteOrder;
-import java.nio.file.Files;
-import java.nio.file.InvalidPathException;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.attribute.PosixFilePermission;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-/**
- * A tool for building a runtime image.
- *
- * java build.tools.module.ImageBuilder <options> --output <path> top/modules.xml,...
- *  Possible options are:
- *  --cmds                  Location of native commands
- *  --configs               Location of config files
- *  --help                  Print this usage message
- *  --classes               Location of module classes files
- *  --libs                  Location of native libraries
- *  --mods                  Comma separated list of module names
- *  --output                Location of the output path
- *  --endian                Byte order of the target runtime; {little,big}
- */
-class ImageBuilder {
-    static class BadArgs extends Exception {
-        private static final long serialVersionUID = 0L;
-        BadArgs(String format, Object... args) {
-            super(String.format(format, args));
-            this.format = format;
-            this.args = args;
-        }
-        BadArgs showUsage(boolean b) {
-            showUsage = b;
-            return this;
-        }
-        final String format;
-        final Object[] args;
-        boolean showUsage;
-    }
-
-    static abstract class Option {
-        final boolean hasArg;
-        final String[] aliases;
-        Option(boolean hasArg, String... aliases) {
-            this.hasArg = hasArg;
-            this.aliases = aliases;
-        }
-        boolean isHidden() {
-            return false;
-        }
-        boolean matches(String opt) {
-            for (String a : aliases) {
-                if (a.equals(opt)) {
-                    return true;
-                } else if (opt.startsWith("--") && hasArg && opt.startsWith(a + "=")) {
-                    return true;
-                }
-            }
-            return false;
-        }
-        boolean ignoreRest() {
-            return false;
-        }
-        abstract void process(ImageBuilder task, String opt, String arg) throws BadArgs;
-        abstract String description();
-    }
-
-    private static Path CWD = Paths.get("");
-
-    private static List<Path> splitPath(String arg, String separator)
-        throws BadArgs
-    {
-        List<Path> paths = new ArrayList<>();
-        for (String p: arg.split(separator)) {
-            if (p.length() > 0) {
-                try {
-                    Path path = CWD.resolve(p);
-                    if (Files.notExists(path))
-                        throw new BadArgs("path not found: %s", path);
-                    paths.add(path);
-                } catch (InvalidPathException x) {
-                    throw new BadArgs("path not valid: %s", p);
-                }
-            }
-        }
-        return paths;
-    }
-
-    static Option[] recognizedOptions = {
-        new Option(true, "--cmds") {
-            void process(ImageBuilder task, String opt, String arg) throws BadArgs {
-                task.options.cmds = splitPath(arg, File.pathSeparator);
-            }
-            String description() { return "Location of native commands"; }
-        },
-        new Option(true, "--configs") {
-            void process(ImageBuilder task, String opt, String arg) throws BadArgs {
-                task.options.configs = splitPath(arg, File.pathSeparator);
-            }
-            String description() { return "Location of config files"; }
-        },
-        new Option(false, "--help") {
-            void process(ImageBuilder task, String opt, String arg) {
-                task.options.help = true;
-            }
-            String description() { return "Print this usage message"; }
-        },
-        new Option(true, "--classes") {
-            void process(ImageBuilder task, String opt, String arg) throws BadArgs {
-                task.options.classes = splitPath(arg, File.pathSeparator);
-            }
-            String description() { return "Location of module classes files"; }
-        },
-        new Option(true, "--libs") {
-            void process(ImageBuilder task, String opt, String arg) throws BadArgs {
-                task.options.libs = splitPath(arg, File.pathSeparator);
-            }
-            String description() { return "Location of native libraries"; }
-        },
-        new Option(true, "--mods") {
-            void process(ImageBuilder task, String opt, String arg) throws BadArgs {
-                for (String mn : arg.split(",")) {
-                    if (mn.isEmpty())
-                        throw new BadArgs("Module not found", mn);
-                    task.options.mods.add(mn);
-                }
-            }
-            String description() { return "Comma separated list of module names"; }
-        },
-        new Option(true, "--output") {
-            void process(ImageBuilder task, String opt, String arg) throws BadArgs {
-                Path path = Paths.get(arg);
-                task.options.output = path;
-            }
-            String description() { return "Location of the output path"; }
-        },
-        new Option(true, "--endian") {
-            void process(ImageBuilder task, String opt, String arg) throws BadArgs {
-                if (arg.equals("little"))
-                    task.options.endian = ByteOrder.LITTLE_ENDIAN;
-                else if (arg.equals("big"))
-                    task.options.endian = ByteOrder.BIG_ENDIAN;
-                else
-                    throw new BadArgs("Unknown byte order " + arg);
-            }
-            String description() { return "Byte order of the target runtime; {little,big}"; }
-        }
-    };
-
-    private final Options options = new Options();
-
-    private PrintWriter log;
-    void setLog(PrintWriter out) {
-        log = out;
-    }
-
-    Set<Module> moduleGraph = new java.util.HashSet<>();
-
-    /** Module list files */
-    private static final String BOOT_MODULES = "boot.modules";
-    private static final String EXT_MODULES = "ext.modules";
-
-    /**
-     * Result codes.
-     */
-    static final int EXIT_OK = 0,       // Completed with no errors.
-                     EXIT_ERROR = 1,    // Completed but reported errors.
-                     EXIT_CMDERR = 2,   // Bad command-line arguments
-                     EXIT_SYSERR = 3,   // System error or resource exhaustion.
-                     EXIT_ABNORMAL = 4; // terminated abnormally
-
-
-    static class Options {
-        boolean help;
-        List<Path> classes;
-        List<Path> cmds;
-        List<Path> configs;
-        List<Path> libs;
-        Set<String> mods = new HashSet<>();
-        Path output;
-        ByteOrder endian = ByteOrder.nativeOrder(); // default, if not specified
-    }
-
-    public static void main(String[] args) throws Exception {
-        ImageBuilder builder = new ImageBuilder();
-        int rc = builder.run(args);
-        System.exit(rc);
-    }
-
-    int run(String[] args) {
-        if (log == null)
-            log = new PrintWriter(System.out);
-
-        try {
-            handleOptions(args);
-            if (options.help) {
-                showHelp();
-                return EXIT_OK;
-            }
-
-            if (options.classes == null)
-                throw new BadArgs("--classes must be specified").showUsage(true);
-
-            Path output = options.output;
-            if (output == null)
-                throw new BadArgs("--output must be specified").showUsage(true);
-            Files.createDirectories(output);
-            if (Files.list(output).findFirst().isPresent())
-                throw new BadArgs("dir not empty", output);
-
-            if (options.mods.isEmpty())
-                throw new BadArgs("--mods must be specified").showUsage(true);
-
-            if (moduleGraph.isEmpty())
-                throw new BadArgs("modules.xml must be specified").showUsage(true);
-
-            if (options.cmds == null || options.cmds.isEmpty())
-                warning("--commands is not set");
-            if (options.libs == null || options.libs.isEmpty())
-                warning("--libs is not set");
-            //if (options.configs == null || options.configs.isEmpty())
-            //    warning("--configs is not set");
-
-            // additional option combination validation
-
-            boolean ok = run();
-            return ok ? EXIT_OK : EXIT_ERROR;
-        } catch (BadArgs e) {
-            reportError(e.format, e.args);
-            if (e.showUsage)
-                log.println(USAGE_SUMMARY);
-            return EXIT_CMDERR;
-        } catch (Exception x) {
-            x.printStackTrace();
-            return EXIT_ABNORMAL;
-        } finally {
-            log.flush();
-        }
-    }
-
-    private boolean run() throws IOException {
-        createImage();
-        return true;
-    }
-
-    class SimpleResolver {
-        private final Set<Module> initialMods;
-        private final Map<String,Module> nameToModule = new HashMap<>();
-
-        SimpleResolver(Set<String> mods, Set<Module> graph) {
-            graph.stream()
-                 .forEach(m -> nameToModule.put(m.name(), m));
-            initialMods = mods.stream()
-                         .map(this::nameToModule)
-                         .collect(Collectors.toSet());
-        }
-
-        /** Returns th