changeset 7930:6bf99c2519a3

Compile modules.{config,group} into serialized form
author mchung
date Thu, 29 Aug 2013 14:37:18 -0700
parents c442171f1d17
children e55f1e7e39f0
files make/modules/modules.config make/modules/modules.group make/modules/modules.properties make/modules/tools/src/com/sun/tools/classanalyzer/ClassAnalyzer.java make/modules/tools/src/com/sun/tools/classanalyzer/ClassFileReader.java make/modules/tools/src/com/sun/tools/classanalyzer/ClassPath.java make/modules/tools/src/com/sun/tools/classanalyzer/Dependence.java make/modules/tools/src/com/sun/tools/classanalyzer/JigsawModules.java make/modules/tools/src/com/sun/tools/classanalyzer/Klass.java make/modules/tools/src/com/sun/tools/classanalyzer/Module.java make/modules/tools/src/com/sun/tools/classanalyzer/ModuleBuilder.java make/modules/tools/src/com/sun/tools/classanalyzer/ModuleConfig.java make/modules/tools/src/com/sun/tools/classanalyzer/Package.java make/modules/tools/src/com/sun/tools/classanalyzer/Resource.java make/modules/tools/src/com/sun/tools/classanalyzer/Service.java make/modules/tools/src/com/sun/tools/classanalyzer/filelist make/modules/tools/src/com/sun/tools/classanalyzer/resources/classanalyzer.properties makefiles/BuildJdk.gmk makefiles/GenerateModules.gmk makefiles/ModulesCommon.gmk makefiles/profile-rtjar-includes.txt test/jdk/jigsaw/module/JdkModules.java
diffstat 21 files changed, 5969 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/modules/modules.config	Thu Aug 29 14:37:18 2013 -0700
@@ -0,0 +1,1123 @@
+/*
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**************************************************************************
+ * modules.config defines a list of fine-grained modules whose name
+ * matches the value of the MODULE variable defined in the Makefiles.
+ * These fine-grained modules may be merged as defined in modules.group
+ * and they may not be the real modules created during the jdk build.
+ *
+ * This file also defines the modules for the jdk tools (one for each
+ * tool named "jdk.<tool's name>").
+ *
+ * Note: Renaming a module name must make sure that the change is 
+ * made in both this file, the MODULE variable in jdk makefiles,
+ * and also make/common/Defs-modules.gmk.
+ **************************************************************************/
+
+// These classes are not referenced in the JDK but we can't
+// remove them for compatibility reason.  Define this module
+// first so that other modules don't need to exclude these clases
+module private-legacy {
+    include sun.misc.ClassLoaderUtil,
+            sun.misc.Compare,
+            sun.misc.ConditionLock,
+            sun.misc.CRC16,
+            sun.misc.Lock,
+            sun.misc.Regexp,
+            sun.misc.Sort,
+            sun.misc.Timeable,
+            sun.misc.Timer,
+            sun.misc.TimerThread,
+            sun.misc.TimerTickThread,
+            sun.misc.UCDecoder,
+            sun.misc.UCEncoder,
+            sun.misc.UUDecoder,
+            sun.misc.UUEncoder,
+            sun.net.NetworkServer,
+            sun.net.URLCanonicalizer,
+            sun.reflect.FieldInfo,
+            sun.reflect.SignatureIterator,
+            sun.reflect.generics.reflectiveObjects.NotImplementedException,
+            sunw.io.Serializable,
+            sunw.util.EventListener,
+            sunw.util.EventObject;
+    // ## keep SSLContext in the base to get one fewer split package
+    // include com.sun.net.ssl.SSLContext;
+}
+
+// Deprecated classes that aren't referenced/used go here.
+module deprecated {
+    // add deprecated security classes once b78 is promoted
+}
+
+/**************************************************************************/
+
+module base {
+    // core classes
+    include java.lang.*,
+            java.lang.annotation.*,
+            java.lang.ref.*,
+            java.lang.reflect.*,
+            java.math.*,
+            java.net.*,
+            java.util.*,
+            java.util.concurrent.**,
+            java.util.jar.*,
+            java.util.regex.*,
+            java.util.spi.*,
+            java.util.stream.*,
+            java.util.zip.*,
+            java.text.**;
+    exclude java.util.jar.Pack200*;
+
+    // invokedynamic
+    include java.lang.invoke.**, sun.invoke.**;
+
+    // lambda & ASM
+    include java.util.function.**;
+    include jdk.Supported;
+    include jdk.internal.org.objectweb.asm.**;
+
+    include java.io.*;
+
+    include java.nio.**, com.sun.nio.file.*;
+    include com.oracle.nio.**;
+    include com.oracle.net.*;
+    include com.oracle.util.*;
+
+    // MAC
+    include apple.security.*;
+    include com.apple.concurrent.**;
+    include com.apple.eio.**;
+
+    include sun.nio.fs.*, sun.nio.ch.*, sun.nio.ByteBuffered;
+    exclude META-INF/services/java.nio.file.spi.FileSystemProvider;
+
+    // security APIs
+    // javax.crypto and javax.security.auth are included to avoid inconsistent
+    // spliting of JCA and JAAS. This adds about 85k. Also note that some deprecated
+    // classes must be included for now (see 6876158, 6876170)
+    include java.security.*,
+            java.security.cert.*,
+            java.security.interfaces.*,
+            java.security.spec.*,
+            javax.security.auth.**,
+            javax.crypto.**;
+
+    // Sun and RSA security providers (except LDAP CertStore)
+    // roots sun.security.provider.* sun.security.provider.certpath.* sun.security.rsa.*
+
+    include sun.security.action.*,
+            sun.security.ec.*,
+            sun.security.jca.*,
+            sun.security.pkcs.*,
+            sun.security.pkcs12.*,
+            sun.security.provider.*,
+            sun.security.provider.certpath.*,
+            sun.security.rsa.*,
+            sun.security.util.*,
+            sun.security.validator.*,
+            sun.security.x509.*,
+            sun.security.timestamp.*;
+
+    // this list is based on the classlist generated from the rootset
+    // need investigation - see JDK-7194075
+    exclude sun.security.ec.ECD*,
+            sun.security.ec.ECKeyPairGenerator,
+            sun.security.ec.SunEC*,
+            sun.security.util.HostnameChecker;
+
+    // Kerberos not needed
+    exclude javax.security.auth.kerberos.**,
+            sun.security.jgss.**,
+            sun.security.krb5.**,
+            sun.security.ssl.Kerberos*,
+            org.ietf.jgss.**;
+
+    // mandatory charsets
+    include sun.nio.cs.*;
+
+    include sun.text.*,
+            sun.text.bidi.*,
+            sun.text.normalizer.*;
+
+    // CLDR
+    include sun.util.cldr.*,
+            sun.util.resources.cldr.*,
+            sun.util.resources.cldr.en.*,
+            sun.text.resources.cldr.*,
+            sun.text.resources.cldr.en.*;
+
+    // resource files
+    include sun/text/resources/*.icu;
+    include sun/text/resources/CharacterBreakIteratorData,
+            sun/text/resources/WordBreakIteratorData,
+            sun/text/resources/LineBreakIteratorData,
+            sun/text/resources/SentenceBreakIteratorData;
+
+    include sun.util.*,
+            sun.util.calendar.*,
+            sun.util.locale.**,
+            sun.util.logging.*,
+            sun.util.spi.*,
+            sun.util.resources.*,
+            sun.util.resources.en.*;
+
+    // US_en locale
+    include sun.text.resources.*,
+            sun.text.resources.en.*,
+            sun.util.EmptyListResourceBundle;
+
+    // resources file needed by
+    // - sun.misc.ExtensionInfo
+    // - sun.security.provider.PolicyFile
+    // - com.sun.security.auth.PolicyFile
+    include sun.misc.resources.Messages,
+            sun.security.util.AuthResources,
+            sun.security.util.Resources;
+
+    exclude sun.security.util.AuthResources_*,
+            sun.security.util.Resources_*;
+
+    include sun.reflect.**;
+
+    // protocol handlers
+    include sun.net.www.protocol.file.*,
+            sun.net.www.protocol.jar.*,
+            sun.net.www.protocol.http.*,
+	    sun.net.www.protocol.module.*;
+
+    include sun.net.*,
+            sun.net.sdp.*,
+            sun.net.spi.*,
+            sun.net.idn.*,
+            sun.net.util.*,
+            sun.net.www.*,
+            sun.net.www.http.*,
+            sun.net.spi.nameservice.*;
+
+    // resource file for sun.net.idn
+    include sun/net/idn/*;
+
+    // classes in net-compat
+    exclude sun.net.Telnet*, sun.net.TransferProtocolClient;
+
+    // classes in deploy
+    exclude sun.net.www.protocol.http.AuthCacheBridge;
+
+    // classes in security-jsse
+    exclude java.net.SecureCacheResponse;
+
+    // launcher
+    include sun.launcher.LauncherHelper, sun.launcher.resources.launcher*;
+
+    include sun.misc.*;
+    exclude sun.misc.FIFOQueueEnumerator,
+            sun.misc.LIFOQueueEnumerator,
+            sun.misc.PerformanceLogger,
+            sun.misc.Queue,
+            sun.misc.QueueElement,
+            sun.misc.Ref;
+    // these classes are included in the client module
+    exclude sun.misc.Cache*,
+            sun.misc.Request,
+            sun.misc.RequestProcessor;
+
+    // include usage tracker 
+    include sun.usagetracker.*;
+
+    // On Windows, OSEnvironment dependency
+    include sun.io.Win32ErrorMode;
+
+    // unicode scripting support 
+    include java/lang/uniName.dat;
+}
+
+
+module xmlparser {
+    include jdk.internal.org.xml.**,
+            jdk.internal.util.xml.**;
+}
+
+module time {
+    include java.time.**;
+}
+
+/**************************************************************************/
+
+module charsets {
+    include sun.nio.cs.ext.**;
+}
+
+/**************************************************************************/
+
+// For now, retains the current JRE extensions where localedata.jar in jre/lib/ext 
+module localedata {
+    include sun.util.resources.**,
+            sun.text.resources.**;
+}
+
+module resources {
+    include sun.text.resources.*,
+            sun.util.resources.*,
+            sun.security.util.AuthResources_*,
+            sun.security.util.Resources_*,
+            sun.misc.resources.*;
+    include sun/text/resources/th/*;
+}
+
+/**************************************************************************/
+
+/*
+ * unpack200 is needed in the boot for native packaging support.
+ */
+module unpack200-tool {
+    include java.util.jar.Pack200*;
+    include com.sun.java.util.jar.pack.**;
+}
+
+/**************************************************************************/
+
+module logging {
+    include java.util.logging.*, sun.util.logging.**;
+
+    // Formatter for HTTP messages
+    include sun.net.www.protocol.http.logging.*;
+}
+
+/**************************************************************************/
+
+module management-snmp {
+    include com.sun.jmx.snmp.**, sun.management.snmp.**;
+}
+
+module management-iiop {
+    include com.sun.jmx.remote.protocol.iiop.*;
+
+    // stubs and ties
+    include javax.management.remote.rmi._*,
+            org.omg.stub.javax.management.remote.rmi.**;
+}
+
+module management {
+    include java.lang.management.*, com.sun.management.**, sun.management.**;
+    include javax.management.**, com.sun.jmx.**;
+}
+
+module jfr {
+    include com.oracle.jrockit.**;
+    include jdk.jfr.**;
+    include oracle.jrockit.**;
+}
+
+/**************************************************************************/
+
+module tracing {
+    // tracing
+    include com.sun.tracing.**, sun.tracing.**;
+}
+
+module instrument {
+    // java.lang.instrument
+    include java.lang.instrument.*, sun.instrument.*;
+}
+
+module hprof {
+    // HPROF support
+    include com.sun.demo.jvmti.hprof.*;
+}
+
+module attach {
+    include com.sun.tools.attach.**,
+            sun.tools.attach.**;
+}
+
+module jdi {
+    include com.sun.jdi.**, com.sun.tools.jdi.**;
+    include META-INF/services/com.sun.tools.jdi.**;
+}
+
+module jdwp {
+    // contains native library
+}
+
+module jvmstat {
+    include sun.jvmstat.**;
+}
+
+// ## SA should be separated into sajdi.gui and sajdi 
+// sun.jvm.hotspot.CommandProcessor references both
+// gui and non-gui tools
+module sajdi {
+    // GUI tools
+    include sun.jvm.hotspot.HSDB,
+            sun.jvm.hotspot.tools.Tool,
+            sun.jvm.hotspot.bugspot.**,
+            sun.jvm.hotspot.ui.**,
+            com.sun.java.swing.ui.**,
+            com.sun.java.swing.action.**;
+    include toolbarButtonGraphics/**;
+
+    // non-GUI tools
+    include sun.jvm.hotspot.**;
+    include sa.properties;
+}
+
+/**************************************************************************/
+
+module tools.rmic {
+    include sun.rmi.rmic.**;
+    include sun.tools.asm.*,
+            sun.tools.java.*,
+            sun.tools.javac.**,
+            sun.tools.tree.*,
+            sun.tools.util.*;
+    class sun.rmi.rmic.Main;
+}
+
+module rmi {
+    include java.rmi.**, sun.rmi.**, com.sun.rmi.**;
+
+    // SSL factories are in rmi
+    include javax.rmi.ssl.**;
+}
+
+/**************************************************************************/
+
+module prefs {
+    include java.util.prefs.*;
+}
+
+/**************************************************************************/
+
+module security-jsse {
+    include javax.net.**,
+            javax.security.cert.*,
+            java.net.SecureCacheResponse,
+            com.sun.net.ssl.**,
+            com.sun.security.cert.internal.x509.*,
+            sun.security.ssl.*,
+            sun.net.www.protocol.https.**,
+            sun.security.internal.interfaces.Tls*,
+            sun.security.internal.spec.Tls*,
+            sun.security.util.HostnameChecker,
+            sun.security.provider.certpath.ssl.**;
+}
+
+module security-sunpkcs11 {
+    include sun.security.pkcs11.**;
+}
+
+module security-ucrypto {
+    include com.oracle.security.ucrypto.**;
+}
+
+module security-sunjce {
+    include com.sun.crypto.provider.*;
+}
+
+module security-sunec {
+    include sun.security.ec.*;
+}
+
+module security-sunmscapi {
+    include sun.security.mscapi.*;
+}
+
+module security-kerberos {
+    include javax.security.auth.kerberos.*,
+            com.sun.security.jgss.**,
+            com.sun.security.sasl.gsskerb.**,             // GSSAPI SASL mechanism
+            sun.security.jgss.**,
+            sun.security.ssl.krb5.**,
+            sun.security.krb5.**,
+            org.ietf.jgss.**,
+            sun.net.www.protocol.http.spnego.*;
+}
+
+module security-sasl-ntlm {
+    include com.sun.security.ntlm.**;
+    include com.sun.security.sasl.ntlm.**;
+
+    // NTLM authentication support
+    include sun.net.www.protocol.http.ntlm.*;
+}
+
+module security-sasl {
+    include javax.security.sasl.**,
+            com.sun.security.sasl.**;
+}
+
+module security-xmldsig {
+    include javax.xml.crypto.**,
+            org.jcp.xml.dsig.**,
+            com.sun.org.apache.xml.internal.security.**;
+}
+
+// ## TODO: make sun.security.smartcardio.** to be module-private
+// 
+module security-smartcardio {
+    include javax.smartcardio.**, sun.security.smartcardio.**;
+}
+
+module sun.auth.ldap {
+    include com.sun.security.auth.LdapPrincipal;
+    include com.sun.security.auth.module.LdapLoginModule;
+}
+
+module sun.auth.jndi {
+    include com.sun.security.auth.module.JndiLoginModule;
+}
+
+module sun.auth.kerberos {
+    include com.sun.security.auth.module.Krb5LoginModule;
+}
+
+module security-auth {
+    include com.sun.security.auth.**;
+}
+
+// ## deprecated but public APIs
+module security-acl {
+    include java.security.acl.*, sun.security.acl.*;
+}
+
+/**************************************************************************/
+
+module jndi-ldap {
+    include javax.naming.ldap.**,
+            com.sun.jndi.ldap.**,
+            com.sun.jndi.url.ldap.*,
+            com.sun.jndi.url.ldaps.*,
+            sun.security.provider.certpath.ldap.**;
+}
+
+module jndi-rmiregistry {
+    include com.sun.jndi.rmi.**, com.sun.jndi.url.rmi.**;
+}
+
+module jndi-dns {
+    include net-dns;
+    include com.sun.jndi.dns.**, com.sun.jndi.url.dns.**;
+}
+
+module jndi-cosnaming {
+    include com.sun.jndi.cosnaming.**,
+            com.sun.jndi.toolkit.corba.**,
+            com.sun.jndi.url.corbaname.**,
+            com.sun.jndi.url.iiop.**,
+            com.sun.jndi.url.iiopname.**;
+}
+
+// framework/API and classes used by providers
+module jndi {
+    include javax.naming.**,
+            com.sun.naming.**,
+            com.sun.jndi.toolkit.ctx.**,
+            com.sun.jndi.toolkit.dir.**,
+            com.sun.jndi.toolkit.url.**;
+}
+
+/**************************************************************************/
+
+module jta {
+    include javax.transaction.**;  // JTA
+}
+
+// JDBC 4.1, JSR 221
+module jdbc {
+    include java.sql.**, javax.sql.*;
+}
+
+// JDBC Rowset interface, JSR 114
+module jdbc-rowset {
+    include javax.sql.rowset.**;
+    include com.sun.rowset.**;
+}
+
+
+/**************************************************************************/
+
+module scripting {
+    include javax.script.**;
+
+    // supporting classes for scripting engines
+    include com.sun.script.util.**;
+
+    // MAC
+    include apple.applescript.*;
+}
+
+module scripting-rhino {
+    include com.sun.script.javascript.**, sun.org.mozilla.**;
+}
+
+module nashorn {
+    include jdk.nashorn.**,
+            jdk.internal.dynalink.**,
+            netscape.**;
+    include jdk/nashorn/**;
+    include META-INF/services/javax.script.ScriptEngineFactory;
+}
+
+/**************************************************************************/
+
+module httpserver {
+    include com.sun.net.httpserver.**, sun.net.httpserver.**;
+}
+
+/**************************************************************************/
+
+module sctp {
+    include com.sun.nio.sctp.**, sun.nio.ch.sctp.*;
+}
+
+module zipfs {
+    include com.sun.nio.zipfs.*;
+    include META-INF/services/java.nio.file.spi.FileSystemProvider;
+}
+
+/**************************************************************************/
+
+module beans {
+    include java.beans.**, com.sun.beans.**, sun.beans.**;
+}
+
+/**************************************************************************/
+
+module jaxp-api {
+    include javax.xml.**,
+            org.w3c.dom.**,
+            org.w3c.sax.**,
+            org.xml.sax.**;
+
+    // Not part of JAXP API; bundled with xalan
+    exclude org.w3c.dom.xpath.*;
+
+    exclude javax.xml.crypto.**,   // XML-DSIG
+            javax.xml.bind.**,     // JAX-WS
+            javax.xml.soap.**,
+            javax.xml.ws.**;
+
+    include sun.util.xml.*;
+}
+
+module jaxp-xerces-impl {
+    include com.sun.org.apache.xerces.internal.**;
+
+    // include in xerces-impl due to circular dependencies
+    include com.sun.org.apache.xml.internal.serialize.**,
+            com.sun.xml.internal.stream.**;
+    exclude com.sun.xml.internal.stream.buffer.**;  // JAX-WS
+}
+
+// required by Xerces and JAX-WS
+module jaxp-xerces-resolver {
+    include com.sun.org.apache.xml.internal.resolver.**;
+}
+
+module jaxp-xalan {
+    include org.w3c.dom.xpath.*;
+
+    include com.sun.org.apache.xalan.internal.**,
+            com.sun.org.apache.xpath.internal.**,
+            com.sun.org.apache.xml.internal.dtm.**,
+            com.sun.org.apache.xml.internal.res.**,
+            com.sun.org.apache.xml.internal.serializer.**,
+            com.sun.org.apache.xml.internal.utils.**,
+            com.sun.org.apache.bcel.internal.**,
+            com.sun.org.apache.regexp.internal.**,
+            com.sun.java_cup.internal.**;
+}
+
+/**************************************************************************/
+
+module tools.schemagen {
+    class com.sun.tools.internal.jxc.SchemaGenerator;
+}
+
+module tools.xjc {
+    class com.sun.tools.internal.xjc.Driver;
+}
+
+
+module tools.wsgen {
+    class com.sun.tools.internal.ws.WsGen;
+}
+
+module tools.wsimport {
+    class com.sun.tools.internal.ws.WsImport;
+}
+
+// Implementation for xjc, wsgen, wsimport, and schemagen tools
+module jdk.tools.jaxws {
+    include com.sun.codemodel.**,
+            com.sun.xml.internal.dtdparser.**,
+            com.sun.xml.internal.rngom.**,
+            com.sun.xml.internal.xsom.**,
+            com.sun.istack.internal.tools.**,
+            com.sun.istack.internal.ws.**,
+            com.sun.tools.xjc.**,
+            com.sun.tools.internal.xjc.**,
+            com.sun.tools.internal.ws.**,
+            com.sun.tools.internal.jxc.**,
+            org.relaxng.datatype.**;
+
+    include tools.schemagen;
+    include tools.xjc;
+    include tools.wsgen;
+    include tools.wsimport;
+
+    requires service com.sun.tools.internal.ws.wscompile.Plugin;
+    requires service com.sun.tools.internal.xjc.Plugin;
+
+    view jdk.schemagen {
+        class com.sun.tools.internal.jxc.SchemaGenerator;
+    }
+    
+    view jdk.xjc {
+        class com.sun.tools.internal.xjc.Driver;
+    }
+    
+    
+    view jdk.wsgen {
+        class com.sun.tools.internal.ws.WsGen;
+    }
+    
+    view jdk.wsimport {
+        class com.sun.tools.internal.ws.WsImport;
+    }
+
+// Implementation for xjc, wsgen, wsimport, and schemagen tools
+}
+
+module jaxws {
+    include javax.jws.**,
+            javax.xml.bind.**,
+            javax.xml.soap.**,
+            javax.xml.ws.**,
+            org.relaxng.**,
+            com.oracle.webservices.**,
+            com.oracle.xmlns.**,
+            com.sun.istack.internal.*,
+            com.sun.istack.internal.localization.*,
+            com.sun.istack.internal.logging.**,
+            com.sun.org.glassfish.**,
+            com.sun.xml.internal.**;
+
+    // include JAF in this module
+    include javax.activation.**, com.sun.activation.**;
+
+    include META-INF/mailcap.default,
+            META-INF/mimetypes.default;
+}
+
+
+module common-annotations {
+    include javax.annotation.*;    // Common annotations (JSR-250)
+}
+
+/**************************************************************************/
+
+module tools.idlj {
+    include com.sun.tools.corba.**;
+    class com.sun.tools.corba.se.idl.toJavaPortable.Compile;
+}
+
+module corba {
+    include javax.activity.**,
+            javax.rmi.*,
+            javax.rmi.CORBA.*,
+            com.sun.corba.**,
+            com.sun.org.omg.**,
+            org.omg.**,
+            sun.corba.**;
+
+    // JMX remote API
+    exclude org.omg.stub.javax.management.**;
+}
+
+/**************************************************************************/
+
+module applet {
+    include java.applet.**;
+    include sun.applet.**;
+}
+
+module awt {
+    include java.awt.**,
+            sun.awt.**,
+
+            // MAC 
+            sun.lwawt.**,
+            com.apple.**,
+            apple.laf.**,
+            com.sun.awt.**;
+
+    exclude com.apple.concurrent.**;
+    exclude com.apple.eio.**;
+}
+
+module font {
+    include sun.font.**;
+}
+
+module imageio {
+    include javax.imageio.**,
+            com.sun.imageio.**;
+}
+
+module java2d {
+    include sun.dc.**,
+            sun.java2d.**,
+            com.sun.image.**;
+}
+
+module media {
+    include com.sun.media.**;
+}
+
+module print {
+    include javax.print.**,
+            sun.print.**;
+}
+
+module sound {
+    include javax.sound.**;
+}
+
+module swing {
+    include javax.swing.**,
+            sun.swing.**,
+            // sajdi also contains classes in subpackages of com.sun.java.swing;
+            // so use '*' instead of '**' 
+            com.sun.java.swing.*,
+            com.sun.java.swing.plaf.**,
+            com.sun.swing.**;
+}
+
+module accessbridge {
+    include com.sun.java.accessibility.**;
+}
+
+module client {
+    include awt,
+            accessbridge,
+            font,
+            imageio,
+            java2d,
+            media,
+            print,
+            sound,
+            swing;
+
+    include javax.accessibility.*,
+            sun.audio.**,
+            com.sun.accessibility.**;
+
+    // PerformanceLogger and dependencies
+    include sun.misc.Ref, sun.misc.PerformanceLogger;
+
+    // misc. dependencies that we need to examine
+    include sun.misc.Queue*,
+            sun.misc.FIFOQueueEnumerator,
+            sun.misc.LIFOQueueEnumerator;
+
+    // Legacy dead code but references sun.misc types
+    include sun.misc.Cache*,
+            sun.misc.Request,
+            sun.misc.RequestProcessor;
+
+    // content handlers
+    include sun.net.www.content.audio.**,
+            sun.net.www.content.image.**;
+}
+
+/**************************************************************************/
+
+module deploy {
+    // see JDK-8003847
+    include apple.launcher.*;
+
+    include com.oracle.deploy.**,
+            com.sun.applet2.**;
+
+    // For now, all plugin and JNLP
+    include com.sun.java.browser.**,
+            netscape.**,
+            sun.plugin.**,
+            sun.plugin2.**,,
+            com.sun.deploy.**,
+            com.sun.javaws.**,
+            javax.jnlp.*,
+            com.sun.jnlp.*;
+
+    // Hook for http authentication
+    include sun.net.www.protocol.http.AuthCacheBridge;
+}
+
+/**************************************************************************/
+
+module net-dns {
+    include sun.net.dns.**;                 // to access DNS config.
+    include sun.net.spi.nameservice.dns.**; // for DNS-only name service.
+}
+
+module net-compat {
+
+    // ftp and mail clients
+    include sun.net.ftp.**, sun.net.smtp.**;
+
+    // Legacy protocol handlers
+    include sun.net.www.protocol.**;
+
+    // Legacy content handlers
+    include sun.net.www.content.**;
+
+    include sun.net.Telnet*,
+            sun.net.TransferProtocolClient;
+}
+
+/**************************************************************************
+ *            language tools                                              *
+ **************************************************************************/
+
+// standalone technology (JSR-199 & JSR-269)
+module jdk.compiler {
+    requires optional jdk.devtools;
+
+    provides java.compiler;
+    include javax.tools.**,
+            javax.lang.model.**,
+            javax.annotation.processing.**;
+}
+
+module tools.javac {
+    include com.sun.tools.javac.**,
+            com.sun.source.**;
+    exclude com.sun.tools.javac.Launcher;
+    include com.sun.tools.sjavac.**;
+    class com.sun.tools.javac.Main;
+}
+
+module tools.javadoc {
+    include com.sun.tools.doclint.**,
+            com.sun.tools.doclets.**;
+    include com.sun.tools.javadoc.**,
+            com.sun.javadoc.**;
+    class com.sun.tools.javadoc.Main;
+}
+
+module tools.javah {
+    include com.sun.tools.javah.**;
+    class com.sun.tools.javah.Main;
+}
+
+module tools.javap {
+    include com.sun.tools.javap.**,
+            com.sun.tools.classfile.**;
+    class com.sun.tools.javap.Main;
+}
+module tools.jdeps {
+    include com.sun.tools.jdeps.**;
+    class com.sun.tools.jdeps.Main;
+}
+
+/**************************************************************************
+ *            jdk tools                                                   *
+ **************************************************************************/
+
+module tools.jar {
+    include sun.tools.jar.**;
+    exclude sun.tools.jar.JarImageSource; // see 6915797
+    class sun.tools.jar.Main;
+}
+
+module tools.policytool {
+     include sun.security.tools.policytool.*;
+     class sun.security.tools.policytool.PolicyTool;
+}
+
+module tools.jarsigner {
+    include sun.security.tools.jarsigner.**;
+    include com.sun.jarsigner.**;
+    class sun.security.tools.jarsigner.Main;
+}
+
+module tools.keytool {
+    include sun.security.pkcs10.*,
+            sun.security.tools.*,
+            sun.security.tools.keytool.**;
+
+    class sun.security.tools.keytool.Main;
+}
+
+module tools.jconsole {
+    include sun.tools.jconsole.**,
+            com.sun.tools.jconsole.*;
+    class sun.tools.jconsole.JConsole;
+}
+
+module tools.serialver {
+    include sun.tools.serialver.**;
+    class sun.tools.serialver.SerialVer;
+}
+
+module tools.jdb.gui {
+    include com.sun.tools.example.debug.bdi.**,
+            com.sun.tools.example.debug.gui.**;
+}
+
+module tools.jdb {
+    include com.sun.tools.example.debug.**;
+    class com.sun.tools.example.debug.tty.TTY;
+}
+
+module tools.jcmd {
+    include sun.tools.jcmd.**;
+    class sun.tools.jcmd.JCmd;
+}
+
+module tools.jps {
+    include sun.tools.jps.**;
+    class sun.tools.jps.Jps;
+}
+
+module tools.jstatd {
+    include  sun.tools.jstatd.**;
+    class sun.tools.jstatd.Jstatd;
+}
+
+module tools.jstat {
+    include sun.tools.jstat.**;
+    class sun.tools.jstat.Jstat;
+}
+
+module tools.jhat {
+    include com.sun.tools.hat.**;
+    class com.sun.tools.hat.Main;
+}
+
+module tools.jinfo {
+    include sun.tools.jinfo.**;
+    class sun.tools.jinfo.JInfo;
+}
+module tools.jmap {
+    include sun.tools.jmap.**;
+    class sun.tools.jmap.JMap;
+}
+
+module tools.jrunscript {
+    include com.sun.tools.script.**;
+    class com.sun.tools.script.shell.Main;
+}
+
+module tools.jstack {
+     include sun.tools.jstack.**;
+     class sun.tools.jstack.JStack;
+}
+
+module tools.extcheck {
+    include com.sun.tools.extcheck.**;
+    class com.sun.tools.extcheck.Main;
+}
+
+module tools.native2ascii {
+    include sun.tools.native2ascii.**;
+    class sun.tools.native2ascii.Main;
+}
+
+module tools.jsadebugd {
+     class sun.jvm.hotspot.jdi.SADebugServer;
+}
+
+module tools.appletviewer {
+    class sun.applet.Main;
+}
+
+module tools.kinit {
+    class sun.security.krb5.internal.tools.Kinit;
+}
+
+module tools.klist {
+    class sun.security.krb5.internal.tools.Klist;
+}
+
+module tools.ktab {
+    class sun.security.krb5.internal.tools.Ktab;
+}
+
+module tools.rmiregistry {
+    class sun.rmi.registry.RegistryImpl;
+}
+
+module tools.rmid {
+    class sun.rmi.server.Activation;
+}
+
+module tools.orbd {
+    class com.sun.corba.se.impl.activation.ORBD;
+}
+
+module tools.servertool {
+    class com.sun.corba.se.impl.activation.ServerTool;
+}
+
+module tools.tnameserv {
+    class com.sun.corba.se.impl.naming.cosnaming.TransientNameServer;
+}
+
+/*
+ * This module is for the pack200 binary.
+ * Can't include com.sun.java.util.jar.pack.Driver due to its
+ * dependency with other runtime classes.
+ *
+ * Driver is made to be public in com.sun.java.util.jar.pack
+ * as a workaround until we clean up the dependency.
+ */
+module tools.pack200 {
+    class com.sun.java.util.jar.pack.Driver;
+}
+
+/**************************************************************************/
+
+// Workaround for US export and local policy files 
+// They are currently in signed jars under the jre/lib/security directory
+module US_export_policy {
+    include default_US_export.policy;
+}
+
+module local_policy {
+    include default_local.policy,
+            exempt_local.policy;
+}
+
+/**************************************************************************/
+
+module other {
+    // A hack to facilitate starting javac from NetBeans for debugging.
+    // Not to include in any module
+    include com.sun.tools.javac.Launcher;
+    include **;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/modules/modules.group	Thu Aug 29 14:37:18 2013 -0700
@@ -0,0 +1,642 @@
+/*
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**************************************************************************
+ * modules.group defines the top-level modules that merge the 
+ * fine-grained modules defined in modules.config.  There are 
+ * different kinds of top-level modules:
+ * 1. implementation modules that only permit jdk modules to use (sun.*)
+ * 2. modules exporting APIs (jdk.* defined here or generated by
+ *    the class analyzer to export sun.* module).
+ * 3. tool modules (defined in modules.config) 
+ * 4. aggregator modules that do not contain any class
+ *
+ **************************************************************************
+
+/*
+ * Example:
+ *    module jdbc {
+ *        include jdbc-base, jdbc-enterprise, jdbc-odbc;
+ *    }
+ */
+
+module jdk.base {
+    provides java.base;
+
+    include base;
+    include unpack200-tool;
+    include xmlparser;
+
+    // ## Include JSR 310 in the base module (680K + 40K tzdb.jar) due to
+    // ## java.util.Formatter -> java.time API
+    include time;
+
+    // Workaround: include the policy files for now.
+    // They have to be bundled in signed jars.
+    include US_export_policy;
+    include local_policy;
+
+    // This optional dependency is needed for SecurityManager.checkTopLevelWindows
+    // and a few other methods that check for java.awt.AWTPermission which is
+    // in the desktop module
+    requires optional jdk.desktop;
+    requires optional jdk.tls;
+
+    // ## To be converted as services
+    requires optional sun.resources;
+    requires optional sun.localedata;
+
+    // no META-INF/services
+    requires service java.nio.channels.spi.AsynchronousChannelProvider;
+    requires service java.nio.channels.spi.SelectorProvider;
+    requires service java.nio.charset.spi.CharsetProvider;
+    requires service java.nio.file.spi.FileSystemProvider;
+    requires service java.nio.file.spi.FileTypeDetector;
+    requires service java.text.spi.BreakIteratorProvider;
+    requires service java.text.spi.CollatorProvider;
+    requires service java.text.spi.DateFormatProvider;
+    requires service java.text.spi.DateFormatSymbolsProvider;
+    requires service java.text.spi.DecimalFormatSymbolsProvider;
+    requires service java.text.spi.NumberFormatProvider;
+    requires service java.time.zone.ZoneRulesProvider;
+    requires service java.util.spi.CurrencyNameProvider;
+    requires service java.util.spi.LocaleNameProvider;
+    requires service sun.net.spi.nameservice.NameServiceDescriptor;
+    requires service sun.util.spi.XmlPropertiesProvider;
+
+    // ## workaround for reflection
+    //
+    // ## reflection generated code is a subclass of sun.reflect.MethodAccessorImpl
+    // ## ConstructorAccessorImpl, or SerializationConstructorAccessorImpl
+    // ## The generated code is defined by a new loader that delegates to
+    // ## the defining loader of the declaring class
+    exports sun.reflect;
+
+    view jdk.base.oracle {
+        exports com.oracle.nio;
+        exports com.oracle.net;
+        exports com.oracle.util;
+    }
+
+}
+
+module jdk.instrument {
+    provides java.instrument;
+    include instrument;
+}
+
+module jdk.desktop {
+    provides java.desktop;
+
+    include beans;
+    include client;
+
+    // jndi and corba have a dependency on Applet but 
+    // applet can't be separated from client due to circular dependency
+    include applet;
+
+    requires service java.awt.im.spi.InputMethodDescriptor;
+    requires service javax.imageio.spi.IIOServiceProvider;
+    requires service javax.imageio.spi.ImageInputStreamSpi;
+    requires service javax.imageio.spi.ImageOutputStreamSpi;
+    requires service javax.imageio.spi.ImageReaderSpi;
+    requires service javax.imageio.spi.ImageReaderWriterSpi;
+    requires service javax.imageio.spi.ImageTranscoderSpi;
+    requires service javax.imageio.spi.ImageWriterSpi;
+    requires service javax.print.PrintServiceLookup;
+    requires service javax.print.StreamPrintServiceFactory;
+    requires service javax.sound.midi.spi.MidiDeviceProvider;
+    requires service javax.sound.midi.spi.MidiFileReader;
+    requires service javax.sound.midi.spi.MidiFileWriter;
+    requires service javax.sound.midi.spi.SoundbankReader;
+    requires service javax.sound.sampled.spi.AudioFileReader;
+    requires service javax.sound.sampled.spi.AudioFileWriter;
+    requires service javax.sound.sampled.spi.FormatConversionProvider;
+    requires service javax.sound.sampled.spi.MixerProvider;
+    requires service sun.java2d.cmm.PCMM;
+    requires service sun.java2d.pipe.RenderingEngine;
+
+    // Swing Look & Feels (no need to export com.sun.java.swing.plaf.nimbus)
+    exports com.sun.java.swing.plaf.gtk;
+    exports com.sun.java.swing.plaf.motif;
+    exports com.sun.java.swing.plaf.windows;
+}
+
+// ## java.util.prefs should be moved to the base module
+// ## once we eliminate the Preferences implementation for Unix
+// ## to XML (currently stored as a XML file).
+module jdk.prefs {
+    provides java.prefs;
+    include prefs;
+    requires service java.util.prefs.PreferencesFactory;
+}
+
+module jdk.management {
+    provides java.management;
+    include management;
+
+    requires optional jdk.management.iiop;
+
+    // ## temporary: need discussion with JFR team
+    // ## this adds a dependency on jaxp
+    include jfr;
+
+    view oracle.jfr {
+        exports com.oracle.jrockit.jfr;
+        exports com.oracle.jrockit.jfr.client;
+        exports com.oracle.jrockit.jfr.management;
+    }
+}
+
+// JMX RMI-IIOP connector
+module jdk.management.iiop {
+    include management-iiop;
+    exports com.sun.jmx.remote.protocol.iiop;
+    permits jdk.management;
+}
+
+module jdk.snmp {
+    include management-snmp;
+}
+
+module jdk.corba {
+    provides java.corba;
+
+    include corba;
+
+    // include corba-specific tools 
+    include tools.orbd;
+    include tools.servertool;
+    include tools.tnameserv;
+
+    view jdk.orbd {
+        class com.sun.corba.se.impl.activation.ORBD;
+    }
+    
+    view jdk.servertool {
+        class com.sun.corba.se.impl.activation.ServerTool;
+    }
+    
+    view jdk.tnameserv {
+        class com.sun.corba.se.impl.naming.cosnaming.TransientNameServer;
+    }
+
+    // development tools
+    include tools.idlj;
+
+    view jdk.idlj {
+        class com.sun.tools.corba.se.idl.toJavaPortable.Compile;
+    }
+}
+
+module jdk.jdbc {
+    provides java.jdbc;
+    include jdbc;
+
+    requires optional jdk.jaxp;
+    requires optional jdk.jta;
+    requires optional jdk.logging;
+    requires service java.sql.Driver;
+}
+
+module jdk.jdbc.rowset {
+    provides java.jdbc.rowset;
+    include jdbc-rowset;
+
+    requires service javax.sql.rowset.RowSetFactory;
+    exports com.sun.sql.rowset;
+}
+
+module jdk.compat {
+    include private-legacy;
+    include net-compat;
+    include deprecated;
+
+    // ## avoid com.sun.security.auth be splitted among many modules
+    // ## most of the com.sun.security.auth should be deprecated.
+    // ## need to sort out which one is still needed
+    //
+    // include sun.auth.ldap;
+    // include sun.auth.kerberos;
+    // include sun.auth.jndi;
+    // include security-auth;
+
+}
+
+// Deprecated APIs used by snmp
+module jdk.security.acl {
+    provides java.security.acl;
+    include security-acl;
+}
+
+module jdk.kerberos {
+    provides java.auth.kerberos;
+    include security-kerberos;
+    include sun.auth.kerberos;
+
+    // kerberos-related tools (windows only)
+    include tools.kinit;
+    include tools.klist;
+    include tools.ktab;
+
+    view jdk.kinit {
+        class sun.security.krb5.internal.tools.Kinit;
+    }
+
+    view jdk.klist {
+        class sun.security.krb5.internal.tools.Klist;
+    }
+
+    view jdk.ktab {
+        class sun.security.krb5.internal.tools.Ktab;
+    }
+}
+
+module jdk.sunec {
+    include security-sunec;
+}
+
+module jdk.sunpkcs11 {
+    include security-sunpkcs11;
+}
+
+module jdk.ucrypto {
+    include security-ucrypto;
+}
+
+module jdk.crypto {
+    include security-sunjce;
+}
+
+module jdk.sunmscapi {
+    include security-sunmscapi;
+}
+
+module jdk.xmldsig {
+    provides javax.xmldsig;
+    include security-xmldsig;
+}
+
+module jdk.smartcardio {
+    provides javax.smartcardio;
+    include security-smartcardio;
+}
+
+module sun.xml {
+    include jaxp-api;
+}
+
+module sun.xalan {
+    include jaxp-xalan;
+}
+
+module sun.xerces {
+    include jaxp-xerces-impl;
+    include jaxp-xerces-resolver;
+}
+
+module jdk.jaxp {
+    provides javax.xml;
+
+    include sun.xml;
+    include sun.xalan;
+    include sun.xerces;
+
+    requires service javax.xml.datatype.DatatypeFactory;
+    requires service javax.xml.parsers.DocumentBuilderFactory;
+    requires service javax.xml.parsers.SAXParserFactory;
+    requires service javax.xml.stream.XMLEventFactory;
+    requires service javax.xml.stream.XMLInputFactory;
+    requires service javax.xml.stream.XMLOutputFactory;
+    requires service javax.xml.transform.TransformerFactory;
+    requires service javax.xml.validation.SchemaFactory;
+    requires service javax.xml.xpath.XPathFactory;
+}
+
+module jdk.jndi {
+    provides javax.naming;
+
+    include jndi;
+
+    // ## jndi providers
+    include jndi-ldap;
+    include jndi-dns;
+    include jndi-rmiregistry;
+    include sun.auth.ldap;
+    include sun.auth.jndi;
+
+    requires optional jdk.desktop;
+    requires service javax.naming.ldap.StartTlsResponse;
+}
+
+module jdk.cosnaming {
+    // include COS naming service provider for JNDI 
+    // that pulls in jndi module
+    include jndi-cosnaming;
+}
+
+module jdk.rmi {
+    provides java.rmi;
+
+    include rmi;
+    include rmi-activation;
+
+    requires service java.rmi.server.RMIClassLoaderSpi;
+
+    // rmi runtime tools
+    include tools.rmiregistry;
+    include tools.rmid;
+
+    view jdk.rmiregistry {
+        class sun.rmi.registry.RegistryImpl;
+    }
+
+    view jdk.rmid {
+        class sun.rmi.server.Activation;
+    }
+
+}
+
+module jdk.auth {
+    provides java.auth;
+    include security-auth;
+
+    // combine SASL with JAAS
+    include security-sasl;
+    include security-sasl-ntlm;
+}
+
+module jdk.tls {
+    provides java.tls;
+    include security-jsse;
+}
+
+module jdk.deploy {
+    include deploy;
+}
+
+module jdk.jaxws {
+    provides javax.jaxws;
+    include jaxws;
+}
+
+// standalone technology (JSR-250) 
+module jdk.jx.annotations {
+    provides javax.annotation;
+    include common-annotations;
+}
+
+// standalone technology (JSR-223)
+module jdk.scripting {
+    provides javax.script;
+    include scripting;
+    include scripting-rhino;
+    include nashorn;
+
+    requires optional service javax.script.ScriptEngineFactory;
+}
+
+// ## corba and jdbc depends on javax.transaction.
+// ## jigsaw resolver fails if any of its transitive dependencies
+// ## doesn't require jdk.boot
+module jdk.jta {
+    provides javax.transaction;
+    include jta;
+}
+
+module jdk.logging {
+    provides java.logging;
+    requires optional jdk.desktop;
+    include logging;
+    include tracing;
+}
+
+// ## localedata is loaded by the extension class loader
+// ## for now, in the same connected graph loaded by the bootstrap class loader
+module sun.localedata {
+    include localedata;
+}
+
+module sun.charsets {
+    include charsets;
+}
+
+module sun.resources {
+    include resources;
+}
+
+// Oracle's platform extension (supported APIs)
+module jdk.sctp {
+    include sctp;
+}
+
+module jdk.zipfs {
+    include zipfs;
+    exports com.sun.nio.zipfs;
+}
+
+module jdk.httpserver {
+    include httpserver;
+
+    requires optional service com.sun.net.httpserver.spi.HttpServerProvider;
+}
+
+module jdk.devtools {
+    include tools.javac;
+    include tools.javah;
+    include tools.javap;
+    include tools.javadoc;
+    include tools.jdeps;
+
+    // ## temporary: exports this package so that jdk.tools.base
+    // ##     requires public jdk.devtools;
+    // ## to workaround its dependency by the jar tool that causes the
+    // ## ClassAnalyzer to generate "requires public jdk.devtools.internal;"
+    exports com.sun.tools.classfile;
+
+    view jdk.javac {
+        class com.sun.tools.javac.Main;
+    }
+    view jdk.javah {
+        class com.sun.tools.javah.Main;
+    }
+    view jdk.javap {
+        class com.sun.tools.javap.Main;
+    }
+    view jdk.javadoc {
+        class com.sun.tools.javadoc.Main;
+    }
+    view jdk.jdeps {
+        class com.sun.tools.jdeps.Main;
+    }
+}
+
+// developer tools to be included in the jdk-base-image
+module jdk.tools.base {
+    requires public jdk.devtools;
+
+    include tools.jar;
+    include tools.jarsigner;
+    include tools.keytool;
+    include tools.pack200;
+
+    view jdk.jar {
+        class sun.tools.jar.Main;
+    }
+
+    view jdk.jarsigner {
+       class sun.security.tools.jarsigner.Main;
+    }
+
+    view jdk.keytool {
+       class sun.security.tools.keytool.Main;
+    }
+
+    view jdk.pack200 {
+        class com.sun.java.util.jar.pack.Driver;
+    }
+}
+
+// JRE tools to be included in the jdk-module-image and jre-module-image
+module jdk.tools.jre {
+    // tools support
+    include hprof;
+    include servicetag;
+
+    // JRE tools
+    include tools.policytool;
+    view jdk.policytool {
+         class sun.security.tools.policytool.PolicyTool;
+    }
+}
+
+// Other developer tools to be included in the jdk-module-image
+module jdk.tools {
+    requires public jdk.tools.jre;     // Tools in JRE
+    requires public jdk.tools.base;    // developer tools for the base module
+    requires public jdk.tools.jaxws;   // developer tools for the jaxws module
+
+    include attach;
+    include jdi;
+    include jdwp;
+    include jvmstat;
+    include sajdi;
+
+    include tools.appletviewer;
+    include tools.extcheck;
+    include tools.jcmd;
+    include tools.jconsole;
+    include tools.jdb;
+    include tools.jdb.gui;
+    include tools.jhat;
+    include tools.jinfo;
+    include tools.jmap;
+    include tools.jps;
+    include tools.jrunscript;
+    include tools.jsadebugd;
+    include tools.jstack;
+    include tools.jstat;
+    include tools.jstatd;
+    include tools.native2ascii;
+    include tools.rmic;
+    include tools.serialver;
+
+    requires service com.sun.jdi.connect.Connector;
+    requires service com.sun.jdi.connect.spi.TransportService;
+    requires service com.sun.tools.attach.spi.AttachProvider;
+
+    view jdk.attach {
+        exports com.sun.tools.attach;
+        exports com.sun.tools.attach.spi;
+    }
+
+
+    view jdk.jconsole {
+        class sun.tools.jcmd.JCmd;
+    }
+
+    view jdk.jconsole {
+        exports com.sun.tools.jconsole;
+        class sun.tools.jconsole.JConsole;
+    }
+
+    view jdk.serialver {
+        class sun.tools.serialver.SerialVer;
+    }
+   
+    view jdk.jdb {
+        class com.sun.tools.example.debug.tty.TTY;
+    }
+
+    view jdk.jps {
+        class sun.tools.jps.Jps;
+    }
+
+    view jdk.jstatd {
+        class sun.tools.jstatd.Jstatd;
+    }
+
+    view jdk.jstat {
+        class sun.tools.jstat.Jstat;
+    }
+
+    view jdk.jhat {
+        class com.sun.tools.hat.Main;
+    }
+
+    view jdk.jinfo {
+        class sun.tools.jinfo.JInfo;
+    }
+    view jdk.jmap {
+        class sun.tools.jmap.JMap;
+    }
+
+    view jdk.jrunscript {
+        class com.sun.tools.script.shell.Main;
+    }
+
+    view jdk.jstack {
+         class sun.tools.jstack.JStack;
+    }
+
+    view jdk.extcheck {
+        class com.sun.tools.extcheck.Main;
+    }
+
+    view jdk.native2ascii {
+        class sun.tools.native2ascii.Main;
+    }
+
+    view jdk.jsadebugd {
+         class sun.jvm.hotspot.jdi.SADebugServer;
+    }
+
+    view jdk.appletviewer {
+        class sun.applet.Main;
+    }
+
+    view jdk.rmic {
+        class sun.rmi.rmic.Main;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/modules/modules.properties	Thu Aug 29 14:37:18 2013 -0700
@@ -0,0 +1,333 @@
+#
+# Copyright (c) 2010, 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.
+#
+
+#
+# supported properties of a module (default is false)
+#   <module-name>.allows.empty :
+#       include the module even if it's empty
+#   <module-name>.modules.list :
+#       print an ordered list of its required modules.
+#       The property value can be set to "true" or additional modules
+#       be appended to the output modules.list
+#   <module-name>.exports.all :
+#       exports all APIs
+#   <module-name>.allows.permits :
+#       allows permits on the default view (i.e. no internal view)
+#
+
+jdwp.allows.empty =  true
+
+## workaround until services are implemented
+sun.resources.exports.all = true
+sun.charsets.exports.all = false
+sun.localedata.exports.all = true
+
+## for compatibility
+jdk.compat.exports.all = true
+
+# default view allows permits (i.e. no internal view generated)
+sun.resources.allows.permits = true
+sun.charsets.allows.permits = true
+sun.localedata.allows.permits = true
+
+# suffix represents a view name
+module.view.suffix = internal
+
+# List of external exported packages
+# Copied from jdk/make/docs/CORE_PKGS.gmk
+#
+# sun.reflect.annotation is exported as an interim solution
+# it's required by javac for serializaton of annotation these
+# types are essentially de facto platform classes
+#
+exported.packages = \
+   java.applet \
+   java.awt \
+   java.awt.color \
+   java.awt.datatransfer \
+   java.awt.dnd \
+   java.awt.event \
+   java.awt.font \
+   java.awt.geom \
+   java.awt.im \
+   java.awt.im.spi \
+   java.awt.image \
+   java.awt.image.renderable \
+   java.awt.print \
+   java.beans \
+   java.beans.beancontext \
+   java.io \
+   java.lang \
+   java.lang.annotation \
+   java.lang.instrument \
+   java.lang.invoke \
+   java.lang.management \
+   java.lang.module \
+   java.lang.ref \
+   java.lang.reflect \
+   java.math \
+   java.net \
+   java.nio \
+   java.nio.channels \
+   java.nio.channels.spi \
+   java.nio.charset \
+   java.nio.charset.spi \
+   java.nio.file \
+   java.nio.file.attribute \
+   java.nio.file.spi \
+   java.rmi \
+   java.rmi.activation \
+   java.rmi.dgc \
+   java.rmi.registry \
+   java.rmi.server \
+   java.security \
+   java.security.acl \
+   java.security.cert \
+   java.security.interfaces \
+   java.security.spec \
+   java.sql \
+   java.text \
+   java.text.spi \
+   java.time \
+   java.time.chrono \
+   java.time.format \
+   java.time.temporal \
+   java.time.zone \
+   java.util \
+   java.util.concurrent \
+   java.util.concurrent.atomic \
+   java.util.concurrent.locks \
+   java.util.function \
+   java.util.jar \
+   java.util.logging \
+   java.util.prefs \
+   java.util.regex \
+   java.util.spi \
+   java.util.stream \
+   java.util.zip \
+   javax.accessibility \
+   javax.activation \
+   javax.activation \
+   javax.activity \
+   javax.annotation \
+   javax.annotation.processing \
+   javax.crypto \
+   javax.crypto.interfaces \
+   javax.crypto.spec \
+   javax.imageio \
+   javax.imageio.event \
+   javax.imageio.metadata \
+   javax.imageio.plugins.bmp \
+   javax.imageio.plugins.jpeg \
+   javax.imageio.spi \
+   javax.imageio.stream \
+   javax.jws \
+   javax.jws.soap \
+   javax.lang.model \
+   javax.lang.model.element \
+   javax.lang.model.type \
+   javax.lang.model.util \
+   javax.management \
+   javax.management.loading \
+   javax.management.modelmbean \
+   javax.management.monitor \
+   javax.management.openmbean \
+   javax.management.relation \
+   javax.management.remote \
+   javax.management.remote.rmi \
+   javax.management.timer \
+   javax.naming \
+   javax.naming.directory \
+   javax.naming.event \
+   javax.naming.ldap \
+   javax.naming.spi \
+   javax.net \
+   javax.net.ssl \
+   javax.print \
+   javax.print.attribute \
+   javax.print.attribute.standard \
+   javax.print.event \
+   javax.rmi \
+   javax.rmi.CORBA \
+   javax.rmi.ssl \
+   javax.script \
+   javax.script \
+   javax.security.auth \
+   javax.security.auth.callback \
+   javax.security.auth.kerberos \
+   javax.security.auth.login \
+   javax.security.auth.spi \
+   javax.security.auth.x500 \
+   javax.security.cert \
+   javax.security.sasl \
+   javax.sound.midi \
+   javax.sound.midi.spi \
+   javax.sound.sampled \
+   javax.sound.sampled.spi \
+   javax.sql \
+   javax.sql.rowset \
+   javax.sql.rowset.serial \
+   javax.sql.rowset.spi \
+   javax.swing \
+   javax.swing.border \
+   javax.swing.colorchooser \
+   javax.swing.event \
+   javax.swing.filechooser \
+   javax.swing.plaf \
+   javax.swing.plaf.basic \
+   javax.swing.plaf.metal \
+   javax.swing.plaf.multi \
+   javax.swing.plaf.nimbus \
+   javax.swing.plaf.synth \
+   javax.swing.table \
+   javax.swing.text \
+   javax.swing.text.html \
+   javax.swing.text.html.parser \
+   javax.swing.text.rtf \
+   javax.swing.tree \
+   javax.swing.undo \
+   javax.tools \
+   javax.tools.annotation \
+   javax.transaction \
+   javax.transaction.xa \
+   javax.xml \
+   javax.xml.bind \
+   javax.xml.bind.annotation \
+   javax.xml.bind.annotation.adapters \
+   javax.xml.bind.attachment \
+   javax.xml.bind.helpers \
+   javax.xml.bind.util \
+   javax.xml.crypto \
+   javax.xml.crypto.dom \
+   javax.xml.crypto.dsig \
+   javax.xml.crypto.dsig.dom \
+   javax.xml.crypto.dsig.keyinfo \
+   javax.xml.crypto.dsig.spec \
+   javax.xml.datatype \
+   javax.xml.namespace \
+   javax.xml.parsers \
+   javax.xml.soap \
+   javax.xml.stream \
+   javax.xml.stream.events \
+   javax.xml.stream.util \
+   javax.xml.transform \
+   javax.xml.transform.dom \
+   javax.xml.transform.sax \
+   javax.xml.transform.stax \
+   javax.xml.transform.stream \
+   javax.xml.validation \
+   javax.xml.ws \
+   javax.xml.ws.handler \
+   javax.xml.ws.handler.soap \
+   javax.xml.ws.http \
+   javax.xml.ws.soap \
+   javax.xml.ws.spi \
+   javax.xml.ws.spi.http \
+   javax.xml.ws.wsaddressing \
+   javax.xml.xpath \
+   org.ietf.jgss \
+   org.omg.CORBA \
+   org.omg.CORBA.DynAnyPackage \
+   org.omg.CORBA.ORBPackage \
+   org.omg.CORBA.TypeCodePackage \
+   org.omg.CORBA.portable \
+   org.omg.CORBA_2_3 \
+   org.omg.CORBA_2_3.portable \
+   org.omg.CosNaming \
+   org.omg.CosNaming.NamingContextExtPackage \
+   org.omg.CosNaming.NamingContextPackage \
+   org.omg.Dynamic \
+   org.omg.DynamicAny \
+   org.omg.DynamicAny.DynAnyFactoryPackage \
+   org.omg.DynamicAny.DynAnyPackage \
+   org.omg.IOP \
+   org.omg.IOP.CodecFactoryPackage \
+   org.omg.IOP.CodecPackage \
+   org.omg.Messaging \
+   org.omg.PortableInterceptor \
+   org.omg.PortableInterceptor.ORBInitInfoPackage \
+   org.omg.PortableServer \
+   org.omg.PortableServer.CurrentPackage \
+   org.omg.PortableServer.POAManagerPackage \
+   org.omg.PortableServer.POAPackage \
+   org.omg.PortableServer.ServantLocatorPackage \
+   org.omg.PortableServer.portable \
+   org.omg.SendingContext \
+   org.omg.stub.java.rmi \
+   org.w3c \
+   org.w3c.dom \
+   org.w3c.dom.bootstrap \
+   org.w3c.dom.events \
+   org.w3c.dom.ls \
+   org.xml.sax \
+   org.xml.sax \
+   org.xml.sax.ext \
+   org.xml.sax.helpers \
+   com.sun.java.browser.dom \
+   com.sun.management \
+   com.sun.net.httpserver \
+   com.sun.net.httpserver.spi \
+   com.sun.net.ssl \
+   com.sun.nio.file \
+   com.sun.nio.sctp \
+   com.sun.security.auth \
+   com.sun.security.auth.callback \
+   com.sun.security.auth.login \
+   com.sun.security.auth.module \
+   com.sun.security.jgss \
+   javax.smartcardio \
+   org.w3c.dom \
+   org.w3c.dom.bootstrap \
+   org.w3c.dom.css \
+   org.w3c.dom.events \
+   org.w3c.dom.html \
+   org.w3c.dom.ls \
+   org.w3c.dom.ranges \
+   org.w3c.dom.stylesheets \
+   org.w3c.dom.traversal \
+   org.w3c.dom.views \
+   com.sun.jdi \
+   com.sun.jdi.connect \
+   com.sun.jdi.connect.spi \
+   com.sun.jdi.event \
+   com.sun.jdi.request \
+   com.sun.javadoc \
+   com.sun.tools.doclets \
+   com.sun.source.doctree \
+   com.sun.source.tree \
+   com.sun.source.util \
+   com.sun.tools.attach \
+   com.sun.tools.attach.spi \
+   com.sun.tools.jconsole \
+   com.sun.tools.javac \
+   com.sun.tools.javah \
+   com.sun.tools.javap \
+   com.sun.tools.javadoc \
+   com.sun.servicetag \
+   com.apple.concurrent   \
+   com.apple.eawt         \
+   com.apple.eawt.event   \
+   com.apple.eio
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/modules/tools/src/com/sun/tools/classanalyzer/ClassAnalyzer.java	Thu Aug 29 14:37:18 2013 -0700
@@ -0,0 +1,421 @@
+/*
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.classanalyzer;
+
+import com.sun.tools.classanalyzer.Module.ModuleVisitor;
+import java.io.*;
+import java.text.MessageFormat;
+import java.util.*;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+/**
+ * Implementation for the ClassAnalyzer tool
+ */
+class ClassAnalyzer {
+    static class BadArgs extends Exception {
+        static final long serialVersionUID = 8765093759964640721L;
+        BadArgs(String key, Object... args) {
+            super(ClassAnalyzer.getMessage(key, args));
+            this.key = key;
+            this.args = args;
+        }
+
+        BadArgs showUsage(boolean b) {
+            showUsage = b;
+            return this;
+        }
+        final String key;
+        final Object[] args;
+        boolean showUsage;
+    }
+
+    static abstract class Option {
+        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;
+                if (hasArg && a.startsWith("--") && opt.startsWith(a + "="))
+                    return true;
+            }
+            return false;
+        }
+
+        boolean ignoreRest() {
+            return false;
+        }
+
+        abstract void process(ClassAnalyzer task, String opt, String arg) throws BadArgs;
+        final boolean hasArg;
+        final String[] aliases;
+    }
+
+    static abstract class HiddenOption extends Option {
+        HiddenOption(boolean hasArg, String... aliases) {
+            super(hasArg, aliases);
+        }
+
+        boolean isHidden() {
+            return true;
+        }
+    }
+
+    static Option[] recognizedOptions = {
+        new Option(false, "-h", "-?", "--help") {
+            void process(ClassAnalyzer task, String opt, String arg) {
+                task.options.help = true;
+            }
+        },
+        new Option(true, "-j", "--javahome") {
+            void process(ClassAnalyzer task, String opt, String arg) {
+                task.options.javahome = arg;
+            }
+        },
+        new Option(true, "-v", "--version") {
+            void process(ClassAnalyzer task, String opt, String arg) {
+                task.options.version = arg;
+            }
+        },
+        new Option(true, "-c", "--classlist") {
+            void process(ClassAnalyzer task, String opt, String arg) {
+                task.options.classlistDir = arg;
+            }
+        },
+        new Option(true, "--moduleinfo") {
+            void process(ClassAnalyzer task, String opt, String arg) {
+                task.options.moduleInfoDir = arg;
+            }
+        },
+        new Option(true, "-o", "--out") {
+            void process(ClassAnalyzer task, String opt, String arg) {
+                task.options.outFile = arg;
+            }
+        },
+        new Option(true, "-f", "--config") {
+            void process(ClassAnalyzer task, String opt, String arg) {
+                task.options.configs.add(arg);
+            }
+        },
+        new Option(true, "-p", "--properties") {
+            void process(ClassAnalyzer task, String opt, String arg) {
+                task.options.props = arg;
+            }
+        },
+    };
+
+    private static final String PROGNAME = "ClassAnalyzer";
+    private final Options options = new Options();
+
+    private PrintWriter log;
+    void setLog(PrintWriter out) {
+        log = out;
+    }
+
+    /**
+     * 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
+
+    int run(String[] args) {
+        if (log == null) {
+            log = new PrintWriter(System.out);
+        }
+        try {
+            handleOptions(args);
+            if (options.help) {
+                showHelp();
+            }
+            if (options.configs.isEmpty() || options.version == null) {
+                if (options.help) {
+                    return EXIT_OK;
+                } else {
+                    showHelp();
+                    return EXIT_CMDERR;
+                }
+            }
+            boolean ok = run();
+            return ok ? EXIT_OK : EXIT_ERROR;
+        } catch (BadArgs e) {
+            reportError(e.key, e.args);
+            if (e.showUsage) {
+                log.println(getMessage("main.usage.summary", PROGNAME));
+            }
+            return EXIT_CMDERR;
+        } catch (IOException e) {
+            e.printStackTrace();
+            return EXIT_ABNORMAL;
+        } finally {
+            log.flush();
+        }
+    }
+
+    private boolean run() throws IOException {
+        if (options.props != null) {
+            Module.setModuleProperties(options.props);
+        }
+        final ModuleBuilder builder = new ModuleBuilder(options.configs,
+                                                  ClassPath.getArchives(options.javahome),
+                                                  options.version);
+        builder.run();
+
+        final Path dir = Paths.get(options.classlistDir);
+        dir.toFile().mkdirs();
+        File list = dir.resolve("modules.list").toFile();
+        int count;
+        try (PrintWriter writer = new PrintWriter(list)) {
+            builder.visit(new ModuleBuilder.Visitor<Void, Void>() {
+                @Override
+                public Void visitModule(Module m) throws IOException {
+                    printModulePackages(m, dir);
+                    printModuleGroup(m, writer);
+                    printModuleSummary(m, dir, builder);
+                    return null;
+                }
+            });
+        }
+
+        // write split packages
+        Map<String, Set<Module>> modulesForPackage = builder.getPackages();
+        File pkginfo = dir.resolve("modules.pkginfo").toFile();
+        try (PrintWriter writer = new PrintWriter(pkginfo)) {
+            // packages that are splitted among multiple modules
+            writer.println("Packages splitted across modules:-\n");
+            writer.format("%-60s  %s\n", "Package", "Module");
+            for (Map.Entry<String, Set<Module>> e : modulesForPackage.entrySet()) {
+                if (e.getValue().size() > 1) {
+                    String pkgname = e.getKey();
+                    writer.format("%-60s", pkgname);
+                    for (Module m : e.getValue()) {
+                        writer.format("  %s", m);
+                    }
+                    writer.println();
+                }
+            }
+        }
+        if (options.outFile != null) {
+            Path p = Paths.get(options.outFile).getParent();
+            if (p != null)
+                p.toFile().mkdirs();
+            try (FileOutputStream out = new FileOutputStream(options.outFile)) {
+                builder.store(out);
+            }
+
+        }
+        if (options.moduleInfoDir != null) {
+            builder.printModuleInfos(options.moduleInfoDir);
+        }
+        return true;
+    }
+
+    private void printModuleSummary(Module m, Path dir, ModuleBuilder builder) throws IOException {
+        if (!m.classes().isEmpty()) {
+            File classlist = dir.resolve(m.name() + ".classlist").toFile();
+            File depslist = dir.resolve(m.name() + ".dependencies").toFile();
+            try (PrintWriter writer = new PrintWriter(classlist);
+                    PrintWriter dwriter = new PrintWriter(depslist)) {
+                Set<Klass> classes = new TreeSet<>(m.classes());
+                for (Klass k : classes) {
+                    writer.format("%s\n", k.getClassFilePathname());
+                    for (Klass to : builder.getDeps(k)) {
+                        dwriter.format("%-40s -> %s (%s)%n",
+                                k.getClassName(), to, to.getModule().group());
+                    }
+                }
+            }
+        }
+
+        if (!m.resources().isEmpty()) {
+            File reslist = dir.resolve(m.name() + ".resources").toFile();
+            try (PrintWriter writer = new PrintWriter(reslist)) {
+                Set<Resource> resources = new TreeSet<Resource>(m.resources());
+                for (Resource res : resources) {
+                    writer.format("%s\n", res.getPathname());
+                }
+            }
+        }
+    }
+
+    private void printModulePackages(Module m, Path dir) throws IOException {
+        File summary = dir.resolve(m.name() + ".summary").toFile();
+        try (PrintWriter writer = new PrintWriter(summary)) {
+            long total = 0;
+            int count = 0;
+            long resBytes = 0;
+            int resCount = 0;
+            writer.format("%10s\t%10s\t%s%n", "Bytes", "Classes", "Package name");
+            Set<Package> pkgs = new TreeSet<>(m.packages());
+            for (Package p : pkgs) {
+                writer.format("%10d\t%10d\t%s%n",
+                        p.classBytes, p.classCount, p.name());
+                total += p.classBytes;
+                count += p.classCount;
+
+            }
+            for (Resource rf : m.resources()) {
+                resCount++;
+                resBytes += rf.getFileSize();
+            }
+
+            writer.format("%nTotal: %d bytes (uncompressed) %d classes "
+                    + "%d bytes %d resources %n",
+                    total, count, resBytes, resCount);
+        }
+    }
+
+    private void printModuleGroup(Module group, PrintWriter writer) throws IOException {
+        ModuleVisitor<Set<Module>> visitor = new ModuleVisitor<Set<Module>>() {
+            public void preVisit(Module p, Set<Module> leafnodes) {
+            }
+
+            public void visited(Module p, Module m, Set<Module> leafnodes) {
+                if (m.members().isEmpty()) {
+                    leafnodes.add(m);
+                }
+            }
+
+            public void postVisit(Module p, Set<Module> leafnodes) {
+            }
+        };
+
+        Set<Module> visited = new TreeSet<>();
+        Set<Module> members = new TreeSet<>();
+        group.visitMembers(visited, visitor, members);
+
+        // prints leaf members that are the modules defined in
+        // the modules.config files
+        writer.format("%s ", group);
+        for (Module m : members) {
+            writer.format("%s ", m);
+        }
+        writer.println();
+    }
+
+    public void handleOptions(String[] args) throws BadArgs {
+        // process options
+        for (int i=0; i < args.length; i++) {
+            if (args[i].charAt(0) == '-') {
+                String name = args[i];
+                Option option = getOption(name);
+                String param = null;
+                if (option.hasArg) {
+                    if (name.indexOf('=') > 0) {
+                        param = name.substring(name.indexOf('=') + 1, name.length());
+                    } else if (i + 1 < args.length) {
+                        param = args[++i];
+                    }
+                    if (param == null || param.isEmpty() || param.charAt(0) == '-') {
+                        throw new BadArgs("err.missing.arg", name).showUsage(true);
+                    }
+                }
+                option.process(this, name, param);
+                if (option.ignoreRest()) {
+                    i = args.length;
+                }
+            } else {
+                throw new IllegalArgumentException("Invalid arguments");
+            }
+        }
+    }
+
+    private Option getOption(String name) throws BadArgs {
+        for (Option o : recognizedOptions) {
+            if (o.matches(name)) {
+                return o;
+            }
+        }
+        throw new BadArgs("err.unknown.option", name).showUsage(true);
+    }
+
+    private void reportError(String key, Object... args) {
+        log.println(getMessage("error.prefix") + " " + getMessage(key, args));
+    }
+
+    private void warning(String key, Object... args) {
+        log.println(getMessage("warn.prefix") + " " + getMessage(key, args));
+    }
+
+    private void showHelp() {
+        log.println(getMessage("main.usage", PROGNAME));
+        for (Option o : recognizedOptions) {
+            String name = o.aliases[0].substring(1); // there must always be at least one name
+            name = name.charAt(0) == '-' ? name.substring(1) : name;
+            if (o.isHidden() || name.equals("h")) {
+                continue;
+            }
+            log.println(getMessage("main.opt." + name));
+        }
+    }
+
+    static String getMessage(String key, Object... args) {
+        try {
+            return MessageFormat.format(ResourceBundleHelper.bundle.getString(key), args);
+        } catch (MissingResourceException e) {
+            throw new InternalError("Missing message: " + key);
+        }
+    }
+
+    private static class Options {
+        boolean help;
+        String outFile;
+        String javahome = System.getProperty("java.home");
+        String props;
+        String classlistDir;
+        String moduleInfoDir;
+        List<String> configs = new ArrayList<>();
+        String version;
+    }
+
+    private static class ResourceBundleHelper {
+        static final ResourceBundle bundle;
+        static {
+            Locale locale = Locale.getDefault();
+            try {
+                bundle = ResourceBundle.getBundle("com.sun.tools.classanalyzer.resources.classanalyzer", locale);
+            } catch (MissingResourceException e) {
+                throw new InternalError("Cannot find classanalyzer resource bundle for locale " + locale);
+            }
+        }
+    }
+
+    public static void main(String... args) throws Exception {
+        ClassAnalyzer analyzer = new ClassAnalyzer();
+        int rc = analyzer.run(args);
+        System.exit(rc);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/modules/tools/src/com/sun/tools/classanalyzer/ClassFileReader.java	Thu Aug 29 14:37:18 2013 -0700
@@ -0,0 +1,312 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.classanalyzer;
+
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.Dependencies.ClassFileError;
+import java.io.*;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.*;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+/**
+ * ClassFileReader reads ClassFile(s) of a given path that can be
+ * a .class file, a directory, or a JAR file.
+ */
+public class ClassFileReader {
+    /**
+     * Returns a ClassFileReader instance of a given path.
+     */
+    public static ClassFileReader newInstance(File path) throws IOException {
+        if (!path.exists()) {
+            throw new FileNotFoundException(path.getAbsolutePath());
+        }
+
+        if (path.isDirectory()) {
+            return new DirectoryReader(path.toPath());
+        } else if (path.getName().endsWith(".jar")) {
+            return new JarFileReader(path.toPath());
+        } else {
+            return new ClassFileReader(path.toPath());
+        }
+    }
+
+    /**
+     * Returns a ClassFileReader instance of a given JarFile.
+     */
+    public static ClassFileReader newInstance(Path path, JarFile jf) throws IOException {
+        return new JarFileReader(path, jf);
+    }
+
+    protected final Path path;
+    protected final String baseFileName;
+    private ClassFileReader(Path path) {
+        this.path = path;
+        this.baseFileName = path.getFileName() != null
+                                ? path.getFileName().toString()
+                                : path.toString();
+    }
+
+    public String getFileName() {
+        return baseFileName;
+    }
+
+    public Iterable<ClassFile> getClassFiles() throws IOException {
+        return new Iterable<ClassFile>() {
+            public Iterator<ClassFile> iterator() {
+                return new FileIterator();
+            }
+        };
+    }
+
+    public Iterable<Resource> getResources() throws IOException {
+        String fn = path.toFile().getName();
+        if (Resource.isResource(fn)) {
+            return Collections.singletonList(readResource(path));
+        }
+        return Collections.<Resource>emptyList();
+    }
+
+    private static ClassFile readClassFile(Path p) throws IOException {
+        try (InputStream is = Files.newInputStream(p)) {
+            return ClassFile.read(is);
+        } catch (ConstantPoolException e) {
+            throw new ClassFileError(e);
+        }
+    }
+
+    private static Resource readResource(Path p) throws IOException {
+        String fn = p.toFile().getName();
+        if (Resource.isResource(fn)) {
+            try (InputStream is = Files.newInputStream(p)) {
+                return Resource.getResource(fn, is, p.toFile().length());
+            }
+        }
+        return null;
+    }
+
+    class FileIterator implements Iterator<ClassFile> {
+        int count;
+        FileIterator() {
+            this.count = 0;
+        }
+        public boolean hasNext() {
+            return count == 0 && baseFileName.endsWith(".class");
+        }
+
+        public ClassFile next() {
+            if (!hasNext()) {
+                throw new NoSuchElementException();
+            }
+            try {
+                ClassFile cf = readClassFile(path);
+                count++;
+                return cf;
+            } catch (IOException e) {
+                throw new ClassFileError(e);
+            }
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+    }
+
+    public String toString() {
+        return path.toString();
+    }
+
+    private static class DirectoryReader extends ClassFileReader {
+        final DirectoryIterator iter = new DirectoryIterator();
+        DirectoryReader(Path path) throws IOException {
+            super(path);
+        }
+
+        public Iterable<ClassFile> getClassFiles() throws IOException {
+            iter.walkTree(path);
+            return new Iterable<ClassFile>() {
+                public Iterator<ClassFile> iterator() {
+                    return iter;
+                }
+            };
+        }
+
+        public Iterable<Resource> getResources() throws IOException {
+            iter.walkTree(path);
+            if (iter.hasNext()) {
+                throw new RuntimeException("getClassFile must be called first");
+            }
+            return iter.resources;
+        }
+
+        class DirectoryIterator implements Iterator<ClassFile> {
+            final List<Path> classFiles = new ArrayList<>();
+            final List<Resource> resources = new ArrayList<>();
+            private boolean inited = false;
+            private int index = 0;
+            DirectoryIterator() throws IOException {
+                index = 0;
+            }
+
+            public boolean hasNext() {
+                return index != classFiles.size();
+            }
+
+            public ClassFile next() {
+                if (!hasNext()) {
+                    throw new NoSuchElementException();
+                }
+                Path path = classFiles.get(index++);
+                try {
+                    return readClassFile(path);
+                } catch (IOException e) {
+                    throw new ClassFileError(e);
+                }
+            }
+
+            public void remove() {
+                throw new UnsupportedOperationException("Not supported yet.");
+            }
+
+            synchronized void walkTree(Path dir) throws IOException {
+                if (inited) return;
+
+                inited = true;
+                Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
+                    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+                            throws IOException {
+                        String fn = file.toFile().getName();
+                        if (fn.endsWith(".class")) {
+                            classFiles.add(file);
+                        } else if (Resource.isResource(fn)) {
+                            resources.add(readResource(file));
+                        }
+                        return FileVisitResult.CONTINUE;
+                    }
+                });
+            }
+        }
+    }
+
+    private static class JarFileReader extends ClassFileReader {
+        final JarFileIterator iter;
+        JarFileReader(Path path) throws IOException {
+            this(path, new JarFile(path.toFile()));
+        }
+        JarFileReader(Path path, JarFile jf) throws IOException {
+            super(path);
+            this.iter = new JarFileIterator(jf);
+        }
+
+        public Iterable<ClassFile> getClassFiles() throws IOException {
+            return new Iterable<ClassFile>() {
+                public Iterator<ClassFile> iterator() {
+                    return iter;
+                }
+            };
+        }
+
+        public Iterable<Resource> getResources() throws IOException {
+            if (iter.hasNext()) {
+                throw new RuntimeException("getClassFile must be called first");
+            }
+            return iter.resources;
+        }
+
+        class JarFileIterator implements Iterator<ClassFile> {
+            private Enumeration<JarEntry> entries;
+            final List<Resource> resources = new ArrayList<>();
+            final JarFile jarfile;
+
+            private JarEntry nextEntry;
+            JarFileIterator(JarFile jarfile) {
+                this.jarfile = jarfile;
+                this.entries = jarfile.entries();
+                this.nextEntry = nextEntry();
+            }
+
+            private JarEntry nextEntry() {
+                while (entries.hasMoreElements()) {
+                    JarEntry e = entries.nextElement();
+                    if (e.isDirectory())
+                        continue;
+
+                    String name = e.getName();
+                    if (name.endsWith(".class")) {
+                        return e;
+                    } else if (Resource.isResource(name)) {
+                        resources.add(getResource(e));
+                    }
+                }
+                return null;
+            }
+            private Resource getResource(JarEntry e) {
+                try (InputStream is = jarfile.getInputStream(e)) {
+                    return Resource.getResource(e.getName(), is, e.getSize());
+                } catch (IOException ex) {
+                    throw new RuntimeException(ex);
+                }
+            }
+
+            public boolean hasNext() {
+                return nextEntry != null;
+            }
+
+            public ClassFile next() {
+                if (!hasNext()) {
+                    throw new NoSuchElementException();
+                }
+
+                ClassFile cf;
+                try {
+                    cf = readClassFile(jarfile, nextEntry);
+                } catch (IOException ex) {
+                    throw new ClassFileError(ex);
+                }
+                JarEntry entry = nextEntry;
+                nextEntry = nextEntry();
+                return cf;
+            }
+
+            private ClassFile readClassFile(JarFile jf, JarEntry e) throws IOException {
+                try (InputStream is = jf.getInputStream(e)) {
+                    return ClassFile.read(is);
+                } catch (ConstantPoolException ex) {
+                    throw new ClassFileError(ex);
+                }
+            }
+
+            public void remove() {
+                throw new UnsupportedOperationException("Not supported yet.");
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/modules/tools/src/com/sun/tools/classanalyzer/ClassPath.java	Thu Aug 29 14:37:18 2013 -0700
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.classanalyzer;
+
+import com.sun.tools.classfile.ClassFile;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.*;
+
+/**
+ * ClassPath for Java SE and JDK
+ */
+class ClassPath {
+
+    static List<Archive> getArchives(String jdkhome) throws IOException {
+        List<Archive> result = new ArrayList<>();
+        Path home = Paths.get(jdkhome);
+
+        if (home.endsWith("jre")) {
+            // jar files in <javahome>/jre/lib
+            result.addAll(addJarFiles(home.resolve("lib")));
+            result.addAll(addJarFiles(home.getParent().resolve("lib")));
+
+        } else if (home.resolve("lib").toFile().exists()) {
+            // either a JRE or a jdk build image
+            File classes = home.resolve("classes").toFile();
+            if (classes.exists() && classes.isDirectory()) {
+                // jdk build outputdir
+                result.add(new Archive(classes, ClassFileReader.newInstance(classes)));
+            }
+            // add other JAR files
+            result.addAll(addJarFiles(home.resolve("lib")));
+        } else {
+            throw new RuntimeException("\"" + home + "\" not a JDK home");
+        }
+        return result;
+    }
+
+    private static List<String> SKIP_JARFILES =
+            Arrays.asList("alt-rt.jar", "jfxrt.jar", "ant-javafx.jar", "javafx-mx.jar");
+    private static List<Archive> addJarFiles(final Path root) throws IOException {
+        final List<Archive> result = new ArrayList<Archive>();
+        final Path ext = root.resolve("ext");
+        Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
+            @Override
+            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
+                    throws IOException {
+                if (dir.equals(root) || dir.equals(ext)) {
+                    return FileVisitResult.CONTINUE;
+                } else {
+                    // skip other cobundled JAR files
+                    return FileVisitResult.SKIP_SUBTREE;
+                }
+            }
+
+            @Override
+            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+                    throws IOException {
+                File f = file.toFile();
+                String fn = f.getName();
+                if (fn.endsWith(".jar") && !SKIP_JARFILES.contains(fn)) {
+                    result.add(new Archive(f, ClassFileReader.newInstance(f)));
+                }
+                return FileVisitResult.CONTINUE;
+            }
+        });
+        return result;
+    }
+
+    /**
+     * Represents the source of the class files.
+     */
+    public static class Archive {
+        private final File file;
+        private final String filename;
+        private final ClassFileReader reader;
+        public Archive(File file, ClassFileReader reader) {
+            this.file = file;
+            this.filename = file.getName();
+            this.reader = reader;
+        }
+
+        public String getFileName() {
+            return filename;
+        }
+
+        public Iterable<ClassFile> getClassFiles() throws IOException {
+            return reader.getClassFiles();
+        }
+
+        public Iterable<Resource> getResources() throws IOException {
+            return reader.getResources();
+        }
+        public String toString() {
+            return file != null ? file.getPath() : filename;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/modules/tools/src/com/sun/tools/classanalyzer/Dependence.java	Thu Aug 29 14:37:18 2013 -0700
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.classanalyzer;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+public class Dependence implements Comparable<Dependence> {
+    enum Identifier { PUBLIC, OPTIONAL, SERVICE };
+
+    private final String name;
+    private final Set<Identifier> identifiers;
+
+    public Dependence(String name, Set<Identifier> ids) {
+        this.name = name;
+        this.identifiers = new HashSet<>(ids);
+        if (identifiers.contains(Identifier.SERVICE) &&
+                identifiers.contains(Identifier.PUBLIC)) {
+            throw new IllegalArgumentException("Can't have requires service public");
+        }
+    }
+
+    public String name() {
+        return name;
+    }
+
+    public boolean requiresService() {
+        return identifiers.contains(Identifier.SERVICE);
+    }
+
+    public boolean requiresPublic() {
+        return identifiers.contains(Identifier.PUBLIC);
+    }
+
+    public boolean requiresOptional() {
+        return identifiers.contains(Identifier.OPTIONAL);
+    }
+
+    @Override
+    public int compareTo(Dependence d) {
+        if (this.equals(d)) {
+            return 0;
+        }
+        return name.compareTo(d.name);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof Dependence)) {
+            return false;
+        }
+        if (this == obj) {
+            return true;
+        }
+
+        Dependence d = (Dependence) obj;
+        return this.name.equals(d.name) && identifiers.equals(d.identifiers);
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 3;
+        hash = 19 * hash + this.name.hashCode();
+        return hash;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("requires");
+        for (Dependence.Identifier id : identifiers) {
+            sb.append(" ").append(id.name().toLowerCase());
+        }
+        sb.append(" ").append(name).append(";");
+        return sb.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/modules/tools/src/com/sun/tools/classanalyzer/JigsawModules.java	Thu Aug 29 14:37:18 2013 -0700
@@ -0,0 +1,280 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.tools.classanalyzer;
+
+import jdk.jigsaw.module.View;
+import jdk.jigsaw.module.ViewDependence;
+import jdk.jigsaw.module.ServiceDependence;
+import jdk.jigsaw.module.Module.Builder;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * Jigsaw module builder
+ */
+public class JigsawModules {
+    private final Set<jdk.jigsaw.module.Module> modules;
+    public JigsawModules() {
+        this.modules = new HashSet<>();
+    }
+
+    public void build(Module m, Collection<Dependence> requires) {
+        Builder b = new Builder();
+        b.main(build(m.defaultView()));
+        requires.stream().forEach(d -> {
+            if (d.requiresService()) {
+                b.requires(serviceDependence(d));
+            } else {
+                b.requires(viewDependence(d));
+            }
+        });
+        m.views().stream()
+            .filter(v -> !v.isEmpty() && v != m.defaultView())
+            .forEach(v -> b.view(build(v)));
+        m.packages().stream().forEach(p -> b.include(p.name()));
+        modules.add(b.build());
+    }
+
+    private ViewDependence viewDependence(Dependence d) {
+        Set<ViewDependence.Modifier> ms = new HashSet<>();
+        if (d.requiresOptional())
+            ms.add(ViewDependence.Modifier.OPTIONAL);
+        if (d.requiresPublic())
+            ms.add(ViewDependence.Modifier.PUBLIC);
+        return new ViewDependence(ms, d.name());
+    }
+    private ServiceDependence serviceDependence(Dependence d) {
+        Set<ServiceDependence.Modifier> ms =
+            d.requiresOptional() ? EnumSet.of(ServiceDependence.Modifier.OPTIONAL) :
+                EnumSet.noneOf(ServiceDependence.Modifier.class);
+        return new ServiceDependence(ms, d.name());
+    }
+
+    private View build(Module.View v) {
+        View.Builder b = new View.Builder();
+        b.id(v.id());
+        v.aliases().stream().forEach(alias -> b.alias(alias));
+
+        // a view may have a platform-specific class
+        if (v.mainClass() != null) {
+            b.mainClass(v.mainClassName());
+        }
+
+        // filter out platform-specific exports
+        v.exports().stream()
+            .filter(pn -> v.module.getPackage(pn) != null)
+            .forEach(pn -> b.export(pn));
+
+        for (Map.Entry<String, Set<String>> e : v.providers().entrySet()) {
+            String service = e.getKey();
+            e.getValue().stream().forEach((impl) -> {
+                b.service(service, impl);
+            });
+        }
+
+        v.permits().stream().forEach((String name) -> {
+            b.permit(name);
+        });
+        return b.build();
+    }
+
+    /**
+     * Write an array of jigsaw Module to the given OutputStream
+     */
+    public void store(OutputStream out) throws IOException {
+        try (ObjectOutputStream sout = new ObjectOutputStream(out)) {
+            sout.writeObject(modules.toArray(new jdk.jigsaw.module.Module[0]));
+        }
+    }
+
+    public void load(InputStream in) throws IOException, ClassNotFoundException {
+        int count = 0;
+        try (ObjectInputStream sin = new ObjectInputStream(in)) {
+            modules.addAll(Arrays.asList((jdk.jigsaw.module.Module[]) sin.readObject()));
+        }
+    }
+
+    public void printModuleInfos(String minfoDir) throws IOException {
+        for (jdk.jigsaw.module.Module m : modules) {
+            Path mdir = Paths.get(minfoDir, m.id().name());
+            mdir.toFile().mkdirs();
+            try (PrintWriter writer = new PrintWriter(mdir.resolve("module-info.java").toFile())) {
+                printModule(writer, m);
+            }
+        }
+    }
+
+    private <E> Iterable<E> orderedSet(Set<E> set, Function<E, String> f) {
+        Map<String, E> result = new TreeMap<>();
+        set.stream().forEach((e) -> {
+            result.put(f.apply(e), e);
+        });
+        return result.values();
+    }
+
+    private static final String INDENT = "    ";
+    private void printModule(PrintWriter writer, jdk.jigsaw.module.Module m) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(String.format("module %s {%n", m.id()));
+        for (ViewDependence vd : orderedSet(m.viewDependences(),
+                                            (ViewDependence d) -> d.query().name())) {
+            String ms = vd.modifiers().stream()
+                          .map(e -> e.name().toLowerCase())
+                          .collect(Collectors.joining(" "));
+            sb.append(format(1, "requires %s%s%s;%n",
+                             ms, vd.modifiers().isEmpty() ? "" : " ",
+                             vd.query()));
+        }
+        for (ServiceDependence sd : orderedSet(m.serviceDependences(),
+                                               (ServiceDependence d) -> d.service())) {
+            String ms = sd.modifiers().stream()
+                          .map(e -> e.name().toLowerCase())
+                          .collect(Collectors.joining(" "));
+            sb.append(format(1, "requires %s%sservice %s;%n",
+                             ms, sd.modifiers().isEmpty() ? "" : " ",
+                             sd.service()));
+        }
+
+        for (Map.Entry<String,Set<String>> entry: m.mainView().services().entrySet()) {
+            String sn = entry.getKey();
+            for (String cn: entry.getValue()) {
+                sb.append(format(1, "provides service %s with %s;%n", sn, cn));
+            }
+        }
+        sb.append("\n");
+        // print main view first
+        printView(0, sb, m.mainView());
+
+        for (View view : orderedSet(m.views(), (View v) -> v.id().name())) {
+            if (view != m.mainView()) {
+                printView(1, sb, view);
+            }
+        }
+        sb.append("}\n");
+        writer.println(sb.toString());
+    }
+
+    private String format(String fmt, Object... args) {
+        return format(0, fmt, args);
+    }
+
+    private String format(int level, String fmt, Object... args) {
+        String s = "";
+        for (int i=0; i < level; i++) {
+            s += INDENT;
+        }
+        return s + String.format(fmt, args);
+    }
+
+    private StringBuilder formatList(StringBuilder sb, int level, String fmt, Collection<?> c) {
+        return formatList(sb, level, fmt, c, false);
+    }
+
+    private StringBuilder formatList(StringBuilder sb, int level, String fmt, Collection<?> c, boolean newline) {
+        if (c.isEmpty())
+            return sb;
+
+        if (newline)
+            sb.append("\n");
+
+        TreeSet<?> ls = new TreeSet<>(c);
+        for (Object o : ls) {
+            sb.append(format(level, fmt, o));
+        }
+        return sb;
+    }
+
+    private void printView(int level, StringBuilder sb, View view) {
+        if (level > 0) {
+            // non-default view
+            sb.append("\n");
+            sb.append(format(level, "view %s {%n", view.id().name()));
+        }
+
+        formatList(sb, level+1, "provides %s;%n", view.aliases());
+        if (view.mainClass() != null) {
+            sb.append(format(level+1, "class %s;%n", view.mainClass()));
+        }
+
+        boolean newline = !view.aliases().isEmpty() || view.mainClass() != null;
+        if (!view.exports().isEmpty()) {
+            if (level == 0) {
+                sb.append(newline ? "\n" : "");
+                sb.append(format(level+1, "// default view exports%n"));
+                newline = false;
+            }
+            Set<String> exports = view.exports();
+            formatList(sb, level+1, "exports %s;%n", exports, newline);
+            newline = true;
+        }
+
+        formatList(sb, level + 1, "permits %s;%n", view.permits(), newline);
+
+        if (level > 0)
+            sb.append(format(level, "}%n"));
+    }
+
+    /**
+     * Load the module graph.
+     */
+    public static void main(String... argv) throws Exception {
+        JigsawModules graph = new JigsawModules();
+        if (argv.length == 0) {
+            // default path
+            String MODULES_SER = "jdk/jigsaw/module/resources/modules.ser";
+            try (InputStream in = ClassLoader.getSystemResourceAsStream(MODULES_SER)) {
+                graph.load(in);
+            }
+        } else {
+            System.out.println("reading from " + argv[0]);
+            try (FileInputStream in = new FileInputStream(argv[0])) {
+                graph.load(in);
+            }
+        }
+
+        System.out.format("%d modules:%n", graph.modules.size());
+        PrintWriter writer = new PrintWriter(System.out);
+        for (jdk.jigsaw.module.Module m : graph.modules) {
+            graph.printModule(writer, m);
+        }
+        writer.flush();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/modules/tools/src/com/sun/tools/classanalyzer/Klass.java	Thu Aug 29 14:37:18 2013 -0700
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.tools.classanalyzer;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.HashSet;
+
+import com.sun.tools.classfile.AccessFlags;
+import com.sun.tools.classfile.Dependency.Location;
+import java.util.Collections;
+
+/**
+ *
+ */
+public class Klass implements Comparable<Klass> {
+    private final String classname;
+    private final String packagename;
+    private Module module;
+    private boolean isJavaLangObject;
+    private String[] paths;
+    private AccessFlags accessFlags;
+    private long filesize;
+
+    private Set<Location> deps;
+    public Klass(String cn, AccessFlags accessFlags, long bytelength) {
+        this.classname = cn.replace('/', '.');
+        this.paths = cn.replace('.', '/').split("/");
+        this.isJavaLangObject = this.classname.equals("java.lang.Object");
+        this.deps = new HashSet<>();
+        this.accessFlags = accessFlags;
+        this.filesize = bytelength;
+
+        int pos = this.classname.lastIndexOf('.');
+        this.packagename = (pos > 0) ? this.classname.substring(0, pos) : "<unnamed>";
+    }
+
+    String getBasename() {
+        return paths[paths.length - 1];
+    }
+
+    String getClassName() {
+        return classname;
+    }
+
+    String getClassFilePathname() {
+        StringBuilder sb = new StringBuilder(paths[0]);
+        for (int i = 1; i < paths.length; i++) {
+            String p = paths[i];
+            sb.append(File.separator).append(p);
+        }
+        return sb.append(".class").toString();
+    }
+
+    String getPackageName() {
+        return packagename;
+    }
+
+    boolean isPublic() {
+        return accessFlags == null || accessFlags.is(AccessFlags.ACC_PUBLIC);
+    }
+
+    Module getModule() {
+        return module;
+    }
+
+    void setModule(Module m) {
+        if (module != null) {
+            throw new RuntimeException("Module for " + this + " already set");
+        }
+        this.module = m;
+    }
+
+    long getFileSize() {
+        return this.filesize;
+    }
+
+    boolean exists() {
+        return filesize > 0;
+    }
+
+    boolean skip(Klass k) {
+        // skip if either class is a root or same class
+        return k.isJavaLangObject || this == k || k.classname.equals(classname);
+    }
+
+    public void reference(Location target) {
+        deps.add(target);
+    }
+
+    Set<Location> getDeps() {
+        return deps;
+    }
+
+    @Override
+    public String toString() {
+        return classname;
+    }
+
+    @Override
+    public int compareTo(Klass o) {
+        return classname.compareTo(o.classname);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/modules/tools/src/com/sun/tools/classanalyzer/Module.java	Thu Aug 29 14:37:18 2013 -0700
@@ -0,0 +1,670 @@
+/*
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.tools.classanalyzer;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+/**
+ * Module contains a list of classes and resources.
+ *
+ */
+public class Module implements Comparable<Module> {
+    static Properties moduleProps = new Properties();
+    static String getModuleProperty(String key) {
+        return getModuleProperty(key, null);
+    }
+    static String getModuleProperty(String key, String defaultValue) {
+        String value = moduleProps.getProperty(key);
+        if (value == null)
+            return defaultValue;
+        else
+            return value;
+    }
+
+    static void setModuleProperties(String file) throws IOException {
+        File f = new File(file);
+        BufferedReader reader = null;
+        try {
+            reader = new BufferedReader(new FileReader(f));
+            moduleProps.load(reader);
+        } finally {
+            if (reader != null) {
+                reader.close();
+            }
+        }
+    }
+
+    private final String name;
+    private final String version;
+    private final ModuleConfig config;
+    private final Set<Klass> classes;
+    private final Set<Resource> resources;
+    private final Set<Module> members;
+    private final Map<String,View> views;
+    private final View defaultView;
+    private final View internalView;
+    private final Set<Service> services;
+    private final Map<Service, Set<Klass>> providers;
+    private final Map<String, Package> packages;
+    private final Map<String, Dependence> configRequires; // requires came from ModuleConfig
+
+    // update during the analysis
+    private Module group;
+    protected Module(ModuleConfig config) {
+        this.name = config.module;
+        this.version = config.version;
+        this.classes = new HashSet<>();
+        this.resources = new HashSet<>();
+        this.config = config;
+        this.members = new HashSet<>();
+        this.providers = new HashMap<>();
+        this.configRequires = new LinkedHashMap<>(config.requires());
+        this.services = new HashSet<>();
+        this.packages = new HashMap<>();
+
+        this.group = this; // initialize to itself
+
+        this.views = new LinkedHashMap<>();
+        for (ModuleConfig.View mcv : config.viewForName.values()) {
+            addView(mcv.name, mcv);
+        }
+        this.defaultView = views.get(name);
+
+        // create an internal view
+        this.internalView = addView(name + ".internal");
+    }
+
+    String name() {
+        return name;
+    }
+
+    String version() {
+        return version;
+    }
+
+    ModuleConfig config() {
+        return config;
+    }
+
+    Module group() {
+        return group;
+    }
+
+    Collection<Package> packages() {
+        return packages.values();
+    }
+
+    Set<Klass> classes() {
+        return Collections.unmodifiableSet(classes);
+    }
+
+    Set<Resource> resources() {
+        return Collections.unmodifiableSet(resources);
+    }
+
+    Set<Service> services() {
+        return services;
+    }
+
+    Map<Service,Set<Klass>> providers() {
+        return providers;
+    }
+
+    Map<String, Dependence> configRequires() {
+        return configRequires;
+    }
+
+    Set<Module> members() {
+        return Collections.unmodifiableSet(members);
+    }
+
+    Module.View defaultView() {
+        return defaultView;
+    }
+
+    Module.View internalView() {
+        return internalView;
+    }
+
+    Collection<View> views() {
+        return views.values();
+    }
+
+    View addView(String name) {
+        View v = new View(this, name);
+        views.put(name, v);
+        return v;
+    }
+
+    private View addView(String name, ModuleConfig.View mcv) {
+        View v = new View(this, mcv, name);
+        views.put(name, v);
+        return v;
+    }
+
+    Module.View getView(String name) {
+        return views.get(name);
+    }
+
+    Module.View getView(Klass k) {
+        String pn = k.getPackageName();
+        View view = internalView;
+        for (View v : views.values()) {
+            if (v.exports.contains(pn)) {
+                view = v;
+                break;
+            }
+        }
+        // make sure a package referenced by other modules
+        // is exported either in the default view or internal view
+        Package pinfo = packages.get(pn);
+        if (contains(k) && !defaultView.exports.contains(pn)) {
+            if (!pinfo.isExported && !internalView.exports.contains(pn)) {
+                internalView.exports.add(pn);
+            }
+        }
+        assert view.exports.contains(pn);
+        return view;
+    }
+
+    boolean contains(Klass k) {
+        return k != null && classes.contains(k);
+    }
+
+    // returns true if a property named <module-name>.<key> is set to "true"
+    // otherwise; return false
+    boolean moduleProperty(String key) {
+        String value = moduleProps.getProperty(name + "." + key);
+        if (value == null)
+            return false;
+        else
+            return Boolean.parseBoolean(value);
+    }
+
+    boolean isEmpty() {
+        if (!classes.isEmpty() || !resources.isEmpty())
+            return false;
+
+        for (View v : views.values()) {
+            if (v.mainClass() != null)
+                return false;
+        }
+        return true;
+    }
+
+    boolean allowsEmpty() {
+        return moduleProperty("allows.empty");
+    }
+
+    @Override
+    public int compareTo(Module o) {
+        if (o == null) {
+            return -1;
+        }
+        return name.compareTo(o.name);
+    }
+
+    @Override
+    public String toString() {
+        return name;
+    }
+
+    void addKlass(Klass k) {
+        classes.add(k);
+        k.setModule(this);
+    }
+
+    void addPackage(Package p) {
+        packages.put(p.name(), p);
+    }
+
+    Package getPackage(String pn) {
+        return packages.get(pn);
+    }
+
+    void addResource(Resource res) {
+        resources.add(res);
+        res.setModule(this);
+    }
+
+    void addService(Service s) {
+        assert classes.contains(s.service);
+        services.add(s);
+    }
+
+    void addProvider(Service s, Klass k) {
+        assert k.getModule() == this;
+        Set<Klass> implClasses = providers.get(s);
+        if (implClasses == null) {
+            providers.put(s, implClasses = new LinkedHashSet<>());
+        }
+        if (!implClasses.contains(k)) {
+            implClasses.add(k);
+        }
+    }
+
+    <P> void visitMembers(Set<Module> visited, ModuleVisitor<P> visitor, P p) {
+        if (!visited.contains(this)) {
+            visited.add(this);
+            visitor.preVisit(this, p);
+            for (Module m : members) {
+                m.visitMembers(visited, visitor, p);
+                visitor.visited(this, m, p);
+            }
+            visitor.postVisit(this, p);
+        } else {
+            throw new RuntimeException("Cycle detected: module " + this.name);
+        }
+    }
+
+    private <K, E> void mergeMaps(Map<K, Set<E>> map1, Map<K, Set<E>> map2) {
+        // merge providers
+        for (Map.Entry<K, Set<E>> e : map2.entrySet()) {
+            if (!map1.containsKey(e.getKey())) {
+                map1.put(e.getKey(), e.getValue());
+            }
+            Set<E> value = map1.get(e.getKey());
+            value.addAll(e.getValue());
+        }
+    }
+
+    private static <K, V> void mergeMaps(Map<K,V> map1, Map<K,V> map2, BiFunction<V,V,Void> function) {
+        // merge providers
+        for (Map.Entry<K, V> e : map2.entrySet()) {
+            if (!map1.containsKey(e.getKey())) {
+                map1.put(e.getKey(), e.getValue());
+            } else {
+                V value = map1.get(e.getKey());
+                function.apply(value, e.getValue());
+            }
+        }
+    }
+
+    void addMember(Module m) {
+        // merge class list and resource list
+        classes.addAll(m.classes);
+        resources.addAll(m.resources);
+        services.addAll(m.services);
+
+        // merge providers
+        mergeMaps(this.providers, m.providers, new BiFunction<Set<Klass>,Set<Klass>,Void>() {
+            @Override
+            public Void apply(Set<Klass> v1, Set<Klass> v2) {
+                v1.addAll(v2);
+                return null;
+            }
+        });
+
+        // merge package infos
+        mergeMaps(this.packages, m.packages, new BiFunction<Package,Package,Void>() {
+            @Override
+            public Void apply(Package p1, Package p2) {
+                p1.merge(p2);
+                return null;
+            }
+        });
+
+        // merge requires from module configs
+        mergeMaps(this.configRequires, m.configRequires, new BiFunction<Dependence,Dependence,Void>() {
+            @Override
+            public Void apply(Dependence d1, Dependence d2) {
+                if (!d1.equals(d2)) {
+                    throw new UnsupportedOperationException();
+                }
+                return null;
+            }
+        });
+
+        // merge views
+        for (View v : m.views.values()) {
+            if (views.containsKey(v.name)) {
+                throw new RuntimeException(name + " and member " + m.name
+                        + " already has view " + v.name);
+            }
+            if (v == m.defaultView) {
+                // merge default view
+                defaultView.merge(v);
+            } else if (v == m.internalView) {
+                internalView.merge(v);
+            } else {
+                views.put(v.name, v);
+            }
+        }
+    }
+
+    void buildExports() {
+        // rebuild default view's exports after Package are merged
+        boolean all = moduleProperty("exports.all");
+        for (Package p : packages.values()) {
+            if (all || p.isExported)
+                defaultView.exports.add(p.name());
+        }
+    }
+
+    public static class View implements Comparable<View> {
+        final Module module;
+        final String name;
+        private final Set<String> exports = new HashSet<>();
+        private final Set<String> permitNames = new HashSet<>();
+        private final Set<String> aliases = new HashSet<>();
+        private final String mainClassName;
+        private Klass mainClass;
+        private final Set<String> permits = new HashSet<>();
+        private final Map<String, Set<String>> providers = new HashMap<>();
+
+        int refCount;
+
+        // specified in modules.config; always include it in module-info.java
+        View(Module m, ModuleConfig.View mcv, String name) {
+            this.module = m;
+            this.name = name;
+            this.refCount = 0;
+            this.mainClassName = mcv != null ? mcv.mainClass : null;
+            if (mcv != null) {
+                exports.addAll(mcv.exports);
+                permitNames.addAll(mcv.permits);
+                aliases.addAll(mcv.aliases);
+                providers.putAll(mcv.providers);
+            }
+        }
+
+        // only show up in module-info.java if there is a reference to it.
+        View(Module m, String name) {
+            this.module = m;
+            this.name = name;
+            this.refCount = -1;
+            this.mainClassName = null;
+        }
+
+        boolean isEmpty() {
+            // Internal view may have non-empty exports but it's only
+            // non-empty if any module requires it
+            return mainClass == null &&
+                    (refCount < 0 || exports.isEmpty()) &&
+                    permits.isEmpty() && providers.isEmpty() &&
+                    aliases.isEmpty();
+        }
+
+        Set<String> permitNames() {
+            return Collections.unmodifiableSet(permitNames);
+        }
+
+        Set<String> permits() {
+            return Collections.unmodifiableSet(permits);
+        }
+
+        Set<String> aliases() {
+            return Collections.unmodifiableSet(aliases);
+        }
+
+        Set<String> exports() {
+            return Collections.unmodifiableSet(exports);
+        }
+
+        Map<String,Set<String>> providers() {
+            return Collections.unmodifiableMap(providers);
+        }
+
+        void addPermit(String name) {
+            permits.add(name);
+        }
+
+        void addProviders(Map<String,Set<String>> map) {
+             mergeMaps(this.providers, map, new BiFunction<Set<String>,Set<String>,Void>() {
+                @Override
+                public Void apply(Set<String> v1, Set<String> v2) {
+                    v1.addAll(v2);
+                    return null;
+                }
+            });
+        }
+
+        void merge(View v) {
+            // main class is not propagated to the default view
+            this.aliases.addAll(v.aliases);
+            this.permitNames.addAll(v.permitNames);
+            mergeMaps(this.providers, v.providers, new BiFunction<Set<String>,Set<String>,Void>() {
+                @Override
+                public Void apply(Set<String> v1, Set<String> v2) {
+                    v1.addAll(v2);
+                    return null;
+                }
+            });
+        }
+
+        String mainClassName() {
+            return mainClassName;
+        }
+
+        void setMainClass(Klass k) {
+            mainClass = k;
+        }
+
+        Klass mainClass() {
+            return mainClass;
+        }
+
+        void addRefCount() {
+            refCount++;
+        }
+
+        String id() {
+            return name + "@" + module.version();
+        }
+
+        public String toString() {
+            return id();
+        }
+
+        public int compareTo(Module.View o) {
+            if (o == null) {
+                return -1;
+            }
+            int rc = module.compareTo(o.module);
+            if (rc == 0) {
+                return name.compareTo(o.name);
+            }
+            return rc;
+        }
+    }
+
+    private static Factory INSTANCE = new Factory();
+    public static Factory getFactory() {
+        return INSTANCE;
+    }
+
+    static class Factory {
+        protected Map<String, Module> modules = new LinkedHashMap<>();
+
+        protected final void addModule(Module m) {
+            // ## For now, maintain the static all modules list.
+            // ## Need to revisit later
+            String name = m.name();
+            if (modules.containsKey(name)) {
+                throw new RuntimeException("module \"" + name + "\" already exists");
+            }
+            modules.put(name, m);
+        }
+
+        public final Module findModule(String name) {
+            return modules.get(name);
+        }
+
+        public final Module getModuleForView(String name) {
+            Module m = findModule(name);
+            if (m != null)
+                return m;
+
+            String[] suffices = getModuleProperty("module.view.suffix", "").split("\\s+");
+            for (String s : suffices) {
+                int i = name.lastIndexOf("." + s);
+                if (i != -1 && name.endsWith("." + s)) {
+                    String mn = name.substring(0, i);
+                    if ((m = findModule(mn)) != null) {
+                        if (m.getView(name) == null)
+                            throw new RuntimeException("module view " + name + " doesn't exist");
+                        return m;
+                    }
+                }
+            }
+            throw new RuntimeException("module " + name + " doesn't exist");
+        }
+
+        public final Set<Module> getAllModules() {
+            // initialize unknown module (last to add to the list)
+            unknownModule();
+            Set<Module> ms = new LinkedHashSet<>(modules.values());
+            return ms;
+        }
+
+        public void init(List<ModuleConfig> mconfigs) {
+            for (ModuleConfig mconfig : mconfigs) {
+                Module m = this.newModule(mconfig);
+                addModule(m);
+            }
+        }
+
+        public Module newModule(String name, String version) {
+            return this.newModule(new ModuleConfig(name, version));
+        }
+
+        public Module newModule(ModuleConfig config) {
+            return new Module(config);
+        }
+
+        public final void addModules(Set<Module> ms) {
+            for (Module m : ms) {
+                addModule(m);
+            }
+        }
+        private static Module unknown;
+        Module unknownModule() {
+            synchronized (Factory.class) {
+                if (unknown == null) {
+                    unknown = this.newModule(ModuleConfig.moduleConfigForUnknownModule());
+                    addModule(unknown);
+                }
+            }
+            return unknown;
+        }
+
+        void buildModuleMembers() {
+            // set up module member relationship
+            for (Module m : getAllModules()) {
+                m.group = m;       // initialize to itself
+                for (String name : m.config.members()) {
+                    Module member = findModule(name);
+                    if (member != null) {
+                        m.members.add(member);
+                    }
+                }
+            }
+
+            // set up the top-level module
+            ModuleVisitor<Module> groupSetter = new ModuleVisitor<Module>() {
+                public void preVisit(Module m, Module p) {
+                    m.group = p;
+                }
+
+                public void visited(Module m, Module child, Module p) {
+                    // nop - breadth-first search
+                }
+
+                public void postVisit(Module m, Module p) {
+                    // nop - breadth-first search
+                }
+            };
+
+            // propagate the top-level module to all its members
+            for (Module p : getAllModules()) {
+                for (Module m : p.members) {
+                    if (m.group == m) {
+                        m.visitMembers(new HashSet<Module>(), groupSetter, p);
+                    }
+                }
+            }
+
+            ModuleVisitor<Module> mergeClassList = new ModuleVisitor<Module>() {
+                public void preVisit(Module m, Module p) {
+                    // nop - depth-first search
+                }
+
+                public void visited(Module m, Module child, Module p) {
+                    m.addMember(child);
+                }
+
+                public void postVisit(Module m, Module p) {
+                }
+            };
+
+            Set<Module> visited = new HashSet<>();
+            Set<Module> groups = new HashSet<>();
+            for (Module m : getAllModules()) {
+                if (m.group() == m) {
+                    groups.add(m);
+                    if (m.members().size() > 0) {
+                        // merge class list from all its members
+                        m.visitMembers(visited, mergeClassList, m);
+                    }
+                    m.buildExports();
+                }
+            }
+        }
+    }
+
+    public interface Visitor<R, P> {
+        R visitClass(Klass k, P p);
+        R visitResource(Resource r, P p);
+    }
+
+    public <R, P> void visit(Visitor<R, P> visitor, P p) {
+        for (Klass c : classes) {
+            visitor.visitClass(c, p);
+        }
+        for (Resource res : resources) {
+            visitor.visitResource(res, p);
+        }
+    }
+
+    interface ModuleVisitor<P> {
+        public void preVisit(Module m, P param);
+        public void visited(Module m, Module child, P param);
+        public void postVisit(Module m, P param);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/modules/tools/src/com/sun/tools/classanalyzer/ModuleBuilder.java	Thu Aug 29 14:37:18 2013 -0700
@@ -0,0 +1,470 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.classanalyzer;
+
+import com.sun.tools.classanalyzer.ClassPath.Archive;
+import com.sun.tools.classanalyzer.Module.Factory;
+import com.sun.tools.classanalyzer.Service.ProviderConfigFile;
+import static com.sun.tools.classanalyzer.Dependence.Identifier.*;
+
+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 com.sun.tools.classfile.Dependency.Location;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.*;
+
+/**
+ * Module builder that creates modules as defined in the given
+ * module configuration files.  The run() method assigns
+ * all classes and resources according to the module definitions.
+ * Additional dependency information can be specified e.g.
+ * Class.forName, JNI_FindClass, and service providers.
+ *
+ * @see DependencyConfig
+ */
+public class ModuleBuilder {
+    protected final List<ModuleConfig> mconfigs = new ArrayList<ModuleConfig>();
+    protected final String version;
+    private final List<Archive> archives;
+    private final Map<String, Klass> classes = new HashMap<>();
+    private final Map<String, Set<Package>> packages = new HashMap<>();
+    private final Map<String, Service> services = new HashMap<>();
+    private final Map<Module, Map<String,Dependence>> dependencesForModule = new HashMap<>();
+    private final JigsawModules graph = new JigsawModules();
+    public ModuleBuilder(List<String> configs,
+                         List<Archive> archives,
+                         String version) throws IOException {
+        if (configs != null) {
+            for (String file : configs) {
+                mconfigs.addAll(ModuleConfig.readConfigurationFile(file, version));
+            }
+        }
+        this.archives = archives;
+        this.version = version;
+    }
+
+    public void store(OutputStream out) throws IOException {
+        graph.store(out);
+    }
+
+    public void printModuleInfos(String minfoDir) throws IOException {
+        graph.printModuleInfos(minfoDir);
+    }
+
+    /**
+     * Returns the module factory.
+     */
+    protected Factory factory() {
+        return Module.getFactory();
+    }
+
+    /**
+     * This method assigns the classes and resource files
+     * to modules and generates the package information and
+     * the module information.
+     *
+     * This method can be overridden in a subclass implementation.
+     */
+    public void run() throws IOException {
+        // assign classes and resource files to the modules and
+        // group fine-grained modules per configuration files
+        buildModules();
+
+        // build jigsaw modules
+        for (Map.Entry<Module, Map<String,Dependence>> e : dependencesForModule.entrySet()) {
+            graph.build(e.getKey(), e.getValue().values());
+        }
+        System.out.format("%d modules %d classes analyzed%n",
+                          dependencesForModule.size(), classes.size());
+    }
+
+    /**
+     * Builds modules from the existing list of classes and resource
+     * files according to the module configuration files.
+     *
+     */
+    protected void buildModules() throws IOException {
+        // create the modules for the given configs
+        factory().init(mconfigs);
+
+        // analyze class dependencies
+        findDependencies();
+
+        // group fine-grained modules
+        factory().buildModuleMembers();
+
+        // analyze cross-module dependencies
+        for (Module m : factory().getAllModules()) {
+            if (m.group() == m) {
+                // module with no class is not included except the base module
+                // or reexporting APIs from required modules
+                boolean reexports = false;
+                for (Dependence d : m.config().requires().values()) {
+                    reexports = reexports || d.requiresPublic();
+                }
+                if (isBaseModule(m) || !m.isEmpty() || m.allowsEmpty() || reexports) {
+                    dependencesForModule.put(m, buildModuleDependences(m));
+                }
+            }
+        }
+
+        // fixup permits after dependences are found
+        fixupPermits();
+    }
+
+    private Module findModule(String name) {
+        Module module = null;
+        for (Module m : Module.getFactory().getAllModules()) {
+            ModuleConfig config = m.config();
+            if (config.matchesIncludes(name) && !config.isExcluded(name)) {
+                return m;
+            }
+        }
+        return null;
+    }
+
+    private void findDependencies() throws IOException {
+        Dependency.Finder finder = Dependencies.getClassDependencyFinder();
+        Dependency.Filter filter = new Dependency.Filter() {
+            @Override
+            public boolean accepts(Dependency dependency) {
+                return !dependency.getOrigin().equals(dependency.getTarget());
+            }
+        };
+
+        // get the immediate dependencies of the input files
+        for (Archive a : archives) {
+            for (ClassFile cf : a.getClassFiles()) {
+                String classFileName;
+                try {
+                    classFileName = cf.getName();
+                } catch (ConstantPoolException e) {
+                    throw new Dependencies.ClassFileError(e);
+                }
+
+                Klass k = classes.get(classFileName);
+                if (k == null) {
+                    k = new Klass(classFileName, cf.access_flags, cf.byteLength());
+                    String cn = k.getClassName();
+                    Module module = getPackage(k).module;
+                    module.addKlass(k);
+                    classes.put(classFileName, k);
+                }
+                for (Dependency d : finder.findDependencies(cf)) {
+                    if (filter.accepts(d)) {
+                        k.reference(d.getTarget());
+                    }
+                }
+            }
+        }
+
+        // process resources and service providers
+        for (Archive a : archives) {
+            for (Resource res : a.getResources()) {
+                if (!res.isService()) {
+                    Module module = getPackage(res).module;
+                    module.addResource(res);
+                } else {
+                    ProviderConfigFile pcf = ProviderConfigFile.class.cast(res);
+                    String name = pcf.getName().replace('.', '/');
+                    Klass k = classes.get(name);
+                    Service s = services.get(k.getClassName());
+                    if (s == null) {
+                        services.put(k.getClassName(), s = new Service(k));
+                        k.getModule().addService(s);
+                    }
+                    for (String p : pcf.providers) {
+                        Klass provider = classes.get(p.replace('.', '/'));
+                        if (provider == null) {
+                            throw new RuntimeException(s + " provider not exist: " + p);
+                        }
+                        provider.getModule().addProvider(s, provider);
+                    }
+                }
+            }
+        }
+    }
+
+    // returns true if the given class is not in module m and
+    // not in an exported package of the base module
+    private boolean requiresModuleDependence(Module m, Klass k) {
+        return m.group() != k.getModule().group();
+    }
+
+    private Module.View getRequiresModule(Module m, Klass k) {
+        if (m.group() == k.getModule().group())
+            return null;
+
+        // Returns true if class k is exported from another module
+        // and not from the base's default view
+        Module other = k.getModule().group();
+        return other.getView(k);
+    }
+
+    interface KlassFilter {
+        boolean accept(Klass k);
+    }
+
+    // returns all classes that are not in the base module
+    // referenced by the given class
+    public Set<Klass> getDeps(Klass from) {
+        return getDeps(from, new KlassFilter() {
+            public boolean accept(Klass k) {
+                Module m = k.getModule().group();
+                return !isBaseModule(m) || !m.getPackage(k.getPackageName()).isExported;
+            }
+        });
+    }
+
+    public Set<Klass> getDeps(Klass from, KlassFilter filter) {
+        Set<Klass> deps = new TreeSet<>();
+        for (Location target : from.getDeps()) {
+            Klass to = classes.get(target.getName());
+            if (to == null) {
+                System.err.println(target.getName() + " not found");
+            } else if (requiresModuleDependence(from.getModule(), to)) {
+                if (filter == null || filter.accept(to)) {
+                    deps.add(to);
+                }
+            }
+        }
+        return deps;
+    }
+
+    private Package getPackage(Klass k) {
+        String pn = k.getPackageName();
+        Package p = getPackage(pn, k.getClassName());
+        p.addKlass(k);
+        return p;
+    }
+
+    private Package getPackage(Resource res) {
+        String pn = "";
+        int i = res.getName().lastIndexOf('/');
+        if (i > 0) {
+            pn = res.getName().substring(0, i).replace('/', '.');
+        }
+        Package p = getPackage(pn, res.getName());
+        p.addResource(res);
+        return p;
+    }
+
+    private Package getPackage(String pn, String name) {
+        Module module = findModule(name);
+        Package p = module.getPackage(pn);
+        if (p == null) {
+            Set<Package> pkgs = packages.get(pn);
+            if (pkgs == null) {
+                packages.put(pn, pkgs = new HashSet<>());
+            }
+            pkgs.add(p = new Package(pn, module));
+            module.addPackage(p);
+        }
+        return p;
+    }
+
+    public Map<String, Set<Module>> getPackages() {
+        Map<String, Set<Module>> modulesForPackage = new TreeMap<>();
+        for (Module m : dependencesForModule.keySet()) {
+            for (Package p : m.packages()) {
+                Set<Module> ms = modulesForPackage.get(p.name());
+                if (ms == null) {
+                    modulesForPackage.put(p.name(), ms = new HashSet<>());
+                }
+                ms.add(m);
+            }
+        }
+        return modulesForPackage;
+    }
+
+    private static List<String> baseModules = Arrays.asList("base", "jdk.base", "java.base");
+    private boolean isBaseModule(Module m) {
+        return baseModules.contains(m.name());
+    }
+
+    private void fixupPermits() {
+        // fixup permits after all ModuleInfo are created in two passes:
+        // 1. permits the requesting module if it requires local dependence
+        // 2. if permits set is non-empty, permits
+        //    all of its requesting modules
+        for (Map.Entry<Module.View, Set<Module>> e : backedges.entrySet()) {
+            Module.View dmv = e.getKey();
+            if (dmv.permits().size() > 0) {
+                for (Module m : e.getValue()) {
+                    dmv.addPermit(m.defaultView().name);
+                }
+            }
+        }
+    }
+
+    protected Map<String, Dependence> buildModuleDependences(Module m) {
+        Map<String, Dependence> requires = new TreeMap<>();
+        for (Map.Entry<String, Dependence> e : m.configRequires().entrySet()) {
+            Dependence d = e.getValue();
+            if (d.requiresService()) {
+                Service s = services.get(e.getKey());
+                if (s == null) {
+                    // no service provider config file
+                    String cf = e.getKey().replace('.', '/');
+                    Klass k = classes.get(cf);
+                    if (k == null) {
+                        throw new RuntimeException("service " + e.getKey() + " not found");
+                    }
+                    services.put(k.getClassName(), s = new Service(k));
+                    k.getModule().addService(s);
+                }
+                if (requiresModuleDependence(m, s.service)) {
+                    addDependence(m, s.service, requires);
+                }
+                requires.put(e.getKey(), d);
+            } else {
+                addDependence(m, d, requires);
+            }
+        }
+
+        // add static dependences
+        for (Klass from : m.classes()) {
+            for (Klass to : getDeps(from, null)) {
+                addDependence(m, to, requires);
+            }
+        }
+
+        // add dependency due to the main class
+        for (Module.View v : m.views()) {
+            if (v.mainClassName() != null) {
+                Klass k = classes.get(v.mainClassName().replace('.', '/'));
+                if (k != null) {
+                    v.setMainClass(k);
+                    // this main class may possibly be a platform-specific class
+                    if (requiresModuleDependence(m, k)) {
+                        addDependence(m, k, requires);
+                    }
+                }
+            }
+            for (String name : v.permitNames()) {
+                Module pm = factory().getModuleForView(name);
+                if (pm != null) {
+                    v.addPermit(pm.group().defaultView().name);
+                    addBackEdge(m, v);
+                } else {
+                    throw new RuntimeException("module " + name
+                            + " specified in the permits rule for " + m.name()
+                            + " doesn't exist");
+                }
+            }
+        }
+
+        for (Service s : m.services()) {
+            String name = s.service.getClassName();
+            requires.put(name, new Dependence(name, EnumSet.of(OPTIONAL, SERVICE)));
+        }
+
+        Map<String,Set<String>> providesServices = new HashMap<>();
+        for (Map.Entry<Service,Set<Klass>> entry: m.providers().entrySet()) {
+            String sn = entry.getKey().service.getClassName();
+            Set<String> impls = providesServices.get(sn);
+            if (impls == null) {
+                providesServices.put(sn, impls = new LinkedHashSet<>());
+            }
+            // preserve order, assume no dups in input
+            for (Klass k : entry.getValue()) {
+                impls.add(k.getClassName());
+            }
+        }
+        m.defaultView().addProviders(providesServices);
+
+        return requires;
+    }
+
+    // backedges (i.e. reverse dependences)
+    private final Map<Module.View, Set<Module>> backedges = new HashMap<>();
+    private void addDependence(Module from, Klass k, Map<String, Dependence> requires) {
+        Module dm = k.getModule().group();
+        Module.View view = dm.getView(k);
+        if (view == null)
+            throw new RuntimeException("No view exporting " + k);
+
+        addDependence(from, dm, view, requires);
+    }
+
+    private void addBackEdge(Module from, Module.View view) {
+        Set<Module> refs = backedges.get(view);
+        if (refs == null) {
+            backedges.put(view, refs = new HashSet<>());
+        }
+        refs.add(from);
+    }
+    private void addDependence(Module m, Dependence d, Map<String, Dependence> requires) {
+        Module other = factory().getModuleForView(d.name());
+        if (other == null) {
+            throw new RuntimeException(m.name() + " requires "
+                    + d.name() + "not found");
+        }
+        Module.View view = other.getView(d.name());
+        addDependence(m, other, view, requires, d.requiresOptional());
+    }
+
+    private void addDependence(Module from, Module to, Module.View view,
+                               Map<String, Dependence> requires) {
+        addDependence(from, to, view, requires, false);
+    }
+
+    private void addDependence(Module from, Module to, Module.View view,
+                               Map<String, Dependence> requires, boolean optional) {
+        assert from.group() != to.group();
+        addBackEdge(from, view);
+
+        if (view == to.internalView()) {
+            // if there is an optional dependence on the main view,
+            // make this an optional dependence
+            Dependence d = requires.get(to.group().name());
+            if (d != null && d.requiresOptional()) {
+                 optional= true;
+            }
+            view.addPermit(from.group().name());
+        }
+
+        String name = view.name;
+        Dependence dep = requires.get(name);
+        if (dep == null) {
+            Set<Dependence.Identifier> ids = optional ? EnumSet.of(OPTIONAL)
+                         : EnumSet.noneOf(Dependence.Identifier.class);
+            requires.put(name, dep = new Dependence(name, ids));
+        } else {
+            assert dep.name().equals(name);
+        }
+    }
+
+    public interface Visitor<R, P> {
+        R visitModule(Module m) throws IOException;
+    }
+
+    public <R, P> void visit(Visitor<R, P> visitor) throws IOException {
+        for (Module m : dependencesForModule.keySet()) {
+            visitor.visitModule(m);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/modules/tools/src/com/sun/tools/classanalyzer/ModuleConfig.java	Thu Aug 29 14:37:18 2013 -0700
@@ -0,0 +1,745 @@
+/*
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.classanalyzer;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.regex.Pattern;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+
+/**
+ * module config file parser
+ */
+public class ModuleConfig {
+    public static class View {
+        final String modulename;
+        final String name;
+        final Set<String> exports;
+        final Set<String> permits;
+        final Set<String> aliases;
+        final Map<String, Set<String>> providers;
+        String mainClass;
+
+        public View(String modulename, String name) {
+            this.modulename = modulename;
+            this.name = name;
+            this.exports = new HashSet<>();
+            this.permits = new HashSet<>();
+            this.aliases = new HashSet<>();
+            this.providers = new HashMap<>();
+        }
+
+        void addPermit(Module m) {
+            permits.add(m.name());
+        }
+    }
+
+    private final Set<String> roots;
+    private final Set<String> includes;
+    private final Map<String, Dependence> requires;
+    private final Filter filter;
+    private List<String> members;
+    final String module;
+    final String version;
+    final View defaultView;
+    final Map<String,View> viewForName;
+
+    ModuleConfig(String name, String version) {
+        this(name, version, null);
+    }
+
+    ModuleConfig(String name, String version, String mainClass)
+    {
+        assert name != null && version != null;
+
+        this.module = name;
+        this.version = version;
+        this.roots = new TreeSet<>();
+        this.includes = new TreeSet<>();
+        this.requires = new LinkedHashMap<>();
+        this.viewForName = new LinkedHashMap<>();
+        this.defaultView = newView(name);
+        this.filter = new Filter(this);
+    }
+
+    static ModuleConfig moduleConfigForUnknownModule() {
+        ModuleConfig mc = new ModuleConfig("unknown", "unknown");
+        mc.includes.add("**");
+        return mc;
+    }
+
+    List<String> members() {
+        if (members == null) {
+            members = new LinkedList<>();
+
+            for (String s : includes) {
+                if (!s.contains("*")) {
+                    // this isn't necessarily a module.  Will determine later.
+                    members.add(s);
+                }
+            }
+        }
+        return members;
+    }
+
+    Map<String, Dependence> requires() {
+        return requires;
+    }
+
+    private View newView(String name) {
+         View view = new View(module, name);
+         viewForName.put(name, view);
+         return view;
+    }
+
+    boolean matchesRoot(String name) {
+        for (String pattern : roots) {
+            if (matches(name, pattern)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    boolean matchesIncludes(String name) {
+        for (String pattern : includes) {
+            if (matches(name, pattern)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    boolean isExcluded(String name) {
+        return filter.isExcluded(name);
+    }
+
+    boolean matchesPackage(String packageName, String pattern) {
+        int pos = pattern.lastIndexOf('.');
+        String pkg = pos > 0 ? pattern.substring(0, pos) : "<unnamed>";
+        return packageName.equals(pkg);
+    }
+
+    boolean matches(String name, String pattern) {
+        if (pattern.contains("**") && !pattern.endsWith("**")) {
+            throw new UnsupportedOperationException("Not yet implemented");
+        }
+
+        String javaName = name;
+
+        boolean isResourceFile = name.indexOf('/') >= 0;
+        if (isResourceFile) {
+            // it's a resource file; convert the name as a java
+            javaName = name.replace('/', '.');
+        }
+        if (pattern.indexOf('/') < 0) {
+            // if the pattern doesn't contain '/
+            return matchesJavaName(javaName, pattern);
+        } else {
+            if (isResourceFile) {
+                // the pattern is for matching resource file
+                return matchesNameWithSlash(name, pattern);
+            } else {
+                return false;
+            }
+        }
+    }
+
+    boolean matchesJavaName(String name, String pattern) {
+        int pos = name.lastIndexOf('.');
+        String packageName = pos > 0 ? name.substring(0, pos) : "<unnamed>";
+        if (pattern.endsWith("**")) {
+            String p = pattern.substring(0, pattern.length() - 2);
+            return name.startsWith(p);
+        } else if (pattern.endsWith("*") && pattern.indexOf('*') == pattern.lastIndexOf('*')) {
+            if (matchesPackage(packageName, pattern)) {
+                // package name has to be exact match
+                String p = pattern.substring(0, pattern.length() - 1);
+                return name.startsWith(p);
+            } else {
+                return false;
+            }
+        } else if (pattern.contains("*")) {
+            String basename = pos > 0 ? name.substring(pos + 1, name.length()) : name;
+            pos = pattern.indexOf('*');
+            String prefix = pattern.substring(0, pos);
+            String suffix = pattern.substring(pos + 1, pattern.length());
+            if (name.startsWith(prefix) && matchesPackage(packageName, prefix)) {
+                // package name has to be exact match
+                if (suffix.contains("*")) {
+                    return name.matches(convertToRegex(pattern));
+                } else {
+                    return basename.endsWith(suffix);
+                }
+            } else {
+                // we don't support wildcard be used in the package name
+                return false;
+            }
+        } else {
+            // exact match or inner class
+            return name.equals(pattern) || name.startsWith(pattern + "$");
+        }
+    }
+
+    boolean matchesNameWithSlash(String name, String pattern) {
+        if (pattern.endsWith("**")) {
+            String p = pattern.substring(0, pattern.length() - 2);
+            return name.startsWith(p);
+        } else if (pattern.contains("*")) {
+            int pos = pattern.indexOf('*');
+            String prefix = pattern.substring(0, pos);
+            String suffix = pattern.substring(pos + 1, pattern.length());
+            if (!name.startsWith(prefix)) {
+                // prefix has to exact match
+                return false;
+            }
+
+            String tail = name.substring(pos, name.length());
+            if (pattern.indexOf('*') == pattern.lastIndexOf('*')) {
+                // exact match prefix with no '/' in the tail string
+                String wildcard = tail.substring(0, tail.length() - suffix.length());
+                return tail.indexOf('/') < 0 && tail.endsWith(suffix);
+            }
+
+            if (suffix.contains("*")) {
+                return matchesNameWithSlash(tail, suffix);
+            } else {
+                // tail ends with the suffix while no '/' in the wildcard matched string
+                String any = tail.substring(0, tail.length() - suffix.length());
+                return tail.endsWith(suffix) && any.indexOf('/') < 0;
+            }
+        } else {
+            // exact match
+            return name.equals(pattern);
+        }
+    }
+
+    private String convertToRegex(String pattern) {
+        StringBuilder sb = new StringBuilder();
+        int i = 0;
+        int index = 0;
+        int plen = pattern.length();
+        while (i < plen) {
+            char p = pattern.charAt(i);
+            if (p == '*') {
+                sb.append("(").append(pattern.substring(index, i)).append(")");
+                if (i + 1 < plen && pattern.charAt(i + 1) == '*') {
+                    sb.append(".*");
+                    index = i + 2;
+                } else {
+                    sb.append("[^\\.]*");
+                    index = i + 1;
+                }
+            }
+            i++;
+        }
+        if (index < plen) {
+            sb.append("(").append(pattern.substring(index, plen)).append(")");
+        }
+        return sb.toString();
+    }
+
+    static class Filter {
+
+        final ModuleConfig config;
+        final Set<String> exclude = new TreeSet<>();
+        final Set<String> allow = new TreeSet<>();
+
+        Filter(ModuleConfig config) {
+            this.config = config;
+        }
+
+        Filter exclude(String pattern) {
+            exclude.add(pattern);
+            return this;
+        }
+
+        Filter allow(String pattern) {
+            allow.add(pattern);
+            return this;
+        }
+
+        String allowedBy(String name) {
+            String allowedBy = null;
+            for (String pattern : allow) {
+                if (config.matches(name, pattern)) {
+                    if (name.equals(pattern)) {
+                        return pattern;  // exact match
+                    }
+                    if (allowedBy == null) {
+                        allowedBy = pattern;
+                    } else {
+                        if (pattern.length() > allowedBy.length()) {
+                            allowedBy = pattern;
+                        }
+                    }
+                }
+            }
+            return allowedBy;
+        }
+
+        String excludedBy(String name) {
+            String allowedBy = allowedBy(name);
+            String excludedBy = null;
+
+            if (allowedBy != null && name.equals(allowedBy)) {
+                return null;  // exact match
+            }
+            for (String pattern : exclude) {
+                if (config.matches(name, pattern)) {
+                    // not matched by allowed rule or exact match
+                    if (allowedBy == null || name.equals(pattern)) {
+                        return pattern;
+                    }
+                    if (excludedBy == null) {
+                        excludedBy = pattern;
+                    } else {
+                        if (pattern.length() > excludedBy.length()) {
+                            excludedBy = pattern;
+                        }
+                    }
+                }
+            }
+            return excludedBy;
+        }
+
+        boolean isExcluded(String name) {
+            String allowedBy = allowedBy(name);
+            String excludedBy = excludedBy(name);
+
+            if (excludedBy == null) {
+                return false;
+            }
+            // not matched by allowed rule or exact match
+            if (allowedBy == null || name.equals(excludedBy)) {
+                return true;
+            }
+
+            if (allowedBy == null) {
+                return true;
+            }
+            if (allowedBy != null &&
+                    excludedBy.length() > allowedBy.length()) {
+                return true;
+            }
+            return false;
+        }
+    }
+
+    private static String trimComment(String line) {
+        StringBuilder sb = new StringBuilder();
+
+        int pos = 0;
+        while (pos >= 0 && pos < line.length()) {
+            int c1 = line.indexOf("//", pos);
+            if (c1 > 0 && !Character.isWhitespace(line.charAt(c1 - 1))) {
+                // not a comment
+                c1 = -1;
+            }
+
+            int c2 = line.indexOf("/*", pos);
+            if (c2 > 0 && !Character.isWhitespace(line.charAt(c2 - 1))) {
+                // not a comment
+                c2 = -1;
+            }
+
+            int c = line.length();
+            int n = line.length();
+            if (c1 >= 0 || c2 >= 0) {
+                if (c1 >= 0) {
+                    c = c1;
+                }
+                if (c2 >= 0 && c2 < c) {
+                    c = c2;
+                }
+                int c3 = line.indexOf("*/", c2 + 2);
+                if (c == c2 && c3 > c2) {
+                    n = c3 + 2;
+                }
+            }
+            if (c > 0) {
+                if (sb.length() > 0) {
+                    // add a whitespace if multiple comments on one line
+                    sb.append(" ");
+                }
+                sb.append(line.substring(pos, c));
+            }
+            pos = n;
+        }
+        return sb.toString();
+    }
+
+    private static boolean beginBlockComment(String line) {
+        int pos = 0;
+        while (pos >= 0 && pos < line.length()) {
+            int c = line.indexOf("/*", pos);
+            if (c < 0) {
+                return false;
+            }
+
+            if (c > 0 && !Character.isWhitespace(line.charAt(c - 1))) {
+                return false;
+            }
+
+            int c1 = line.indexOf("//", pos);
+            if (c1 >= 0 && c1 < c) {
+                return false;
+            }
+
+            int c2 = line.indexOf("*/", c + 2);
+            if (c2 < 0) {
+                return true;
+            }
+            pos = c + 2;
+        }
+        return false;
+    }
+    // TODO: we shall remove "-" from the regex once we define
+    // the naming convention for the module names without dashes
+    static final Pattern classNamePattern = Pattern.compile("[\\w\\.\\*_$-/]+");
+
+    static List<ModuleConfig> readConfigurationFile(String file, String version) throws IOException {
+        List<ModuleConfig> result = new ArrayList<>();
+        // parse configuration file
+        try (FileInputStream in = new FileInputStream(file);
+             BufferedReader reader = new BufferedReader(new InputStreamReader(in)))
+        {
+            String line;
+            int lineNumber = 0;
+            boolean inRoots = false;
+            boolean inIncludes = false;
+            boolean inAllows = false;
+            boolean inExcludes = false;
+            boolean inPermits = false;
+            boolean inRequires = false;
+            boolean inProvides = false;
+            boolean inExports = false;
+            boolean inView = false;
+            Set<Dependence.Identifier> identifiers = new HashSet<>();
+
+            boolean inBlockComment = false;
+            ModuleConfig config = null;
+            View view = null;
+
+            while ((line = reader.readLine()) != null) {
+                lineNumber++;
+
+                if (inBlockComment) {
+                    int c = line.indexOf("*/");
+                    if (c >= 0) {
+                        line = line.substring(c + 2, line.length());
+                        inBlockComment = false;
+                    } else {
+                        // skip lines until end of comment block
+                        continue;
+                    }
+                }
+
+                inBlockComment = beginBlockComment(line);
+
+                line = trimComment(line).trim();
+                // ignore empty lines
+                if (line.length() == 0) {
+                    continue;
+                }
+
+                String values;
+                if (inRoots || inIncludes || inExcludes || inAllows ||
+                    inPermits || inRequires || inExports ) {
+                    values = line;
+                } else {
+                    String[] s = line.split("\\s+");
+                    String keyword = s[0].trim();
+                    int nextIndex = keyword.length();
+                    if (keyword.equals("module")) {
+                        if (s.length != 3 || !s[2].trim().equals("{")) {
+                            throw new RuntimeException(file + ", line " +
+                                    lineNumber + ", is malformed");
+                        }
+                        // use the given version
+                        String name = s[1].trim();
+                        config = new ModuleConfig(name, version);
+                        view = config.defaultView;
+
+                        result.add(config);
+                        // switch to a new module; so reset the flags
+                        inRoots = false;
+                        inIncludes = false;
+                        inExcludes = false;
+                        inAllows = false;
+                        inRequires = false;
+                        inPermits = false;
+                        inProvides = false;
+                        inExports = false;
+                        inView = false;
+                        continue;
+                    } else if (keyword.equals("class")) {
+                        if (s.length != 2 || !s[1].trim().endsWith(";")) {
+                            throw new RuntimeException(file + ", line "
+                                    + lineNumber + ", is malformed");
+                        }
+                        view.mainClass = s[1].substring(0, s[1].length() - 1);
+                        continue;
+                    } else if (keyword.equals("roots")) {
+                        inRoots = true;
+                    } else if (keyword.equals("include")) {
+                        inIncludes = true;
+                    } else if (keyword.equals("exclude")) {
+                        inExcludes = true;
+                    } else if (keyword.equals("allow")) {
+                        inAllows = true;
+                    } else if (keyword.equals("permits")) {
+                        inPermits = true;
+                    } else if (keyword.equals("provides")) {
+                        inProvides = true;
+                        if ((s.length != 2 && s.length != 5) ||
+                            (s.length == 5 &&
+                                (!s[1].trim().equals("service") || !s[3].trim().equals("with")))) {
+                            throw new RuntimeException(file + ", line "
+                                    + lineNumber + ", is malformed");
+                        }
+                    } else if (keyword.equals("exports")) {
+                        inExports = true;
+                    } else if (keyword.equals("requires")) {
+                        inRequires = true;
+                        identifiers.clear();
+                        String name = null;
+                        for (int i=1; i < s.length; i++) {
+                            String ss = s[i].trim();
+                            switch (ss) {
+                                case "public":
+                                    identifiers.add(Dependence.Identifier.PUBLIC);
+                                    break;
+                                case "optional":
+                                    identifiers.add(Dependence.Identifier.OPTIONAL);
+                                    break;
+                                case "service":
+                                    // default to requires optional service
+                                    identifiers.add(Dependence.Identifier.OPTIONAL);
+                                    identifiers.add(Dependence.Identifier.SERVICE);
+                                    break;
+                                default:
+                                    name = ss;
+                            }
+                            if (name == null) {
+                                nextIndex = line.indexOf(ss) + ss.length();
+                            } else {
+                                break;
+                            }
+                        }
+                    } else if (keyword.equals("view")) {
+                        if (s.length != 3 || !s[2].trim().equals("{")) {
+                            throw new RuntimeException(file + ", line " +
+                                    lineNumber + ", is malformed");
+                        }
+
+                        // use the given version
+                        inView = true;
+                        String name = s[1].trim();
+                        view = config.newView(name);
+                        continue;
+                    } else if (keyword.equals("}")) {
+                        if (config == null || s.length != 1) {
+                            throw new RuntimeException(file + ", line " +
+                                    lineNumber + ", is malformed");
+                        } else if (inView) {
+                            inView = false;
+                            view = config.defaultView;
+                        } else {
+                            // end of a module
+                            config = null;
+                            view = null;
+                        }
+                         continue;
+                    } else {
+                        throw new RuntimeException(file + ", \"" + keyword + "\" on line " +
+                                lineNumber + ", is not recognized");
+                    }
+
+                    values = line.substring(nextIndex, line.length()).trim();
+                }
+
+                if (config == null) {
+                    throw new RuntimeException(file + ", module not specified");
+                }
+
+                int len = values.length();
+                if (len == 0) {
+                    continue;
+                }
+                char lastchar = values.charAt(len - 1);
+                if (lastchar != ',' && lastchar != ';') {
+                    throw new RuntimeException(file + ", line " +
+                            lineNumber + ", is malformed:" +
+                            " ',' or ';' is missing.");
+                }
+
+                values = values.substring(0, len - 1);
+                // parse the values specified for a keyword specified
+                for (String s : values.split(",")) {
+                    s = s.trim();
+                    if (s.length() > 0) {
+                        if (!classNamePattern.matcher(s).matches() && !inProvides) {
+                            throw new RuntimeException(file + ", line " +
+                                    lineNumber + ", is malformed: \"" + s + "\"");
+                        }
+                        if (inRoots) {
+                            config.roots.add(s);
+                        } else if (inIncludes) {
+                            config.includes.add(s);
+                        } else if (inExcludes) {
+                            config.filter.exclude(s);
+                        } else if (inAllows) {
+                            config.filter.allow(s);
+                        } else if (inPermits) {
+                            view.permits.add(s);
+                        } else if (inProvides) {
+                            if (s.startsWith("service")) {
+                                String[] names = values.split("\\s+");
+                                assert names.length == 4;
+                                Set<String> providers = view.providers.get(names[1]);
+                                if (providers == null) {
+                                    view.providers.put(names[1], providers = new LinkedHashSet<>());
+                                }
+                                providers.add(names[3]);
+                            } else {
+                                view.aliases.add(s);
+                            }
+                        } else if (inExports) {
+                            String e = s.equals("**") ? "*" : s;
+                            view.exports.add(e);
+                        } else if (inRequires) {
+                            if (config.requires.containsKey(s)) {
+                                throw new RuntimeException(file + ", line "
+                                        + lineNumber + " duplicated requires: \"" + s + "\"");
+                            }
+                            Dependence d = new Dependence(s, identifiers);
+                            config.requires.put(s, d);
+                        }
+                    }
+                }
+                if (lastchar == ';') {
+                    inRoots = false;
+                    inIncludes = false;
+                    inExcludes = false;
+                    inAllows = false;
+                    inPermits = false;
+                    inProvides = false;
+                    inRequires = false;
+                    inExports = false;
+                }
+            }
+
+            if (inBlockComment) {
+                throw new RuntimeException(file + ", line " +
+                        lineNumber + ", missing \"*/\" to end a block comment");
+            }
+            if (config != null) {
+                throw new RuntimeException(file + ", line " +
+                        lineNumber + ", missing \"}\" to end module definition" +
+                        " for \"" + config.module + "\"");
+            }
+        }
+
+        return result;
+    }
+
+    private String formatServices(int level, String keyword, Map<String, Set<String>> services) {
+        if (services.isEmpty()) {
+            return "";
+        }
+
+        StringBuilder sb = new StringBuilder();
+        String format = level == 1 ? "%4s%-9s" : "%8s%-9s";
+        String spaces = String.format(format, "", "");
+        sb.append(String.format(format, "", keyword));
+        int count = 0;
+        for (Map.Entry<String, Set<String>> e : services.entrySet()) {
+            String s = " service " + e.getKey() + " with ";
+            for (String v : e.getValue()) {
+                sb.append(keyword).append(s).append(v).append(";\n");
+            }
+        }
+        return sb.toString();
+    }
+
+    private String format(int level, String keyword, Collection<String> values) {
+        if (values.size() == 0) {
+            return "";
+        }
+
+        StringBuilder sb = new StringBuilder();
+        String format = level == 1 ? "%4s%-9s" : "%8s%-9s";
+        String spaces = String.format(format, "", "");
+        sb.append(String.format(format, "", keyword));
+        int count = 0;
+        for (String s : values) {
+            if (count > 0) {
+                sb.append(",\n").append(spaces);
+            } else if (count++ > 0) {
+                sb.append(", ");
+            }
+            sb.append(s);
+        }
+        if (count > 0) {
+            sb.append(";\n");
+        }
+        return sb.toString();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("module " + module).append(" {\n");
+        sb.append(format(1, "include", includes));
+        sb.append(format(1, "root", roots));
+        sb.append(format(1, "allow", filter.allow));
+        sb.append(format(1, "exclude", filter.exclude));
+        Set<String> reqs = new TreeSet<>();
+        for (Dependence rm : requires.values()) {
+            reqs.add(rm.toString());
+        }
+        sb.append(format(1, "requires", reqs));
+        for (View v : viewForName.values()) {
+            sb.append("    ").append("view ").append(v.name).append(" {\n");
+            sb.append(format(2, "permits", v.permits));
+            sb.append(format(2, "exports", v.exports));
+            sb.append(format(2, "provides", v.aliases));
+            sb.append(formatServices(2, "provides", v.providers));
+        }
+        sb.append("}\n");
+        return sb.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/modules/tools/src/com/sun/tools/classanalyzer/Package.java	Thu Aug 29 14:37:18 2013 -0700
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.classanalyzer;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Package Information
+ */
+public class Package implements Comparable<Package> {
+    private final String pkgName;
+    final Module module;
+    boolean isExported;
+    int  classCount;
+    long classBytes;
+    int  resourceCount;
+    long resourceBytes;
+    private int publicClassCount;
+    Package(String name, Module m) {
+        this.pkgName = name;
+        this.module = m;
+        this.isExported = isExportedPackage(name);
+    }
+
+    String name() {
+        return pkgName;
+    }
+
+    boolean hasPublicClasses() {
+        return publicClassCount > 0;
+    }
+    void addKlass(Klass k) {
+        classCount++;
+        classBytes += k.getFileSize();
+        if (k.isPublic()) {
+            publicClassCount++;
+        }
+    }
+
+    void addResource(Resource r) {
+        resourceCount++;
+        resourceBytes += r.getFileSize();
+    }
+
+    void merge(Package p) {
+        if (!pkgName.equals(p.pkgName) || module.group() != p.module.group()) {
+            throw new IllegalArgumentException(this + " != " + p);
+        }
+        classCount += p.classCount;
+        classBytes += p.classBytes;
+        resourceCount += p.resourceCount;
+        resourceBytes += p.resourceBytes;
+        publicClassCount += p.publicClassCount;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 5;
+        hash = 59 * hash + (this.module != null ? this.module.hashCode() : 0);
+        hash = 59 * hash + (this.pkgName != null ? this.pkgName.hashCode() : 0);
+        return hash;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o instanceof Package) {
+            Package p = (Package) o;
+            return p.module.equals(this.module) && p.pkgName.equals(this.pkgName);
+        }
+        return false;
+    }
+
+    @Override
+    public int compareTo(Package p) {
+        if (this.equals(p)) {
+            return 0;
+        } else if (pkgName.compareTo(p.pkgName) == 0) {
+            return module.compareTo(p.module);
+        } else {
+            return pkgName.compareTo(p.pkgName);
+        }
+    }
+
+    @Override
+    public String toString() {
+        return pkgName + " : " + module.name();
+    }
+    private final static Set<String> exportedPackages = new HashSet<String>();
+    static {
+        // if exported.packages property is not set,
+        // exports all packages
+        String apis = Module.getModuleProperty("exported.packages");
+        if (apis != null) {
+            for (String s : apis.split("\\s+")) {
+                exportedPackages.add(s.trim());
+            }
+        }
+    }
+
+    static boolean isExportedPackage(String pkg) {
+        return exportedPackages.isEmpty() || exportedPackages.contains(pkg);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/modules/tools/src/com/sun/tools/classanalyzer/Resource.java	Thu Aug 29 14:37:18 2013 -0700
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2009, 20013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.tools.classanalyzer;
+
+import java.io.File;
+import java.io.InputStream;
+
+/**
+ *
+ */
+public class Resource implements Comparable<Resource> {
+    private final String pathname;
+    private final long filesize;
+    protected final String name;
+    Module module;
+    Resource(String fname) {
+        this(fname, 0);
+    }
+
+    Resource(String fname, long size) {
+        this.pathname = fname.replace('/', File.separatorChar);
+        this.name = fname.replace(File.separatorChar, '/');
+        this.filesize = size;
+    }
+
+    String getName() {
+        return name;
+    }
+
+    String getPathname() {
+        return pathname;
+    }
+
+    long getFileSize() {
+        return filesize;
+    }
+
+    boolean isService() {
+        return false;
+    }
+
+
+    Module getModule() {
+        return module;
+    }
+
+    void setModule(Module m) {
+        if (module != null) {
+            throw new RuntimeException("Module for " + this + " already set");
+        }
+        this.module = m;
+    }
+
+    @Override
+    public String toString() {
+        return name;
+    }
+
+    @Override
+    public int compareTo(Resource o) {
+        return name.compareTo(o.name);
+    }
+
+    static boolean isResource(String pathname) {
+        // skip these files
+        String name = pathname.replace(File.separatorChar, '/');
+        if (name.endsWith("META-INF/MANIFEST.MF")) {
+            return false;
+        }
+        if (name.contains("META-INF/JCE_RSA.")) {
+            return false;
+        }
+        if (name.contains("META-INF/") &&
+                (name.endsWith(".RSA") || name.endsWith(".SF"))) {
+            return false;
+        }
+
+        return true;
+    }
+
+    static Resource getResource(String fname, InputStream in, long size) {
+        Resource res;
+        fname = fname.replace(File.separatorChar, '/');
+        if (fname.startsWith(Service.METAINF_SERVICES)) {
+            res = Service.loadProviderConfig(fname, in, size);
+        } else {
+            res = new Resource(fname, size);
+        }
+        return res;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/modules/tools/src/com/sun/tools/classanalyzer/Service.java	Thu Aug 29 14:37:18 2013 -0700
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.tools.classanalyzer;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ */
+public class Service {
+    final Klass service;
+    public Service(Klass s) {
+        this.service = s;
+    }
+
+    public String toString() {
+        return "service " + service.getClassName();
+    }
+
+    public static Resource loadProviderConfig(String fname, InputStream in, long size) {
+        return new ProviderConfigFile(fname, in, size);
+    }
+
+    static final String METAINF_SERVICES = "META-INF/services";
+    static final String METAINF_SERVICES_PATH =
+            METAINF_SERVICES.replace('/', File.separatorChar);
+
+    public static class ProviderConfigFile extends Resource {
+        final List<String> providers = new ArrayList<>();
+        final String service;
+
+        ProviderConfigFile(String fname, InputStream in) {
+            this(fname, in, 0);
+        }
+
+        ProviderConfigFile(String fname, InputStream in, long size) {
+            super(fname, size);
+            readServiceConfiguration(in, providers);
+            this.service = name.substring(METAINF_SERVICES.length() + 1, name.length());
+        }
+
+        @Override
+        boolean isService() {
+            return true;
+        }
+
+        String getName() {
+            return service;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o instanceof ProviderConfigFile) {
+                ProviderConfigFile sp = (ProviderConfigFile) o;
+                if (service.equals(sp.service) && providers.size() == sp.providers.size()) {
+                    List<String> tmp = new ArrayList<String>(providers);
+                    if (tmp.removeAll(sp.providers)) {
+                        return tmp.size() == 0;
+                    }
+                }
+            }
+            return false;
+        }
+
+        public int hashCode() {
+            int hash = 7;
+            hash = 73 * hash + (this.providers != null ? this.providers.hashCode() : 0);
+            hash = 73 * hash + (this.service != null ? this.service.hashCode() : 0);
+            return hash;
+        }
+
+        @Override
+        public int compareTo(Resource o) {
+            if (this.equals(o)) {
+                return 0;
+            } else {
+                if (getName().compareTo(o.getName()) < 0) {
+                    return -1;
+                } else {
+                    return 1;
+                }
+            }
+        }
+
+        @SuppressWarnings("empty-statement")
+        void readServiceConfiguration(InputStream in, List<String> names) {
+            try (BufferedReader br = new BufferedReader(new InputStreamReader(in, "utf-8"))) {
+                int lc = 1;
+                while ((lc  = parseLine(br, lc, names)) >= 0);
+            } catch (IOException ex) {
+                throw new RuntimeException(ex);
+            }
+        }
+
+        // Parse a single line from the given configuration file, adding the name
+        // on the line to the names list.
+        //
+        private int parseLine(BufferedReader r, int lc, List<String> names) throws IOException {
+            String ln = r.readLine();
+            if (ln == null) {
+                return -1;
+            }
+            int ci = ln.indexOf('#');
+            if (ci >= 0) {
+                ln = ln.substring(0, ci);
+            }
+            ln = ln.trim();
+            int n = ln.length();
+            if (n != 0) {
+                if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0)) {
+                    throw new RuntimeException("Illegal configuration-file syntax");
+                }
+                int cp = ln.codePointAt(0);
+                if (!Character.isJavaIdentifierStart(cp)) {
+                    throw new RuntimeException("Illegal provider-class name: " + ln);
+                }
+                for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) {
+                    cp = ln.codePointAt(i);
+                    if (!Character.isJavaIdentifierPart(cp) && (cp != '.')) {
+                        throw new RuntimeException("Illegal provider-class name: " + ln);
+                    }
+                }
+                if (!names.contains(ln)) {
+                    names.add(ln);
+                }
+            }
+            return lc + 1;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/modules/tools/src/com/sun/tools/classanalyzer/resources/classanalyzer.properties	Thu Aug 29 14:37:18 2013 -0700
@@ -0,0 +1,34 @@
+main.usage.summary=\
+Usage: {0} <options>\n\
+use -h, -? or --help for a list of possible options
+
+main.usage=\
+Usage: {0} <options>\n\
+
+error.prefix=Error:
+warn.prefix=Warning:
+
+main.opt.h=\
+\  -h -?      --help                    Print this usage message
+
+main.opt.V=\
+\  -j         --javahome=<javahome>     JAVA_HOME to be analyzed
+
+main.opt.v=\
+\  -v         --version                 Module version
+
+main.opt.c=\
+\  -c <path>  --classlist=<dir>        Specify the directory to write the classlist
+
+main.opt.d=\
+\  -d <depth> --moduleinfo=<dir>       Specify the directory to write the module-info.java
+
+main.opt.o=\
+\  -o <path>  --out=<path>             Specify the path for the serialized module.config
+
+err.unknown.option=unknown option: {0}
+err.missing.arg=no value given for {0}
+err.internal.error=internal error: {0} {1} {2}
+err.option.unsupported={0} not supported: {1}
+warn.invalid.arg=Invalid classname or pathname not exist: {0}
+
--- a/makefiles/BuildJdk.gmk	Wed Aug 21 05:56:46 2013 -0400
+++ b/makefiles/BuildJdk.gmk	Thu Aug 29 14:37:18 2013 -0700
@@ -74,13 +74,19 @@
 #       Finally compile the launchers.
 	+$(MAKE) -f CompileLaunchers.gmk
 
+genmodules-only:
+#       Generate static module graph
+	+$(MAKE) -f GenerateModules.gmk
+
+genmodules: genmodules-only
+
 genclasses: launchers genclasses-only
 genclasses-only:
 #	Generate classes that have other sources. Needs
 #       to execute launchers.
 	+$(MAKE) -f GenerateClasses.gmk
 
-jdk: genclasses
+jdk: genclasses genmodules
 #       Now we have a complete jdk, which you can run.
 #       It is not yet wrapped up as an installed image.
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/makefiles/GenerateModules.gmk	Thu Aug 29 14:37:18 2013 -0700
@@ -0,0 +1,65 @@
+#
+# 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.
+#
+
+# Default target declared first
+default: all
+
+include $(SPEC)
+include ModulesCommon.gmk
+include MakeBase.gmk
+include JavaCompilation.gmk
+include Setup.gmk
+
+MODULES_CONFIG      := $(JDK_TOPDIR)/make/modules/modules.config
+MODULES_GROUP       := $(JDK_TOPDIR)/make/modules/modules.group
+MODULES_PROPERTIES  := $(JDK_TOPDIR)/make/modules/modules.properties
+CLASSANALYZER_CLASSES  := $(GENMODULES_DIR)/bt_classanalyzer_classes
+CLASSANALYZER_RESOURCES := $(CLASSANALYZER_CLASSES)/com/sun/tools/classanalyzer/resources
+MODULES_SER_OUT   := $(JDK_OUTPUTDIR)/classes/jdk/jigsaw/module/resources/modules.ser
+
+$(eval $(call SetupJavaCompilation,BUILD_CLASSANALYZER,\
+       SETUP:=GENERATE_JDKBYTECODE,\
+       SRC:=$(JDK_TOPDIR)/make/modules/tools/src,\
+       BIN:=$(CLASSANALYZER_CLASSES)))
+
+all: $(MODULES_LIST)
+
+$(CLASSANALYZER_CLASSES)/com/sun/tools/classanalyzer/resources/% : $(JDK_TOPDIR)/make/modules/tools/src/com/sun/tools/classanalyzer/resources/%
+	$(call install-file)
+
+$(MODULES_LIST): $(MODULES_CONFIG) $(MODULES_GROUP) \
+                 $(MODULES_PROPERTIES) \
+                 $(BUILD_CLASSANALYZER) \
+		 $(CLASSANALYZER_RESOURCES)/classanalyzer.properties
+	$(TOOL_CLASSANALYZER) \
+                --config $(MODULES_CONFIG) \
+                --config $(MODULES_GROUP) \
+                --properties $(MODULES_PROPERTIES) \
+                --version $(MODULE_VERSION) \
+                --classlist $(MODULE_CLASSLIST_DIR) \
+                --out $(MODULES_SER_OUT) \
+                --moduleinfo $(MODULEINFO_DIR)
+
+.NOTPARALLEL:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/makefiles/ModulesCommon.gmk	Thu Aug 29 14:37:18 2013 -0700
@@ -0,0 +1,51 @@
+#
+# 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.
+#
+
+# Default target declared first
+default: all
+
+include $(SPEC)
+
+# Most, if not all of this will be moved elsewhere.
+
+# Temporary copy of contents from Defs-modules.gmk. Need to figure out where
+# this should be defined.
+GENMODULES_DIR       := $(JDK_OUTPUTDIR)/genmodules
+SUBMODULES_DIR       := $(GENMODULES_DIR)/submodules
+MODULEINFO_DIR       := $(GENMODULES_DIR)/src
+MODULE_CLASSLIST_DIR := $(GENMODULES_DIR)/classlist
+MODULES_LIST         := $(MODULE_CLASSLIST_DIR)/modules.list
+
+# This needs to go into spec at least
+# RELEASE is JDK_VERSION and -MILESTONE if MILESTONE is set
+ifneq ($(MILESTONE),fcs)
+  MODULE_VERSION = ${JDK_MINOR_VERSION}-ea
+else
+  MODULE_VERSION = ${JDK_MINOR_VERSION}
+endif
+
+TOOL_CLASSANALYZER=$(BUILD_JAVA) -esa -ea -cp $(GENMODULES_DIR)/bt_classanalyzer_classes \
+        com.sun.tools.classanalyzer.ClassAnalyzer
+
--- a/makefiles/profile-rtjar-includes.txt	Wed Aug 21 05:56:46 2013 -0400
+++ b/makefiles/profile-rtjar-includes.txt	Thu Aug 29 14:37:18 2013 -0700
@@ -71,7 +71,8 @@
     sun/usagetracker \
     sun/util
 
-PROFILE_1_RTJAR_INCLUDE_TYPES := 
+PROFILE_1_RTJAR_INCLUDE_TYPES := \
+    jdk/jigsaw/module/resources/modules.ser
 
 PROFILE_1_RTJAR_EXCLUDE_TYPES := 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/jigsaw/module/JdkModules.java	Thu Aug 29 14:37:18 2013 -0700
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+import java.io.*;
+import java.util.*;
+import static java.lang.System.out;
+
+import jdk.jigsaw.module.*;
+
+import org.testng.annotations.*;
+import static org.testng.Assert.*;
+
+@Test
+public class JdkModules {
+    private static final String MODULES_SER = "jdk/jigsaw/module/resources/modules.ser";
+    private boolean testBase(Module m) throws Exception {
+        assertEquals(m.mainView().aliases(), Collections.singleton(ViewId.parse("java.base")));
+
+        // base module only has optional dependences
+        m.viewDependences().stream().forEach(vd -> {
+            assertEquals(vd.modifiers(), EnumSet.of(ViewDependence.Modifier.OPTIONAL));
+        });
+
+        return true;
+    }
+
+    public void go() throws Exception {
+        Set<Module> modules = new HashSet<>();
+        try (ObjectInputStream sin = new ObjectInputStream(
+                 ClassLoader.getSystemResourceAsStream(MODULES_SER)))
+        {
+            modules.addAll(Arrays.asList((Module[]) sin.readObject()));
+        }
+
+        // do sanity test for the base module for now
+        for (Module m : modules) {
+            if (m.id().name().equals("jdk.base")) {
+                testBase(m);
+            }
+        }
+    }
+
+}