changeset 1842:f9e6d666883e default tip

Merge
author mchung
date Tue, 07 May 2013 17:14:17 -0700
parents a1e10f3adc47 (current diff) 2985b07bd288 (diff)
children
files .hgtags .jcheck/conf make/build.properties make/build.xml makefiles/BuildLangtools.gmk src/share/classes/com/sun/source/tree/Tree.java src/share/classes/com/sun/source/tree/TreeVisitor.java src/share/classes/com/sun/source/util/SimpleTreeVisitor.java src/share/classes/com/sun/source/util/TreeScanner.java src/share/classes/com/sun/tools/classfile/AccessFlags.java src/share/classes/com/sun/tools/classfile/ClassWriter.java src/share/classes/com/sun/tools/javac/code/Flags.java src/share/classes/com/sun/tools/javac/code/Printer.java src/share/classes/com/sun/tools/javac/code/Source.java src/share/classes/com/sun/tools/javac/code/Symbol.java src/share/classes/com/sun/tools/javac/code/Symtab.java src/share/classes/com/sun/tools/javac/code/Type.java src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java src/share/classes/com/sun/tools/javac/code/Types.java src/share/classes/com/sun/tools/javac/comp/Attr.java src/share/classes/com/sun/tools/javac/comp/Check.java src/share/classes/com/sun/tools/javac/comp/Flow.java src/share/classes/com/sun/tools/javac/comp/Lower.java src/share/classes/com/sun/tools/javac/comp/MemberEnter.java src/share/classes/com/sun/tools/javac/comp/Resolve.java src/share/classes/com/sun/tools/javac/jvm/ClassReader.java src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java src/share/classes/com/sun/tools/javac/jvm/Pool.java src/share/classes/com/sun/tools/javac/jvm/Target.java src/share/classes/com/sun/tools/javac/main/JavaCompiler.java src/share/classes/com/sun/tools/javac/main/Main.java src/share/classes/com/sun/tools/javac/main/Option.java src/share/classes/com/sun/tools/javac/model/JavacElements.java src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java src/share/classes/com/sun/tools/javac/parser/JavacParser.java src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java src/share/classes/com/sun/tools/javac/resources/compiler.properties src/share/classes/com/sun/tools/javac/resources/javac.properties src/share/classes/com/sun/tools/javac/tree/JCTree.java src/share/classes/com/sun/tools/javac/tree/TreeInfo.java src/share/classes/com/sun/tools/javac/util/Names.java src/share/classes/com/sun/tools/javap/AttributeWriter.java src/share/classes/com/sun/tools/javap/ClassWriter.java src/share/classes/com/sun/tools/javap/JavapTask.java src/share/classes/com/sun/tools/javap/Options.java src/share/classes/javax/lang/model/element/Element.java src/share/classes/javax/lang/model/element/Modifier.java src/share/classes/javax/lang/model/type/TypeKind.java test/tools/javac/T6558476.java
diffstat 157 files changed, 11573 insertions(+), 609 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Thu Apr 25 09:24:40 2013 -0700
+++ b/.hgtags	Tue May 07 17:14:17 2013 -0700
@@ -30,6 +30,7 @@
 dbdeb4a7581b2a8699644b91cae6793cb01953f7 jdk7-b53
 197a7f881937d406a01214aa9ded49c073f7d380 jdk7-b54
 7394a8694cedea574c7dbd38de87f4cbe0e27b8a jdk7-b55
+9359f5d705289c8680748d11bc80978edc957ba1 j1-2009-demo
 825f23a4f262eb06cfc94406140f3bfecb17ffe8 jdk7-b56
 4030cc469205bbd517ca629fb170afb81760bbc5 jdk7-b57
 5bcac54d408b436d2364925ee7947b5609e07962 jdk7-b58
@@ -68,6 +69,11 @@
 97b6fa97b8ddb3a49394011c2a0ec5d6535e594c jdk7-b91
 98cba5876cb50fa3c58a313ddd668f5014ff14f6 jdk7-b92
 683cd1f6bc4b562b0ddf29d5f80f05c2123b76b0 jdk7-b93
+51b53bc20417668e7e9a013238d3079f3df1800f jigsaw-b01
+e2879c758bac08ca28218f781b8baccb8e07256f jigsaw-b03
+1d3e1ab9bfccc6c297ee5bb4f2231dbb4c88be5a jigsaw-b04
+71bc65043b3579ad26a3464e1a6dd1cd37c87cf4 jigsaw-b05
+2c30424a82834d0b7ad45adb7de4404e1d43e9f7 jigsaw-b06
 bb3d7c75a56df0c00246072b996fad1858a771a1 jdk7-b94
 752bb790fc2d6df91e91d84420c9c87136eb81eb jdk7-b95
 89cd267c216751bdacf8629bb07a40c0950fc4f2 jdk7-b96
--- a/.jcheck/conf	Thu Apr 25 09:24:40 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-project=jdk8
--- a/make/build.properties	Thu Apr 25 09:24:40 2013 -0700
+++ b/make/build.properties	Tue May 07 17:14:17 2013 -0700
@@ -44,10 +44,13 @@
 target.java = ${target.java.home}/bin/java
 
 # Version info -- override as needed
-jdk.version = 1.7.0
+jdk.version = 1.8.0
 build.number = b00
 milestone = internal
 
+# version for modules
+module.version = 8-ea
+
 # FIXME -- these need to match the standard values
 # If we include date in full.version (ie for developer build)
 # we will need to make sure the build is idempotent (i.e.
@@ -68,7 +71,12 @@
 # set the following to -version to verify the versions of javac being used
 javac.version.opt =
 # in time, there should be no exceptions to -Xlint:all
-javac.lint.opts = -Xlint:all -Werror
+#
+# NOTE: rawtypes warnings temporarily disabled because of warnings generated by
+# use of diamond operator in generated stubs.
+#
+#javac.lint.opts = -Xlint:all -Werror
+javac.lint.opts = -Xlint:all,-rawtypes,-options -Werror
 
 # options for the <javadoc> task for javac
 #javadoc.jls3.url=http://java.sun.com/docs/books/jls/
@@ -124,6 +132,33 @@
 javac.tests = \
         tools/javac
 
+# Additional modules for langtools public API
+
+javax.tools.module.name = jdk.compiler
+javax.tools.module.includes = \
+    javax/tools/** \
+    javax/lang/model/** \
+    javax/annotation/processing/**
+
+#
+
+langtools.module.name = jdk.devtools
+langtools.module.includes = \
+    com/sun/source/** \
+    com/sun/tools/javac/** \
+    com/sun/tools/javah/** \
+    com/sun/tools/javap/** \
+    com/sun/tools/classfile/** \
+    com/sun/javadoc/** \
+    com/sun/tools/doclets/** \
+    com/sun/tools/javadoc/**
+
+#
+
+mirror.module.name = jdk.mirror
+mirror.module.includes = \
+    com/sun/mirror/**
+
 #
 
 javadoc.includes = \
@@ -141,6 +176,8 @@
 doclets.tests = \
         com/sun/javadoc/
 
+# doclets are included in javadoc module
+
 #
 
 javah.includes = \
@@ -174,25 +211,15 @@
 # The API can be provided by using a suitable boot.java.home
 # or by setting import.jdk
 require.latest.jdk.files = \
-    com/sun/tools/javac/nio/*.java
+    com/sun/tools/javac/jigsaw/*.java
 
 # The following files in the import jdk source directory are required
 # in order to compile the files defined in ${require.latest.jdk.files}
 #
-# For NIO, the list of stub files is defined by the contents of the primary
-# API packages, together with such types that may be required in order to
-# compile the stubs. Some of these dependencies would go away if the stub
-# generator were to be improved -- e.g. by removing unnecessary imports.
-#
 import.jdk.stub.files = \
-    java/io/File.java \
-    java/nio/file/**.java \
-    java/nio/file/attribute/**.java \
-    java/nio/file/spi/**.java \
-    java/nio/channels/AsynchronousChannel.java \
-    java/nio/channels/AsynchronousFileChannel.java \
-    java/nio/channels/CompletionHandler.java \
-    java/nio/channels/SeekableByteChannel.java
+    java/lang/module/**.java \
+    java/lang/reflect/Module.java \
+    org/openjdk/jigsaw/**.java
 
 # The following value is used by the main jtreg target.
 # An empty value means all tests
@@ -202,3 +229,7 @@
 # Check style configuration
 # overridable name and version
 checkstyle.name.version = checkstyle-5.4
+
+# Set the verbosity used for displaying bootstrap.opts. The value should
+# be suitable for the level attribute of the echo task.
+bootstrap.opts.verbose=verbose
--- a/make/build.xml	Thu Apr 25 09:24:40 2013 -0700
+++ b/make/build.xml	Tue May 07 17:14:17 2013 -0700
@@ -120,12 +120,14 @@
     <!-- Convenient shorthands for standard locations within the workspace. -->
     <property name="build.dir" location="build"/>
     <property name="build.bootstrap.dir" location="${build.dir}/bootstrap"/>
+    <property name="build.bootstrap.lib.dir" location="${build.dir}/bootstrap/lib"/>
     <property name="build.coverage.dir" location="${build.dir}/coverage"/>
     <property name="build.classes.dir" location="${build.dir}/classes"/>
     <property name="build.gensrc.dir" location="${build.dir}/gensrc"/>
     <property name="build.genstubs.dir" location="${build.dir}/genstubs"/>
     <property name="build.javadoc.dir" location="${build.dir}/javadoc"/>
     <property name="build.jtreg.dir" location="${build.dir}/jtreg"/>
+    <property name="build.modules.dir" location="${build.dir}/modules"/>
     <property name="build.toolclasses.dir" location="${build.dir}/toolclasses"/>
     <property name="dist.dir" location="dist"/>
     <property name="dist.bin.dir" location="${dist.dir}/bin"/>
@@ -154,15 +156,36 @@
     <!-- Standard property values, if not overriden by earlier settings. -->
     <property file="${make.dir}/build.properties"/>
 
-    <!-- launcher.java is used in the launcher scripts provided to run
-        the tools' jar files.  If it has not already been set, then
-        default it to use ${target.java.home}, if available, otherwise
-        quietly default to simply use "java". -->
-    <condition property="launcher.java"
-        value="${target.java.home}/bin/java" else="java">
-        <isset property="target.java.home"/>
+
+    <!-- Characteristics of boot.java.home. -->
+
+    <!-- If ${boot.java.home} is a modular image, then we need to build modules
+         during the bootstrap phase for use in the second phase. -->
+    <condition property="boot.java.provides.modules">
+        <available file="${boot.java.home}/lib/modules/%jigsaw-library" type="file"/>
     </condition>
 
+    <!-- If ${boot.java.home} contains the latest JDK API, we don't need to generate stubs
+         in order to compile the javac files that use the latest API. -->
+    <condition property="boot.java.provides.latest.jdk">
+        <or>
+            <isset property="boot.java.provides.modules"/>
+            <available
+                ignoresystemclasses="true"
+                classpath="${boot.java.home}/jre/lib/rt.jar" classname="java.lang.module.ModuleInfo"/>
+        </or>
+    </condition>
+
+
+    <!-- Characteristics of target.java.home (if set). -->
+
+    <!-- If ${target.java.home} is a modular image, then we need to generate modules
+         in the second phase for use by the langtools launcher scripts. -->
+    <condition property="target.java.provides.modules">
+        <available file="${target.java.home}/lib/modules/%jigsaw-library" type="file"/>
+    </condition>
+
+
     <!-- Logic for handling access import jdk classes, if available.
         import.jdk should be unset, or set to jdk home (to use rt.jar)
         or to jdk repo (to use src/share/classes).
@@ -171,39 +194,14 @@
         in the build-bootstrap-classes macro. -->
 
     <available property="import.jdk.src.dir" value="${import.jdk}/src/share/classes"
-        filepath="${import.jdk}/src/share/classes" file="java/nio/file/Path.java"/>
+        filepath="${import.jdk}/src/share/classes" file="java/lang/module/ModuleInfo.java"/>
     <available property="import.jdk.jar" value="${import.jdk}/jre/lib/rt.jar"
         ignoresystemclasses="true"
-        classpath="${import.jdk}/jre/lib/rt.jar" classname="java.nio.file.Path"/>
+        classpath="${import.jdk}/jre/lib/rt.jar" classname="java.lang.module.ModuleInfo"/>
 
-    <!-- Set the default bootclasspath option used for javac.
-        Note that different variants of the option are used, meaning we can't just
-        define the value for the option.
-        Note the explicit use of the standard property ${path.separator} in the following.
-        This is because Ant is not clever enough to handle direct use of : or ; -->
-    <condition property="javac.bootclasspath.opt"
-            value="-Xbootclasspath:${build.classes.dir}${path.separator}${import.jdk.jar}"
-            else="-Xbootclasspath/p:${build.classes.dir}">
-        <isset property="import.jdk.jar"/>
-    </condition>
 
-    <condition property="boot.java.provides.latest.jdk">
-        <available
-            ignoresystemclasses="true"
-            classpath="${boot.java.home}/jre/lib/rt.jar" classname="java.nio.file.Path"/>
-    </condition>
-
-    <condition property="bootstrap.exclude.files" value="" else="${require.latest.jdk.files}">
-        <isset property="boot.java.provides.latest.jdk"/>
-    </condition>
-
-    <condition property="exclude.files" value="" else="${require.latest.jdk.files}">
-        <or>
-            <isset property="boot.java.provides.latest.jdk"/>
-            <isset property="import.jdk"/>
-        </or>
-    </condition>
-
+    <!-- Require stubs if ${boot.java.home} does not provide latest JDK API and
+         ${import.jdk} is set to jdk/src/share/classes. -->
     <condition property="require.import.jdk.stubs">
         <and>
             <not>
@@ -213,6 +211,50 @@
         </and>
     </condition>
 
+
+    <!-- No need to exclude any files during bootstrap phase if ${boot.java.home}
+         provides the latest API. -->
+    <condition property="bootstrap.exclude.files" value="" else="${require.latest.jdk.files}">
+        <isset property="boot.java.provides.latest.jdk"/>
+    </condition>
+
+    <!-- No need to exclude any files during second phase if ${boot.java.home}
+         provides the latest API or if import.jdk is set. -->
+    <condition property="exclude.files" value="" else="${require.latest.jdk.files}">
+        <or>
+            <isset property="boot.java.provides.latest.jdk"/>
+            <isset property="import.jdk"/>
+        </or>
+    </condition>
+
+
+    <!-- Determine how to use bootstrap-javac in the second phase.
+         If ${boot.java.home} is a modular image, use -L <library>,
+         otherwise use -Xbootclasspath/p:<classes>.   In both cases,
+         prefix all words with -J to tunnel them through the javac
+         launcher to the underlying JVM. -->
+    <!-- javac -L -Xbootclasspath/p in classpath mode fails to compile.
+         Not use -L for now.
+         value="-J-L -J${build.bootstrap.dir}/lib/modules -J-Xmode:module"
+         -->
+    <condition property="default.bootstrap.opts"
+        value="-J-Xbootclasspath/p:${build.bootstrap.dir}/classes"
+        else="-J-Xbootclasspath/p:${build.bootstrap.dir}/classes">
+           <isset property="boot.java.provides.modules"/>
+    </condition>
+
+
+    <!-- Set the default bootclasspath option used for javac.
+        Note that different variants of the option are used (-Xbcp: and -Xbcp/p:),
+        meaning we can't just define the value for the option (i.e the path after the ':').
+        Note the explicit use of the standard property ${path.separator} in the following.
+        This is because Ant is not clever enough to handle direct use of : or ; -->
+    <condition property="javac.bootclasspath.opt"
+            value="-Xbootclasspath:${build.classes.dir}${path.separator}${import.jdk.jar}"
+            else="-Xbootclasspath/p:${build.classes.dir}">
+        <isset property="import.jdk.jar"/>
+    </condition>
+
     <!-- Set the default value of the sourcepath used for javac. -->
     <condition property="javac.sourcepath" value="${build.genstubs.dir}" else="">
         <isset property="require.import.jdk.stubs"/>
@@ -222,6 +264,16 @@
     <property name="javac.classpath" value=""/>
 
 
+    <!-- launcher.java is used in the launcher scripts provided to run
+        the tools' jar files.  If it has not already been set, then
+        default it to use ${target.java.home}, if available, otherwise
+        quietly default to simply use "java". -->
+    <condition property="launcher.java"
+        value="${target.java.home}/bin/java" else="java">
+        <isset property="target.java.home"/>
+    </condition>
+
+
     <!--
     **** General top level targets.
     -->
@@ -513,9 +565,12 @@
     **** javac targets.
     -->
 
+    <target name="build-bootstrap-classes-javac" depends="-check-boot.java.home,-def-build-bootstrap-classes">
+        <build-bootstrap-classes includes="${javac.includes}"/>
+    </target>
+
     <target name="build-bootstrap-javac"
-            depends="-def-build-bootstrap-classes,-def-build-bootstrap-jar,-def-build-bootstrap-tool">
-        <build-bootstrap-classes includes="${javac.includes}"/>
+            depends="build-bootstrap-classes-javac,build-bootstrap-module-langtools,-def-build-bootstrap-jar,-def-build-bootstrap-tool">
         <build-bootstrap-jar     name="javac" includes="${javac.includes}"/>
         <build-bootstrap-tool    name="javac"/>
     </target>
@@ -524,7 +579,7 @@
         <build-classes includes="${javac.includes}"/>
     </target>
 
-    <target name="build-javac" depends="build-classes-javac">
+    <target name="build-javac" depends="build-classes-javac,build-module-langtools">
         <build-jar  name="javac" includes="${javac.includes}"/>
         <build-tool name="javac"/>
     </target>
@@ -543,13 +598,42 @@
 
     <target name="javac" depends="build-javac,jtreg-javac,findbugs-javac"/>
 
+    <!-- langtools module targets -->
+
+    <target name="build-bootstrap-module-javax-tools"
+            depends="build-bootstrap-classes-javac,-def-build-bootstrap-module"
+            if="boot.java.provides.modules">
+        <build-bootstrap-module module.name="${javax.tools.module.name}" includes="${javax.tools.module.includes}"/>
+    </target>
+
+    <target name="build-module-javax-tools" depends="build-classes-javac,-def-build-module"
+            if="target.java.provides.modules">
+        <build-module module.name="${javax.tools.module.name}" includes="${javax.tools.module.includes}"/>
+    </target>
+    
+    <target name="build-bootstrap-module-langtools"
+            depends="build-bootstrap-classes-javac,build-bootstrap-classes-javah,build-bootstrap-classes-javap,build-bootstrap-classes-javadoc,build-bootstrap-classes-doclets,build-bootstrap-module-javax-tools,-def-build-bootstrap-module"
+            if="boot.java.provides.modules">
+        <build-bootstrap-module module.name="${langtools.module.name}" includes="${langtools.module.includes}"/>
+    </target>
+
+    <target name="build-module-langtools"
+            depends="build-classes-javac,build-classes-javah,build-classes-javap,build-classes-javadoc,build-classes-doclets,build-module-javax-tools,-def-build-module"
+            if="target.java.provides.modules">
+        <build-module module.name="${langtools.module.name}" includes="${langtools.module.includes}"/>
+    </target>
 
     <!--
     **** javadoc targets.
     -->
 
-    <target name="build-bootstrap-javadoc" depends="build-bootstrap-javac">
+    <target name="build-bootstrap-classes-javadoc"
+            depends="build-bootstrap-classes-javac">
         <build-bootstrap-classes includes="${javadoc.includes}"/>
+    </target>
+
+    <target name="build-bootstrap-javadoc"
+            depends="build-bootstrap-classes-javadoc,build-bootstrap-javac,build-bootstrap-module-langtools">
         <build-bootstrap-jar     name="javadoc" includes="${javadoc.includes}"
                                  jarclasspath="javac.jar doclets.jar"/>
         <build-bootstrap-tool    name="javadoc"/>
@@ -559,7 +643,7 @@
         <build-classes includes="${javadoc.includes}"/>
     </target>
 
-    <target name="build-javadoc" depends="build-javac,build-classes-javadoc">
+    <target name="build-javadoc" depends="build-javac,build-classes-javadoc,build-module-langtools">
         <build-jar  name="javadoc" includes="${javadoc.includes}"
                     jarclasspath="javac.jar doclets.jar"/>
         <build-tool name="javadoc"/>
@@ -584,8 +668,13 @@
     **** doclets targets.
     -->
 
-    <target name="build-bootstrap-doclets" depends="build-bootstrap-javadoc,-def-build-bootstrap-jar">
+    <!-- no module targets ... classes are included in javadoc module -->
+
+    <target name="build-bootstrap-classes-doclets" depends="build-bootstrap-classes-javadoc">
         <build-bootstrap-classes includes="${doclets.includes}"/>
+    </target>
+
+    <target name="build-bootstrap-doclets" depends="build-bootstrap-javadoc">
         <build-bootstrap-jar     name="doclets" includes="${doclets.includes}"
                                  jarmainclass="com.sun.tools.javadoc.Main"
                                  jarclasspath="javadoc.jar"/>
@@ -617,22 +706,27 @@
     **** javah targets.
     -->
 
-    <target name="build-bootstrap-javah" depends="build-bootstrap-javadoc">
+    <target name="build-bootstrap-classes-javah"
+            depends="build-bootstrap-classes-javac">
         <build-bootstrap-classes includes="${javah.includes}"/>
-        <build-bootstrap-jar     name="javah" includes="${javah.includes}"
-                                 jarclasspath="javadoc.jar doclets.jar javac.jar"/>
-        <build-bootstrap-tool    name="javah"/>
     </target>
 
-    <target name="build-javah" depends="build-javac,build-classes-javah">
-        <build-jar  name="javah" includes="${javah.includes}" jarclasspath="javac.jar"/>
-        <build-tool name="javah"/>
+    <target name="build-bootstrap-javah"
+            depends="build-bootstrap-classes-javah,build-bootstrap-javac,build-bootstrap-module-langtools">
+        <build-bootstrap-jar     name="javah" includes="${javah.includes}"
+                                 jarclasspath="javac.jar"/>
+        <build-bootstrap-tool    name="javah"/>
     </target>
 
     <target name="build-classes-javah" depends="build-classes-javadoc">
         <build-classes includes="${javah.includes}"/>
     </target>
 
+    <target name="build-javah" depends="build-javac,build-classes-javah,build-module-langtools">
+        <build-jar  name="javah" includes="${javah.includes}" jarclasspath="javac.jar"/>
+        <build-tool name="javah"/>
+    </target>
+
     <!-- (no javadoc for javah) -->
 
     <target name="jtreg-javah" depends="build-javah,-def-jtreg">
@@ -650,11 +744,15 @@
     **** javap targets.
     -->
 
-    <target name="build-bootstrap-javap"
-            depends="-def-build-bootstrap-classes,-def-build-bootstrap-jar,-def-build-bootstrap-tool">
+    <target name="build-bootstrap-classes-javap"
+            depends="build-bootstrap-classes-javac">
         <build-bootstrap-classes includes="${javap.includes}"/>
+    </target>
+
+    <target name="build-bootstrap-javap"
+            depends="build-bootstrap-classes-javap,build-bootstrap-javac,build-bootstrap-module-langtools">
         <build-bootstrap-jar     name="javap" includes="${javap.includes}"
-                                 jarmainclass="sun.tools.javap.Main"/>
+                                 jarclasspath="javac.jar"/>
         <build-bootstrap-tool    name="javap"/>
     </target>
 
@@ -662,14 +760,14 @@
         <build-classes includes="${javap.includes}"/>
     </target>
 
-    <target name="build-javap" depends="build-javac,build-classes-javap">
+    <target name="build-javap" depends="build-javac,build-classes-javap,build-module-langtools">
         <build-jar  name="javap" includes="${javap.includes}"
                     jarmainclass="com.sun.tools.javap.Main"
                     jarclasspath="javac.jar"/>
         <build-tool name="javap"/>
     </target>
 
-    <!-- (no javadoc for javap) -->
+    <!-- (no javadoc for javap ... what about classfile library? ) -->
 
     <target name="jtreg-javap" depends="build-javap,-def-jtreg">
         <jtreg-tool name="javap" tests="${javap.tests}"/>
@@ -770,6 +868,69 @@
     **** Targets for Ant macro and task definitions.
     -->
 
+    <target name="-def-jigsaw">
+        <mkdir dir="${build.toolclasses.dir}"/>
+        <javac fork="true"
+               source="${boot.javac.source}"
+               target="${boot.javac.target}"
+               executable="${boot.java.home}/bin/javac"
+               srcdir="${make.tools.dir}/Jigsaw"
+               destdir="${build.toolclasses.dir}/"
+               classpath="${ant.home}/lib/ant.jar"/>
+        <taskdef name="fpkg"
+                 classname="FpkgTask"
+                 classpath="${build.toolclasses.dir}/"/>
+        <taskdef name="jmod"
+                 classname="JmodTask"
+                 classpath="${build.toolclasses.dir}/"/>
+    </target>
+
+    <target name="-def-build-module" depends="-def-jigsaw">
+        <macrodef name="build-module">
+            <attribute name="module.name"/>
+            <attribute name="module.version" default="${module.version}"/>
+            <attribute name="classes.dir"    default="${build.classes.dir}"/>
+            <attribute name="includes"/>
+            <attribute name="excludes"       default=""/>
+            <attribute name="dest.dir"       default="${dist.lib.dir}"/>
+            <attribute name="jdk"            default="${target.java.home}"/>
+            <attribute name="library"        default="${dist.lib.dir}/modules"/>
+            <sequential>
+                <fpkg name="@{module.name}" version="@{module.version}"
+                    dir="@{classes.dir}" includes="@{includes}" excludes="@{excludes}"
+                    jdk="@{jdk}"
+                    destdir="@{dest.dir}"
+                    fork="true" executable="@{jdk}/bin/jpkg"/>
+                <jmod task="create" library="@{library}" parent="@{jdk}/lib/modules"
+                    fork="true" executable="@{jdk}/bin/jmod"/>
+                <jmod task="install" library="@{library}"
+                    fork="true" executable="@{jdk}/bin/jmod">
+                    <arg file="@{dest.dir}/@{module.name}@@@{module.version}.jmod"/>
+                </jmod>
+            </sequential>
+        </macrodef>
+    </target>
+
+<!--
+    <target name="-def-jmod">
+        <macrodef name="jmod">
+            <attribute name="task"/>
+            <attribute name="library"/>
+            <attribute name="java.home" default="${target.java.home}"/>
+            <element name="args" implicit="true" optional="true"/>
+            <sequential>
+                <echo message="jmod @{task} -L @{library} ..."/>
+                <exec executable="@{java.home}/bin/jmod" failonerror="true">
+                    <arg value="@{task}"/>
+                    <arg value="-L"/>
+                    <arg file="@{library}"/>
+                    <args/>
+                </exec>
+            </sequential>
+        </macrodef>
+    </target>
+-->
+
     <target name="-def-build-tool">
         <macrodef name="build-tool">
             <attribute name="name"/>
@@ -817,7 +978,7 @@
             <attribute name="excludes" default="${exclude.files} **/package-info.java"/>
             <attribute name="classes.dir" default="${build.classes.dir}"/>
             <attribute name="gensrc.dir" default="${build.gensrc.dir}"/>
-            <attribute name="javac.bootclasspath" default="${build.bootstrap.dir}/classes"/>
+            <attribute name="bootstrap.opts" default="${default.bootstrap.opts}"/>
             <attribute name="bootclasspath.opt" default="${javac.bootclasspath.opt}"/>
             <attribute name="classpath" default="${javac.classpath}"/>
             <attribute name="sourcepath" default="${javac.sourcepath}"/>
@@ -827,6 +988,7 @@
             <attribute name="release" default="${release}"/>
             <attribute name="full.version" default="${full.version}"/>
             <sequential>
+                <echo level="${bootstrap.opts.verbose}" message="build-classes: bootstrap.opts=@{bootstrap.opts}"/>
                 <echo level="verbose" message="build-classes: excludes=@{excludes}"/>
                 <echo level="verbose" message="build-classes: bootclasspath.opt=@{bootclasspath.opt}"/>
                 <echo level="verbose" message="build-classes: classpath=@{classpath}"/>
@@ -863,7 +1025,7 @@
                        debuglevel="${javac.debuglevel}">
                     <compilerarg value="-implicit:none"/>
                     <compilerarg value="-Xprefer:source"/>
-                    <compilerarg value="-J-Xbootclasspath/p:@{javac.bootclasspath}"/>
+                    <compilerarg line="@{bootstrap.opts}"/>
                     <compilerarg line="@{bootclasspath.opt}"/>
                     <compilerarg line="${javac.no.jdk.warnings}"/>
                     <compilerarg line="${javac.version.opt}"/>
@@ -878,6 +1040,11 @@
                         <exclude name="**/*.orig"/>
                         <exclude name="**/overview.html"/>
                         <exclude name="**/package.html"/>
+                        <exclude name="**/overview.html"/>
+                        <exclude name="**/*.orig"/>
+                        <exclude name="**/*.rej"/>
+                        <exclude name="**/*.BAK"/>
+                        <exclude name="**/*~"/>
                     </fileset>
                 </copy>
             </sequential>
@@ -907,7 +1074,7 @@
                 target="${boot.javac.target}"
                 gensrc.dir="${build.bootstrap.dir}/gensrc"
                 classes.dir="${build.bootstrap.dir}/classes"
-                javac.bootclasspath=""
+                bootstrap.opts=""
                 bootclasspath.opt="-Xbootclasspath/p:${build.bootstrap.dir}/classes"
                 sourcepath=""
                 release="${bootstrap.release}"
@@ -916,6 +1083,16 @@
         </presetdef>
     </target>
 
+    <target name="-def-build-bootstrap-module" depends="-def-build-module">
+        <presetdef name="build-bootstrap-module">
+            <build-module
+                classes.dir="${build.bootstrap.dir}/classes"
+                dest.dir="${build.bootstrap.dir}/lib"
+                library="${build.bootstrap.dir}/lib/modules"
+                jdk="${boot.java.home}"/>
+        </presetdef>
+    </target>
+
     <target name="-def-pcompile">
         <mkdir dir="${build.toolclasses.dir}"/>
         <javac fork="true"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/Jigsaw/FpkgTask.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2010, 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.BufferedReader;
+import java.io.File;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.MatchingTask;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * This class provides a specialized form of jpkg, to create a module package file
+ * from the appropriate langtools classes, and (re)using the module-info.class
+ * file from a previously installed copy of the module.
+ * If the package file exists and is up to date, it will not be modified.
+ *
+ * Note: the code here relies on the internal layout of a module library.
+ * Ideally, there would be tool support to extract module info.class from
+ * a library.
+ */
+public class FpkgTask extends MatchingTask {
+    /**
+     * Set the module name.
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * Set the module version.
+     */
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    /**
+     * Set the directory in which to write the package file.
+     * See jpkg --dest-dir.
+     */
+    public void setDestDir(File destDir) {
+        this.destDir = destDir;
+    }
+
+    /**
+     * Set the type of package to be written: (deb or jmod)
+     * See the first anonymous arg for jpkg.
+     */
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    /**
+     * Set the root directory of the implicit fileset of files to be included
+     * in the package.
+     * All the related attributes of an implicit fileset may be used.
+     * The fileset may include classes (*.class) and resources (other files.)
+     */
+    public void setDir(File dir) {
+        this.dir = dir;
+    }
+
+    /**
+     * Set the JDK from which to import the copy of module-info to be used.
+     * It is assumed the module library will be at jdk/lib/modules
+     * and that the library follows the SimpleLibrary layout.
+     */
+    public void setJDK(File jdk) {
+        this.jdk = jdk;
+    }
+
+    /**
+     * Set whether or not jpkg should be executed in a separate process.
+     */
+    public void setFork(boolean fork) {
+        this.fork = fork;
+    }
+
+    /**
+     * Set the path for the executable for jpkg, for use when fork is true.
+     */
+    public void setExecutable(String executable) {
+        this.executable = executable;
+    }
+
+    @Override
+    public void execute() {
+        if (name == null || name.length() == 0)
+            throw new BuildException("no name given");
+
+        if (version == null || version.length() == 0)
+            throw new BuildException("no version given");
+
+        if (destDir == null)
+            throw new BuildException("no output directory given");
+
+        if (type == null)
+            type = "jmod";
+        else if (!(type.equals("jmod") || type.equals("deb")))
+            throw new BuildException("invalid type given");
+
+        // if fork is true, validate executable?
+
+        File file = new File(destDir, name + "@" + version + "." + type);
+        if (isUptodate(file)) {
+            log("Skipping " + name + "@" + version + " because it is up to date",
+                    Project.MSG_VERBOSE);
+            return;
+        }
+
+        // The following code presumes knowledge of the layout of the JDK module library
+        File jdkModulesDir = new File(new File(jdk, "lib"), "modules");
+        File jdkModulesMarker = new File(jdkModulesDir, "%jigsaw-library");
+        if (!jdkModulesMarker.exists())
+            throw new BuildException("cannot find JDK module library");
+
+        File importModuleDir = new File(new File(jdkModulesDir, name), version);
+        if (!importModuleDir.exists())
+            throw new BuildException("cannot find module " + name + "@" + version + " in JDK module library");
+
+        File importModuleInfo = new File(importModuleDir, "info");
+        if (!importModuleInfo.exists())
+            throw new BuildException("cannot find module info for module " + name + "@" + version + " in JDK module library");
+
+        File javaTmpDir = new File(System.getProperty("java.io.tmpdir"));
+        File tmpDir = new File(javaTmpDir, (getClass().getSimpleName() + "." + System.currentTimeMillis()));
+
+        try {
+            File tmpModuleDir = new File(tmpDir, name);
+            File tmpClassesDir = new File(tmpModuleDir, "classes");
+
+            tmpClassesDir.mkdirs();
+            destDir.mkdirs();
+            FileUtils fu = FileUtils.getFileUtils();
+            fu.copyFile(importModuleInfo, new File(tmpClassesDir, "module-info.class"));
+            copyFiles(tmpClassesDir);
+
+            List<String> opts = new ArrayList<String>();
+            add(opts, "--module-dir", tmpClassesDir.getPath());
+            add(opts, "--dest-dir", destDir.getPath());
+            add(opts, type);
+            add(opts, name);
+
+            log("Creating module file for " + name, Project.MSG_INFO);
+            jpkg(opts);
+        } catch (InterruptedException e) {
+            throw new BuildException("error occurred", e);
+        } catch (IOException e) {
+            throw new BuildException("error occurred", e);
+        } finally {
+            delete(tmpDir);
+        }
+    }
+
+    void jpkg(List<String> opts) throws IOException, InterruptedException {
+        if (fork) {
+            List<String> cmd = new ArrayList<String>();
+            cmd.add(executable);
+            cmd.addAll(opts);
+//            log("exec: " + cmd, Project.MSG_VERBOSE);
+//            ProcessBuilder pb = new ProcessBuilder(cmd);
+//            pb.redirectErrorStream(true);
+//            Process p = pb.start();
+//            BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
+//            try {
+//                String line;
+//                while ((line = in.readLine()) != null)
+//                    System.out.println(line);
+//            } finally {
+//                in.close();
+//            }
+//            int rc = p.waitFor();
+//            if (rc != 0)
+//                throw new BuildException("unexpected exit from jpkg: " + rc);
+            Execute.runCommand(this, cmd.toArray(new String[cmd.size()]));
+        } else {
+            throw new BuildException("fork=false not supported yet");
+        }
+    }
+
+    boolean isUptodate(File file) {
+        long fileTime = file.lastModified();
+
+        DirectoryScanner s = getDirectoryScanner(dir);
+        for (String path: s.getIncludedFiles()) {
+            File f = new File(dir, path);
+            if (f.lastModified() > fileTime)
+                return false;
+        }
+
+        return true;
+    }
+
+    void copyFiles(File classesDir) throws IOException {
+        FileUtils fu = FileUtils.getFileUtils();
+        DirectoryScanner s = getDirectoryScanner(dir);
+        for (String path: s.getIncludedFiles()) {
+            File toDir = classesDir;
+            fu.copyFile(new File(dir, path), new File(toDir, path));
+        }
+    }
+
+    boolean delete(File file) {
+        if (file.isDirectory()) {
+            boolean ok = true;
+            for (File f: file.listFiles())
+                ok &= delete(f);
+            ok &= file.delete();
+            return ok;
+        } else
+            return file.delete();
+    }
+
+    void add(List<String> list, String... values) {
+        for (String v: values)
+            list.add(v);
+    }
+
+    private String name;
+    private String version;
+    private File destDir;
+    private String type;
+    private File dir;
+    private File jdk;
+    private boolean fork;
+    private String executable;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/Jigsaw/JmodTask.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2010, 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.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * This class provides simple limited support for using jmod.
+ * Only the "create" and "install" options are supported.
+ */
+public class JmodTask extends Task {
+    /**
+     * Set the task to be performed: "create" or "install".
+     * If the task is "create", the library will be created if it does not
+     * already exist.
+     * If the task is "install" and the module is up to date in the library
+     * it will not be modified.  If the module exists but is not up to date,
+     * it will be deleted before jmod is invoked.
+     */
+    public void setTask(String task) {
+        this.task = task;
+    }
+
+    /**
+     * Set the library to be created/used.
+     * See jmod -L/--library.
+     */
+    public void setLibrary(File library) {
+        this.library = library;
+    }
+
+    /**
+     * Set the parent of the library to be created.
+     * See jmod -P/--parent-path.
+     */
+    public void setParent(File parent) {
+        this.parent = parent;
+    }
+
+    /**
+     * Set whether or not jmod should be executed in a separate process.
+     */
+    public void setFork(boolean fork) {
+        this.fork = fork;
+    }
+
+    /**
+     * Set the path for the executable for jmod, for use when fork is true.
+     */
+    public void setExecutable(String executable) {
+        this.executable = executable;
+    }
+
+    /**
+     * Set additional arguments for the task. If the task is "install",
+     * use this to specify module package files to be installed.
+     */
+    public void addArg(Commandline.Argument arg) {
+        args.add(arg);
+    }
+
+    @Override
+    public void execute() {
+        if (task == null)
+            throw new BuildException("task not set");
+
+        if (task.equals("create"))
+            doCreate();
+        else if (task.equals("install"))
+            doInstall();
+        else
+            throw new BuildException("task not recognized");
+    }
+
+    void doCreate() {
+        if (library.exists()) {
+            if (new File(library, "%jigsaw-library").exists()) {
+                log("Skipping " + library + " because it already exists",
+                        Project.MSG_VERBOSE);
+                return;
+            } else
+                throw new BuildException("library exists but is not a valid Jigsaw library");
+        } else {
+            File libDir = library.getParentFile();
+            libDir.mkdirs();
+            List<String> opts = new ArrayList<String>();
+            add(opts, "create");
+            add(opts, "--library", library.getPath());
+            if (parent == null)
+                add(opts, "--no-parent");
+            else
+                add(opts, "--parent-path", parent.getPath());
+
+            System.out.println("Creating module library " + library);
+
+            try {
+                jmod(opts);
+            } catch (InterruptedException e) {
+                throw new BuildException("error occurred", e);
+            } catch (IOException e) {
+               throw new BuildException("error occurred", e);
+            }
+        }
+    }
+
+    void doInstall() {
+        List<File> files = new ArrayList<File>();
+
+        for (Commandline.Argument arg: args) {
+            for (String s: arg.getParts()) {
+                File f = new File(s);
+                String fname = f.getName();
+                int lastDot = fname.lastIndexOf(".");
+                String fbase = (lastDot == -1 ? fname : fname.substring(0, lastDot));
+                int at = fbase.indexOf("@");
+                String mname = (at == -1 ? fbase : fbase.substring(0, at));
+                String mversion = (at == -1 ? "" : fbase.substring(at + 1));
+                File mdir = new File(new File(library, mname), mversion);
+                if (mdir.exists() && mdir.lastModified() > f.lastModified()) {
+                    log("Skipping " + f + " because installed module is up to date",
+                        Project.MSG_VERBOSE);
+                    continue;
+                }
+                log("Deleting " + mdir, Project.MSG_VERBOSE);
+                delete(mdir);
+                files.add(f);
+            }
+        }
+
+        if (files.isEmpty())
+            return;
+
+        try {
+            List<String> opts = new ArrayList<String>();
+            add(opts, "install");
+            add(opts, "--library", library.getPath());
+            for (File f: files)
+                add(opts, f.getPath());
+
+            log("Installing " + files.size()
+                    + " module" + (files.size() == 1 ? "" : "s")
+                    + " in " + library,
+                    Project.MSG_INFO);
+            jmod(opts);
+        } catch (InterruptedException e) {
+            throw new BuildException("error occurred", e);
+        } catch (IOException e) {
+            throw new BuildException("error occurred", e);
+        }
+    }
+
+    void jmod(List<String> opts) throws IOException, InterruptedException {
+        if (fork) {
+            List<String> cmd = new ArrayList<String>();
+            cmd.add(executable);
+            cmd.addAll(opts);
+//            log("exec: " + cmd, Project.MSG_VERBOSE);
+//            ProcessBuilder pb = new ProcessBuilder(cmd);
+//            pb.redirectErrorStream(true);
+//            Process p = pb.start();
+//            BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
+//            try {
+//                String line;
+//                while ((line = in.readLine()) != null)
+//                    System.out.println(line);
+//            } finally {
+//                in.close();
+//            }
+//            int rc = p.waitFor();
+//            if (rc != 0)
+//                throw new BuildException("unexpected exit from jmod: " + rc);
+            Execute.runCommand(this, cmd.toArray(new String[cmd.size()]));
+        } else {
+            throw new BuildException("fork=false not supported yet");
+        }
+    }
+
+    boolean delete(File file) {
+        if (file.isDirectory()) {
+            boolean ok = true;
+            for (File f: file.listFiles())
+                ok &= delete(f);
+            ok &= file.delete();
+            return ok;
+        } else
+            return file.delete();
+    }
+
+    void add(List<String> list, String... values) {
+        for (String v: values)
+            list.add(v);
+    }
+
+    private String task;
+    private File library;
+    private File parent;
+    private boolean fork;
+    private String executable;
+    private List<Commandline.Argument> args = new ArrayList<Commandline.Argument>();
+}
--- a/make/tools/genstubs/GenStubs.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/make/tools/genstubs/GenStubs.java	Tue May 07 17:14:17 2013 -0700
@@ -284,9 +284,9 @@
             tree.accept(this);
             ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
             for (JCTree def: tree.defs) {
-                if (def.getTag() == JCTree.Tag.IMPORT) {
+                if (def.hasTag(JCTree.Tag.IMPORT)) {
                     JCImport imp = (JCImport) def;
-                    if (imp.qualid.getTag() == JCTree.Tag.SELECT) {
+                    if (imp.qualid.hasTag(JCTree.Tag.SELECT)) {
                         JCFieldAccess qualid = (JCFieldAccess) imp.qualid;
                         if (!qualid.name.toString().equals("*")
                                 && !names.contains(qualid.name)) {
@@ -296,7 +296,7 @@
                 }
                 defs.add(def);
             }
-            return m.TopLevel(tree.packageAnnotations, tree.pid, defs.toList());
+            return m.TopLevel(defs.toList());
         }
 
         @Override
--- a/makefiles/BuildLangtools.gmk	Thu Apr 25 09:24:40 2013 -0700
+++ b/makefiles/BuildLangtools.gmk	Tue May 07 17:14:17 2013 -0700
@@ -105,7 +105,8 @@
 		SETUP:=BOOT_JAVAC,\
 		DISABLE_SJAVAC:=true,\
 		SRC:=$(LANGTOOLS_TOPDIR)/src/share/classes $(LANGTOOLS_OUTPUTDIR)/gensrc,\
-		EXCLUDES:=com/sun/tools/javac/nio,\
+		EXCLUDES:=com/sun/tools/javac/nio \
+			  com/sun/tools/javac/jigsaw,\
 		COPY:=$(RESOURCE_SUFFIXES),\
 		BIN:=$(LANGTOOLS_OUTPUTDIR)/btclasses/bootstrap))
 
@@ -123,10 +124,11 @@
              genstubs.GenStubs
         # We fetch source from the JDK...
         JDKS=$(JDK_TOPDIR)/src/share/classes
-        # Build the list of classes to generate stubs from. java/util/Objects.java isn't
-        # currently needed, but is used as a demo for now.
+        # Build the list of classes to generate stubs from. 
 	 STUBSOURCES:=$(shell $(FIND) $(JDKS) -name "*.java" | $(GREP) \
-		    -e "$(JDKS)/java/util/Objects.java")
+                    -e "$(JDKS)/java/lang/module/" \
+                    -e "$(JDKS)/java/lang/reflect/Module.java" \
+                    -e "$(JDKS)/org/openjdk/jigsaw/")
         # Rewrite the file names into class names because the GenStubs tool require this.
         STUBCLASSES:=$(subst /,.,$(patsubst $(JDKS)/%.java,%,$(STUBSOURCES)))
 
@@ -170,7 +172,7 @@
 			SETUP:=GENERATE_NEWBYTECODE,\
 			SRC:=$(LANGTOOLS_TOPDIR)/src/share/classes $(LANGTOOLS_OUTPUTDIR)/gensrc \
 			     $(LANGTOOLS_OUTPUTDIR)/genstubs,\
-			EXCLUDES:=java/util java/io java/nio,\
+			EXCLUDES:=java/util java/io java/nio java/lang org/openjdk,\
 			COPY:=$(RESOURCE_SUFFIXES),\
 			BIN:=$(LANGTOOLS_OUTPUTDIR)/classes))
 
--- a/src/share/bin/launcher.sh-template	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/bin/launcher.sh-template	Tue May 07 17:14:17 2013 -0700
@@ -33,22 +33,6 @@
 esac
 mylib="$mydir/../lib"
 
-# By default, put the jar file and its dependencies on the bootclasspath.
-# This is always required on a Mac, because the system langtools classes
-# are always on the main class path; in addition, it may be required on
-# standard versions of JDK (i.e. using rt.jar and tools.jar) because some
-# langtools interfaces are in rt.jar.
-# Assume that the jar file being invoked lists all the necessary langtools
-# jar files in its Class-Path manifest entry, so there is no need to search
-# dependent jar files for additional dependencies.
-
-if [ "$LANGTOOLS_USE_BOOTCLASSPATH" != "no" ]; then
-   cp=`unzip -c "$mylib/#PROGRAM#.jar" META-INF/MANIFEST.MF |
-       grep "Class-Path:" |
-       sed -e 's|Class-Path: *||' -e 's|\([a-z]*\.jar\) *|'"$mylib"'/\1#PS#|g'`
-   bcp="$mylib/#PROGRAM#.jar#PS#$cp"
-fi
-
 # tools currently assumes that assertions are enabled in the launcher
 ea=-ea:com.sun.tools...
 
@@ -71,5 +55,32 @@
 done
 unset DUALCASE
 
+# Use newline as arg separator to preserve spaces in args
+javahome=`dirname "\`dirname \"#TARGET_JAVA#\" \`"`
+if [ -r "$javahome"/lib/modules/%jigsaw-library ]; then
+    if [ -r $mylib/modules/%jigsaw-library ]; then
+      langtools="-L$nl$mylib/modules"
+      tool="-m${nl}#PROGRAM#"
+    fi
+else
+    # By default, put the jar file and its dependencies on the bootclasspath.
+    # This is always required on a Mac, because the system langtools classes
+    # are always on the main class path; in addition, it may be required on
+    # standard versions of JDK (i.e. using rt.jar and tools.jar) because some
+    # langtools interfaces are in rt.jar.
+    # Assume that the jar file being invoked lists all the necessary langtools
+    # jar files in its Class-Path manifest entry, so there is no need to search
+    # dependent jar files for additional dependencies.
+
+    if [ "$LANGTOOLS_USE_BOOTCLASSPATH" != "no" ]; then
+        cp=`unzip -c "$mylib/#PROGRAM#.jar" META-INF/MANIFEST.MF |
+            grep "Class-Path:" |
+            sed -e 's|Class-Path: *||' -e 's|\([a-z]*\.jar\) *|'"$mylib"'/\1#PS#|g'`
+        bcp="$mylib/#PROGRAM#.jar"#PS#$cp 
+    fi
+    langtools="${bcp:+-Xbootclasspath/p:"$bcp"}"
+    tool="-jar$nl${mylib}/#PROGRAM#.jar"
+fi
+
 IFS=$nl
-"#TARGET_JAVA#" "${bcp:+-Xbootclasspath/p:"$bcp"}" ${ea} ${javaOpts} -jar "${mylib}/#PROGRAM#.jar" ${toolOpts}
+"#TARGET_JAVA#" ${langtools} ${ea} ${javaOpts} ${tool} ${toolOpts}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/source/tree/EntrypointDirectiveTree.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2009, 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.source.tree;
+
+public interface EntrypointDirectiveTree extends ModuleDirectiveTree {
+    ExpressionTree getClassName();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/source/tree/ExportDirectiveTree.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2009, 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.source.tree;
+
+/**
+ *
+ */
+public interface ExportDirectiveTree extends ModuleDirectiveTree {
+    ExpressionTree getExportName();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/source/tree/ModuleDirectiveTree.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.tree;
+
+/**
+ * A super-type for all the directives in a ModuleTree.
+ */
+public interface ModuleDirectiveTree extends Tree { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/source/tree/ModuleIdTree.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2009, 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.source.tree;
+
+import javax.lang.model.element.Name;
+
+/**
+ *
+ */
+public interface ModuleIdTree extends Tree {
+    Tree getName();
+    Name getVersion();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/source/tree/ModuleQueryTree.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2009, 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.source.tree;
+
+import javax.lang.model.element.Name;
+
+/**
+ *
+ */
+public interface ModuleQueryTree extends Tree {
+    Tree getName();
+    Name getVersionQuery();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/source/tree/ModuleTree.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2009, 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.source.tree;
+
+import java.util.List;
+
+
+/**
+ *
+ */
+public interface ModuleTree extends Tree {
+    ModuleIdTree getId();
+    List<? extends ModuleDirectiveTree> getDirectives();
+    CharSequence getExtendedMetadata();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/source/tree/PackageTree.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,13 @@
+
+package com.sun.source.tree;
+
+import java.util.List;
+
+
+/**
+ *
+ */
+public interface PackageTree extends Tree {
+    List<? extends AnnotationTree> getAnnotations();
+    Tree getPackageId();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/source/tree/PermitsDirectiveTree.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2009, 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.source.tree;
+
+/**
+ *
+ */
+public interface PermitsDirectiveTree extends Tree {
+    Tree getModuleName();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/source/tree/ProvidesModuleDirectiveTree.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2009, 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.source.tree;
+
+public interface ProvidesModuleDirectiveTree extends ModuleDirectiveTree {
+    ModuleIdTree getModuleId();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/source/tree/ProvidesServiceDirectiveTree.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2009, 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.source.tree;
+
+/*
+ *
+ */
+public interface ProvidesServiceDirectiveTree extends ModuleDirectiveTree {
+    ExpressionTree getServiceName();
+    ExpressionTree getImplementationName();
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/source/tree/RequiresFlag.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.tree;
+
+/**
+ * This may go away in favor of a public definition in javax.lang.model
+ */
+public enum RequiresFlag {
+    OPTIONAL,
+    LOCAL,
+    REEXPORT,
+    SYNTHETIC,
+    SYNTHESIZED
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/source/tree/RequiresModuleDirectiveTree.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2009, 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.source.tree;
+
+import java.util.List;
+
+public interface RequiresModuleDirectiveTree extends ModuleDirectiveTree {
+    List<RequiresFlag> getFlags();
+    ModuleQueryTree getModuleQuery();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/source/tree/RequiresServiceDirectiveTree.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2009, 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.source.tree;
+
+import java.util.List;
+
+public interface RequiresServiceDirectiveTree extends ModuleDirectiveTree {
+    List<RequiresFlag> getFlags();
+    ExpressionTree getServiceName();
+}
--- a/src/share/classes/com/sun/source/tree/Tree.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/source/tree/Tree.java	Tue May 07 17:14:17 2013 -0700
@@ -581,6 +581,30 @@
          */
         ERRONEOUS(ErroneousTree.class),
 
+        MODULE(ModuleTree.class),
+
+        ENTRYPOINT_DIRECTIVE(EntrypointDirectiveTree.class),
+
+        EXPORT_DIRECTIVE(ExportDirectiveTree.class),
+
+        MODULE_ID(ModuleIdTree.class),
+
+        MODULE_QUERY(ModuleQueryTree.class),
+
+        PERMITS_DIRECTIVE(PermitsDirectiveTree.class),
+
+        PROVIDES_MODULE_DIRECTIVE(ProvidesModuleDirectiveTree.class),
+
+        PROVIDES_SERVICE_DIRECTIVE(ProvidesServiceDirectiveTree.class),
+
+        REQUIRES_MODULE_DIRECTIVE(RequiresModuleDirectiveTree.class),
+
+        REQUIRES_SERVICE_DIRECTIVE(RequiresServiceDirectiveTree.class),
+
+        VIEW_DECLARATION(ViewDeclarationTree.class),
+
+        PACKAGE(PackageTree.class),
+
         /**
          * Used for instances of {@link ClassTree} representing interfaces.
          */
--- a/src/share/classes/com/sun/source/tree/TreeVisitor.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/source/tree/TreeVisitor.java	Tue May 07 17:14:17 2013 -0700
@@ -73,7 +73,9 @@
     R visitConditionalExpression(ConditionalExpressionTree node, P p);
     R visitContinue(ContinueTree node, P p);
     R visitDoWhileLoop(DoWhileLoopTree node, P p);
+    R visitEntrypoint(EntrypointDirectiveTree node, P p);
     R visitErroneous(ErroneousTree node, P p);
+    R visitExport(ExportDirectiveTree node, P p);
     R visitExpressionStatement(ExpressionStatementTree node, P p);
     R visitEnhancedForLoop(EnhancedForLoopTree node, P p);
     R visitForLoop(ForLoopTree node, P p);
@@ -85,10 +87,20 @@
     R visitLiteral(LiteralTree node, P p);
     R visitMethod(MethodTree node, P p);
     R visitModifiers(ModifiersTree node, P p);
+    R visitModule(ModuleTree node, P p);
+    R visitModuleId(ModuleIdTree node, P p);
+    R visitModuleQuery(ModuleQueryTree node, P p);
     R visitNewArray(NewArrayTree node, P p);
     R visitNewClass(NewClassTree node, P p);
     R visitLambdaExpression(LambdaExpressionTree node, P p);
+    R visitPackage(PackageTree node, P p);
     R visitParenthesized(ParenthesizedTree node, P p);
+    R visitPermits(PermitsDirectiveTree node, P p);
+    R visitProvidesModule(ProvidesModuleDirectiveTree node, P p);
+    R visitProvidesService(ProvidesServiceDirectiveTree node, P p);
+    R visitRequiresModule(RequiresModuleDirectiveTree node, P p);
+    R visitRequiresService(RequiresServiceDirectiveTree node, P p);
+    R visitView(ViewDeclarationTree node, P p);
     R visitReturn(ReturnTree node, P p);
     R visitMemberSelect(MemberSelectTree node, P p);
     R visitMemberReference(MemberReferenceTree node, P p);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/source/tree/ViewDeclarationTree.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2009, 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.source.tree;
+
+import java.util.List;
+
+/**
+ *
+ */
+public interface ViewDeclarationTree extends Tree {
+    ExpressionTree getName();
+    List<? extends ModuleDirectiveTree> getDirectives();
+}
--- a/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java	Tue May 07 17:14:17 2013 -0700
@@ -34,7 +34,7 @@
  * @since 1.6
  */
 @jdk.Supported
-public class SimpleTreeVisitor <R,P> implements TreeVisitor<R,P> {
+public class SimpleTreeVisitor<R,P> implements TreeVisitor<R,P> {
     protected final R DEFAULT_VALUE;
 
     protected SimpleTreeVisitor() {
@@ -269,6 +269,65 @@
         return defaultAction(node, p);
     }
 
+    @Override
+    public R visitModule(ModuleTree node, P p) {
+        return defaultAction(node, p);
+    }
+
+    @Override
+    public R visitModuleId(ModuleIdTree node, P p) {
+        return defaultAction(node, p);
+    }
+
+    @Override
+    public R visitModuleQuery(ModuleQueryTree node, P p) {
+        return defaultAction(node, p);
+    }
+
+    @Override
+    public R visitView(ViewDeclarationTree node, P p) {
+        return defaultAction(node, p);
+    }
+
+    @Override
+    public R visitEntrypoint(EntrypointDirectiveTree node, P p) {
+        return defaultAction(node, p);
+    }
+
+    @Override
+    public R visitExport(ExportDirectiveTree node, P p) {
+        return defaultAction(node, p);
+    }
+
+    @Override
+    public R visitPermits(PermitsDirectiveTree node, P p) {
+        return defaultAction(node, p);
+    }
+
+    @Override
+    public R visitProvidesModule(ProvidesModuleDirectiveTree node, P p) {
+        return defaultAction(node, p);
+    }
+
+    @Override
+    public R visitProvidesService(ProvidesServiceDirectiveTree node, P p) {
+        return defaultAction(node, p);
+    }
+
+    @Override
+    public R visitRequiresModule(RequiresModuleDirectiveTree node, P p) {
+        return defaultAction(node, p);
+    }
+
+    @Override
+    public R visitRequiresService(RequiresServiceDirectiveTree node, P p) {
+        return defaultAction(node, p);
+    }
+
+    public R visitPackage(PackageTree node, P p) {
+        return defaultAction(node, p);
+    }
+
     public R visitOther(Tree node, P p) {
         return defaultAction(node, p);
     }
--- a/src/share/classes/com/sun/source/util/TreeScanner.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/source/util/TreeScanner.java	Tue May 07 17:14:17 2013 -0700
@@ -403,6 +403,62 @@
        return r;
    }
 
+    public R visitModule(ModuleTree node, P p) {
+        R r = scan(node.getId(), p);
+        r = scanAndReduce(node.getDirectives(), p, r);
+        return r;
+    }
+
+    public R visitView(ViewDeclarationTree node, P p) {
+        R r = scan(node.getName(), p);
+        r = scanAndReduce(node.getDirectives(), p, r);
+        return r;
+    }
+
+    public R visitEntrypoint(EntrypointDirectiveTree node, P p) {
+        return scan(node.getClassName(), p);
+    }
+
+    public R visitExport(ExportDirectiveTree node, P p) {
+        return scan(node.getExportName(), p);
+    }
+
+    public R visitModuleId(ModuleIdTree node, P p) {
+        return scan(node.getName(), p);
+    }
+
+    public R visitModuleQuery(ModuleQueryTree node, P p) {
+        return scan(node.getName(), p);
+    }
+
+    public R visitPermits(PermitsDirectiveTree node, P p) {
+        return scan(node.getModuleName(), p);
+    }
+
+    public R visitProvidesModule(ProvidesModuleDirectiveTree node, P p) {
+        return scan(node.getModuleId(), p);
+    }
+
+    public R visitProvidesService(ProvidesServiceDirectiveTree node, P p) {
+        R r = scan(node.getServiceName(), p);
+        r = scanAndReduce(node.getImplementationName(), p, r);
+        return r;
+    }
+
+    public R visitRequiresModule(RequiresModuleDirectiveTree node, P p) {
+        return scan(node.getModuleQuery(), p);
+    }
+
+    public R visitRequiresService(RequiresServiceDirectiveTree node, P p) {
+        return scan(node.getServiceName(), p);
+    }
+
+    public R visitPackage(PackageTree node, P p) {
+        R r = scan(node.getAnnotations(), p);
+        r = scanAndReduce(node.getPackageId(), p, r);
+        return r;
+    }
+
     public R visitOther(Tree node, P p) {
         return null;
     }
--- a/src/share/classes/com/sun/tools/classfile/AccessFlags.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/classfile/AccessFlags.java	Tue May 07 17:14:17 2013 -0700
@@ -57,6 +57,7 @@
     public static final int ACC_ANNOTATION    = 0x2000; // class, inner
     public static final int ACC_ENUM          = 0x4000; // class, inner, field
     public static final int ACC_MANDATED      = 0x8000; // class, inner, field, method
+    public static final int ACC_MODULE        = 0x10000; // class, inner, field, method
 
     public static enum Kind { Class, InnerClass, Field, Method};
 
@@ -81,12 +82,12 @@
     }
 
     private static final int[] classModifiers = {
-        ACC_PUBLIC, ACC_FINAL, ACC_ABSTRACT
+        ACC_PUBLIC, ACC_FINAL, ACC_ABSTRACT, ACC_MODULE
     };
 
     private static final int[] classFlags = {
         ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_INTERFACE, ACC_ABSTRACT,
-        ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM
+        ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM, ACC_MODULE
     };
 
     public Set<String> getClassModifiers() {
@@ -100,12 +101,12 @@
 
     private static final int[] innerClassModifiers = {
         ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
-        ACC_ABSTRACT
+        ACC_ABSTRACT, ACC_MODULE
     };
 
     private static final int[] innerClassFlags = {
         ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SUPER,
-        ACC_INTERFACE, ACC_ABSTRACT, ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM
+        ACC_INTERFACE, ACC_ABSTRACT, ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM, ACC_MODULE
     };
 
     public Set<String> getInnerClassModifiers() {
@@ -119,12 +120,12 @@
 
     private static final int[] fieldModifiers = {
         ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
-        ACC_VOLATILE, ACC_TRANSIENT
+        ACC_VOLATILE, ACC_TRANSIENT, ACC_MODULE
     };
 
     private static final int[] fieldFlags = {
         ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
-        ACC_VOLATILE, ACC_TRANSIENT, ACC_SYNTHETIC, ACC_ENUM
+        ACC_VOLATILE, ACC_TRANSIENT, ACC_SYNTHETIC, ACC_ENUM, ACC_MODULE
     };
 
     public Set<String> getFieldModifiers() {
@@ -137,13 +138,13 @@
 
     private static final int[] methodModifiers = {
         ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
-        ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT
+        ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT, ACC_MODULE
     };
 
     private static final int[] methodFlags = {
         ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
         ACC_SYNCHRONIZED, ACC_BRIDGE, ACC_VARARGS, ACC_NATIVE, ACC_ABSTRACT,
-        ACC_STRICT, ACC_SYNTHETIC
+        ACC_STRICT, ACC_SYNTHETIC, ACC_MODULE
     };
 
     public Set<String> getMethodModifiers() {
@@ -210,6 +211,8 @@
                 return "strictfp";
             case ACC_MANDATED:
                 return "mandated";
+            case ACC_MODULE:
+                return "module";
             default:
                 return null;
         }
@@ -249,6 +252,8 @@
             return "ACC_ENUM";
         case ACC_MANDATED:
             return "ACC_MANDATED";
+        case ACC_MODULE:
+            return "ACC_MODULE";
         default:
             return null;
         }
--- a/src/share/classes/com/sun/tools/classfile/Attribute.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/classfile/Attribute.java	Tue May 07 17:14:17 2013 -0700
@@ -66,6 +66,12 @@
     public static final String StackMapTable            = "StackMapTable";
     public static final String Synthetic                = "Synthetic";
 
+    // JSR 294
+    public static final String Module                   = "Module";
+    public static final String ModuleData               = "ModuleData";
+    public static final String ModuleProvides           = "ModuleProvides";
+    public static final String ModuleRequires           = "ModuleRequires";
+
     public static class Factory {
         public Factory() {
             // defer init of standardAttributeClasses until after options set up
@@ -115,6 +121,11 @@
             standardAttributes.put(LocalVariableTable, LocalVariableTable_attribute.class);
             standardAttributes.put(LocalVariableTypeTable, LocalVariableTypeTable_attribute.class);
 
+            standardAttributes.put(Module,            Module_attribute.class);
+            standardAttributes.put(ModuleData,        ModuleData_attribute.class);
+            standardAttributes.put(ModuleProvides,    ModuleProvides_attribute.class);
+            standardAttributes.put(ModuleRequires,    ModuleRequires_attribute.class);
+
             if (!compat) { // old javap does not recognize recent attributes
                 standardAttributes.put(MethodParameters, MethodParameters_attribute.class);
                 standardAttributes.put(CompilationID, CompilationID_attribute.class);
@@ -191,5 +202,10 @@
         R visitStackMap(StackMap_attribute attr, P p);
         R visitStackMapTable(StackMapTable_attribute attr, P p);
         R visitSynthetic(Synthetic_attribute attr, P p);
+
+        R visitModule(Module_attribute attr, P p);
+        R visitModuleData(ModuleData_attribute attr, P p);
+        R visitModuleProvides(ModuleProvides_attribute attr, P p);
+        R visitModuleRequires(ModuleRequires_attribute attr, P p);
     }
 }
--- a/src/share/classes/com/sun/tools/classfile/ClassTranslator.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/classfile/ClassTranslator.java	Tue May 07 17:14:17 2013 -0700
@@ -38,6 +38,8 @@
 import com.sun.tools.classfile.ConstantPool.CONSTANT_MethodHandle_info;
 import com.sun.tools.classfile.ConstantPool.CONSTANT_MethodType_info;
 import com.sun.tools.classfile.ConstantPool.CONSTANT_Methodref_info;
+import com.sun.tools.classfile.ConstantPool.CONSTANT_ModuleId_info;
+import com.sun.tools.classfile.ConstantPool.CONSTANT_ModuleQuery_info;
 import com.sun.tools.classfile.ConstantPool.CONSTANT_NameAndType_info;
 import com.sun.tools.classfile.ConstantPool.CONSTANT_String_info;
 import com.sun.tools.classfile.ConstantPool.CONSTANT_Utf8_info;
@@ -331,6 +333,32 @@
         return info;
     }
 
+    public CPInfo visitModuleId(CONSTANT_ModuleId_info info, Map<Object, Object> translations) {
+        CONSTANT_ModuleId_info info2 = (CONSTANT_ModuleId_info) translations.get(info);
+        if (info2 == null) {
+            ConstantPool cp2 = translate(info.cp, translations);
+            if (cp2 == info.cp)
+                info2 = info;
+            else
+                info2 = new CONSTANT_ModuleId_info(cp2, info.name_index, info.version_index);
+            translations.put(info, info2);
+        }
+        return info;
+    }
+
+    public CPInfo visitModuleQuery(CONSTANT_ModuleQuery_info info, Map<Object, Object> translations) {
+        CONSTANT_ModuleQuery_info info2 = (CONSTANT_ModuleQuery_info) translations.get(info);
+        if (info2 == null) {
+            ConstantPool cp2 = translate(info.cp, translations);
+            if (cp2 == info.cp)
+                info2 = info;
+            else
+                info2 = new CONSTANT_ModuleQuery_info(cp2, info.name_index, info.version_index);
+            translations.put(info, info2);
+        }
+        return info;
+    }
+
     public CPInfo visitNameAndType(CONSTANT_NameAndType_info info, Map<Object, Object> translations) {
         CONSTANT_NameAndType_info info2 = (CONSTANT_NameAndType_info) translations.get(info);
         if (info2 == null) {
@@ -344,6 +372,7 @@
         return info;
     }
 
+
     public CPInfo visitMethodref(CONSTANT_Methodref_info info, Map<Object, Object> translations) {
         CONSTANT_Methodref_info info2 = (CONSTANT_Methodref_info) translations.get(info);
         if (info2 == null) {
@@ -356,7 +385,6 @@
         }
         return info;
     }
-
     public CPInfo visitMethodHandle(CONSTANT_MethodHandle_info info, Map<Object, Object> translations) {
         CONSTANT_MethodHandle_info info2 = (CONSTANT_MethodHandle_info) translations.get(info);
         if (info2 == null) {
--- a/src/share/classes/com/sun/tools/classfile/ClassWriter.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/classfile/ClassWriter.java	Tue May 07 17:14:17 2013 -0700
@@ -278,6 +278,18 @@
             return 2;
         }
 
+        public Integer visitModuleId(CONSTANT_ModuleId_info info, ClassOutputStream out) {
+            out.writeShort(info.name_index);
+            out.writeShort(info.version_index);
+            return 1;
+        }
+
+        public Integer visitModuleQuery(CONSTANT_ModuleQuery_info info, ClassOutputStream out) {
+            out.writeShort(info.name_index);
+            out.writeShort(info.version_index);
+            return 1;
+        }
+
         public Integer visitNameAndType(CONSTANT_NameAndType_info info, ClassOutputStream out) {
             out.writeShort(info.name_index);
             out.writeShort(info.type_index);
@@ -479,6 +491,57 @@
             out.writeShort(entry.index);
         }
 
+        public Void visitModule(Module_attribute attr, ClassOutputStream out) {
+            out.writeShort(attr.module_id_index);
+            return null;
+        }
+
+        public Void visitModuleData(ModuleData_attribute attr, ClassOutputStream out) {
+            out.writeShort(attr.data_index);
+            return null;
+        }
+
+        public Void visitModuleProvides(ModuleProvides_attribute attr, ClassOutputStream out) {
+            out.writeShort(attr.view_table.length);
+            for (ModuleProvides_attribute.View v: attr.view_table)
+                writeView(v, out);
+            return null;
+        }
+
+        protected void writeView(ModuleProvides_attribute.View v, ClassOutputStream out) {
+            out.writeShort(v.view_name_index);
+            out.writeShort(v.entrypoint_index);
+            out.writeShort(v.alias_table.length);
+            for (int alias_index: v.alias_table)
+                out.writeShort(alias_index);
+            out.writeShort(v.service_table.length);
+            for (ModuleProvides_attribute.Service s: v.service_table) {
+                out.writeShort(s.service_index);
+                out.writeShort(s.impl_index);
+            }
+            out.writeShort(v.export_table.length);
+            for (int export_index: v.export_table) {
+                out.writeShort(export_index);
+            }
+            out.writeShort(v.permit_table.length);
+            for (int permit_index: v.permit_table)
+                out.writeShort(permit_index);
+        }
+
+        public Void visitModuleRequires(ModuleRequires_attribute attr, ClassOutputStream out) {
+            out.writeShort(attr.module_table.length);
+            for (ModuleRequires_attribute.Entry e: attr.module_table) {
+                out.writeShort(e.index);
+                out.writeInt(e.flags);
+            }
+            out.writeShort(attr.service_table.length);
+            for (ModuleRequires_attribute.Entry e: attr.service_table) {
+                out.writeShort(e.index);
+                out.writeInt(e.flags);
+            }
+            return null;
+        }
+
         public Void visitMethodParameters(MethodParameters_attribute attr, ClassOutputStream out) {
             out.writeByte(attr.method_parameter_table.length);
             for (MethodParameters_attribute.Entry e : attr.method_parameter_table) {
--- a/src/share/classes/com/sun/tools/classfile/ConstantPool.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/classfile/ConstantPool.java	Tue May 07 17:14:17 2013 -0700
@@ -117,6 +117,8 @@
     public static final int CONSTANT_MethodHandle = 15;
     public static final int CONSTANT_MethodType = 16;
     public static final int CONSTANT_InvokeDynamic = 18;
+    public static final int CONSTANT_ModuleId = 19;
+    public static final int CONSTANT_ModuleQuery = 20;
 
     public static enum RefKind {
         REF_getField(1, "getfield"),
@@ -215,6 +217,14 @@
                 pool[i] = new CONSTANT_Methodref_info(this, cr);
                 break;
 
+            case CONSTANT_ModuleId:
+                pool[i] = new CONSTANT_ModuleId_info(this, cr);
+                break;
+
+            case CONSTANT_ModuleQuery:
+                pool[i] = new CONSTANT_ModuleQuery_info(this, cr);
+                break;
+
             case CONSTANT_NameAndType:
                 pool[i] = new CONSTANT_NameAndType_info(this, cr);
                 break;
@@ -278,6 +288,14 @@
         return ((CONSTANT_Class_info) get(index, CONSTANT_Class));
     }
 
+    public CONSTANT_ModuleId_info getModuleIdInfo(int index) throws InvalidIndex, UnexpectedEntry {
+        return ((CONSTANT_ModuleId_info) get(index, CONSTANT_ModuleId));
+    }
+
+    public CONSTANT_ModuleQuery_info getModuleQueryInfo(int index) throws InvalidIndex, UnexpectedEntry {
+        return ((CONSTANT_ModuleQuery_info) get(index, CONSTANT_ModuleQuery));
+    }
+
     public CONSTANT_NameAndType_info getNameAndTypeInfo(int index) throws InvalidIndex, UnexpectedEntry {
         return ((CONSTANT_NameAndType_info) get(index, CONSTANT_NameAndType));
     }
@@ -341,6 +359,8 @@
         R visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, P p);
         R visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, P p);
         R visitLong(CONSTANT_Long_info info, P p);
+        R visitModuleId(CONSTANT_ModuleId_info info, P p);
+        R visitModuleQuery(CONSTANT_ModuleQuery_info info, P p);
         R visitNameAndType(CONSTANT_NameAndType_info info, P p);
         R visitMethodref(CONSTANT_Methodref_info info, P p);
         R visitMethodHandle(CONSTANT_MethodHandle_info info, P p);
@@ -783,6 +803,91 @@
         }
     }
 
+    public static class CONSTANT_ModuleId_info extends CPInfo {
+        CONSTANT_ModuleId_info(ConstantPool cp, ClassReader cr) throws IOException {
+            super(cp);
+            name_index = cr.readUnsignedShort();
+            version_index = cr.readUnsignedShort();
+        }
+
+        public CONSTANT_ModuleId_info(ConstantPool cp, int name_index, int version_index) {
+            super(cp);
+            this.name_index = name_index;
+            this.version_index = version_index;
+        }
+
+        public int getTag() {
+            return CONSTANT_ModuleId;
+        }
+
+        public String getName() throws ConstantPoolException {
+            return cp.getUTF8Value(name_index);
+        }
+
+        public int byteLength() {
+            return 5;
+        }
+
+        public String getVersion() throws ConstantPoolException {
+            return (version_index == 0 ? null : cp.getUTF8Value(version_index));
+        }
+
+        @Override
+        public String toString() {
+            return "CONSTANT_ModuleId_info[name_index: " + name_index + ", version_index: " + version_index + "]";
+        }
+
+        public <R, D> R accept(Visitor<R, D> visitor, D data) {
+            return visitor.visitModuleId(this, data);
+        }
+
+        public final int name_index;
+        public final int version_index;
+    }
+
+
+    public static class CONSTANT_ModuleQuery_info extends CPInfo {
+        CONSTANT_ModuleQuery_info(ConstantPool cp, ClassReader cr) throws IOException {
+            super(cp);
+            name_index = cr.readUnsignedShort();
+            version_index = cr.readUnsignedShort();
+        }
+
+        public CONSTANT_ModuleQuery_info(ConstantPool cp, int name_index, int version_index) {
+            super(cp);
+            this.name_index = name_index;
+            this.version_index = version_index;
+        }
+
+        public int getTag() {
+            return CONSTANT_ModuleQuery;
+        }
+
+        public String getName() throws ConstantPoolException {
+            return cp.getUTF8Value(name_index);
+        }
+
+        public int byteLength() {
+            return 5;
+        }
+
+        public String getVersion() throws ConstantPoolException {
+            return (version_index == 0 ? null : cp.getUTF8Value(version_index));
+        }
+
+        @Override
+        public String toString() {
+            return "CONSTANT_ModuleQuery_info[name_index: " + name_index + ", version_index: " + version_index + "]";
+        }
+
+        public <R, D> R accept(Visitor<R, D> visitor, D data) {
+            return visitor.visitModuleQuery(this, data);
+        }
+
+        public final int name_index;
+        public final int version_index;
+    }
+
     public static class CONSTANT_NameAndType_info extends CPInfo {
         CONSTANT_NameAndType_info(ConstantPool cp, ClassReader cr) throws IOException {
             super(cp);
@@ -812,15 +917,15 @@
             return cp.getUTF8Value(type_index);
         }
 
-        public <R, D> R accept(Visitor<R, D> visitor, D data) {
-            return visitor.visitNameAndType(this, data);
-        }
-
         @Override
         public String toString() {
             return "CONSTANT_NameAndType_info[name_index: " + name_index + ", type_index: " + type_index + "]";
         }
 
+        public <R, D> R accept(Visitor<R, D> visitor, D data) {
+            return visitor.visitNameAndType(this, data);
+        }
+
         public final int name_index;
         public final int type_index;
     }
--- a/src/share/classes/com/sun/tools/classfile/Dependencies.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/classfile/Dependencies.java	Tue May 07 17:14:17 2013 -0700
@@ -709,6 +709,14 @@
                 return visitRef(info, p);
             }
 
+            public Void visitModuleId(CONSTANT_ModuleId_info info, Void p) {
+                return null;
+            }
+
+            public Void visitModuleQuery(CONSTANT_ModuleQuery_info info, Void p) {
+                return null;
+            }
+
             public Void visitNameAndType(CONSTANT_NameAndType_info info, Void p) {
                 try {
                     new Signature(info.type_index).getType(constant_pool).accept(this, null);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/classfile/ModuleData_attribute.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.classfile;
+
+import java.io.IOException;
+
+import com.sun.tools.classfile.ConstantPool.*;
+
+/**
+ * See Jigsaw.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class ModuleData_attribute extends Attribute {
+    ModuleData_attribute(ClassReader cr, int name_index, int length) throws IOException {
+        super(name_index, length);
+        data_index = cr.readUnsignedShort();
+    }
+
+    public ModuleData_attribute(int name_index, int data_index) {
+        super(name_index, 2);
+        this.data_index = data_index;
+    }
+
+    public String getData(ConstantPool constant_pool) throws ConstantPoolException {
+        if (data_index == 0)
+            return null;
+        return constant_pool.getUTF8Info(data_index).value;
+    }
+
+    public <R, D> R accept(Visitor<R, D> visitor, D data) {
+        return visitor.visitModuleData(this, data);
+    }
+
+    public final int data_index;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/classfile/ModuleProvides_attribute.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.classfile;
+
+import java.io.IOException;
+
+/**
+ * See Jigsaw.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class ModuleProvides_attribute extends Attribute {
+    ModuleProvides_attribute(ClassReader cr, int name_index, int length) throws IOException {
+        super(name_index, length);
+        view_length = cr.readUnsignedShort();
+        view_table = new View[view_length];
+        for (int i = 0; i < view_length; i++)
+            view_table[i] = new View(cr);
+    }
+
+    public ModuleProvides_attribute(ConstantPool constant_pool, View[] provides_table)
+            throws ConstantPoolException {
+        this(constant_pool.getUTF8Index(Attribute.ModuleProvides), provides_table);
+    }
+
+    public ModuleProvides_attribute(int name_index, View[] view_table) {
+        super(name_index, 2 + length(view_table));
+        this.view_length = view_table.length;
+        this.view_table = view_table;
+    }
+
+    public <R, D> R accept(Visitor<R, D> visitor, D data) {
+        return visitor.visitModuleProvides(this, data);
+    }
+
+    public final int view_length;
+    public final View[] view_table;
+    
+    private static int length(View[] view_table) {
+        int n = 0;
+        for (View v: view_table)
+            n += v.length();
+        return n;
+    }
+
+    public static class View {
+        public final int view_name_index;
+        public final int entrypoint_index;
+        public final int alias_length;
+        public final int[] alias_table;
+        public final int service_length;
+        public final Service[] service_table;
+        public final int export_length;
+        public final int[] export_table;
+        public final int  permit_length;
+        public final int[] permit_table;
+
+        View(ClassReader cr) throws IOException {
+            view_name_index = cr.readUnsignedShort();
+            entrypoint_index = cr.readUnsignedShort();
+            alias_length = cr.readUnsignedShort();
+            alias_table = new int[alias_length];
+            for (int i = 0; i < alias_table.length; i++)
+                alias_table[i] = cr.readUnsignedShort();
+            service_length = cr.readUnsignedShort();
+            service_table = new Service[service_length];
+            for (int i = 0; i < service_table.length; i++)
+                service_table[i] = new Service(cr);
+            export_length = cr.readUnsignedShort();
+            export_table = new int[export_length];
+            for (int i = 0; i < export_table.length; i++)
+                export_table[i] = cr.readUnsignedShort();
+            permit_length = cr.readUnsignedShort();
+            permit_table = new int[permit_length];
+            for (int i = 0; i < permit_table.length; i++)
+                permit_table[i] = cr.readUnsignedShort();
+        }
+        
+        public View(int view_name_index, int entrypoint_index,
+                    int[] alias_table, Service[] service_table,
+                    int[] export_table, int[] permit_table)
+        {
+            this.view_name_index = view_name_index;
+            this.entrypoint_index = entrypoint_index;
+            this.alias_length = alias_table.length;
+            this.alias_table = alias_table;
+            this.export_length = export_table.length;
+            this.export_table = export_table;
+            this.permit_length = permit_table.length;
+            this.permit_table = permit_table;
+            this.service_length = service_table.length;
+            this.service_table = service_table;
+        }
+        
+        int length() {
+            return  2   // view_name_index
+                    + 2 // entrypoint_index
+                    + 2 + 2 * alias_table.length
+                    + 2 + Service.length * service_table.length
+                    + 2 + 2 * export_table.length
+                    + 2 + 2 * permit_table.length;
+
+        }
+    }
+
+    public static class Service {
+        static final int length = 4;
+
+        public final int service_index;
+        public final int impl_index;
+
+        Service(ClassReader cr) throws IOException {
+            service_index = cr.readUnsignedShort();
+            impl_index = cr.readUnsignedShort();
+        }
+
+	public Service(int service_index, int impl_index) {
+	    this.service_index = service_index;
+	    this.impl_index = impl_index;
+	}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/classfile/ModuleRequires_attribute.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.classfile;
+
+import java.io.IOException;
+
+/**
+ * See Jigsaw.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class ModuleRequires_attribute extends Attribute {
+    public static final int ACC_OPTIONAL = 0x1;
+    public static final int ACC_LOCAL = 0x2;
+    public static final int ACC_REEXPORT = 0x4;
+    public static final int ACC_SYNTHETIC = 0x1000;
+    public static final int ACC_SYNTHESIZED = 0x10000;
+
+    ModuleRequires_attribute(ClassReader cr, int name_index, int length) throws IOException {
+        super(name_index, length);
+        module_length = cr.readUnsignedShort();
+        module_table = new Entry[module_length];
+        for (int i = 0; i < module_length; i++)
+            module_table[i] = new Entry(cr);
+        service_length = cr.readUnsignedShort();
+        service_table = new Entry[service_length];
+        for (int i = 0; i < service_length; i++)
+            service_table[i] = new Entry(cr);
+    }
+
+    public ModuleRequires_attribute(ConstantPool constant_pool, Entry[] module_table, Entry[] service_table)
+            throws ConstantPoolException {
+        this(constant_pool.getUTF8Index(Attribute.ModuleRequires), module_table, service_table);
+    }
+
+    public ModuleRequires_attribute(int name_index, Entry[] module_table, Entry[] service_table) {
+        super(name_index, 2 + length(module_table) + 2 + length(service_table));
+        this.module_length = module_table.length;
+        this.module_table = module_table;
+        this.service_length = service_table.length;
+        this.service_table = service_table;
+    }
+
+    public <R, D> R accept(Visitor<R, D> visitor, D data) {
+        return visitor.visitModuleRequires(this, data);
+    }
+
+    public final int module_length;
+    public final Entry[] module_table;
+    public final int service_length;
+    public final Entry[] service_table;
+
+    private static int length(Entry[] table) {
+        return table.length * Entry.length;
+    }
+
+    public static class Entry {
+        Entry(ClassReader cr) throws IOException {
+            index = cr.readUnsignedShort();
+            flags = cr.readInt();
+        }
+
+        public Entry(int index, int flags) {
+            this.index = index;
+            this.flags = flags;
+        }
+
+        public static final int length = 4;
+
+        public final int index;
+        public final int flags;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/classfile/Module_attribute.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.classfile;
+
+import java.io.IOException;
+
+/**
+ * See Jigsaw.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class Module_attribute extends Attribute {
+    Module_attribute(ClassReader cr, int name_index, int length) throws IOException {
+        super(name_index, length);
+        module_id_index = cr.readUnsignedShort();
+    }
+
+    public Module_attribute(int name_index, int module_id_index) {
+        super(name_index, 2);
+        this.module_id_index = module_id_index;
+    }
+
+    public String getModuleName(ConstantPool constant_pool) throws ConstantPoolException {
+        return constant_pool.getModuleIdInfo(module_id_index).getName();
+    }
+
+    public String getModuleVersion(ConstantPool constant_pool) throws ConstantPoolException {
+        return constant_pool.getModuleIdInfo(module_id_index).getVersion();
+    }
+
+    public <R, D> R accept(Visitor<R, D> visitor, D data) {
+        return visitor.visitModule(this, data);
+    }
+
+    public final int module_id_index;
+
+}
--- a/src/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java	Tue May 07 17:14:17 2013 -0700
@@ -55,6 +55,7 @@
 import javax.tools.JavaFileManager.Location;
 import javax.tools.JavaFileObject;
 import javax.tools.JavaFileObject.Kind;
+import javax.tools.ModuleFileManager;
 
 import com.sun.source.util.TaskEvent;
 import com.sun.source.util.TaskListener;
@@ -111,13 +112,16 @@
     }
 
     public JavaFileManager wrap(JavaFileManager fm) {
-        if (isTrusted(fm))
+        if (fm == null || isTrusted(fm))
             return fm;
-        return new WrappedJavaFileManager(fm);
+        if (fm instanceof ModuleFileManager)
+            return new WrappedModuleFileManager(fm);
+        else
+            return new WrappedJavaFileManager(fm);
     }
 
     public FileObject wrap(FileObject fo) {
-        if (isTrusted(fo))
+        if (fo == null || isTrusted(fo))
             return fo;
         return new WrappedFileObject(fo);
     }
@@ -130,7 +134,7 @@
     }
 
     public JavaFileObject wrap(JavaFileObject fo) {
-        if (isTrusted(fo))
+        if (fo == null || isTrusted(fo))
             return fo;
         return new WrappedJavaFileObject(fo);
     }
@@ -150,13 +154,13 @@
     }
 
     public <T /*super JavaFileOject*/> DiagnosticListener<T> wrap(DiagnosticListener<T> dl) {
-        if (isTrusted(dl))
+        if (dl == null || isTrusted(dl))
             return dl;
         return new WrappedDiagnosticListener<T>(dl);
     }
 
     TaskListener wrap(TaskListener tl) {
-        if (isTrusted(tl))
+        if (tl == null || isTrusted(tl))
             return tl;
         return new WrappedTaskListener(tl);
     }
@@ -387,7 +391,63 @@
         }
     }
 
-    protected class WrappedFileObject implements FileObject {
+    protected class WrappedModuleFileManager extends WrappedJavaFileManager implements ModuleFileManager {
+        protected ModuleFileManager clientModuleFileManager;
+        WrappedModuleFileManager(JavaFileManager clientJavaFileManager) {
+            super(clientJavaFileManager);
+            this.clientModuleFileManager = (ModuleFileManager) clientJavaFileManager;
+        }
+
+        public ModuleMode getModuleMode() {
+            try {
+                return ((clientModuleFileManager).getModuleMode());
+            } catch (ClientCodeException e) {
+                throw e;
+            } catch (RuntimeException e) {
+                throw new ClientCodeException(e);
+            } catch (Error e) {
+                throw new ClientCodeException(e);
+            }
+        }
+
+        public Location getModuleLocation(Location location, JavaFileObject fo, String packageName) throws IllegalArgumentException {
+            try {
+                return ((clientModuleFileManager).getModuleLocation(location, unwrap(fo), packageName));
+            } catch (ClientCodeException e) {
+                throw e;
+            } catch (RuntimeException e) {
+                throw new ClientCodeException(e);
+            } catch (Error e) {
+                throw new ClientCodeException(e);
+            }
+        }
+
+        public Iterable<? extends Location> getModuleLocations(Location location) {
+            try {
+                return ((clientModuleFileManager).getModuleLocations(location));
+            } catch (ClientCodeException e) {
+                throw e;
+            } catch (RuntimeException e) {
+                throw new ClientCodeException(e);
+            } catch (Error e) {
+                throw new ClientCodeException(e);
+            }
+        }
+
+        public Location join(Iterable<? extends Location> locations) {
+            try {
+                return ((clientModuleFileManager).join(locations));
+            } catch (ClientCodeException e) {
+                throw e;
+            } catch (RuntimeException e) {
+                throw new ClientCodeException(e);
+            } catch (Error e) {
+                throw new ClientCodeException(e);
+            }
+        }
+    }
+
+    protected class WrappedFileObject implements FileObject, FileObject.Locatable {
         protected FileObject clientFileObject;
         WrappedFileObject(FileObject clientFileObject) {
             clientFileObject.getClass(); // null check
@@ -512,6 +572,22 @@
         }
 
         @Override
+        public Location getLocation() {
+            try {
+                if (clientFileObject instanceof Locatable)
+                    return ((Locatable) clientFileObject).getLocation();
+                else
+                    return null;
+            } catch (ClientCodeException e) {
+                throw e;
+            } catch (RuntimeException e) {
+                throw new ClientCodeException(e);
+            } catch (Error e) {
+                throw new ClientCodeException(e);
+            }
+        }
+
+        @Override
         public String toString() {
             return wrappedToString(getClass(), clientFileObject);
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/javac/code/Directive.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,496 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javac.code;
+
+import java.util.EnumSet;
+import java.util.Set;
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.code.Symbol.PackageSymbol;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.Name;
+
+
+/**
+ *  Root class for the directives that may appear in module compilation units.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public abstract class Directive {
+    public enum Kind {
+        REQUIRES_MODULE,
+        REQUIRES_SERVICE,
+        PROVIDES_MODULE,
+        PROVIDES_SERVICE,
+        EXPORTS,
+        PERMITS,
+        ENTRYPOINT,
+        VIEW
+    }
+
+    /** Flags for RequiresModuleDirective and RequiresServiceDirective. */
+    public enum RequiresFlag {
+        OPTIONAL(0x0001),
+        LOCAL(0x0002),
+        REEXPORT(0x0004),
+        SYNTHETIC(0x1000),
+        SYNTHESIZED(0x10000);
+
+        // overkill? move to ClassWriter?
+        public static int value(Set<RequiresFlag> s) {
+            int v = 0;
+            for (RequiresFlag f: s)
+                v |= f.value;
+            return v;
+        }
+        
+        RequiresFlag(int value) {
+            this.value = value;
+        }
+        
+        public final int value;
+    }
+
+    public abstract Kind getKind();
+
+    abstract <R, P> R accept(Visitor<R, P> visitor, P data);
+
+    static <T extends Directive> List<T> filter(List<Directive> directives, Kind kind, Class<T> clazz) {
+        ListBuffer<T> list = ListBuffer.lb();
+        for (Directive d: directives) {
+            if (d.getKind() == kind)
+                list.add(clazz.cast(d));
+        }
+        return list.toList();
+    }
+
+    /**
+     * 'requires' ['optional'] {'local' | 'public'} ModuleNameAndVersionQuery ';'
+     */
+    public static class RequiresModuleDirective extends Directive {
+        public final ModuleQuery moduleQuery;
+        public final Set<RequiresFlag> flags;
+
+        public RequiresModuleDirective(ModuleQuery moduleQuery) {
+            this(moduleQuery, EnumSet.noneOf(RequiresFlag.class));
+        }
+
+        public RequiresModuleDirective(ModuleQuery moduleQuery, Set<RequiresFlag> flags) {
+            this.moduleQuery = moduleQuery;
+            this.flags = flags;
+        }
+
+        @Override
+        public Kind getKind() {
+            return Kind.REQUIRES_MODULE;
+        }
+
+        @Override
+        public String toString() {
+            return "RequiresModule[" + flags + "," + moduleQuery + "]";
+        }
+
+        @Override
+        public <R, P> R accept(Visitor<R, P> visitor, P data) {
+            return visitor.visitRequiresModule(this, data);
+        }
+    }
+
+    /**
+     * 'requires' ['optional'] 'service' ServiceName ';'
+     */
+    public static class RequiresServiceDirective extends Directive {
+        public final ClassSymbol sym;
+        public final Set<RequiresFlag> flags;
+
+        public RequiresServiceDirective(ClassSymbol sym, Set<RequiresFlag> flags) {
+            this.sym = sym;
+            this.flags = flags;
+        }
+
+        @Override
+        public Kind getKind() {
+            return Kind.REQUIRES_SERVICE;
+        }
+
+        @Override
+        public String toString() {
+            return "RequiresService[" + flags + "," + sym + "]";
+        }
+
+        @Override
+        public <R, P> R accept(Visitor<R, P> visitor, P data) {
+            return visitor.visitRequiresService(this, data);
+        }
+    }
+
+    /**
+     * 'provides' ModuleNameAndVersion ';'
+     */
+    public static class ProvidesModuleDirective extends Directive {
+        public final ModuleId moduleId;
+
+        public ProvidesModuleDirective(ModuleId moduleId) {
+            this.moduleId = moduleId;
+        }
+
+        @Override
+        public Kind getKind() {
+            return Kind.PROVIDES_MODULE;
+        }
+
+        @Override
+        public String toString() {
+            return "ProvidesModule[" + moduleId + "]";
+        }
+
+        @Override
+        public <R, P> R accept(Visitor<R, P> visitor, P data) {
+            return visitor.visitProvidesModule(this, data);
+        }
+    }
+
+    /**
+     * 'provides' 'service' ServiceName 'with' QualifiedIdentifer ';'
+     */
+    public static class ProvidesServiceDirective extends Directive {
+        public final ClassSymbol service;
+        public final ClassSymbol impl;
+
+        public ProvidesServiceDirective(ClassSymbol service, ClassSymbol impl) {
+            this.service = service;
+            this.impl = impl;
+        }
+
+        @Override
+        public Kind getKind() {
+            return Kind.PROVIDES_SERVICE;
+        }
+
+        @Override
+        public String toString() {
+            return "ProvidesService[" + service + "," + impl + "]";
+        }
+
+        @Override
+        public <R, P> R accept(Visitor<R, P> visitor, P data) {
+            return visitor.visitProvidesService(this, data);
+        }
+    }
+
+    /**
+     * 'exports' Package ';'
+     */
+    public static class ExportsDirective extends Directive {
+        public final PackageSymbol sym;
+
+        public ExportsDirective(PackageSymbol sym) {
+            this.sym = sym;
+        }
+
+        @Override
+        public Kind getKind() {
+            return Kind.EXPORTS;
+        }
+
+        @Override
+        public String toString() {
+            return "Exports[" + sym + "]";
+        }
+
+        @Override
+        public <R, P> R accept(Visitor<R, P> visitor, P data) {
+            return visitor.visitExports(this, data);
+        }
+    }
+
+    /**
+     * 'permits' ModuleName ';'
+     */
+    public static class PermitsDirective extends Directive {
+        public final ModuleId moduleId;
+
+        public PermitsDirective(ModuleId moduleId) {
+            this.moduleId = moduleId;
+        }
+
+        public PermitsDirective(Name moduleName) {
+            moduleId = new ModuleId(moduleName);
+        }
+
+        @Override
+        public Kind getKind() {
+            return Kind.PERMITS;
+        }
+
+        @Override
+        public String toString() {
+            return "Permits[" + moduleId + "]";
+        }
+
+        @Override
+        public <R, P> R accept(Visitor<R, P> visitor, P data) {
+            return visitor.visitPermits(this, data);
+        }
+    }
+
+    /**
+     * 'class' TypeName ';'
+     */
+    public static class EntrypointDirective extends Directive {
+        public final ClassSymbol sym;
+
+        public EntrypointDirective(ClassSymbol sym) {
+            this.sym = sym;
+        }
+
+        @Override
+        public Kind getKind() {
+            return Kind.ENTRYPOINT;
+        }
+
+        @Override
+        public String toString() {
+            return "Entrypoint[" + sym + "]";
+        }
+
+        @Override
+        public <R, P> R accept(Visitor<R, P> visitor, P data) {
+            return visitor.visitEntrypoint(this, data);
+        }
+    }
+
+    /**
+     * 'view' ModuleName '{' {ProvidesDirective | ExportsDirective | PermitsDirective | EntrypointDirective} '}'
+     */
+    public static class ViewDeclaration extends Directive {
+        public final Name name;
+        public final List<Directive> directives;
+
+        public ViewDeclaration(Name name, List<Directive> directives) {
+            this.name = name;
+            this.directives = directives;
+        }
+
+        public ViewDeclaration(List<Directive> directives) {
+            this.name = null;
+            this.directives = directives;
+        }
+
+        public boolean isDefault() {
+            return name == null;
+        }
+
+        public boolean hasEntrypoint() {
+            for (Directive d: directives) {
+                if (d.getKind() == Directive.Kind.ENTRYPOINT)
+                    return true;
+            }
+            return false;
+        }
+
+        public ClassSymbol getEntrypoint() {
+            List<EntrypointDirective> list =
+                    filter(directives, Kind.ENTRYPOINT, EntrypointDirective.class);
+            return list.isEmpty() ? null : list.head.sym;
+        }
+
+        public List<ProvidesModuleDirective> getAliases() {
+            return filter(directives, Kind.PROVIDES_MODULE, ProvidesModuleDirective.class);
+        }
+
+        public List<ProvidesServiceDirective> getServices() {
+            return filter(directives, Kind.PROVIDES_SERVICE, ProvidesServiceDirective.class);
+        }
+
+        public List<ExportsDirective> getExports() {
+            return filter(directives, Kind.EXPORTS, ExportsDirective.class);
+        }
+
+        public List<PermitsDirective> getPermits() {
+            return filter(directives, Kind.PERMITS, PermitsDirective.class);
+        }
+
+        @Override
+        public Kind getKind() {
+            return Kind.VIEW;
+        }
+
+        @Override
+        public String toString() {
+            return "View[" + directives + "]";
+        }
+
+        @Override
+        public <R, P> R accept(Visitor<R, P> visitor, P data) {
+            return visitor.visitView(this, data);
+        }
+    }
+
+    public static interface Visitor<R, P> {
+        R visitRequiresModule(RequiresModuleDirective d, P p);
+        R visitRequiresService(RequiresServiceDirective d, P p);
+        R visitProvidesModule(ProvidesModuleDirective d, P p);
+        R visitProvidesService(ProvidesServiceDirective d, P p);
+        R visitExports(ExportsDirective d, P p);
+        R visitPermits(PermitsDirective d, P p);
+        R visitEntrypoint(EntrypointDirective d, P p);
+        R visitView(ViewDeclaration d, P p);
+    }
+
+    public static class SimpleVisitor<R, P> implements Visitor<R, P> {
+        protected final R DEFAULT_VALUE;
+
+        protected SimpleVisitor() {
+            DEFAULT_VALUE = null;
+        }
+
+        protected SimpleVisitor(R defaultValue) {
+            DEFAULT_VALUE = defaultValue;
+        }
+
+        protected R defaultAction(Directive d, P p) {
+            return DEFAULT_VALUE;
+        }
+
+        public final R visit(Directive d, P p) {
+            return (d == null) ? null : d.accept(this, p);
+        }
+
+        public final R visit(Iterable<? extends Directive> ds, P p) {
+            R r = null;
+            if (ds != null)
+                for (Directive d : ds)
+                    r = visit(d, p);
+            return r;
+        }
+
+        public R visitRequiresModule(RequiresModuleDirective d, P p) {
+            return defaultAction(d, p);
+        }
+
+        public R visitRequiresService(RequiresServiceDirective d, P p) {
+            return defaultAction(d, p);
+        }
+
+        public R visitProvidesModule(ProvidesModuleDirective d, P p) {
+            return defaultAction(d, p);
+        }
+
+        public R visitProvidesService(ProvidesServiceDirective d, P p) {
+            return defaultAction(d, p);
+        }
+
+        public R visitExports(ExportsDirective d, P p) {
+            return defaultAction(d, p);
+        }
+
+        public R visitPermits(PermitsDirective d, P p) {
+            return defaultAction(d, p);
+        }
+
+        public R visitEntrypoint(EntrypointDirective d, P p) {
+            return defaultAction(d, p);
+        }
+
+        public R visitView(ViewDeclaration d, P p) {
+            return defaultAction(d, p);
+        }
+    }
+
+    public static class Scanner<R, P> implements Visitor<R, P> {
+
+
+        /** Scan a single node.
+         */
+        public R scan(Directive d, P p) {
+            return (d == null) ? null : d.accept(this, p);
+        }
+
+        private R scanAndReduce(Directive d, P p, R r) {
+            return reduce(scan(d, p), r);
+        }
+
+        /** Scan a list of nodes.
+         */
+        public R scan(Iterable<? extends Directive> ds, P p) {
+            R r = null;
+            if (ds != null) {
+                boolean first = true;
+                for (Directive d : ds) {
+                    r = (first ? scan(d, p) : scanAndReduce(d, p, r));
+                    first = false;
+                }
+            }
+            return r;
+        }
+
+        /**
+         * Reduces two results into a combined result.
+         * The default implementation is to return the first parameter.
+         * The general contract of the method is that it may take any action whatsoever.
+         */
+        public R reduce(R r1, R r2) {
+            return r1;
+        }
+
+        public R visitRequiresModule(RequiresModuleDirective d, P p) {
+            return null;
+        }
+
+        public R visitRequiresService(RequiresServiceDirective d, P p) {
+            return null;
+        }
+
+        public R visitProvidesModule(ProvidesModuleDirective d, P p) {
+            return null;
+        }
+
+        public R visitProvidesService(ProvidesServiceDirective d, P p) {
+            return null;
+        }
+
+        public R visitExports(ExportsDirective d, P p) {
+            return null;
+        }
+
+        public R visitPermits(PermitsDirective d, P p) {
+            return null;
+        }
+
+        public R visitEntrypoint(EntrypointDirective d, P p) {
+            return null;
+        }
+
+        public R visitView(ViewDeclaration d, P p) {
+            return scan(d.directives, p);
+        }
+
+    }
+}
--- a/src/share/classes/com/sun/tools/javac/code/Flags.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Flags.java	Tue May 07 17:14:17 2013 -0700
@@ -378,6 +378,7 @@
             this.name = name;
         }
 
+        @Override
         public String toString() {
             return name;
         }
--- a/src/share/classes/com/sun/tools/javac/code/Kinds.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Kinds.java	Tue May 07 17:14:17 2013 -0700
@@ -73,9 +73,13 @@
      */
     public final static int MTH = 1 << 4;
 
+    /** The kind of modules.
+     */
+    public final static int MDL = 1 << 5;
+
     /** The error kind, which includes all other kinds.
      */
-    public final static int ERR = (1 << 5) - 1;
+    public final static int ERR = (1 << 6) - 1;
 
     /** The set of all kinds.
      */
@@ -108,7 +112,8 @@
         CLASS("kindname.class"),
         STATIC_INIT("kindname.static.init"),
         INSTANCE_INIT("kindname.instance.init"),
-        PACKAGE("kindname.package");
+        PACKAGE("kindname.package"),
+        MODULE("kindname.module");
 
         private final String name;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/javac/code/ModuleId.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javac.code;
+
+import com.sun.tools.javac.api.Formattable;
+import com.sun.tools.javac.api.Messages;
+import com.sun.tools.javac.util.Name;
+import java.util.Locale;
+
+/**
+ * Representation of a module id, {@literal module-name[@version]}
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class ModuleId implements javax.lang.model.element.ModuleElement.ModuleId, Formattable {
+    public final Name name;
+    public final Name version;
+
+    public ModuleId(Name name) {
+        this.name = name;
+        this.version = null;
+    }
+
+    public ModuleId(Name name, Name version) {
+        this.name = name;
+        this.version = version;
+    }
+
+    public CharSequence getName() {
+        return name;
+    }
+
+    public CharSequence getVersion() {
+        return version;
+    }
+
+    public ModuleQuery toQuery() {
+        return new ModuleQuery(name, version);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (!(other instanceof ModuleId))
+            return false;
+
+        ModuleId m = (ModuleId) other;
+        if (name != m.name)
+            return false;
+
+        return (version == null ? m.version == null : version.equals(m.version));
+    }
+
+    @Override
+    public int hashCode() {
+        if (version == null) {
+            return name.hashCode();
+        } else {
+            return name.hashCode() * version.hashCode();
+        }
+    }
+
+    // for debugging
+    @Override
+    public String toString() {
+        return "ModuleId[" + name + (version == null ? "" : "@" + version) + "]";
+    }
+
+    // for use in diagnostics
+    @Override
+    public String toString(Locale locale, Messages messages) {
+        return version == null ? name.toString() : name + "@" + version;
+    }
+
+    public String getKind() {
+        return "ModuleId";
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/javac/code/ModuleQuery.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javac.code;
+
+import java.util.Locale;
+
+import com.sun.tools.javac.api.Formattable;
+import com.sun.tools.javac.api.Messages;
+import com.sun.tools.javac.util.Name;
+
+/**
+ * Representation of a module query, @literal{module-name@version-query}
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class ModuleQuery implements javax.lang.model.element.ModuleElement.ModuleQuery, Formattable {
+    public final Name name;
+    public final Name versionQuery;
+
+    public ModuleQuery(Name name, Name version) {
+        this.name = name;
+        this.versionQuery = version;
+    }
+
+    public CharSequence getName() {
+        return name;
+    }
+
+    public CharSequence getVersionQuery() {
+        return versionQuery;
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (!(other instanceof ModuleQuery))
+            return false;
+
+        ModuleQuery m = (ModuleQuery) other;
+        if (name != m.name)
+            return false;
+
+        return (versionQuery == null) ? (m.versionQuery == null)
+                : versionQuery.equals(m.versionQuery);
+    }
+
+    @Override
+    public int hashCode() {
+        if (versionQuery == null) {
+            return name.hashCode();
+        } else {
+            return name.hashCode() * versionQuery.hashCode();
+        }
+    }
+
+    // for debugging
+    @Override
+    public String toString() {
+        return "ModuleQuery[" + name + (versionQuery == null ? "" : "@" + versionQuery) + "]";
+    }
+
+    // for use in diagnostics
+    @Override
+    public String toString(Locale locale, Messages messages) {
+        return versionQuery == null ? name.toString() : name + "@" + versionQuery;
+    }
+
+    public String getKind() {
+        return "ModuleQuery";
+    }
+
+}
--- a/src/share/classes/com/sun/tools/javac/code/Printer.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Printer.java	Tue May 07 17:14:17 2013 -0700
@@ -244,6 +244,11 @@
         }
     }
 
+    @Override
+    public String visitModuleType(ModuleType t, Locale locale) {
+        return visitType(t, locale);
+    }
+
     public String visitType(Type t, Locale locale) {
         String s = (t.tsym == null || t.tsym.name == null)
                 ? localize(locale, "compiler.misc.type.none")
--- a/src/share/classes/com/sun/tools/javac/code/Scope.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Scope.java	Tue May 07 17:14:17 2013 -0700
@@ -107,7 +107,7 @@
         this.nelems = nelems;
     }
 
-    /** Construct a new scope, within scope next, with given owner,
+    /** Construct a new scope, with given owner,
      *  using a fresh table of length INITIAL_SIZE.
      */
     public Scope(Symbol owner) {
--- a/src/share/classes/com/sun/tools/javac/code/Source.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Source.java	Tue May 07 17:14:17 2013 -0700
@@ -167,6 +167,9 @@
     public boolean allowAnonOuterThis() {
         return compareTo(JDK1_5) >= 0;
     }
+    public boolean allowModules() {
+        return compareTo(JDK1_7) >= 0;
+    }
     public boolean addBridges() {
         return compareTo(JDK1_5) >= 0;
     }
--- a/src/share/classes/com/sun/tools/javac/code/Symbol.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Symbol.java	Tue May 07 17:14:17 2013 -0700
@@ -25,12 +25,15 @@
 
 package com.sun.tools.javac.code;
 
+import java.util.LinkedHashSet;
 import java.util.Set;
 import java.util.concurrent.Callable;
 
 import javax.lang.model.element.*;
+import javax.tools.JavaFileManager;
 import javax.tools.JavaFileObject;
 
+import com.sun.tools.javac.code.Directive.*;
 import com.sun.tools.javac.code.Type.*;
 import com.sun.tools.javac.comp.Attr;
 import com.sun.tools.javac.comp.AttrContext;
@@ -323,6 +326,13 @@
         return (PackageSymbol) sym;
     }
 
+    /** The module which indirectly owns this symbol.
+     */
+    public ModuleSymbol modle() {
+        ClassSymbol c = outermostClass();
+        return c == null ? null : c.modle;
+    }
+
     /** Is this symbol a subclass of `base'? Only defined for ClassSymbols.
      */
     public boolean isSubClass(Symbol base, Types types) {
@@ -662,6 +672,156 @@
         }
     }
 
+    /** A class for module symbols.
+     */
+    public static class ModuleSymbol extends TypeSymbol implements ModuleElement // JIGSAW need TypeSymbol?
+            /*implements ModuleElement*/ {
+
+        public Name fullname;
+        public Name version;
+
+        /** All directives, in natural order. */
+        public List<Directive> directives;
+
+        /** An uninterpreted sequence of characters associated with the module. */
+        public Name extendedMetadata;
+
+        public ClassSymbol module_info;
+
+        public JavaFileManager.Location location;
+
+        public ModuleSymbol() {
+            super(MDL, 0, null, null, null);
+            this.type = new ModuleType(this);
+        }
+
+        public ModuleSymbol(Name name, Symbol owner) {
+            super(MDL, 0, name, null, owner);
+            this.type = new ModuleType(this);
+            this.fullname = formFullName(name, owner);
+        }
+
+        // Currently ModuleId is defined in ModuleElement, which means
+        public com.sun.tools.javac.code.ModuleId getModuleId() {
+            return new com.sun.tools.javac.code.ModuleId(fullname, version);
+        }
+
+        public boolean hasRequires() {
+            for (Directive d: directives) {
+                switch (d.getKind()) {
+                    case REQUIRES_MODULE:
+                    case REQUIRES_SERVICE:
+                        return true;
+                }
+            }
+            return false;
+        }
+
+        public List<RequiresModuleDirective> getRequiredModules() {
+            return Directive.filter(directives, Directive.Kind.REQUIRES_MODULE,
+                    RequiresModuleDirective.class);
+        }
+
+        public List<RequiresServiceDirective> getRequiredServices() {
+            return Directive.filter(directives, Directive.Kind.REQUIRES_SERVICE,
+                    RequiresServiceDirective.class);
+        }
+
+        public boolean hasViews() {
+            for (Directive d: directives) {
+                switch (d.getKind()) {
+                    case REQUIRES_MODULE:
+                    case REQUIRES_SERVICE:
+                        continue;
+                    default:
+                        return true;
+                }
+            }
+            return false;
+        }
+
+        public ViewDeclaration getDefaultView() {
+            ListBuffer<Directive> defaultViewDirectives = ListBuffer.lb();
+            for (Directive d: directives) {
+                switch (d.getKind()) {
+                    case PROVIDES_MODULE:
+                    case PROVIDES_SERVICE:
+                    case EXPORTS:
+                    case PERMITS:
+                    case ENTRYPOINT:
+                        defaultViewDirectives.add(d);
+                }
+            }
+            return new ViewDeclaration(defaultViewDirectives.toList());
+        }
+
+        public List<ViewDeclaration> getViews() {
+            ListBuffer<Directive> defaultViewDirectives = ListBuffer.lb();
+            for (Directive d: directives) {
+                switch (d.getKind()) {
+                    case PROVIDES_MODULE:
+                    case PROVIDES_SERVICE:
+                    case EXPORTS:
+                    case PERMITS:
+                    case ENTRYPOINT:
+                        defaultViewDirectives.add(d);
+                }
+            }
+            List<ViewDeclaration> views =
+                    Directive.filter(directives, Directive.Kind.VIEW,
+                        ViewDeclaration.class);
+            if (defaultViewDirectives.nonEmpty())
+                views = views.prepend(new ViewDeclaration(defaultViewDirectives.toList()));
+            return views;
+        }
+
+        public boolean hasExtendedMetadata() {
+            return (extendedMetadata != null) && !extendedMetadata.isEmpty();
+        }
+
+        public Set<PackageSymbol> getExports(final ViewDeclaration viewDecl) {
+            final Set<PackageSymbol> exports = new LinkedHashSet<PackageSymbol>();
+            Directive.Scanner<Void,Void> s = new Directive.Scanner<Void,Void>() {
+                @Override
+                public Void visitExports(Directive.ExportsDirective d, Void p) {
+                    exports.add(d.sym);
+                    return null;
+                }
+                @Override
+                public Void visitView(Directive.ViewDeclaration d, Void p) {
+                    if (d == viewDecl)
+                        scan(d.directives, null);
+                    return null;
+                }
+            };
+            s.scan(directives, null);
+            return exports;
+        }
+
+        @Override
+        public String toString() {
+            // the following strings should be localized
+            String n = (fullname == null) ? "<unknown>"
+                    : (fullname.isEmpty()) ? "<unnamed>"
+                    : String.valueOf(fullname);
+            return (version == null) ? n : n + "@" + version;
+        }
+
+        @Override
+        public Name getQualifiedName() {
+            return fullname;
+        }
+
+        public boolean isUnnamed() {
+            return name.isEmpty() && owner != null;
+        }
+
+        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
+            // ## 
+            return v.visit(this, p);
+        }
+    }
+
     /** A class for package symbols
      */
     public static class PackageSymbol extends TypeSymbol
@@ -748,6 +908,10 @@
     /** A class for class symbols
      */
     public static class ClassSymbol extends TypeSymbol implements TypeElement {
+        /**
+         * The module for the class.
+         */
+        public ModuleSymbol modle;
 
         /** a scope for all class members; variables, methods and inner classes
          *  type parameters are not part of this scope
--- a/src/share/classes/com/sun/tools/javac/code/Symtab.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Symtab.java	Tue May 07 17:14:17 2013 -0700
@@ -29,6 +29,7 @@
 
 import javax.lang.model.element.ElementVisitor;
 import javax.lang.model.type.TypeVisitor;
+import javax.tools.JavaFileManager.Location;
 
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.code.Type.*;
@@ -36,8 +37,8 @@
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.List;
 import static com.sun.tools.javac.code.Flags.*;
+import static com.sun.tools.javac.code.TypeTag.*;
 import static com.sun.tools.javac.jvm.ByteCodes.*;
-import static com.sun.tools.javac.code.TypeTag.*;
 
 /** A class that defines all predefined constants and operators
  *  as well as special classes such as java.lang.Object, which need
@@ -80,6 +81,18 @@
     private final ClassReader reader;
     private final Target target;
 
+    /** A symbol for the root module.
+     */
+    public final ModuleSymbol rootModule;
+
+    /** A symbol for the unnamed module.
+     */
+    public final ModuleSymbol unnamedModule;
+
+    /** A symbol for no module, for use with -source 7 or less
+     */
+    public final ModuleSymbol noModule;
+
     /** A symbol for the root package.
      */
     public final PackageSymbol rootPackage;
@@ -186,7 +199,7 @@
      */
     public final Type[] typeOfTag = new Type[TypeTag.getTypeTagCount()];
 
-    /** The name of the class that belongs to a basix type tag.
+    /** The name of the class that belongs to a basic type tag.
      */
     public final Name[] boxedName = new Name[TypeTag.getTypeTagCount()];
 
@@ -194,6 +207,22 @@
      */
     public final Set<Name> operatorNames = new HashSet<Name>();
 
+    /** The name of the base module.
+     */
+    public final ModuleId baseModule;
+
+    /** A query for the base module.
+     */
+    public final ModuleQuery baseModuleQuery;
+
+    /** The name of the "legacy JDK" module.
+     */
+    public final ModuleId jdkLegacyModule;
+
+    /** A query for the "legacy JDK" module.
+     */
+    public final ModuleQuery jdkLegacyQuery;
+
     /** A hashtable containing the encountered top-level and member classes,
      *  indexed by flat names. The table does not contain local classes.
      *  It should be updated from the outside to reflect classes defined
@@ -207,6 +236,12 @@
      */
     public final Map<Name, PackageSymbol> packages = new HashMap<Name, PackageSymbol>();
 
+    /** A hashtable containing the encountered modules.
+     *  the table should be updated from outside to reflect modules
+     * found in the host environment.
+     */
+    public Map<Location,ModuleSymbol> allModules = new LinkedHashMap<Location,ModuleSymbol>();
+
     public void initType(Type type, ClassSymbol c) {
         type.tsym = c;
         typeOfTag[type.tag.ordinal()] = type;
@@ -397,14 +432,24 @@
         };
 
         // create the basic builtin symbols
+        final JavacMessages messages = JavacMessages.instance(context);
+        rootModule = new ModuleSymbol(names.empty, null);
+        unnamedModule = new ModuleSymbol(names.empty, rootModule) {
+                @Override
+                public String toString() {
+                    return messages.getLocalizedString("compiler.misc.unnamed.module");
+                }
+            };
+        noModule = new ModuleSymbol(names.empty, rootModule) { };
         rootPackage = new PackageSymbol(names.empty, null);
-        final JavacMessages messages = JavacMessages.instance(context);
         unnamedPackage = new PackageSymbol(names.empty, rootPackage) {
+                @Override
                 public String toString() {
                     return messages.getLocalizedString("compiler.misc.unnamed.package");
                 }
             };
         noSymbol = new TypeSymbol(Kinds.NIL, 0, names.empty, Type.noType, rootPackage) {
+            @Override
             public <R, P> R accept(ElementVisitor<R, P> v, P p) {
                 return v.visitUnknown(this, p);
             }
@@ -724,5 +769,13 @@
 
         enterBinop("&&", booleanType, booleanType, booleanType, bool_and);
         enterBinop("||", booleanType, booleanType, booleanType, bool_or);
+
+        // Create standard module ids and queries
+        Name v = names.fromString(target.name.replaceAll("^1.", ""));
+        baseModule = new ModuleId(names.java_base, v);
+        jdkLegacyModule = new ModuleId(names.jdk_legacy, v);
+        Name q = names.fromString(">=" + v);
+        baseModuleQuery = new ModuleQuery(names.java_base, q);
+        jdkLegacyQuery = new ModuleQuery(names.jdk_legacy, q);
     }
 }
--- a/src/share/classes/com/sun/tools/javac/code/Type.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Type.java	Tue May 07 17:14:17 2013 -0700
@@ -1122,6 +1122,34 @@
         }
     }
 
+    public static class ModuleType extends Type implements NoType {
+
+        ModuleType(TypeSymbol tsym) {
+            super(TypeTag.MODULE, tsym);
+        }
+
+        @Override
+        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
+            return v.visitModuleType(this, s);
+        }
+
+        @Override
+        public String toString() {
+            return tsym.getQualifiedName().toString();
+        }
+
+        @Override
+        public TypeKind getKind() {
+            return TypeKind.MODULE;
+        }
+
+        @Override
+        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
+            return v.visitNoType(this, p);
+        }
+    }
+
+
     public static class TypeVar extends Type implements TypeVariable {
 
         /** The upper bound of this type variable; set from outside.
@@ -1756,6 +1784,7 @@
         R visitArrayType(ArrayType t, S s);
         R visitMethodType(MethodType t, S s);
         R visitPackageType(PackageType t, S s);
+        R visitModuleType(ModuleType t, S s);
         R visitTypeVar(TypeVar t, S s);
         R visitCapturedType(CapturedType t, S s);
         R visitForAll(ForAll t, S s);
--- a/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java	Tue May 07 17:14:17 2013 -0700
@@ -29,10 +29,8 @@
 import javax.lang.model.element.ElementKind;
 import javax.lang.model.type.TypeKind;
 
-import com.sun.tools.javac.code.Attribute;
 import com.sun.tools.javac.code.Attribute.TypeCompound;
-import com.sun.tools.javac.code.Flags;
-import com.sun.tools.javac.code.Kinds;
+import com.sun.tools.javac.code.Symbol.VarSymbol;
 import com.sun.tools.javac.code.Type.AnnotatedType;
 import com.sun.tools.javac.code.Type.ArrayType;
 import com.sun.tools.javac.code.Type.CapturedType;
@@ -40,6 +38,7 @@
 import com.sun.tools.javac.code.Type.ErrorType;
 import com.sun.tools.javac.code.Type.ForAll;
 import com.sun.tools.javac.code.Type.MethodType;
+import com.sun.tools.javac.code.Type.ModuleType;
 import com.sun.tools.javac.code.Type.PackageType;
 import com.sun.tools.javac.code.Type.TypeVar;
 import com.sun.tools.javac.code.Type.UndetVar;
@@ -47,10 +46,9 @@
 import com.sun.tools.javac.code.Type.WildcardType;
 import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntry;
 import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntryKind;
-import com.sun.tools.javac.code.TypeTag;
-import com.sun.tools.javac.code.Symbol.VarSymbol;
 import com.sun.tools.javac.comp.Annotate.Annotator;
 import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.tree.JCTree.JCBlock;
 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
 import com.sun.tools.javac.tree.JCTree.JCExpression;
@@ -58,7 +56,6 @@
 import com.sun.tools.javac.tree.JCTree.JCTypeApply;
 import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
 import com.sun.tools.javac.tree.TreeScanner;
-import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.util.Assert;
 import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.util.ListBuffer;
@@ -467,6 +464,12 @@
                 }
 
                 @Override
+                public Type visitModuleType(ModuleType t, List<TypeCompound> s) {
+                    // Error?
+                    return t;
+                }
+
+                @Override
                 public Type visitType(Type t, List<TypeCompound> s) {
                     return new AnnotatedType(s, t);
                 }
--- a/src/share/classes/com/sun/tools/javac/code/TypeTag.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/TypeTag.java	Tue May 07 17:14:17 2013 -0700
@@ -90,6 +90,11 @@
      */
     PACKAGE,
 
+    /** The tag of all module "types".
+     */
+    MODULE,
+
+
     /** The tag of all (source-level) type variables.
      */
     TYPEVAR,
--- a/src/share/classes/com/sun/tools/javac/code/Types.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Tue May 07 17:14:17 2013 -0700
@@ -4212,6 +4212,7 @@
         public R visitArrayType(ArrayType t, S s)       { return visitType(t, s); }
         public R visitMethodType(MethodType t, S s)     { return visitType(t, s); }
         public R visitPackageType(PackageType t, S s)   { return visitType(t, s); }
+        public R visitModuleType(ModuleType t, S s)     { return visitType(t, s); }
         public R visitTypeVar(TypeVar t, S s)           { return visitType(t, s); }
         public R visitCapturedType(CapturedType t, S s) { return visitType(t, s); }
         public R visitForAll(ForAll t, S s)             { return visitType(t, s); }
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Tue May 07 17:14:17 2013 -0700
@@ -34,9 +34,15 @@
 import com.sun.source.tree.IdentifierTree;
 import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
 import com.sun.source.tree.MemberSelectTree;
+import com.sun.source.tree.RequiresFlag;
 import com.sun.source.tree.TreeVisitor;
 import com.sun.source.util.SimpleTreeVisitor;
 import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Directive.EntrypointDirective;
+import com.sun.tools.javac.code.Directive.ExportsDirective;
+import com.sun.tools.javac.code.Directive.ProvidesServiceDirective;
+import com.sun.tools.javac.code.Directive.RequiresServiceDirective;
+import com.sun.tools.javac.code.Directive.ViewDeclaration;
 import com.sun.tools.javac.code.Lint.LintCategory;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.code.Type.*;
@@ -57,6 +63,7 @@
 import static com.sun.tools.javac.code.Kinds.*;
 import static com.sun.tools.javac.code.Kinds.ERRONEOUS;
 import static com.sun.tools.javac.code.TypeTag.*;
+import static com.sun.tools.javac.code.TypeTag.PACKAGE;
 import static com.sun.tools.javac.code.TypeTag.WILDCARD;
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
 
@@ -94,6 +101,7 @@
     final JCDiagnostic.Factory diags;
     final Annotate annotate;
     final DeferredLintHandler deferredLintHandler;
+    final Modules modules;
 
     public static Attr instance(Context context) {
         Attr instance = context.get(attrKey);
@@ -122,6 +130,7 @@
         diags = JCDiagnostic.Factory.instance(context);
         annotate = Annotate.instance(context);
         deferredLintHandler = DeferredLintHandler.instance(context);
+        modules = Modules.instance(context);
 
         Options options = Options.instance(context);
 
@@ -3966,6 +3975,175 @@
         return buf.toList();
     }
 
+    @Override
+    public void visitModuleDef(JCModuleDecl tree) {
+        env.info.modcon = modules.getModuleContext(tree);
+        env.info.modcon.directives.clear();
+        attribStats(tree.getDirectives(), env);
+        env.toplevel.modle.directives = merge(env.info.modcon.directives,
+                env.toplevel.modle.directives);
+    }
+
+    @Override
+    public void visitExports(JCExportDirective tree) {
+        TypeSymbol tsym = attribTree(tree.qualid, env, new ResultInfo(PCK, Type.noType)).tsym;
+        if (tsym.kind == PCK) {
+            ExportsDirective d = new ExportsDirective((PackageSymbol) tsym);
+            if (env.info.modcon.getDirectives(Directive.Kind.EXPORTS, d.sym.fullname).isEmpty()) {
+                env.info.modcon.addDirective(d, tree, d.sym.fullname);
+            } else {
+                log.error(tree.qualid, "dupl.exports", d.sym);
+            }
+        }
+    }
+
+    @Override
+    public void visitProvidesModule(JCProvidesModuleDirective tree) {
+        Directive d = env.info.modcon.directiveForTree.get(tree);
+        if (d != null)
+            env.info.modcon.directives.add(d);
+    }
+
+    @Override
+    public void visitProvidesService(JCProvidesServiceDirective tree) {
+        TypeSymbol srvc = attribTree(tree.serviceName, env, unknownTypeInfo).tsym;
+        TypeSymbol impl = attribTree(tree.implName, env, unknownTypeInfo).tsym;
+        if (srvc.kind != ERR && impl.kind != ERR) {
+            if ((impl.flags() & ABSTRACT) != 0) {
+                log.error(tree.implName, "service.impl.is.abstract", impl);
+                return;
+            }
+
+            if ((impl.flags() & PUBLIC) == 0) {
+                log.error(tree.implName, "service.impl.not.public", impl);
+                return;
+            }
+
+            boolean hasPublicNoArgsConstructor = false;
+            for (Scope.Entry e = impl.members().lookup(names.init); e.scope != null; e = e.next()) {
+                if (e.sym.kind == MTH && ((e.sym.flags() & PUBLIC) != 0)
+                        && ((MethodSymbol) e.sym).params().isEmpty()) {
+                    hasPublicNoArgsConstructor = true;
+                    break;
+                }
+            }
+            if (!hasPublicNoArgsConstructor) {
+                log.error(tree.implName, "service.impl.no.default.constr", impl);
+                return;
+            }
+
+            if (impl.owner.kind != PCK) {
+                log.error(tree.implName, "service.impl.is.inner", impl);
+                return;
+            }
+
+            ProvidesServiceDirective psd =
+                    new ProvidesServiceDirective((ClassSymbol) srvc, (ClassSymbol) impl);
+            for (Directive d: env.info.modcon.getDirectives(Directive.Kind.PROVIDES_SERVICE, psd.service.fullname)) {
+                if (d.getKind().equals(Directive.Kind.PROVIDES_SERVICE)) {
+                    if (psd.impl.fullname == ((ProvidesServiceDirective) d).impl.fullname) {
+                        log.error(tree.implName, "dupl.provides.service", psd.service, psd.impl);
+                        return;
+                    }
+                }
+            }
+
+            env.info.modcon.addDirective(psd, tree, psd.service.fullname);
+        }
+    }
+
+    @Override
+    public void visitRequiresModule(JCRequiresModuleDirective tree) {
+        Directive d = env.info.modcon.directiveForTree.get(tree);
+        if (d != null)
+            env.info.modcon.directives.add(d);
+    }
+
+    @Override
+    public void visitRequiresService(JCRequiresServiceDirective tree) {
+        Type t = attribType(tree.serviceName, env);
+        if (t.hasTag(TypeTag.CLASS) && env.tree.hasTag(JCTree.Tag.MODULE)) {
+            // FIXME: should check for duplicates
+            Set<Directive.RequiresFlag> flags = EnumSet.noneOf(Directive.RequiresFlag.class);
+            for (RequiresFlag f: tree.flags) {
+                switch (f) {
+                    case OPTIONAL:
+                        flags.add(Directive.RequiresFlag.OPTIONAL);
+                        break;
+                }
+            }
+            RequiresServiceDirective d = new RequiresServiceDirective((ClassSymbol) t.tsym, flags);
+            if (env.info.modcon.getDirectives(Directive.Kind.REQUIRES_SERVICE, d.sym.fullname).isEmpty()) {
+                env.info.modcon.addDirective(d, tree, d.sym.fullname);
+            } else {
+                log.error(tree.serviceName, "dupl.requires.service", d.sym);
+            }
+        }
+    }
+
+    @Override
+    public void visitPermits(JCPermitsDirective tree) {
+        Directive d = env.info.modcon.directiveForTree.get(tree);
+        if (d != null)
+            env.info.modcon.directives.add(d);
+    }
+
+    @Override
+    public void visitEntrypoint(JCEntrypointDirective tree) {
+        Type t = attribType(tree.qualId, env);
+        if (t.hasTag(TypeTag.CLASS)) {
+            Symbol sym = t.tsym;
+
+            boolean hasPublicStaticVoidMain = false;
+            for (Scope.Entry e = sym.members().lookup(names.main); e.scope != null; e = e.next()) {
+                int PUBLIC_STATIC = PUBLIC | STATIC;
+                if (e.sym.kind == MTH && ((e.sym.flags() & PUBLIC_STATIC) == PUBLIC_STATIC)) {
+                    MethodSymbol m = (MethodSymbol) e.sym;
+                    if (!m.getReturnType().hasTag(TypeTag.VOID))
+                        continue;
+                    List<VarSymbol> params = m.params();
+                    if (params.size() != 1)
+                        continue;
+                    VarSymbol p = params.head;
+                    if (types.dimensions(p.type) == 1
+                            && types.elemtype(p.type).tsym == syms.stringType.tsym) {
+                        hasPublicStaticVoidMain = true;
+                        break;
+                    }
+                }
+            }
+            if (!hasPublicStaticVoidMain) {
+                log.error(tree.qualId, "no.psv.main", sym);
+                return;
+            }
+
+            // Duplicate entrypoints should already have been detected and
+            // reported in Modules.visitEntrypoint, so here we just act
+            // defensively to ignore duplicates.
+            EntrypointDirective d = new EntrypointDirective((ClassSymbol) t.tsym);
+            if (env.info.modcon.getDirectives(Directive.Kind.ENTRYPOINT, d.sym.fullname).isEmpty())
+                env.info.modcon.addDirective(d, tree, d.sym.fullname);
+        }
+    }
+
+    @Override
+    public void visitView(JCViewDecl tree) {
+        Name name = TreeInfo.fullName(tree.name);
+        if (env.tree.hasTag(JCTree.Tag.MODULE)) {
+            ViewDeclaration orig = (ViewDeclaration) env.info.modcon.directiveForTree.get(tree);
+            Env<AttrContext> prevEnv = env;
+            env = env.dup(tree, env.info.dup());
+            try {
+                attribStats(tree.directives, env);
+            } finally {
+                ViewDeclaration d = new ViewDeclaration(name,
+                        merge(env.info.modcon.directives, orig.directives));
+                env = prevEnv;
+                env.info.modcon.directives.add(d);
+            }
+        }
+    }
+
     public void visitErroneous(JCErroneous tree) {
         if (tree.errs != null)
             for (JCTree err : tree.errs)
@@ -3979,14 +4157,33 @@
         throw new AssertionError();
     }
 
+    private List<Directive> merge(ListBuffer<Directive> primary, List<Directive> secondary) {
+        Set<Directive> set = new LinkedHashSet<Directive>();
+        set.addAll(primary);
+        for (Directive d: secondary) {
+            if (d.getKind() != Directive.Kind.VIEW)
+                set.add(d);
+        }
+        ListBuffer<Directive> results = new ListBuffer<Directive>();
+        for (Directive d: set)
+            results.add(d);
+        return results.toList();
+    }
+
     /**
      * Attribute an env for either a top level tree or class declaration.
      */
     public void attrib(Env<AttrContext> env) {
-        if (env.tree.hasTag(TOPLEVEL))
-            attribTopLevel(env);
-        else
-            attribClass(env.tree.pos(), env.enclClass.sym);
+        switch (env.tree.getTag()) {
+            case MODULE:
+                attribModule(env.tree.pos(), ((JCModuleDecl)env.tree).sym);
+                break;
+            case TOPLEVEL:
+                attribTopLevel(env);
+                break;
+            default:
+                attribClass(env.tree.pos(), env.enclClass.sym);
+        }
     }
 
     /**
@@ -3997,12 +4194,29 @@
         JCCompilationUnit toplevel = env.toplevel;
         try {
             annotate.flush();
-            chk.validateAnnotations(toplevel.packageAnnotations, toplevel.packge);
+            chk.validateAnnotations(toplevel.getPackageAnnotations(), toplevel.packge);
         } catch (CompletionFailure ex) {
             chk.completionError(toplevel.pos(), ex);
         }
     }
 
+    public void attribModule(DiagnosticPosition pos, ModuleSymbol m) {
+        try {
+            annotate.flush();
+            attribModule(m);
+        } catch (CompletionFailure ex) {
+            chk.completionError(pos, ex);
+        }
+
+    }
+
+    void attribModule(ModuleSymbol m) {
+        // Get environment current at the point of module definition.
+        Env<AttrContext> env = enter.typeEnvs.get(m);
+        //System.err.println("Attr.attribModule: " + env + " " + env.tree);
+        attribStat(env.tree, env);
+    }
+
     /** Main method: attribute class definition associated with given class symbol.
      *  reporting completion failures at the given position.
      *  @param pos The source position at which completion errors are to be
--- a/src/share/classes/com/sun/tools/javac/comp/AttrContext.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/AttrContext.java	Tue May 07 17:14:17 2013 -0700
@@ -58,7 +58,7 @@
      */
     Resolve.MethodResolutionPhase pendingResolutionPhase = null;
 
-    /** A record of the lint/SuppressWarnings currently in effect
+    /** A record of the lint/SuppressWarnings currently in effect.
      */
     Lint lint;
 
@@ -67,6 +67,9 @@
      */
     Symbol enclVar = null;
 
+    /** The module context for the current module. */
+    ModuleContext modcon;
+
     /** ResultInfo to be used for attributing 'return' statement expressions
      * (set by Attr.visitMethod and Attr.visitLambda)
      */
@@ -87,6 +90,7 @@
         info.pendingResolutionPhase = pendingResolutionPhase;
         info.lint = lint;
         info.enclVar = enclVar;
+        info.modcon = modcon == null ? null : modcon.dup();
         info.returnResult = returnResult;
         info.defaultSuperCallSite = defaultSuperCallSite;
         return info;
--- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Tue May 07 17:14:17 2013 -0700
@@ -30,29 +30,26 @@
 import javax.tools.JavaFileManager;
 
 import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Lint;
+import com.sun.tools.javac.code.Lint.LintCategory;
+import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.code.Type.*;
+import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
+import com.sun.tools.javac.comp.Infer.InferenceContext;
+import com.sun.tools.javac.comp.Infer.FreeTypeListener;
 import com.sun.tools.javac.jvm.*;
 import com.sun.tools.javac.tree.*;
+import com.sun.tools.javac.tree.JCTree.*;
+import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 import com.sun.tools.javac.util.List;
-
-import com.sun.tools.javac.code.Lint;
-import com.sun.tools.javac.code.Lint.LintCategory;
-import com.sun.tools.javac.code.Type.*;
-import com.sun.tools.javac.code.Symbol.*;
-import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
-import com.sun.tools.javac.comp.Infer.InferenceContext;
-import com.sun.tools.javac.comp.Infer.FreeTypeListener;
-import com.sun.tools.javac.tree.JCTree.*;
-import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
-
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Flags.ANNOTATION;
 import static com.sun.tools.javac.code.Flags.SYNCHRONIZED;
 import static com.sun.tools.javac.code.Kinds.*;
 import static com.sun.tools.javac.code.TypeTag.*;
 import static com.sun.tools.javac.code.TypeTag.WILDCARD;
-
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
 
 /** Type checking helper class for the attribution phase.
@@ -1127,8 +1124,7 @@
                 mask |= INTERFACE;
             }
             else {
-                log.error(pos,
-                          "mod.not.allowed.here", asFlagSet(illegal));
+                log.error(pos, "mod.not.allowed.here", asFlagSet(illegal));
             }
         }
         else if ((sym.kind == TYP ||
--- a/src/share/classes/com/sun/tools/javac/comp/Enter.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Enter.java	Tue May 07 17:14:17 2013 -0700
@@ -95,7 +95,7 @@
 
     Log log;
     Symtab syms;
-    Check chk;
+     Check chk;
     TreeMaker make;
     ClassReader reader;
     Annotate annotate;
@@ -105,6 +105,8 @@
     Names names;
     JavaFileManager fileManager;
     PkgInfo pkginfoOpt;
+    Modules modules;
+    JCDiagnostic.Factory diags;
 
     private final Todo todo;
 
@@ -128,6 +130,8 @@
         annotate = Annotate.instance(context);
         lint = Lint.instance(context);
         names = Names.instance(context);
+        modules = Modules.instance(context);
+        diags = JCDiagnostic.Factory.instance(context);
 
         predefClassDef = make.ClassDef(
             make.Modifiers(PUBLIC),
@@ -237,6 +241,23 @@
             : env.info.scope;
     }
 
+    /** Create a fresh environment for modules.
+     *
+     *  @param tree     The module definition.
+     *  @param env      The environment current outside of the module definition.
+     */
+    public Env<AttrContext> moduleEnv(JCModuleDecl tree, Env<AttrContext> env) {
+        assert tree.sym != null;
+        Env<AttrContext> localEnv =
+            env.dup(tree, env.info.dup(new Scope(tree.sym)));
+        localEnv.enclClass = predefClassDef;
+        localEnv.outer = env;
+        localEnv.info.isSelfCall = false;
+        localEnv.info.lint = null; // leave this to be filled in by Attr,
+                                   // when annotations have been processed
+        return localEnv;
+    }
+
 /* ************************************************************************
  * Visitor methods for phase 1: class enter
  *************************************************************************/
@@ -282,42 +303,45 @@
 
     @Override
     public void visitTopLevel(JCCompilationUnit tree) {
+        Assert.checkNonNull(tree.modle, tree.sourcefile.toString());
+        
         JavaFileObject prev = log.useSource(tree.sourcefile);
         boolean addEnv = false;
-        boolean isPkgInfo = tree.sourcefile.isNameCompatible("package-info",
-                                                             JavaFileObject.Kind.SOURCE);
-        if (tree.pid != null) {
-            tree.packge = reader.enterPackage(TreeInfo.fullName(tree.pid));
-            if (tree.packageAnnotations.nonEmpty() || pkginfoOpt == PkgInfo.ALWAYS) {
-                if (isPkgInfo) {
-                    addEnv = true;
-                } else {
-                    log.error(tree.packageAnnotations.head.pos(),
-                              "pkg.annotations.sb.in.package-info.java");
-                }
+
+        boolean isPackageInfo = TreeInfo.isPackageInfo(tree);
+        boolean isModuleInfo = TreeInfo.isModuleInfo(tree);
+        JCPackageDecl pd = TreeInfo.getPackage(tree);
+
+        if (pd != null) {
+            tree.packge = pd.sym = reader.enterPackage(TreeInfo.fullName(pd.packageId));
+            if (pd.annots.nonEmpty() && !isPackageInfo) {
+                log.error(pd.annots.head.pos(),
+                          "pkg.annotations.sb.in.package-info.java");
             }
         } else {
             tree.packge = syms.unnamedPackage;
         }
         tree.packge.complete(); // Find all classes in package.
-        Env<AttrContext> topEnv = topLevelEnv(tree);
+
+        Env<AttrContext> treeEnv = topLevelEnv(tree);
 
         // Save environment of package-info.java file.
-        if (isPkgInfo) {
+        if (isPackageInfo) {
+            addEnv = (pd != null) && pd.annots.nonEmpty();
+
             Env<AttrContext> env0 = typeEnvs.get(tree.packge);
             if (env0 == null) {
-                typeEnvs.put(tree.packge, topEnv);
+                typeEnvs.put(tree.packge, treeEnv);
             } else {
                 JCCompilationUnit tree0 = env0.toplevel;
                 if (!fileManager.isSameFile(tree.sourcefile, tree0.sourcefile)) {
-                    log.warning(tree.pid != null ? tree.pid.pos()
-                                                 : null,
+                    log.warning(pd != null ? pd.pos() : null,
                                 "pkg-info.already.seen",
                                 tree.packge);
-                    if (addEnv || (tree0.packageAnnotations.isEmpty() &&
+                    if (addEnv || (tree0.getPackageAnnotations().isEmpty() &&
                                    tree.docComments != null &&
                                    tree.docComments.hasComment(tree))) {
-                        typeEnvs.put(tree.packge, topEnv);
+                        typeEnvs.put(tree.packge, treeEnv);
                     }
                 }
             }
@@ -332,11 +356,17 @@
             c.completer = null;
             c.members_field = new Scope(c);
             tree.packge.package_info = c;
+        } else if (isModuleInfo) {
+            JCModuleDecl md = TreeInfo.getModule(tree);
+            if (md != null) {
+                typeEnvs.put(md.sym, treeEnv);
+            }
         }
-        classEnter(tree.defs, topEnv);
-        if (addEnv) {
-            todo.append(topEnv);
-        }
+
+        classEnter(tree.defs, treeEnv);
+        if (addEnv)
+            todo.append(treeEnv);
+
         log.useSource(prev);
         result = null;
     }
@@ -399,6 +429,7 @@
         c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree);
         c.sourcefile = env.toplevel.sourcefile;
         c.members_field = new Scope(c);
+        c.modle = env.toplevel.modle;
 
         ClassType ct = (ClassType)c.type;
         if (owner.kind != PCK && (c.flags_field & STATIC) == 0) {
@@ -427,6 +458,8 @@
         // Recursively enter all member classes.
         classEnter(tree.defs, localEnv);
 
+        Assert.checkNonNull(c.modle, c.sourcefile.toString());
+
         result = c.type;
     }
     //where
@@ -459,6 +492,13 @@
         result = a;
     }
 
+    @Override
+    public void visitModuleDef(JCModuleDecl tree) {
+        Env<AttrContext> moduleEnv = moduleEnv(tree, env);
+        typeEnvs.put(tree.sym, moduleEnv);
+        todo.append(moduleEnv);
+    }
+
     /** Default class enter visitor method: do nothing.
      */
     @Override
@@ -479,9 +519,22 @@
      *  @param c          The class symbol to be processed.
      */
     public void complete(List<JCCompilationUnit> trees, ClassSymbol c) {
+        // Process module declarations.
+        // If module resolution fails, ignore trees, and if trying to
+        // complete a specific symbol, throw CompletionFailure.
+        // Note that if module resolution failed, we may not even
+        // have enough modules available to access java.lang, and
+        // so risk getting FatalError("no.java.lang") from MemberEnter.
+        if (!modules.enter(trees)) {
+            if (c != null)
+                throw new CompletionFailure(c, diags.fragment("cant.resolve.modules"));
+            return;
+        }
+
         annotate.enterStart();
         ListBuffer<ClassSymbol> prevUncompleted = uncompleted;
-        if (memberEnter.completionEnabled) uncompleted = new ListBuffer<ClassSymbol>();
+        if (memberEnter.completionEnabled)
+            uncompleted = new ListBuffer<ClassSymbol>();
 
         try {
             // enter all classes, and construct uncompleted list
@@ -503,8 +556,8 @@
                 for (JCCompilationUnit tree : trees) {
                     if (tree.starImportScope.elems == null) {
                         JavaFileObject prev = log.useSource(tree.sourcefile);
-                        Env<AttrContext> topEnv = topLevelEnv(tree);
-                        memberEnter.memberEnter(tree, topEnv);
+                        Env<AttrContext> treeEnv = topLevelEnv(tree);
+                        memberEnter.memberEnter(tree, treeEnv);
                         log.useSource(prev);
                     }
                 }
--- a/src/share/classes/com/sun/tools/javac/comp/Flow.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Flow.java	Tue May 07 17:14:17 2013 -0700
@@ -2181,6 +2181,10 @@
             tree.underlyingType.accept(this);
         }
 
+    public void visitModuleDef(JCModuleDecl tree) {
+        // Do nothing for modules
+    }
+
         public void visitTopLevel(JCCompilationUnit tree) {
             // Do nothing for TopLevel since each class is visited individually
         }
@@ -2311,6 +2315,9 @@
 
         /* ------------ Visitor methods for various sorts of trees -------------*/
 
+        public void visitModuleDef(JCModuleDecl tree) {
+        }
+
         public void visitClassDef(JCClassDecl tree) {
             JCTree prevTree = currentTree;
             try {
--- a/src/share/classes/com/sun/tools/javac/comp/Lower.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Lower.java	Tue May 07 17:14:17 2013 -0700
@@ -2347,25 +2347,18 @@
 
     public void visitTopLevel(JCCompilationUnit tree) {
         if (needPackageInfoClass(tree)) {
-            Name name = names.package_info;
+            JCPackageDecl pd = TreeInfo.getPackage(tree);
             long flags = Flags.ABSTRACT | Flags.INTERFACE;
             if (target.isPackageInfoSynthetic())
-                // package-info is marked SYNTHETIC in JDK 1.6 and later releases
-                flags = flags | Flags.SYNTHETIC;
-            JCClassDecl packageAnnotationsClass
-                = make.ClassDef(make.Modifiers(flags,
-                                               tree.packageAnnotations),
-                                name, List.<JCTypeParameter>nil(),
-                                null, List.<JCExpression>nil(), List.<JCTree>nil());
+                flags |= SYNTHETIC;
             ClassSymbol c = tree.packge.package_info;
+            c.annotations.setAttributes(pd.sym.annotations);
+            c.modle = attrEnv.toplevel.modle;
             c.flags_field |= flags;
-            c.annotations.setAttributes(tree.packge.annotations);
             ClassType ctype = (ClassType) c.type;
             ctype.supertype_field = syms.objectType;
             ctype.interfaces_field = List.nil();
-            packageAnnotationsClass.sym = c;
-
-            translated.append(packageAnnotationsClass);
+            createInfoClass(pd.annots, c);
         }
     }
     // where
@@ -2374,7 +2367,7 @@
             case ALWAYS:
                 return true;
             case LEGACY:
-                return tree.packageAnnotations.nonEmpty();
+                return tree.getPackageAnnotations().nonEmpty();
             case NONEMPTY:
                 for (Attribute.Compound a :
                          tree.packge.annotations.getDeclarationAttributes()) {
@@ -2387,6 +2380,23 @@
         throw new AssertionError();
     }
 
+    public void visitModuleDef(JCModuleDecl tree) {
+        ModuleSymbol msym = tree.sym;
+        ClassSymbol c = msym.module_info;
+        c.flags_field |= SYNTHETIC;
+        createInfoClass(List.<JCAnnotation>nil(), tree.sym.module_info);
+    }
+
+    private void createInfoClass(List<JCAnnotation> annots, ClassSymbol c) {
+        long flags = Flags.ABSTRACT | Flags.INTERFACE;
+        JCClassDecl infoClass =
+                make.ClassDef(make.Modifiers(flags, annots),
+                    c.name, List.<JCTypeParameter>nil(),
+                    null, List.<JCExpression>nil(), List.<JCTree>nil());
+        infoClass.sym = c;
+        translated.append(infoClass);
+    }
+
     public void visitClassDef(JCClassDecl tree) {
         ClassSymbol currentClassPrev = currentClass;
         MethodSymbol currentMethodSymPrev = currentMethodSym;
--- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Tue May 07 17:14:17 2013 -0700
@@ -38,6 +38,7 @@
 import com.sun.tools.javac.jvm.*;
 import com.sun.tools.javac.tree.*;
 import com.sun.tools.javac.util.*;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 
 import com.sun.tools.javac.code.Type.*;
 import com.sun.tools.javac.code.Symbol.*;
@@ -51,7 +52,6 @@
 import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
-import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 
 /** This is the second phase of Enter, in which classes are completed
  *  by entering their members into the class scope using
@@ -162,6 +162,7 @@
                                  Env<AttrContext> env) {
         final JavaFileObject sourcefile = env.toplevel.sourcefile;
         final Scope toScope = env.toplevel.starImportScope;
+        final ModuleSymbol modle = env.toplevel.modle;
         final PackageSymbol packge = env.toplevel.packge;
         final TypeSymbol origin = tsym;
 
@@ -182,7 +183,7 @@
                     Symbol sym = e.sym;
                     if (sym.kind == TYP &&
                         (sym.flags() & STATIC) != 0 &&
-                        staticImportAccessible(sym, packge) &&
+                        staticImportAccessible(sym, modle, packge) &&
                         sym.isMemberOf(origin, types) &&
                         !toScope.includes(sym))
                         toScope.enter(sym, fromScope, origin.members());
@@ -210,7 +211,7 @@
                 for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling) {
                     Symbol sym = e.sym;
                     if (sym.isStatic() && sym.kind != TYP &&
-                        staticImportAccessible(sym, packge) &&
+                        staticImportAccessible(sym, modle, packge) &&
                         !toScope.includes(sym) &&
                         sym.isMemberOf(origin, types)) {
                         toScope.enter(sym, fromScope, origin.members());
@@ -224,7 +225,7 @@
     }
 
     // is the sym accessible everywhere in packge?
-    boolean staticImportAccessible(Symbol sym, PackageSymbol packge) {
+    boolean staticImportAccessible(Symbol sym, ModuleSymbol modle, PackageSymbol packge) {
         int flags = (int)(sym.flags() & AccessFlags);
         switch (flags) {
         default:
@@ -255,6 +256,7 @@
         }
 
         final Scope toScope = env.toplevel.namedImportScope;
+        final ModuleSymbol modle = env.toplevel.modle;
         final PackageSymbol packge = env.toplevel.packge;
         final TypeSymbol origin = tsym;
 
@@ -276,7 +278,7 @@
                     Symbol sym = e.sym;
                     if (sym.isStatic() &&
                         sym.kind == TYP &&
-                        staticImportAccessible(sym, packge) &&
+                        staticImportAccessible(sym, modle, packge) &&
                         sym.isMemberOf(origin, types) &&
                         chk.checkUniqueStaticImport(pos, sym, toScope))
                         toScope.enter(sym, sym.owner.members(), origin.members());
@@ -306,7 +308,7 @@
                      e = e.next()) {
                     Symbol sym = e.sym;
                     if (sym.isStatic() &&
-                        staticImportAccessible(sym, packge) &&
+                        staticImportAccessible(sym, modle, packge) &&
                         sym.isMemberOf(origin, types)) {
                         found = true;
                         if (sym.kind == MTH ||
@@ -481,23 +483,31 @@
             return;
         }
 
+        JCModuleDecl md = TreeInfo.getModule(tree);
+        JCPackageDecl pd = TreeInfo.getPackage(tree);
+
         // check that no class exists with same fully qualified name as
         // toplevel package
-        if (checkClash && tree.pid != null) {
+        if (checkClash && pd != null) {
             Symbol p = tree.packge;
             while (p.owner != syms.rootPackage) {
                 p.owner.complete(); // enter all class members of p
                 if (syms.classes.get(p.getQualifiedName()) != null) {
                     log.error(tree.pos,
-                              "pkg.clashes.with.class.of.same.name",
-                              p);
+                            "pkg.clashes.with.class.of.same.name",
+                            p);
                 }
                 p = p.owner;
             }
         }
 
+        // set up module and its dependencies
+        /*temp*/if (tree.modle != null)/*temp*/ // JIGSAW TEMP: tree.modle SHOULD ALWAYS BE SET
+            tree.modle.complete();
+
         // process package annotations
-        annotateLater(tree.packageAnnotations, env, tree.packge);
+        if (pd != null)
+            annotateLater(pd.annots, env, pd.sym);
 
         // Import-on-demand java.lang.
         importAll(tree.pos, reader.enterPackage(names.java_lang), env);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/javac/comp/ModuleContext.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2009, 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.javac.comp;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.sun.tools.javac.code.Directive;
+import com.sun.tools.javac.tree.JCTree.JCModuleDirective;
+import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.Name;
+
+/**
+ *  Contains information specific to the modules/enter/attr
+ *  passes, to be used in place of the generic field in environments.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class ModuleContext {
+
+    ModuleContext() {
+        requiresBaseModule = true;
+        directives = new ListBuffer<Directive>();
+        directiveForTree = new HashMap<JCModuleDirective, Directive>();
+        directiveIndex = new HashMap<Name, Set<Directive>>();
+    }
+
+    ModuleContext dup() {
+        return new ModuleContext();
+    }
+
+    void addDirective(Directive d, JCModuleDirective tree, Name name) {
+        directives.add(d);
+        directiveForTree.put(tree, d);
+        Set<Directive> set = directiveIndex.get(name);
+        if (set == null)
+            directiveIndex.put(name, (set = new LinkedHashSet<Directive>()));
+        set.add(d);
+    }
+
+    Collection<Directive> getDirectives(Name name) {
+        Set<Directive> set = directiveIndex.get(name);
+        return (set != null) ? set : Collections.<Directive>emptySet();
+    }
+
+    Collection<Directive> getDirectives(Directive.Kind kind, Name name) {
+        List<Directive> list = null;
+        Set<Directive> set = directiveIndex.get(name);
+        if (set != null) {
+            for (Directive d: set) {
+                if (d.getKind() == kind) {
+                    if (list == null)
+                        list = new ArrayList<Directive>();
+                    list.add(d);
+                }
+            }
+        }
+        return (list == null) ? Collections.<Directive>emptySet() : list; 
+    }
+
+
+
+    final ListBuffer<Directive> directives;
+    final Map<JCModuleDirective, Directive> directiveForTree;
+    final Map<Name, Set<Directive>> directiveIndex;
+
+    boolean requiresBaseModule;
+    boolean isPlatformModule;
+    boolean hasEntrypoint;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/javac/comp/Modules.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,1201 @@
+/*
+ * Copyright (c) 2009, 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.javac.comp;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileManager.Location;
+import javax.tools.JavaFileObject;
+import javax.tools.ModuleFileManager;
+import javax.tools.ModuleFileManager.InvalidFileObjectException;
+import javax.tools.ModuleFileManager.ModuleMode;
+import javax.tools.StandardLocation;
+import static javax.tools.StandardLocation.*;
+
+import com.sun.source.tree.RequiresFlag;
+import com.sun.tools.javac.code.Directive;
+import com.sun.tools.javac.code.Directive.PermitsDirective;
+import com.sun.tools.javac.code.Directive.ProvidesModuleDirective;
+import com.sun.tools.javac.code.Directive.RequiresModuleDirective;
+import com.sun.tools.javac.code.Directive.ViewDeclaration;
+import com.sun.tools.javac.code.ModuleId;
+import com.sun.tools.javac.code.ModuleQuery;
+import com.sun.tools.javac.code.Scope;
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.code.Symbol.ModuleSymbol;
+import com.sun.tools.javac.code.Symbol.PackageSymbol;
+import com.sun.tools.javac.code.Symtab;
+import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.jvm.ClassReader;
+import com.sun.tools.javac.main.Option;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.JCClassDecl;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
+import com.sun.tools.javac.tree.JCTree.JCEntrypointDirective;
+import com.sun.tools.javac.tree.JCTree.JCExportDirective;
+import com.sun.tools.javac.tree.JCTree.JCExpression;
+import com.sun.tools.javac.tree.JCTree.JCModuleDecl;
+import com.sun.tools.javac.tree.JCTree.JCModuleId;
+import com.sun.tools.javac.tree.JCTree.JCModuleQuery;
+import com.sun.tools.javac.tree.JCTree.JCPermitsDirective;
+import com.sun.tools.javac.tree.JCTree.JCProvidesModuleDirective;
+import com.sun.tools.javac.tree.JCTree.JCProvidesServiceDirective;
+import com.sun.tools.javac.tree.JCTree.JCRequiresModuleDirective;
+import com.sun.tools.javac.tree.JCTree.JCRequiresServiceDirective;
+import com.sun.tools.javac.tree.JCTree.JCViewDecl;
+import com.sun.tools.javac.tree.TreeInfo;
+import com.sun.tools.javac.tree.TreeScanner;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Debug;
+import com.sun.tools.javac.util.JCDiagnostic;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Name;
+import com.sun.tools.javac.util.Names;
+import com.sun.tools.javac.util.Options;
+import static com.sun.tools.javac.main.Option.*;
+
+/**
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public class Modules extends JCTree.Visitor {
+    ClassReader reader;
+    Log log;
+    JavaFileManager fileManager;
+    ModuleFileManager moduleFileManager;
+    Names names;
+    Symtab syms;
+    Debug debug;
+    boolean enabled;
+
+    ModuleMode mode;
+
+    /**
+     * The set of module locations for entered trees.
+     * In single module compilation mode, it is a composite of class path and
+     * source path.
+     * In multi-module compilation mode, it is the set of "module directories"
+     * for the files on the command line (i.e. the directories above each
+     * source files package hierarchy.)
+     */
+    final Set<Location> rootLocns = new LinkedHashSet<Location>();
+
+    final Map<Location,ModuleSymbol> allModules;
+
+    /** The symbol currently being analyzed. */
+    ModuleSymbol currSym;
+
+    Env<ModuleContext> env;
+    Map<ModuleSymbol, Env<ModuleContext>> moduleEnvs = new HashMap<ModuleSymbol, Env<ModuleContext>>();
+
+    /** True if file manager is not a ModuleFileManager and we have
+     * seen module declaration in input trees. */
+    boolean moduleFileManagerUnavailable;
+
+    public static Modules instance(Context context) {
+        Modules instance = context.get(Modules.class);
+        if (instance == null)
+            instance = new Modules(context);
+        return instance;
+    }
+
+    protected Modules(Context context) {
+        context.put(Modules.class, this);
+        log = Log.instance(context);
+        reader = ClassReader.instance(context);
+        fileManager = context.get(JavaFileManager.class);
+        names = Names.instance(context);
+        syms = Symtab.instance(context);
+        allModules = syms.allModules;
+        Options options = Options.instance(context);
+        debug = new Debug("modules", options, log);
+
+        // module system features enabled unless -XDnomodules is set
+        enabled = (options.get("nomodules") == null);
+
+        if (!enabled)
+            return;
+
+        initModuleResolver(context);
+
+        if (fileManager instanceof ModuleFileManager) {
+            moduleFileManager = (ModuleFileManager) fileManager;
+            mode = moduleFileManager.getModuleMode();
+        } else
+            mode = ModuleMode.SINGLE;
+    }
+
+    <T extends JCTree> void acceptAll(List<T> trees) {
+        for (List<T> l = trees; l.nonEmpty(); l = l.tail)
+            l.head.accept(this);
+    }
+
+    public ModuleContext getModuleContext(JCModuleDecl decl) {
+        Env<ModuleContext> e = moduleEnvs.get(decl.sym);
+        return e == null ? null : e.info;
+    }
+
+    @Override
+    public void visitModuleDef(JCModuleDecl tree) {
+        DEBUG("Modules.visitModuleDef " + tree.id);
+
+        if (mode == ModuleMode.SINGLE) {
+            if (moduleFileManager == null) {
+                log.error(tree, "mdl.module.file.manager.required");
+                moduleFileManagerUnavailable = true;
+            } else {
+                env.toplevel.locn = moduleFileManager.join(List.of(CLASS_PATH, SOURCE_PATH));
+                if (state == State.INITIAL)
+                    rootLocns.add(env.toplevel.locn);
+            }
+        }
+
+        ModuleSymbol sym = reader.enterModule(env.toplevel.locn);
+        if (sym.name != null) {
+            log.error(tree.pos(), "mdl.already.defined", sym.module_info.sourcefile);
+            sym = new ModuleSymbol(TreeInfo.fullName(tree.id.qualId), syms.rootModule);
+        } else {
+            sym.name = sym.fullname = TreeInfo.fullName(tree.id.qualId);
+            sym.module_info.fullname = ClassSymbol.formFullName(sym.module_info.name, sym);
+            sym.module_info.flatname = ClassSymbol.formFlatName(sym.module_info.name, sym);
+            sym.extendedMetadata = tree.metadata;
+            sym.module_info.sourcefile = env.toplevel.sourcefile;
+            sym.module_info.members_field = new Scope(sym.module_info);
+            sym.completer = null;
+        }
+
+        DEBUG("Modules.visitModuleDef name "         + sym.name);
+        DEBUG("Modules.visitModuleDef fullname "     + sym.fullname);
+        DEBUG("Modules.visitModuleDef flatName() "   + sym.flatName());
+        DEBUG("Modules.visitModuleDef m-i name "     + sym.module_info.name);
+        DEBUG("Modules.visitModuleDef m-i fullname " + sym.module_info.fullname);
+        DEBUG("Modules.visitModuleDef m-i flatname " + sym.module_info.flatname);
+
+        sym.location = env.toplevel.locn;
+        tree.sym = sym;
+
+        sym.version = tree.getId().version;
+        currSym = sym;
+        Env<ModuleContext> menv = env.dup(tree, new ModuleContext());
+        moduleEnvs.put(sym, menv);
+        Env<ModuleContext> prev = env;
+        env = menv;
+        try {
+            if (isBaseModuleName(sym.name))
+                env.info.requiresBaseModule = false;
+
+            acceptAll(tree.directives);
+
+            DEBUG("Modules.visitModuleDef requiresBaseModule:" + env.info.requiresBaseModule);
+            if (env.info.requiresBaseModule) {
+                env.info.directives.add(new RequiresModuleDirective(syms.baseModuleQuery,
+                        EnumSet.of(Directive.RequiresFlag.SYNTHESIZED)));
+            }
+        } finally {
+            sym.directives = env.info.directives.toList();
+            currSym = null;
+            env = prev;
+        }
+    }
+
+    @Override
+    public void visitTopLevel(JCCompilationUnit tree) {
+        DEBUG("Modules.visitTopLevel " + tree.sourcefile);
+        env = new Env<ModuleContext>(tree, null);
+        env.toplevel = tree;
+        JavaFileObject prev = log.useSource(tree.sourcefile);
+        try {
+            if (mode == ModuleMode.MULTIPLE) {
+                assert moduleFileManager != null;
+                Location l = moduleFileManager.join(List.of(MODULE_PATH, SOURCE_PATH));
+                JCExpression pn = tree.getPackageName();
+                String pkgName = (pn == null) ? "" : TreeInfo.fullName(pn).toString();
+                try {
+                    tree.locn = moduleFileManager.getModuleLocation(l, tree.sourcefile, pkgName);
+                    DEBUG("Modules.visitTopLevel MULTIPLE " + tree.locn);
+                    if (state == State.INITIAL)
+                        rootLocns.add(tree.locn);
+                } catch (InvalidFileObjectException e) {
+                    log.error(pn, "mdl.file.in.wrong.directory", tree.sourcefile, pkgName);
+                }
+            }
+
+            if (TreeInfo.isModuleInfo(tree))
+                acceptAll(tree.defs);
+        } finally {
+            log.useSource(prev);
+            DEBUG("Modules.visitTopLevel EXIT rootLocns=" + rootLocns);
+        }
+    }
+
+    @Override
+    public void visitEntrypoint(JCEntrypointDirective tree) {
+        if (env.info.hasEntrypoint)
+            log.error(tree, "dupl.entrypoint");
+        env.info.hasEntrypoint = true;
+    }
+
+    @Override
+    public void visitExports(JCExportDirective tree) {
+    }
+
+    @Override
+    public void visitPermits(JCPermitsDirective tree) {
+        JCTree qualId = tree.moduleName;
+        Name moduleName = TreeInfo.fullName(qualId);
+        PermitsDirective d = new PermitsDirective(moduleName);
+        if (env.info.getDirectives(Directive.Kind.PERMITS, d.moduleId.name).isEmpty()) {
+            env.info.addDirective(d, tree, d.moduleId.name);
+        } else {
+            log.error(tree.moduleName, "dupl.permits", d.moduleId.name);
+        }
+    }
+
+    @Override
+    public void visitProvidesModule(JCProvidesModuleDirective tree) {
+        JCModuleId moduleId = tree.moduleId;
+        ProvidesModuleDirective d = new ProvidesModuleDirective(
+                new ModuleId(TreeInfo.fullName(moduleId.qualId), moduleId.version));
+        if (env.info.getDirectives(Directive.Kind.PROVIDES_MODULE, d.moduleId.name).isEmpty()) {
+            env.info.addDirective(d, tree, d.moduleId.name);
+            if (isBaseModuleName(d.moduleId.name))
+                env.info.requiresBaseModule = false;
+        } else {
+            log.error(tree.moduleId, "dupl.provides", d.moduleId.name);
+        }
+    }
+
+    @Override
+    public void visitProvidesService(JCProvidesServiceDirective tree) {
+    }
+
+    @Override
+    public void visitRequiresModule(JCRequiresModuleDirective tree) {
+        if (!env.tree.hasTag(JCTree.Tag.MODULE)) {
+            log.error(tree, "requires.not.allowed.in.view");
+            return;
+        }
+
+        JCModuleQuery moduleQuery = tree.moduleQuery;
+        ModuleQuery mq = new ModuleQuery(TreeInfo.fullName(moduleQuery.qualId), moduleQuery.versionQuery);
+        Set<Directive.RequiresFlag> flags = EnumSet.noneOf(Directive.RequiresFlag.class);
+        for (RequiresFlag f: tree.flags) {
+            switch (f) {
+                case REEXPORT:
+                    flags.add(Directive.RequiresFlag.REEXPORT);
+                    break;
+                case OPTIONAL:
+                    flags.add(Directive.RequiresFlag.OPTIONAL);
+                    break;
+                case LOCAL:
+                    flags.add(Directive.RequiresFlag.LOCAL);
+                    break;
+            }
+        }
+        RequiresModuleDirective d = new RequiresModuleDirective(mq, flags);
+        if (env.info.getDirectives(Directive.Kind.REQUIRES_MODULE, mq.name).isEmpty()) {
+            env.info.addDirective(d, tree, mq.name);
+            if (isBaseModuleName(mq.name))
+                env.info.requiresBaseModule = false;
+        } else {
+            log.error(tree, "dupl.requires", mq.name);
+        }
+    }
+
+    @Override
+    public void visitRequiresService(JCRequiresServiceDirective tree) {
+        if (!env.tree.hasTag(JCTree.Tag.MODULE)) {
+            log.error(tree, "requires.not.allowed.in.view");
+            return;
+        }
+    }
+
+    @Override
+    public void visitView(JCViewDecl tree) {
+        List<Directive> viewDirectives;
+        Env<ModuleContext> prevEnv = env;
+        env = env.dup(tree, env.info.dup());
+        try {
+            acceptAll(tree.directives);
+        } finally {
+            viewDirectives = env.info.directives.toList();
+            env = prevEnv;
+        }
+
+        if (!env.tree.hasTag(JCTree.Tag.MODULE)) {
+            log.error(tree, "nested.view.not.allowed");
+            return;
+        }
+
+        ViewDeclaration v = new ViewDeclaration(TreeInfo.fullName(tree.name),
+                viewDirectives);
+        if (!env.info.getDirectives(Directive.Kind.VIEW, v.name).isEmpty()
+                || v.name.equals(((JCModuleDecl) env.tree).sym.fullname)) {
+            log.error(tree, "dupl.view", v.name);
+            return;
+        }
+
+        env.info.addDirective(v, tree, v.name);
+        if (isBaseModuleName(v.name))
+            env.info.requiresBaseModule = false;
+    }
+
+    @Override
+    public void visitTree(JCTree tree) { }
+
+    private boolean resolve(List<JCCompilationUnit> trees) {
+        if (moduleFileManagerUnavailable)
+            return false;
+
+        DEBUG("Modules.resolve: resolve modules");
+
+        DEBUG("Modules.resolve mode=" + mode + ", rootLocns=" + rootLocns + " (" + rootLocns.size() + ")" );
+        if (mode == ModuleMode.SINGLE && rootLocns.isEmpty()) {
+            if (moduleFileManager != null) {
+                rootLocns.add(moduleFileManager.join(List.of(CLASS_PATH, SOURCE_PATH)));
+            } else {
+                // TODO: check for module-info.{java,class} and give error if found
+                // TODO?? use a custom DEFAULT locn, instead of null??
+                return true;
+            }
+        }
+
+        DEBUG("Modules.resolve: building roots, rootLocns=" + rootLocns);
+        if (debug.isEnabled("initialRootLocns"))
+            showRootLocations(rootLocns);
+
+        List<ModuleSymbol> roots = List.nil();
+        for (Location locn: rootLocns) {
+            DEBUG("Modules.resolve: building roots: locn: " + locn);
+            ModuleSymbol msym = reader.enterModule(locn);
+            DEBUG("Modules.resolve: building roots: msym: " + msym);
+            msym.complete();
+            DEBUG("Modules.resolve: building roots: completed: " + msym);
+            roots = roots.prepend(msym);
+        }
+        roots = roots.reverse();
+        DEBUG("Modules.resolve: roots: " + roots);
+
+        updateTrees(trees);
+
+        DEBUG("Modules.resolve: modules so far: " + allModules);
+
+        DEBUG("Modules.resolve: reading module-info as needed");
+        Location l = (moduleFileManager.getModuleMode() == ModuleMode.SINGLE)
+                ? MODULE_PATH : moduleFileManager.join(List.of(MODULE_PATH, SOURCE_PATH));
+        for (Location locn: moduleFileManager.getModuleLocations(l)) {
+            DEBUG("Modules.resolve: ensuring module-info for " + locn);
+            reader.enterModule(locn).complete();
+        }
+
+        ListBuffer<ModuleSymbol> namedModules = new ListBuffer<ModuleSymbol>();
+        for (ModuleSymbol msym: allModules.values()) {
+            if (msym.name != names.empty)
+                namedModules.add(msym);
+        }
+
+        if (debug.isEnabled("resolve")) {
+            debug.println("Module resolver: " + moduleResolver.getClass().getSimpleName());
+            showModules("Module resolution roots:", roots);
+            showModules("Modules in compilation environment:", namedModules);
+        }
+
+        Iterable<? extends ModuleSymbol> modules = moduleResolver.resolve(roots, namedModules);
+        if (modules == null)
+            return false;
+
+        // modules is returned in an order such that if A requires B, then
+        // A will be earlier than B. This means that the root modules, such
+        // as the unnamed module appear ahead of the platform modules,
+        // which will appear last.  This is the reverse of the traditional
+        // ordering, in which the platform classes are read ahead of classes
+        // on the user class path.   Therefore, we build and use a reversed
+        // list of modules before converting the modules to the path used by
+        // ClassReader.
+
+        List<ModuleSymbol> msyms = List.nil();
+        for (ModuleSymbol sym: modules)
+            msyms = msyms.prepend(sym);
+
+        if (debug.isEnabled("resolve"))
+            showModules("Resolved modules: ", msyms);
+
+        JavacFileManager jfm = (fileManager instanceof JavacFileManager)
+                ? (JavacFileManager)fileManager : null;
+
+        ModuleSymbol firstPlatformModule = null;
+        ModuleSymbol lastPlatformModule = null;
+        for (ModuleSymbol msym: msyms) {
+            DEBUG("Modules.resolve: " + msym.fullname + " " + isPlatformModule(msym));
+            if (isPlatformModule(msym)) {
+                if (firstPlatformModule == null)
+                    firstPlatformModule = msym;
+                lastPlatformModule = msym;
+            }
+        }
+
+        ListBuffer<Location> locns = new ListBuffer<Location>();
+        for (ModuleSymbol msym: msyms) {
+            DEBUG("Modules.resolve: msym: " + msym);
+            DEBUG("Modules.resolve: msym.location: " + msym.location);
+            if (jfm != null && isPlatformModule(msym)) {
+                locns.addAll(jfm.augmentPlatformLocation(msym.location,
+                        msym == firstPlatformModule,
+                        msym == lastPlatformModule));
+            } else
+                locns.add(msym.location);
+        }
+        Location merged = moduleFileManager.join(locns);
+        DEBUG("Modules.resolve: merged result: " + merged);
+        reader.setPathLocation(merged);
+
+        return true;
+    }
+
+    boolean isBaseModuleName(Name name) {
+        return name.equals(syms.baseModule.name);
+    }
+
+    boolean isPlatformModule(ModuleSymbol msym) {
+        return isPlatformModuleName(msym.name) || definesPlatformModule(msym.directives);
+    }
+
+    boolean isPlatformModuleName(Name name) {
+        return name.toString().startsWith("java.") || name.toString().startsWith("jdk.") ;
+    }
+
+    boolean definesPlatformModule(List<Directive> directives) {
+        for (Directive d: directives) {
+            switch (d.getKind()) {
+                case PROVIDES_MODULE:
+                    if (isPlatformModuleName(((ProvidesModuleDirective) d).moduleId.name))
+                        return true;
+                    break;
+                case VIEW:
+                    ViewDeclaration v = (ViewDeclaration) d;
+                    if (isPlatformModuleName(v.name) || definesPlatformModule(v.directives))
+                        return true;
+                    break;
+            }
+        }
+        return false;
+    }
+
+    protected ModuleResolver getModuleResolver() {
+        return moduleResolver;
+    }
+
+    protected void initModuleResolver(Context context) {
+        Options options = Options.instance(context);
+        boolean useZeroMod = (options.get("zeroMod") != null);
+
+        if (!useZeroMod) {
+//            ServiceLoader<ModuleResolver> loader = ServiceLoader.load(ModuleResolver.class);
+//            // for now, use the first available, if any
+//            for (Iterator<ModuleResolver> iter = loader.iterator(); iter.hasNext(); ) {
+//                moduleResolver = iter.next();
+//                moduleResolver.init(options);
+//                return;
+//            }
+
+            String library = options.get(Option.L);
+            if (library != null || !isLegacyRuntime()) {
+                // use Class.forName on jigsaw module resolver, to avoid bootstrap dependency
+                try {
+                    String jigsawModuleResolver = "com.sun.tools.javac.jigsaw.JigsawModuleResolver";
+                    Class<? extends ModuleResolver> c =
+                            Class.forName(jigsawModuleResolver).asSubclass(ModuleResolver.class);
+                    Constructor<? extends ModuleResolver> constr =
+                            c.getDeclaredConstructor(new Class<?>[] { Context.class });
+                    moduleResolver = constr.newInstance(context);
+                    DEBUG("Modules.initModuleResolver: " + moduleResolver);
+
+                    Option[] unsupportedOptions = {
+            //            XBOOTCLASSPATH_PREPEND,
+                        ENDORSEDDIRS,
+            //            BOOTCLASSPATH,
+            //            XBOOTCLASSPATH_APPEND,
+                        EXTDIRS
+                    };
+                    for (Option o: unsupportedOptions) {
+                        if (options.get(o) != null) {
+
+                        }
+                    }
+                    context.put(ModuleResolver.class, moduleResolver);
+                    return;
+                } catch (ClassNotFoundException e) {
+                    // running in JDK 7 mode
+                    DEBUG("Modules.initModuleResolver: " + e);
+                } catch (IllegalAccessException e) {
+                    // FIXME: fall through for now; should report error
+                    DEBUG("Modules.initModuleResolver: " + e);
+                } catch (NoSuchMethodException e) {
+                    // FIXME: fall through for now; should report error
+                    DEBUG("Modules.initModuleResolver: " + e);
+                } catch (InstantiationException e) {
+                    // FIXME: fall through for now; should report error
+                    DEBUG("Modules.initModuleResolver: " + e);
+                } catch (InvocationTargetException e) {
+                    DEBUG("Modules.initModuleResolver: " + e);
+                    Throwable t = e.getTargetException();
+                    if (t instanceof FileNotFoundException)
+                        log.error("module.library.not.found", t.getMessage());
+                    else if (t instanceof IOException)
+                        log.error("cannot.open.module.library", t.getMessage()); // FIXME, t.getMessage is a barely helpful string
+                    else if (t instanceof RuntimeException)
+                        throw new RuntimeException(t);
+                    else if (t instanceof Error)
+                        throw new Error(t);
+                    else
+                        throw new AssertionError(t);
+                }
+            }
+        }
+
+        // use ZeroMod
+        moduleResolver = new ZeroMod(new ErrorHandler() {
+            public void report(ModuleSymbol msym, ModuleId mid, String key, Object... args) {
+                error(msym, mid, key, args);
+            }
+            public void report(ModuleSymbol msym, ModuleQuery mq, String key, Object... args) {
+                error(msym, mq, key, args);
+            }
+        });
+        DEBUG("Modules.initModuleResolver: zeromod: " + moduleResolver);
+        context.put(ModuleResolver.class, moduleResolver);
+    }
+    // where
+    private ModuleResolver moduleResolver;
+
+    private boolean isLegacyRuntime() {
+        File javaHome = new File(System.getProperty("java.home"));
+        File rt_jar = new File(new File(javaHome, "lib"), "rt.jar");
+        return rt_jar.exists();
+    }
+
+    private void error(ModuleSymbol msym, ModuleQuery mq, String key, Object... args) {
+        error(msym, new ModuleId(mq.name, mq.versionQuery), key, args);
+    }
+
+    private void error(ModuleSymbol msym, ModuleId id, String key, Object... args) {
+        if (msym == null) {
+            log.error(key, args);
+        } else {
+            // TODO, determine error location from msym, mid
+            ClassSymbol minfo = msym.module_info;
+
+            Env<ModuleContext> menv = moduleEnvs.get(msym);
+            DEBUG("Modules.error " + msym + " -- " + moduleEnvs.get(msym));
+            JavaFileObject fo;
+            JCDiagnostic.DiagnosticPosition pos;
+            if (menv == null) {
+                fo = (minfo.sourcefile != null ? minfo.sourcefile : minfo.classfile);
+                if (fo == null)
+                    fo = msym.module_info.classfile;
+                pos = null;
+            } else {
+                fo = menv.toplevel.sourcefile;
+                pos = treeFinder.find(menv.tree, id);
+            }
+
+            JavaFileObject prev = log.useSource(fo);
+            try {
+                log.error(pos, key, args);
+            } finally {
+                log.useSource(prev);
+            }
+        }
+    }
+
+    class TreeFinder extends JCTree.Visitor {
+        ModuleId mid;
+        JCTree result;
+
+        JCTree find(JCTree tree, ModuleId mid) {
+            DEBUG("Modules.TreeFinder.find mid=" + mid);
+            this.mid = mid;
+            result = null;
+            tree.accept(this);
+            DEBUG("Modules.TreeFinder.find result=" + result);
+            return result;
+        }
+
+        @Override
+        public void visitModuleDef(JCModuleDecl tree) {
+            search(tree.id);
+            search(tree.directives);
+        }
+
+        @Override
+        public void visitExports(JCExportDirective tree) {
+        }
+
+        @Override
+        public void visitPermits(JCPermitsDirective tree) {
+            if (equal(TreeInfo.fullName(tree.moduleName), mid.name) && mid.version == null)
+                result = tree;
+        }
+
+        @Override
+        public void visitRequiresModule(JCRequiresModuleDirective tree) {
+            search(tree.moduleQuery);
+        }
+
+        @Override
+        public void visitModuleId(JCModuleId tree) {
+            DEBUG("Modules.treeFinder.visitModuleId " + tree + " " + mid);
+            if (equal(TreeInfo.fullName(tree.qualId), mid.name) && equal(tree.version, mid.version))
+                result = tree;
+            DEBUG("Modules.treeFinder.visitModuleId result " + result);
+        }
+
+        @Override
+        public void visitModuleQuery(JCModuleQuery tree) {
+            DEBUG("Modules.treeFinder.visitModuleId " + tree + " " + mid);
+            if (equal(TreeInfo.fullName(tree.qualId), mid.name) && equal(tree.versionQuery, mid.version))
+                result = tree;
+            DEBUG("Modules.treeFinder.visitModuleId result " + result);
+        }
+
+        void search(JCTree tree) {
+            if (result != null)
+                return;
+
+            tree.accept(this);
+        }
+
+        void search(List<? extends JCTree> trees) {
+            if (result != null)
+                return;
+
+            for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail) {
+                l.head.accept(this);
+                if (result != null)
+                    return;
+            }
+        }
+
+        <T> boolean equal(T t1, T t2) {
+            DEBUG("Modules.treeFinder.equal " + t1 + " " + t2 + (t1 == null ? t2 == null : t1.equals(t2)));
+            return t1 == null ? t2 == null : t1.equals(t2);
+        }
+    }
+    TreeFinder treeFinder = new TreeFinder();
+
+    private void updateTrees(List<JCCompilationUnit> trees) {
+        if (mode == ModuleMode.SINGLE) {
+            assert rootLocns.size() == 1;
+            Location locn = rootLocns.iterator().next();
+            locn.getClass(); // debug
+            ModuleSymbol msym = allModules.get(locn);
+            DEBUG("Modules.updateTrees: update SINGLE trees: " + locn + " " + msym);
+            if (msym == null) {
+                msym = syms.unnamedModule;
+                DEBUG("Modules.updateTrees: using unnamed module " + syms.unnamedModule.completer);
+            }
+            for (List<JCCompilationUnit> l = trees; l.nonEmpty(); l = l.tail) {
+                JCCompilationUnit tree = l.head;
+                assert tree.locn == null || tree.locn == locn;
+                tree.locn = locn;
+                assert tree.modle == null || tree.modle == msym;
+                tree.modle = msym;
+            }
+        } else {
+            for (List<JCCompilationUnit> l = trees; l.nonEmpty(); l = l.tail) {
+                JCCompilationUnit t = l.head;
+                ModuleSymbol msym = allModules.get(t.locn);
+                if (msym == null) {
+                    msym = syms.unnamedModule;
+                    DEBUG("Modules.updateTrees: using unnamed module " + syms.unnamedModule.completer);
+                }
+                t.modle = msym;
+                DEBUG("Modules.updateTrees: update MULTIPLE trees: " + t.locn + " " + t.modle);
+            }
+        }
+    }
+
+    private enum State { INITIAL, RESOLVING, RESOLVED};
+    private State state = State.INITIAL;
+
+    private int enterCount = 0; // debug only
+
+    public boolean enter(List<JCCompilationUnit> trees) {
+        if (!enabled) {
+            CheckNoModulesVisitor v = new CheckNoModulesVisitor(log);
+            return v.checkNoModules(trees);
+        }
+
+        int count = enterCount++;
+        DEBUG("Modules.enter " + count + " " + state);
+
+        DEBUG("Modules.enter " + count + ": acceptAll");
+        acceptAll(trees);
+
+        try { // debug
+
+        switch (state) {
+            case INITIAL:
+                state = State.RESOLVING;
+                try {
+                    return resolve(trees);
+                } finally {
+                    state = State.RESOLVED;
+                }
+
+            case RESOLVING:
+                updateTrees(trees);
+                return true;
+
+            case RESOLVED:
+                return true;
+
+            default:
+                throw new AssertionError();
+        }
+
+        // debug
+        } finally {
+             DEBUG("Modules.enter " + count + ": exit " + state);
+        }
+    }
+    // where
+    private static class CheckNoModulesVisitor extends TreeScanner {
+        private final Log log;
+        private boolean result = true;
+        CheckNoModulesVisitor(Log log) {
+            this.log = log;
+        }
+        boolean checkNoModules(List<? extends JCTree> trees) {
+            scan(trees);
+            return result;
+        }
+        @Override
+        public void visitClassDef(JCClassDecl tree) {
+        }
+        @Override
+        public void visitModuleDef(JCModuleDecl tree) {
+            result = false;
+            log.error(tree, "module.decl.not.permitted");
+        }
+        @Override
+        public void visitTopLevel(JCCompilationUnit tree) {
+            JavaFileObject prev = log.useSource(tree.sourcefile);
+            try {
+                 super.visitTopLevel(tree);
+            } finally {
+                log.useSource(prev);
+            }
+        }
+    }
+
+    // Quick and dirty temporary debug printing;
+    // this should all be removed prior to final integration
+    boolean DEBUG = (System.getProperty("javac.debug.modules") != null);
+    void DEBUG(String s) {
+        if (DEBUG)
+            System.err.println(s);
+    }
+
+    void showModuleResolver(ModuleResolver mr) {
+        debug.println("Module resolver: " + mr.getClass().getSimpleName());
+    }
+
+    void showRootLocations(Collection<Location> rootLocns) {
+        debug.println("Module root locations: (" + (rootLocns == null ? "null" : rootLocns.size()) + ")");
+        if (rootLocns == null)
+            return;
+        int i = 0;
+        for (Location l: rootLocns) {
+            debug.println("  " + (i++) +": " + l);
+        }
+    }
+
+    void showModules(String desc, Collection<ModuleSymbol> msyms) {
+        boolean showAll = debug.isEnabled("all");
+        boolean showLocation = showAll || debug.isEnabled("location");
+        boolean showRequires = showAll || debug.isEnabled("requires");
+        if (showLocation || showRequires || showAll) {
+            debug.println(desc + " (" + msyms.size() + ")");
+            for (ModuleSymbol msym: msyms) {
+                debug.println("  " + msym);
+                if (showLocation) {
+                    debug.println("    location: " + msym.location);
+                }
+                if (showRequires) {
+                    // short form only, for now
+                    debug.print("    requires: ");
+                    String sep = "";
+                    for (RequiresModuleDirective d: msym.getRequiredModules()) {
+                        debug.print(sep);
+                        showNameAndVersion(d.moduleQuery.name, d.moduleQuery.versionQuery);
+                        sep = ", ";
+                    }
+                    debug.println();
+                }
+            }
+
+        } else {
+            debug.print(desc + " (" + msyms.size() + ")");
+            debug.print(" ");
+            String sep = "";
+            for (ModuleSymbol msym: msyms) {
+                debug.print(sep + msym);
+                sep = ", ";
+            }
+            debug.println();
+        }
+    }
+
+    void showModuleIds(String desc, Collection<ModuleId> mids) {
+        debug.print(desc + " (" + mids.size() + ")");
+        debug.print(" ");
+        String sep = "";
+        for (ModuleId mid: mids) {
+            debug.print(sep);
+            showNameAndVersion(mid.name, mid.version);
+            sep = ", ";
+        }
+        debug.println();
+    }
+
+    private void showNameAndVersion(Name name, Name version) {
+        debug.print(name);
+        if (version != null) {
+            debug.print("@");
+            debug.print(version);
+        }
+    }
+
+    private static <T> String toString(Iterable<T> items) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("[");
+        String sep = "";
+        for (T t: items) {
+            sb.append(sep);
+            sb.append(t);
+            sep = ",";
+        }
+        sb.append("]");
+        return sb.toString();
+    }
+
+    // should be static within ZeroMod
+    enum VersionErrorKind {
+        NO_VERSION_AVAILABLE("mdl.no.version.available"),
+        NO_UNIQUE_VERSION_AVAILABLE("mdl.no.unique.version.available"),
+        REQUIRED_VERSION_NOT_AVAILABLE("mdl.required.version.not.available");
+        VersionErrorKind(String key) { this.key = key; }
+        final String key;
+    };
+
+    interface ErrorHandler {
+        void report(ModuleSymbol msym, ModuleId mid, String key, Object... args);
+        void report(ModuleSymbol msym, ModuleQuery mq, String key, Object... args);
+    }
+
+    /**
+     * Module resolver for modules defined in the Java&trade; Programming Language.
+     *
+     * Given a set of root modules, and an overall set of modules, the resolver determines
+     * which modules are visible from the root modules.
+     */
+    public interface ModuleResolver {
+
+        /**
+         * Resolve a set of modules. The resolution may take additional modules into
+         * account, such as may be found in a system module library.
+         * Returns null if the modules cannot be resolved.
+         * @param roots The root modules whose dependencies need to be resolved
+         * @param modules A set of modules in which to find any dependencies.
+         * @throws ResolutionException if the resolution cannot be successfully completed.
+         */
+        Iterable<? extends ModuleSymbol> resolve(
+                Iterable<? extends ModuleSymbol> roots,
+                Iterable<? extends ModuleSymbol> modules);
+
+        boolean isPackageVisible(ModuleSymbol msym, PackageSymbol psym);
+    }
+
+    class ZeroMod implements ModuleResolver {
+        private ErrorHandler errorHandler;
+
+        ZeroMod(ErrorHandler e) {
+            errorHandler = e;
+        }
+
+        public Iterable<? extends ModuleSymbol> resolve(
+                Iterable<? extends ModuleSymbol> roots,
+                Iterable<? extends ModuleSymbol> modules)
+        {
+            DEBUG("ZeroMod: roots: " + Modules.toString(roots));
+            DEBUG("ZeroMod: modules: " + Modules.toString(modules));
+            roots.getClass();
+            modules.getClass();
+
+            moduleTable = buildModuleTable(modules);
+            List<Node> rootNodes = getNodes(roots);
+            tarjan(rootNodes);
+
+            DEBUG("ZeroMod.NODE MAP {");
+            for (Node n: nodeMap.values())
+                DEBUG("  Node " + n + " " + n.scc);
+            DEBUG("}");
+
+            ListBuffer<ModuleSymbol> results = new ListBuffer<ModuleSymbol>();
+            for (Node node: rootNodes) {
+                if (!results.contains(node.sym))
+                    getVisibleModules(node.scc, results);
+            }
+
+            DEBUG("ZeroMod: results: " + Modules.toString(results));
+            return results;
+        }
+
+        @Override
+        public boolean isPackageVisible(ModuleSymbol msym, PackageSymbol psym) {
+            return true;
+        }
+
+        private void getVisibleModules(SCC scc, ListBuffer<ModuleSymbol> results) {
+            for (Node n: scc.nodes)
+                results.add(n.sym);
+            for (SCC child: scc.getChildren())
+                getVisibleModules(child, results);
+        }
+
+        private Map<Name, Map<Name, ModuleSymbol>> buildModuleTable(
+                Iterable<? extends ModuleSymbol> modules) {
+            Map<Name, Map<Name, ModuleSymbol>> table = new HashMap<Name, Map<Name, ModuleSymbol>>();
+            // build module index
+            for (ModuleSymbol sym: modules) {
+                add(table, sym, new ModuleId(sym.name, sym.version));
+                for (ViewDeclaration v : sym.getViews()) {
+                    for (ProvidesModuleDirective d : v.getAliases())
+                        add(table, sym, d.moduleId);
+                }
+            }
+
+            // Add entry for default platform module if needed
+            for (ModuleId p: Arrays.asList(syms.baseModule, syms.jdkLegacyModule)) {
+                Map<Name,ModuleSymbol> versions = table.get(p.name);
+                ModuleSymbol psym = (versions == null) ? null : versions.get(p.version);
+                if (psym == null) {
+                    if (versions == null)
+                        table.put(p.name, versions = new HashMap<Name,ModuleSymbol>());
+                    psym = new ModuleSymbol(p.name, syms.rootModule);
+                    psym.location = StandardLocation.PLATFORM_CLASS_PATH;
+                    versions.put(p.version, psym);
+                    psym.directives = List.nil();
+                }
+            }
+
+            return table;
+        }
+
+        private void add(Map<Name, Map<Name, ModuleSymbol>> table,
+                ModuleSymbol sym, ModuleId mid) {
+            Map<Name, ModuleSymbol> versions = table.get(mid.name);
+            if (versions == null)
+                table.put(mid.name, versions = new HashMap<Name, ModuleSymbol>());
+            ModuleSymbol m = versions.get(mid.version);
+            if (m != null)
+                // TODO ?? enhance error to disambiguate between define and provides
+                errorHandler.report(sym, mid, "mdl.duplicate.definition", m);
+            else
+                versions.put(mid.version, sym);
+        }
+
+        private ModuleSymbol getModule(ModuleQuery mid) throws ModuleException {
+            Map<Name, ModuleSymbol> versions = moduleTable.get(mid.name);
+            if (versions == null)
+                throw new ModuleException("mdl.no.version.available", mid);
+            if (mid.versionQuery == null) {
+                if (versions.size() > 1)
+                    throw new ModuleException("mdl.no.unique.version.available", mid);
+                return versions.values().iterator().next();
+            } else {
+                Name q = mid.versionQuery;
+                Name ge = names.fromString(">=");
+                if (q.startsWith(ge)) q = q.subName(2, q.length());
+                ModuleSymbol sym = versions.get(q);
+                if (sym == null)
+                    throw new ModuleException("mdl.required.version.not.available", mid);
+                return sym;
+            }
+        }
+        // where
+        private Map<Name, Map<Name, ModuleSymbol>> moduleTable;
+
+        private class ModuleException extends Exception {
+            private static final long serialVersionUID = 0;
+            ModuleException(String key, ModuleQuery moduleQuery) {
+                this.key = key;
+                this.moduleQuery = moduleQuery;
+            }
+            final String key;
+            final ModuleQuery moduleQuery;
+        }
+
+        List<Node> getNodes(Iterable<? extends ModuleSymbol> syms) {
+            ListBuffer<Node> lb = new ListBuffer<Node>();
+            for (ModuleSymbol sym: syms) {
+                lb.add(getNode(sym));
+            }
+            return lb.toList();
+        }
+
+        Node getNode(ModuleSymbol sym) {
+            Node node = nodeMap.get(sym);
+            if (node == null)
+                nodeMap.put(sym, (node = new Node(sym)));
+            return node;
+        }
+        // where
+        private Map<ModuleSymbol, Node> nodeMap= new HashMap<ModuleSymbol, Node>();
+
+        private class Node implements Comparable<Node> {
+            final ModuleSymbol sym;
+            SCC scc;
+            int index = -1;
+            int lowlink;
+            boolean active;
+
+            Node(ModuleSymbol sym) {
+                this.sym = sym;
+            }
+
+            Iterable<Node> getDependencies() {
+                DEBUG("ZeroMod.Node.getDependencies: " + sym + " " + sym.getRequiredModules());
+                ListBuffer<Node> nodes = new ListBuffer<Node>();
+                for (RequiresModuleDirective d: sym.getRequiredModules()) {
+                    try {
+                        nodes.add(getNode(getModule(d.moduleQuery)));
+                    } catch (ModuleException e) {
+                        errorHandler.report(sym, e.moduleQuery, e.key, e.moduleQuery);
+                    }
+                }
+                return nodes.toList();
+            }
+
+            @Override
+            public String toString() {
+                return sym.name + "@" + sym.version + "(index:" + index +",low:" + lowlink + ",active:" + active + ")" ;
+            }
+
+            public int compareTo(Node o) {
+                return (index < o.index) ? -1 : (index == o.index) ? 0 : 1;
+            }
+        }
+
+        private class SCC {
+            void add(Node node) {
+                nodes.add(node);
+                node.scc = this;
+            }
+
+            Set<SCC> getChildren() {
+                if (children == null) {
+                    children = new LinkedHashSet<SCC>();
+                    for (Node node: nodes) {
+                        for (Node n: node.getDependencies()) {
+                            n.scc.getClass(); // nullcheck
+                            if (n.scc != this)
+                                children.add(n.scc);
+                        }
+                    }
+                }
+                return children;
+            }
+
+            @Override
+            public String toString() {
+                return nodes.toString();
+            }
+
+            private SortedSet<Node> nodes = new TreeSet<Node>();
+            private Set<SCC> children;
+        }
+
+        // Tarjan's algorithm to determine strongly connected components of a
+        // directed graph in linear time.
+
+        void tarjan(Iterable<? extends Node> nodes) {
+            for (Node node: nodes) {
+                if (node.index == -1)
+                    tarjan(node);
+            }
+        }
+
+        void tarjan(Node v) {
+            v.index = index;
+            v.lowlink = index;
+            index++;
+            stack.add(0, v);
+            v.active = true;
+            for (Node n: v.getDependencies()) {
+                if (n.index == -1) {
+                    tarjan(n);
+                    v.lowlink = Math.min(v.lowlink, n.lowlink);
+                } else if (stack.contains(n)) {
+                    v.lowlink = Math.min(v.lowlink, n.index);
+                }
+            }
+            if (v.lowlink == v.index) {
+                Node n;
+                SCC scc = new SCC();
+                do {
+                    n = stack.remove(0);
+                    n.active = false;
+                    scc.add(n);
+                } while (n != v);
+            }
+        }
+
+        private int index = 0;
+        private ArrayList<Node> stack = new ArrayList<Node>();
+    }
+}
--- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Tue May 07 17:14:17 2013 -0700
@@ -25,6 +25,15 @@
 
 package com.sun.tools.javac.comp;
 
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import javax.lang.model.element.ElementVisitor;
+
 import com.sun.tools.javac.api.Formattable.LocalizedString;
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Symbol.*;
@@ -46,18 +55,6 @@
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.EnumMap;
-import java.util.EnumSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.Map;
-
-import javax.lang.model.element.ElementVisitor;
-
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Flags.BLOCK;
 import static com.sun.tools.javac.code.Kinds.*;
@@ -284,7 +281,7 @@
 
     public boolean isAccessible(Env<AttrContext> env, TypeSymbol c, boolean checkInner) {
         boolean isAccessible = false;
-        switch ((short)(c.flags() & AccessFlags)) {
+        switch ((int)(c.flags() & AccessFlags)) {
             case PRIVATE:
                 isAccessible =
                     env.enclClass.sym.outermostClass() ==
@@ -354,7 +351,7 @@
     }
     public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym, boolean checkInner) {
         if (sym.name == names.init && sym.owner != site.tsym) return false;
-        switch ((short)(sym.flags() & AccessFlags)) {
+        switch ((int)(sym.flags() & AccessFlags)) {
         case PRIVATE:
             return
                 (env.enclClass.sym == sym.owner // fast special case
--- a/src/share/classes/com/sun/tools/javac/file/BaseFileObject.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/file/BaseFileObject.java	Tue May 07 17:14:17 2013 -0700
@@ -32,13 +32,13 @@
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.nio.charset.CharsetDecoder;
+
 import javax.lang.model.element.Modifier;
 import javax.lang.model.element.NestingKind;
 import javax.tools.FileObject;
+import javax.tools.JavaFileManager.Location;
 import javax.tools.JavaFileObject;
 
-import static javax.tools.JavaFileObject.Kind.*;
-
 import com.sun.tools.javac.util.BaseFileManager;
 
 /**
@@ -47,9 +47,10 @@
  * This code and its internal interfaces are subject to change or
  * deletion without notice.</b>
 */
-public abstract class BaseFileObject implements JavaFileObject {
-    protected BaseFileObject(JavacFileManager fileManager) {
+public abstract class BaseFileObject implements JavaFileObject, FileObject.Locatable {
+    protected BaseFileObject(JavacFileManager fileManager, Location location) {
         this.fileManager = fileManager;
+        this.location = location;
     }
 
     /** Return a short name for the object, such as for use in raw diagnostics
@@ -61,8 +62,10 @@
         return getClass().getSimpleName() + "[" + getName() + "]";
     }
 
+    @Override
     public NestingKind getNestingKind() { return null; }
 
+    @Override
     public Modifier getAccessLevel()  { return null; }
 
     public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
@@ -75,6 +78,8 @@
 
     protected abstract String inferBinaryName(Iterable<? extends File> path);
 
+    protected abstract String inferModuleTag(String binaryName);
+
     protected static JavaFileObject.Kind getKind(String filename) {
         return BaseFileManager.getKind(filename);
     }
@@ -115,6 +120,11 @@
 
     }
 
+    @Override
+    public Location getLocation() {
+        return location;
+    }
+
     // force subtypes to define equals
     @Override
     public abstract boolean equals(Object other);
@@ -125,4 +135,7 @@
 
     /** The file manager that created this JavaFileObject. */
     protected final JavacFileManager fileManager;
+
+    /** The location from which this file object was created, or null if none. */
+    protected final Location location;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/javac/file/CompositeLocation.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2009, 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.javac.file;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Set;
+import javax.tools.ExtendedLocation;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileManager.Location;
+import javax.tools.JavaFileObject;
+import javax.tools.JavaFileObject.Kind;
+import javax.tools.StandardJavaFileManager;
+
+import com.sun.tools.javac.util.ListBuffer;
+
+/**
+ * A location composed of a list of component locations.
+ */
+class CompositeLocation implements ExtendedLocation {
+    final JavaFileManager fileManager;
+    final Iterable<? extends Location> locations;
+    final String name;
+    private static int count; // FIXME, move count/name to creator, or move CompositeLocation to Locations
+
+    CompositeLocation(Iterable<? extends Location> locations, JavaFileManager fileManager) {
+        this.locations = locations;
+        this.fileManager = fileManager;
+        ListBuffer<String> names = new ListBuffer<String>();
+        for (Location l: locations)
+            names.add(l.getName());
+        name = "multiLocation#" + (count++) + names.toString();
+    }
+
+    @Override // javax.tools.ExtendedLocation
+    public Iterable<JavaFileObject> list(String packageName, Set<Kind> kinds, boolean recurse) throws IOException {
+        ListBuffer<JavaFileObject> results = new ListBuffer<JavaFileObject>();
+        for (Location l: locations) {
+            Iterable<JavaFileObject> fileObjects;
+            if (l instanceof ExtendedLocation)
+                fileObjects = ((ExtendedLocation) l).list(packageName, kinds, recurse);
+            else
+                fileObjects = fileManager.list(l, packageName, kinds, recurse);
+            for (JavaFileObject fo: fileObjects)
+                results.add(fo);
+        }
+        return results.toList();
+    }
+
+    @Override // javax.tools.ExtendedLocation
+    public String inferBinaryName(JavaFileObject file) {
+        for (Location l: locations) {
+            String binaryName;
+            if (l instanceof ExtendedLocation)
+                binaryName = ((ExtendedLocation) l).inferBinaryName(file);
+            else
+                binaryName = fileManager.inferBinaryName(l, file);
+            if (binaryName != null)
+                return binaryName;
+        }
+        return null;
+    }
+
+    @Override // javax.tools.JavaFileManager.Location
+    public String getName() {
+        return name;
+    }
+
+    @Override // javax.tools.JavaFileManager.Location
+    public boolean isOutputLocation() {
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return getName();
+    }
+
+    Collection<File> getLocation() {
+        if (!(fileManager instanceof StandardJavaFileManager))
+            throw new IllegalStateException();
+        StandardJavaFileManager fm = (StandardJavaFileManager) fileManager;
+        ListBuffer<File> files = new ListBuffer<File>();
+        for (Location l: locations) {
+            Iterable<? extends File> iter = fm.getLocation(l);
+            // FIXME: need a way to distinguish between empty locations and
+            // non-standard locations
+//            if (iter == null)
+//                throw new IllegalStateException();
+            if (iter != null)
+                for (File f: iter) files.add(f);
+        }
+        return files.toList();
+    }
+}
--- a/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Tue May 07 17:14:17 2013 -0700
@@ -44,16 +44,25 @@
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.zip.ZipFile;
 
 import javax.lang.model.SourceVersion;
+import javax.tools.ExtendedLocation;
 import javax.tools.FileObject;
 import javax.tools.JavaFileManager;
+import javax.tools.JavaFileManager.Location;
 import javax.tools.JavaFileObject;
+import javax.tools.ModuleFileManager;
 import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
 
+import static javax.tools.StandardLocation.*;
+
+import com.sun.tools.javac.file.Locations.Path;
 import com.sun.tools.javac.file.RelativePath.RelativeFile;
 import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
 import com.sun.tools.javac.util.BaseFileManager;
@@ -61,7 +70,7 @@
 import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.util.ListBuffer;
 
-import static javax.tools.StandardLocation.*;
+import static com.sun.tools.javac.main.Option.*;
 
 /**
  * This class provides access to the source, class and other files
@@ -72,7 +81,9 @@
  * This code and its internal interfaces are subject to change or
  * deletion without notice.</b>
  */
-public class JavacFileManager extends BaseFileManager implements StandardJavaFileManager {
+public class JavacFileManager
+        extends BaseFileManager
+        implements StandardJavaFileManager, ModuleFileManager {
 
     public static char[] toArray(CharBuffer buffer) {
         if (buffer.hasArray())
@@ -167,7 +178,7 @@
     }
 
     public JavaFileObject getRegularFile(File file) {
-        return new RegularFileObject(this, file);
+        return new RegularFileObject(this, null, file);
     }
 
     public JavaFileObject getFileForOutput(String classname,
@@ -254,7 +265,7 @@
      * Insert all files in subdirectory subdirectory of directory directory
      * which match fileKinds into resultList
      */
-    private void listDirectory(File directory,
+    private void listDirectory(Location location, File directory,
                                RelativeDirectory subdirectory,
                                Set<JavaFileObject.Kind> fileKinds,
                                boolean recurse,
@@ -274,7 +285,8 @@
             String fname = f.getName();
             if (f.isDirectory()) {
                 if (recurse && SourceVersion.isIdentifier(fname)) {
-                    listDirectory(directory,
+                    listDirectory(location,
+                                  directory,
                                   new RelativeDirectory(subdirectory, fname),
                                   fileKinds,
                                   recurse,
@@ -283,7 +295,7 @@
             } else {
                 if (isValidFile(fname, fileKinds)) {
                     JavaFileObject fe =
-                        new RegularFileObject(this, fname, new File(d, fname));
+                        new RegularFileObject(this, location, fname, new File(d, fname));
                     resultList.append(fe);
                 }
             }
@@ -326,7 +338,7 @@
      * Insert all files in subdirectory subdirectory of container which
      * match fileKinds into resultList
      */
-    private void listContainer(File container,
+    private void listContainer(Location location, File container,
                                RelativeDirectory subdirectory,
                                Set<JavaFileObject.Kind> fileKinds,
                                boolean recurse,
@@ -335,7 +347,8 @@
         if (archive == null) {
             // archives are not created for directories.
             if  (fsInfo.isDirectory(container)) {
-                listDirectory(container,
+                listDirectory(location,
+                              container,
                               subdirectory,
                               fileKinds,
                               recurse,
@@ -345,7 +358,7 @@
 
             // Not a directory; either a file or non-existant, create the archive
             try {
-                archive = openArchive(container);
+                archive = openArchive(location, container);
             } catch (IOException ex) {
                 log.error("error.reading.file",
                           container, getMessage(ex));
@@ -397,6 +410,178 @@
         return j < 0;
     }
 
+    private ModuleMode moduleMode;
+
+    @Override // javax.tools.ModuleFileManager
+    public ModuleMode getModuleMode() {
+        if (moduleMode == null) {
+//            boolean cp = hasLocation(StandardLocation.CLASS_PATH) || options.isSet(CLASSPATH);
+            // MUST-FIX:  mp && !cp does not work well in 199 mode, need something better,
+            // either explicit setModuleMode, or ability to test explicit setLocation -- uugh
+            boolean cp = options.isSet(CLASSPATH);
+            boolean mp = hasLocation(StandardLocation.MODULE_PATH) || options.isSet(MODULEPATH);
+            if (mp && !cp)
+                moduleMode = ModuleMode.MULTIPLE;
+            else
+                moduleMode = ModuleMode.SINGLE;
+        }
+        return moduleMode;
+    }
+
+    @Override // javax.tools.ModuleFileManager
+    public Location getModuleLocation(Location locn, JavaFileObject fo, String pkgName)
+            throws InvalidLocationException, InvalidFileObjectException {
+        if (getModuleMode() == ModuleMode.SINGLE)
+            return locn;
+        else {
+            fo.getClass(); // null check
+            if (!(fo instanceof BaseFileObject))
+                throw new IllegalArgumentException();
+
+            if (!hasLocation(locn))
+                throw new InvalidLocationException();
+            String tag = ((BaseFileObject) fo).inferModuleTag(pkgName);
+            if (tag == null)
+                throw new InvalidFileObjectException();
+            return getModuleLocation(locn, tag);
+        }
+    }
+
+    private Map<Location,Iterable<Location>> moduleLocations =
+            new LinkedHashMap<Location,Iterable<Location>>();
+
+    @Override // javax.tools.ModuleFileManager
+    public Iterable<Location> getModuleLocations(Location locn) {
+        //System.err.println("JavacFileManager.getModuleLocations " + getModuleMode() + " " + locn);
+
+        Iterable<Location> result = moduleLocations.get(locn);
+        if (result == null) {
+            Iterable<File> files = locations.getLocation(locn);
+            if (files == null)
+                result = List.<Location>nil();
+            else {
+                Set<Location> locns = new LinkedHashSet<Location>();
+                for (File file: files) {
+                    if (file.isDirectory()) {
+                        for (File f: file.listFiles()) {
+                            String tag = null;
+                            if (f.isDirectory())
+                                tag = f.getName();
+//                            else if (isArchive(f)) {
+//                                String name = f.getName();
+//                                tag = name.substring(0, name.lastIndexOf("."));
+//                            }
+                            // FIXME: check if tag has already been seen
+                            if (tag != null)
+                                locns.add(getModuleLocation(locn, tag));
+                        }
+                    } else {
+                        // ignore archive files for now, these would be "module archive
+                        // files", containing multiple modules in a new but obvious way
+                    }
+
+                }
+                result = locns;
+            }
+        }
+
+//        System.err.println("JavacFileManager.getModuleLocations.result " + result);
+        return result;
+    }
+
+    // cleared by setLocation
+    private Map<String, Location> locationCache = new HashMap<String,Location>();
+
+    @Override // javax.tools.ModuleFileManager
+    public Location join(Iterable<? extends Location> list)
+            throws IllegalArgumentException {
+        StringBuilder sb = new StringBuilder("{");
+        String sep = "";
+        for (Location l: list) {
+            if (!locations.isSupportedLocation(l))
+                throw new IllegalArgumentException(l.toString());
+            sb.append(sep);
+            sb.append(l.getName());
+            sep = ",";
+        }
+        sb.append("}");
+        String name = sb.toString();
+
+        // ugly, rethink this (using name for key)
+        Location result = locationCache.get(name);
+        if (result == null) {
+            // FIXME, could flatten list, and/or use a LinkedHashSet to
+            // canonicalize list
+            result = new CompositeLocation(list, this);
+            locationCache.put(name, result);
+        }
+
+//        System.err.println("JavacFileManager.join: " + toString(locations) + " = " + result);
+        return result;
+    }
+
+    // Get a location for all the containers named "tag" on given location
+    // Containers may be either directories or archive files.
+    protected Location getModuleLocation(Location location, String tag) {
+        // TODO: should reject bad use when location is already a module location
+        // TODO: should honor location.isOutput()
+        String name = location.getName() + "[" + tag + "]";
+        Location result = locationCache.get(name);
+        if (result == null) {
+            Iterable<? extends File> files = locations.getLocation(location);
+            if (files == null)
+                throw new IllegalArgumentException(location.getName());
+            Path p = locations.new Path();
+            if (files != null) {
+                for (File file: files) {
+                    File dir = new File(file, tag);
+                    if (dir.exists() && dir.isDirectory() || location.isOutputLocation())
+                        p.addFile(dir);
+                    else {
+                        File jar = new File(file, tag + ".jar");
+                        if (jar.exists() && jar.isFile())
+                            p.addFile(jar);
+                    }
+                }
+            }
+            result = locations.createLocation(p, name, locations.getOrigin(location));
+            locationCache.put(name, result);
+        }
+        return result;
+    }
+
+    /**
+     * Update a location based on the bootclasspath options.
+     * @param l the default platform location if no bootclasspath options are given
+     * @param first whether or not this is the first platform location
+     * @param last whether or not this is the last platform location
+     * @return a list of locations based on the default location and on the
+     *  values of any bootclasspath options.
+     */
+    public List<Location> augmentPlatformLocation(Location l, boolean first, boolean last) {
+        if (l == StandardLocation.PLATFORM_CLASS_PATH) {
+            assert (first && last);
+            return List.of(l);
+        }
+
+        Path ppPrepend = first ? locations.getPlatformPathPrepend() : null;
+        Path ppBase = locations.getPlatformPathBase();
+        Path ppAppend = last ? locations.getPlatformPathAppend() : null;
+
+        ListBuffer<Location> results = new ListBuffer<Location>();
+        if (ppPrepend != null)
+            results.add(locations.createLocation(ppPrepend, StandardLocation.PLATFORM_CLASS_PATH));
+        if (ppBase != null) {
+            if (first)
+                results.add(locations.createLocation(ppBase, StandardLocation.PLATFORM_CLASS_PATH));
+        } else
+            results.add(l);
+        if (ppAppend != null)
+            results.add(locations.createLocation(ppAppend, StandardLocation.PLATFORM_CLASS_PATH));
+        //System.out.println("JFM:augmentPlatformLocation: " + l + " " + first + " " + last + " " + results);
+        return results.toList();
+    }
+
     /**
      * An archive provides a flat directory structure of a ZipFile by
      * mapping directory names to lists of files (basenames).
@@ -457,12 +642,12 @@
      * fail over to the platform zip, and allow it to deal with a potentially
      * non compliant zip file.
      */
-    protected Archive openArchive(File zipFilename) throws IOException {
+    protected Archive openArchive(Location location, File zipFilename) throws IOException {
         try {
-            return openArchive(zipFilename, contextUseOptimizedZip);
+            return openArchive(location, zipFilename, contextUseOptimizedZip);
         } catch (IOException ioe) {
             if (ioe instanceof ZipFileIndex.ZipFormatException) {
-                return openArchive(zipFilename, false);
+                return openArchive(location, zipFilename, false);
             } else {
                 throw ioe;
             }
@@ -471,7 +656,7 @@
 
     /** Open a new zip file directory, and cache it.
      */
-    private Archive openArchive(File zipFileName, boolean useOptimizedZip) throws IOException {
+    private Archive openArchive(Location location, File zipFileName, boolean useOptimizedZip) throws IOException {
         File origZipFileName = zipFileName;
         if (symbolFileEnabled && locations.isDefaultBootClassPathRtJar(zipFileName)) {
             File file = zipFileName.getParentFile().getParentFile(); // ${java.home}
@@ -523,9 +708,9 @@
 
             if (origZipFileName == zipFileName) {
                 if (!useOptimizedZip) {
-                    archive = new ZipArchive(this, zdir);
+                    archive = new ZipArchive(this, location, zdir);
                 } else {
-                    archive = new ZipFileIndexArchive(this,
+                    archive = new ZipFileIndexArchive(this, location,
                                     zipFileIndexCache.getZipFileIndex(zipFileName,
                                     null,
                                     usePreindexedCache,
@@ -534,9 +719,9 @@
                 }
             } else {
                 if (!useOptimizedZip) {
-                    archive = new SymbolArchive(this, origZipFileName, zdir, symbolFilePrefix);
+                    archive = new SymbolArchive(this, location, origZipFileName, zdir, symbolFilePrefix);
                 } else {
-                    archive = new ZipFileIndexArchive(this,
+                    archive = new ZipFileIndexArchive(this, location,
                                     zipFileIndexCache.getZipFileIndex(zipFileName,
                                     symbolFilePrefix,
                                     usePreindexedCache,
@@ -560,6 +745,7 @@
 
     /** Flush any output resources.
      */
+    @Override // javax.tools.JavaFileManager
     public void flush() {
         contentCache.clear();
     }
@@ -567,6 +753,7 @@
     /**
      * Close the JavaFileManager, releasing resources.
      */
+    @Override // javax.tools.JavaFileManager
     public void close() {
         for (Iterator<Archive> i = archives.values().iterator(); i.hasNext(); ) {
             Archive a = i.next();
@@ -587,6 +774,7 @@
         return defaultEncodingName;
     }
 
+    @Override // javax.tools.JavaFileManager
     public ClassLoader getClassLoader(Location location) {
         nullCheck(location);
         Iterable<? extends File> path = getLocation(location);
@@ -604,6 +792,7 @@
         return getClassLoader(lb.toArray(new URL[lb.size()]));
     }
 
+    @Override // javax.tools.JavaFileManager
     public Iterable<JavaFileObject> list(Location location,
                                          String packageName,
                                          Set<JavaFileObject.Kind> kinds,
@@ -611,23 +800,35 @@
         throws IOException
     {
         // validatePackageName(packageName);
+        nullCheck(location);
         nullCheck(packageName);
         nullCheck(kinds);
 
-        Iterable<? extends File> path = getLocation(location);
-        if (path == null)
+        if (location instanceof ExtendedLocation) {
+            return ((ExtendedLocation) location).list(packageName, kinds, recurse);
+        }
+
+        Iterable<? extends File> files = locations.getLocation(location);
+        if (files == null)
             return List.nil();
         RelativeDirectory subdirectory = RelativeDirectory.forPackage(packageName);
         ListBuffer<JavaFileObject> results = new ListBuffer<JavaFileObject>();
 
-        for (File directory : path)
-            listContainer(directory, subdirectory, kinds, recurse, results);
+        for (File file: files) {
+            listContainer(location, file, subdirectory, kinds, recurse, results);
+        }
+
         return results.toList();
     }
 
+    @Override // javax.tools.JavaFileManager
     public String inferBinaryName(Location location, JavaFileObject file) {
         file.getClass(); // null check
         location.getClass(); // null check
+
+        if (location instanceof ExtendedLocation)
+            return ((ExtendedLocation) location).inferBinaryName(file);
+
         // Need to match the path semantics of list(location, ...)
         Iterable<? extends File> path = getLocation(location);
         if (path == null) {
@@ -637,9 +838,11 @@
         if (file instanceof BaseFileObject) {
             return ((BaseFileObject) file).inferBinaryName(path);
         } else
-            throw new IllegalArgumentException(file.getClass().getName());
+//            throw new IllegalArgumentException(file.getClass().getName() + ":" + file.toString());
+            return null; // FIXME -- seems OK per spec but need to check
     }
 
+    @Override // javax.tools.JavaFileManager
     public boolean isSameFile(FileObject a, FileObject b) {
         nullCheck(a);
         nullCheck(b);
@@ -650,24 +853,28 @@
         return a.equals(b);
     }
 
+    @Override // javax.tools.JavaFileManager
     public boolean hasLocation(Location location) {
-        return getLocation(location) != null;
+        return (location instanceof ExtendedLocation || (getLocation(location) != null));
     }
 
+    @Override // javax.tools.JavaFileManager
     public JavaFileObject getJavaFileForInput(Location location,
                                               String className,
                                               JavaFileObject.Kind kind)
         throws IOException
     {
         nullCheck(location);
-        // validateClassName(className);
+        // validateClassName(className);g518
+
         nullCheck(className);
         nullCheck(kind);
         if (!sourceOrClass.contains(kind))
             throw new IllegalArgumentException("Invalid kind: " + kind);
-        return getFileForInput(location, RelativeFile.forClass(className, kind));
+        return getFileForInput(location, RelativeFile.forClass(className, kind), kind);
     }
 
+    @Override // javax.tools.JavaFileManager
     public FileObject getFileForInput(Location location,
                                       String packageName,
                                       String relativeName)
@@ -681,25 +888,44 @@
         RelativeFile name = packageName.length() == 0
             ? new RelativeFile(relativeName)
             : new RelativeFile(RelativeDirectory.forPackage(packageName), relativeName);
-        return getFileForInput(location, name);
+        return getFileForInput(location, name, getKindForName(name.path));
+    }
+
+    private JavaFileObject.Kind getKindForName(String name) {
+        for (JavaFileObject.Kind k: JavaFileObject.Kind.values()) {
+            if (k != JavaFileObject.Kind.OTHER && name.endsWith(k.extension)) {
+                return k;
+            }
+        }
+        return JavaFileObject.Kind.OTHER;
     }
 
-    private JavaFileObject getFileForInput(Location location, RelativeFile name) throws IOException {
-        Iterable<? extends File> path = getLocation(location);
-        if (path == null)
+    private JavaFileObject getFileForInput(Location location, RelativeFile name,
+                JavaFileObject.Kind kind) throws IOException {
+        if (location instanceof CompositeLocation) {
+            for (Location l: ((CompositeLocation) location).locations) {
+                JavaFileObject fo = getFileForInput(l, name, kind);
+                if (fo != null)
+                    return fo;
+            }
+            return null;
+        }
+
+        Iterable<? extends File> files = locations.getLocation(location);
+        if (files == null)
             return null;
 
-        for (File dir: path) {
-            Archive a = archives.get(dir);
+        for (File file: files) {
+            Archive a = archives.get(file);
             if (a == null) {
-                if (fsInfo.isDirectory(dir)) {
-                    File f = name.getFile(dir);
+                if (fsInfo.isDirectory(file)) {
+                    File f = name.getFile(file);
                     if (f.exists())
-                        return new RegularFileObject(this, f);
+                        return new RegularFileObject(this, location, f);
                     continue;
                 }
                 // Not a directory, create the archive
-                a = openArchive(dir);
+                a = openArchive(location, file);
             }
             // Process the archive
             if (a.contains(name)) {
@@ -709,6 +935,7 @@
         return null;
     }
 
+    @Override // javax.tools.JavaFileManager
     public JavaFileObject getJavaFileForOutput(Location location,
                                                String className,
                                                JavaFileObject.Kind kind,
@@ -724,6 +951,7 @@
         return getFileForOutput(location, RelativeFile.forClass(className, kind), sibling);
     }
 
+    @Override // javax.tools.JavaFileManager
     public FileObject getFileForOutput(Location location,
                                        String packageName,
                                        String relativeName,
@@ -741,6 +969,7 @@
         return getFileForOutput(location, name, sibling);
     }
 
+    // FIXME: compare against tl
     private JavaFileObject getFileForOutput(Location location,
                                             RelativeFile fileName,
                                             FileObject sibling)
@@ -755,24 +984,28 @@
                 if (sibling != null && sibling instanceof RegularFileObject) {
                     siblingDir = ((RegularFileObject)sibling).file.getParentFile();
                 }
-                return new RegularFileObject(this, new File(siblingDir, fileName.basename()));
+                return new RegularFileObject(this, location, new File(siblingDir, fileName.basename()));
             }
         } else if (location == SOURCE_OUTPUT) {
             dir = (getSourceOutDir() != null ? getSourceOutDir() : getClassOutDir());
         } else {
+            dir = null;
             Iterable<? extends File> path = locations.getLocation(location);
-            dir = null;
-            for (File f: path) {
-                dir = f;
-                break;
+            if (path != null) {
+                for (File e: path) {
+                    dir = e;
+                    break;
+                }
             }
+            //System.err.println("JavacFileManager.getFileForOutput location:" + location + " path:" + toString(path) + " dir:" + dir);
         }
 
         File file = fileName.getFile(dir); // null-safe
-        return new RegularFileObject(this, file);
+        return new RegularFileObject(this, location, file);
 
     }
 
+    @Override // javax.tools.StandardJavaFileManager
     public Iterable<? extends JavaFileObject> getJavaFileObjectsFromFiles(
         Iterable<? extends File> files)
     {
@@ -782,23 +1015,32 @@
         else
             result = new ArrayList<RegularFileObject>();
         for (File f: files)
-            result.add(new RegularFileObject(this, nullCheck(f)));
+            result.add(new RegularFileObject(this, null, nullCheck(f)));
         return result;
     }
 
+    @Override // javax.tools.StandardJavaFileManager
     public Iterable<? extends JavaFileObject> getJavaFileObjects(File... files) {
         return getJavaFileObjectsFromFiles(Arrays.asList(nullCheck(files)));
     }
 
+    @Override // javax.tools.StandardJavaFileManager
     public void setLocation(Location location,
                             Iterable<? extends File> path)
         throws IOException
     {
         nullCheck(location);
         locations.setLocation(location, path);
+        locationCache.clear();
     }
 
-    public Iterable<? extends File> getLocation(Location location) {
+    @Override // javax.tools.StandardJavaFileManager
+    public Iterable<File> getLocation(Location location) {
+        return locations.getLocation(location);
+    }
+
+    @Deprecated // remove uses of this method
+    Iterable<File> getEntriesForLocation(Location location) {
         nullCheck(location);
         return locations.getLocation(location);
     }
--- a/src/share/classes/com/sun/tools/javac/file/Locations.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/file/Locations.java	Tue May 07 17:14:17 2013 -0700
@@ -25,8 +25,8 @@
 
 package com.sun.tools.javac.file;
 
+import javax.tools.ExtendedLocation;
 import java.io.FileNotFoundException;
-import java.util.Iterator;
 import java.io.File;
 import java.io.IOException;
 import java.net.MalformedURLException;
@@ -37,12 +37,13 @@
 import java.util.EnumMap;
 import java.util.EnumSet;
 import java.util.HashMap;
-import java.util.HashSet;
+import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.StringTokenizer;
 import java.util.zip.ZipFile;
+
 import javax.tools.JavaFileManager.Location;
 import javax.tools.StandardLocation;
 
@@ -52,15 +53,15 @@
 import com.sun.tools.javac.util.Log;
 import com.sun.tools.javac.util.Options;
 
-import javax.tools.JavaFileManager;
 import javax.tools.StandardJavaFileManager;
 import static javax.tools.StandardLocation.*;
 import static com.sun.tools.javac.main.Option.*;
 
-/** This class converts command line arguments, environment variables
+/**
+ *  This class converts command line arguments, environment variables
  *  and system properties (in File.pathSeparator-separated String form)
  *  into a boot class path, user class path, and source path (in
- *  {@code Collection<String>} form).
+ *  Collection<PathEntry> form).
  *
  *  <p><b>This is NOT part of any supported API.
  *  If you write code that depends on this, you do so at your own risk.
@@ -98,6 +99,16 @@
         this.fsInfo = fsInfo;
     }
 
+    boolean isSupportedLocation(Location l) {
+        return (l instanceof StandardLocation)
+                || (l instanceof PathLocation)
+                || (l instanceof ExtendedLocation);
+    }
+
+    Location getOrigin(Location l) {
+        return (l instanceof PathLocation) ? ((PathLocation) l).origin : l;
+    }
+
     public Collection<File> bootClassPath() {
         return getLocation(PLATFORM_CLASS_PATH);
     }
@@ -158,15 +169,88 @@
         return entries;
     }
 
+    Location createLocation(Path path, Location origin) {
+        return new PathLocation(path, origin);
+    }
+
+    Location createLocation(Path path, String name, Location origin) {
+        return new PathLocation(path, name, origin);
+    }
+
+    private static class PathLocation implements Location {
+        final Collection<File> files;
+        final String name;
+        final Location origin;
+
+        @Deprecated // FIXME should not use static count
+        static int count;
+
+        PathLocation(Path p, Location origin) {
+            files = p.toFiles();
+            //name = "pathLocation#" + (count++) + p;
+            name = "pathLocation#" + (count++) + "(path=" + p + ")";
+            this.origin = origin;
+        }
+
+        PathLocation(Path p, String name, Location origin) {
+            files = p.toFiles();
+            this.name = name;
+            this.origin = origin;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public boolean isOutputLocation() {
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return getName();
+        }
+    }
+
+    private class PathEntry {
+        PathEntry(File file) {
+            file.getClass(); // null check
+            this.file = file;
+            this.canonFile = fsInfo.getCanonicalFile(file);
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (this == other)
+                return true;
+            if (!(other instanceof PathEntry))
+                return false;
+            PathEntry o = (PathEntry) other;
+            return canonFile.equals(o.canonFile);
+        }
+
+        @Override
+        public int hashCode() {
+            return canonFile.hashCode();
+        }
+
+        @Override
+        public String toString() {
+            return file.getPath();
+        }
+
+        final File file;
+        final File canonFile;
+    }
+
     /**
      * Utility class to help evaluate a path option.
      * Duplicate entries are ignored, jar class paths can be expanded.
      */
-    private class Path extends LinkedHashSet<File> {
+    class Path extends LinkedHashSet<PathEntry> {
         private static final long serialVersionUID = 0;
 
         private boolean expandJarClassPaths = false;
-        private Set<File> canonicalValues = new HashSet<File>();
 
         public Path expandJarClassPaths(boolean x) {
             expandJarClassPaths = x;
@@ -181,8 +265,10 @@
             return this;
         }
 
-        public Path() { super(); }
-
+        /** Add all the jar files found in one or more directories.
+         *  @param dirs one or more directories separated by path separator char
+         *  @param whether to generate a warning if a given directory does not exist
+         */
         public Path addDirectories(String dirs, boolean warn) {
             boolean prev = expandJarClassPaths;
             expandJarClassPaths = true;
@@ -196,10 +282,18 @@
             }
         }
 
+        /** Add all the jar files found in one or more directories.
+         *  Warnings about non-existent directories are given iff Paths.warn is set.
+         *  @param dirs one or more directories separated by path separator char
+         */
         public Path addDirectories(String dirs) {
             return addDirectories(dirs, warn);
         }
 
+        /** Add all the jar files found in a directory.
+         *  @param dirs one or more directories separated by path separator char
+         *  @param whether to generate a warning if a given directory does not exist
+         */
         private void addDirectory(File dir, boolean warn) {
             if (!dir.isDirectory()) {
                 if (warn)
@@ -218,6 +312,10 @@
             }
         }
 
+        /** Add directories and archive files.
+         *  @param files one or more directories and archive files separated by path separator char
+         *  @param whether to generate a warning if a given entry does not exist
+         */
         public Path addFiles(String files, boolean warn) {
             if (files != null) {
                 addFiles(getPathEntries(files, emptyPathDefault), warn);
@@ -241,25 +339,31 @@
             return addFiles(files, warn);
         }
 
+        /** Add a directory or archive file.
+         *  @param file directory or archive file to be added
+         */
+        public void addFile(File file) {
+            addFile(file, warn);
+        }
+
+        /** Add a directory or archive file.
+         *  @param file directory or archive file to be added
+         *  @param warn whether to generate a warning if the file does not exist
+         */
         public void addFile(File file, boolean warn) {
-            if (contains(file)) {
-                // discard duplicates
+            PathEntry entry = new PathEntry(file);
+            if (contains(entry)) {
+                /* Discard duplicates and avoid infinite recursion */
                 return;
             }
 
-            if (! fsInfo.exists(file)) {
+            if (!fsInfo.exists(file)) {
                 /* No such file or directory exists */
                 if (warn) {
                     log.warning(Lint.LintCategory.PATH,
                             "path.element.not.found", file);
                 }
-                super.add(file);
-                return;
-            }
-
-            File canonFile = fsInfo.getCanonicalFile(file);
-            if (canonicalValues.contains(canonFile)) {
-                /* Discard duplicates and avoid infinite recursion */
+                super.add(entry);
                 return;
             }
 
@@ -288,8 +392,7 @@
 
             /* Now what we have left is either a directory or a file name
                conforming to archive naming convention */
-            super.add(file);
-            canonicalValues.add(canonFile);
+            super.add(entry);
 
             if (expandJarClassPaths && fsInfo.isFile(file))
                 addJarClassPath(file, warn);
@@ -308,6 +411,24 @@
                 log.error("error.reading.file", jarFile, JavacFileManager.getMessage(e));
             }
         }
+
+        void addAll(Iterable<PathEntry> entries) {
+            for (PathEntry e: entries) 
+                add(e);
+        }
+
+        Collection<File> toFiles() {
+            ListBuffer<File> files = new ListBuffer<File>();
+            for (PathEntry e: this)
+                files.add(e.file);
+            return files.toList();
+        }
+
+        // DEBUG
+        @Override
+        public String toString() {
+            return "Path(" + super.toString() + ")";
+        }
     }
 
     /**
@@ -345,9 +466,9 @@
 
         /** @see JavaFileManager#handleOption */
         abstract boolean handleOption(Option option, String value);
-        /** @see StandardJavaFileManager#getLocation */
+        /** @see StandardJavaFileManager#getLocation. */
         abstract Collection<File> getLocation();
-        /** @see StandardJavaFileManager#setLocation */
+        /** @see StandardJavaFileManager#setLocation. */
         abstract void setLocation(Iterable<? extends File> files) throws IOException;
     }
 
@@ -419,8 +540,7 @@
         boolean handleOption(Option option, String value) {
             if (!options.contains(option))
                 return false;
-            searchPath = value == null ? null :
-                    Collections.unmodifiableCollection(createPath().addFiles(value));
+            searchPath = (value == null) ? null : computePath(value).toFiles();
             return true;
         }
 
@@ -437,7 +557,7 @@
             } else {
                 p = createPath().addFiles(files);
             }
-            searchPath = Collections.unmodifiableCollection(p);
+            searchPath = p.toFiles();
         }
 
         protected Path computePath(String value) {
@@ -585,7 +705,7 @@
                 defaultBootClassPathRtJar = null;
                 isDefaultBootClassPath = false;
                 Path p = new Path().addFiles(files, false);
-                searchPath = Collections.unmodifiableCollection(p);
+                searchPath = p.toFiles();
                 optionValues.clear();
             }
         }
@@ -639,7 +759,7 @@
 
         private void lazy() {
             if (searchPath == null)
-                searchPath = Collections.unmodifiableCollection(computePath());
+                searchPath = computePath().toFiles();
         }
     }
 
@@ -653,6 +773,7 @@
         LocationHandler[] handlers = {
             new BootClassPathLocationHandler(),
             new ClassPathLocationHandler(),
+            new SimpleLocationHandler(StandardLocation.MODULE_PATH, Option.MODULEPATH),
             new SimpleLocationHandler(StandardLocation.SOURCE_PATH, Option.SOURCEPATH),
             new SimpleLocationHandler(StandardLocation.ANNOTATION_PROCESSOR_PATH, Option.PROCESSORPATH),
             new OutputLocationHandler((StandardLocation.CLASS_OUTPUT), Option.D),
@@ -673,6 +794,11 @@
     }
 
     Collection<File> getLocation(Location location) {
+        if (location instanceof PathLocation)
+            return ((PathLocation) location).files;
+        if (location instanceof CompositeLocation)
+            return ((CompositeLocation) location).getLocation();
+
         LocationHandler h = getHandler(location);
         return (h == null ? null : h.getLocation());
     }
@@ -685,6 +811,7 @@
     }
 
     void setLocation(Location location, Iterable<? extends File> files) throws IOException {
+        //FIXME: should we be able to set values for PathLocation and ExtendedLocation
         LocationHandler h = getHandler(location);
         if (h == null) {
             if (location.isOutputLocation())
@@ -715,6 +842,65 @@
         }
     }
 
+    /**
+     * Get any classes that should appear before the main platform classes.
+     * For compatibility, this is the classes defined by -Xbootclasspath/p:
+     * and the contents of the endorsed directories.
+     * See computeBootClassPath() for the full definition of the legacy
+     * platform class path.
+     */
+    Path getPlatformPathPrepend() {
+        //return getPathForOption(XBOOTCLASSPATH_PREPEND, EnumSet.of(JavaFileObject.Kind.CLASS));
+        Path path = new Path();
+
+        path.addFiles(options.get(XBOOTCLASSPATH_PREPEND));
+
+        String optionValue;
+        if ((optionValue = options.get(ENDORSEDDIRS)) != null)
+            path.addDirectories(optionValue);
+        else
+            path.addDirectories(System.getProperty("java.endorsed.dirs"), false);
+
+        return (path.size() == 0 ? null : path);
+    }
+
+    /**
+     * Get the main platform classes.
+     * For now, this is just the classes defined by -bootclasspath or -Xbootclasspath.
+     * See computeBootClassPath() for the full definition of the legacy
+     * platform class path.
+     */
+    Path getPlatformPathBase() {
+        Path path = new Path();
+        path.addFiles(options.get(BOOTCLASSPATH));
+        return (path.size() == 0 ? null : path);
+    }
+
+    /**
+     * Get any classes that should appear after the main platform classes.
+     * For compatibility, this is the classes defined by -Xbootclasspath/a:
+     * and the contents of the extension directories.
+     * See computeBootClassPath() for the full definition of the legacy
+     * platform class path.
+     */
+    Path getPlatformPathAppend() {
+        //return getPathForOption(XBOOTCLASSPATH_APPEND, EnumSet.of(JavaFileObject.Kind.CLASS));
+        Path path = new Path();
+
+        path.addFiles(options.get(XBOOTCLASSPATH_APPEND));
+
+        // Strictly speaking, standard extensions are not bootstrap
+        // classes, but we treat them identically, so we'll pretend
+        // that they are.
+        String optionValue;
+        if ((optionValue = options.get(EXTDIRS)) != null)
+            path.addDirectories(optionValue);
+        else
+            path.addDirectories(System.getProperty("java.ext.dirs"), false);
+
+        return (path.size() == 0 ? null : path);
+    }
+
     /** Is this the name of an archive file? */
     private boolean isArchive(File file) {
         String n = file.getName().toLowerCase();
--- a/src/share/classes/com/sun/tools/javac/file/RegularFileObject.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/file/RegularFileObject.java	Tue May 07 17:14:17 2013 -0700
@@ -39,6 +39,7 @@
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
 import java.nio.charset.CharsetDecoder;
+import javax.tools.JavaFileManager.Location;
 import javax.tools.JavaFileObject;
 
 /**
@@ -58,12 +59,12 @@
     final File file;
     private Reference<File> absFileRef;
 
-    public RegularFileObject(JavacFileManager fileManager, File f) {
-        this(fileManager, f.getName(), f);
+    public RegularFileObject(JavacFileManager fileManager, Location location, File f) {
+        this(fileManager, location, f.getName(), f);
     }
 
-    public RegularFileObject(JavacFileManager fileManager, String name, File f) {
-        super(fileManager);
+    public RegularFileObject(JavacFileManager fileManager, Location location, String name, File f) {
+        super(fileManager, location);
         if (f.isDirectory()) {
             throw new IllegalArgumentException("directories not supported");
         }
@@ -169,6 +170,25 @@
         return null;
     }
 
+    protected String inferModuleTag(String pkgName) {
+        File fn = file.getAbsoluteFile();
+        //System.err.println("RegularFileObject.inferModuleTag.args " + fn + " '" + pkgName + "'");
+        fn = fn.getParentFile();
+        if (pkgName.length() > 0) {
+            String[] pn = pkgName.replace('/', '.').split("\\.");
+            //System.err.println("RegularFileObject.inferModuleTag.pn " + Arrays.asList(pn) + " " + pn.length);
+            for (int i = pn.length - 1; i >= 0; i--) {
+                String n = fn.getName();
+                if (n.equalsIgnoreCase(pn[i])) // FIXME: should be File.equals
+                    fn = fn.getParentFile();
+                else
+                    return null;
+            }
+        }
+        //System.err.println("RegularFileObject.inferModuleTag.result " + (fn == null ? null : fn.getName()));
+        return (fn == null ? null : fn.getName());
+    }
+
     @Override
     public boolean isNameCompatible(String cn, JavaFileObject.Kind kind) {
         cn.getClass();
--- a/src/share/classes/com/sun/tools/javac/file/SymbolArchive.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/file/SymbolArchive.java	Tue May 07 17:14:17 2013 -0700
@@ -29,6 +29,8 @@
 import java.io.IOException;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
+
+import javax.tools.JavaFileManager.Location;
 import javax.tools.JavaFileObject;
 
 import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
@@ -46,8 +48,8 @@
     final File origFile;
     final RelativeDirectory prefix;
 
-    public SymbolArchive(JavacFileManager fileManager, File orig, ZipFile zdir, RelativeDirectory prefix) throws IOException {
-        super(fileManager, zdir, false);
+    public SymbolArchive(JavacFileManager fileManager, Location location, File orig, ZipFile zdir, RelativeDirectory prefix) throws IOException {
+        super(fileManager, location, zdir, false);
         this.origFile = orig;
         this.prefix = prefix;
         initMap();
--- a/src/share/classes/com/sun/tools/javac/file/ZipArchive.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/file/ZipArchive.java	Tue May 07 17:14:17 2013 -0700
@@ -30,6 +30,8 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.Writer;
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
 import java.net.URI;
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
@@ -41,14 +43,13 @@
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 
+import javax.tools.JavaFileManager.Location;
 import javax.tools.JavaFileObject;
 
 import com.sun.tools.javac.file.JavacFileManager.Archive;
 import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
 import com.sun.tools.javac.file.RelativePath.RelativeFile;
 import com.sun.tools.javac.util.List;
-import java.lang.ref.Reference;
-import java.lang.ref.SoftReference;
 
 /**
  * <p><b>This is NOT part of any supported API.
@@ -58,12 +59,13 @@
  */
 public class ZipArchive implements Archive {
 
-    public ZipArchive(JavacFileManager fm, ZipFile zfile) throws IOException {
-        this(fm, zfile, true);
+    public ZipArchive(JavacFileManager fm, Location location, ZipFile zfile) throws IOException {
+        this(fm, location, zfile, true);
     }
 
-    protected ZipArchive(JavacFileManager fm, ZipFile zfile, boolean initMap) throws IOException {
+    protected ZipArchive(JavacFileManager fm, Location location, ZipFile zfile, boolean initMap) throws IOException {
         this.fileManager = fm;
+        this.location = location;
         this.zfile = zfile;
         this.map = new HashMap<RelativeDirectory,List<String>>();
         if (initMap)
@@ -141,7 +143,13 @@
     /**
      * The file manager that created this archive.
      */
-    protected JavacFileManager fileManager;
+    protected final JavacFileManager fileManager;
+
+    /**
+     * The location containing this archive.
+     */
+    protected final Location location;
+
     /**
      * The index for the contents of this archive.
      */
@@ -165,7 +173,7 @@
         ZipEntry entry;
 
         protected ZipFileObject(ZipArchive zarch, String name, ZipEntry entry) {
-            super(zarch.fileManager);
+            super(zarch.fileManager, zarch.location);
             this.zarch = zarch;
             this.name = name;
             this.entry = entry;
@@ -252,6 +260,12 @@
         }
 
         @Override
+        protected String inferModuleTag(String binaryName) {
+            File zf = new File(zarch.zfile.getName());
+            return removeExtension(zf.getName());
+        }
+
+        @Override
         public boolean isNameCompatible(String cn, JavaFileObject.Kind k) {
             cn.getClass();
             // null check
--- a/src/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java	Tue May 07 17:14:17 2013 -0700
@@ -25,12 +25,9 @@
 
 package com.sun.tools.javac.file;
 
-import java.io.IOException;
-import java.util.Set;
-import javax.tools.JavaFileObject;
-
 import java.io.ByteArrayInputStream;
 import java.io.File;
+import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.Writer;
@@ -38,6 +35,10 @@
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
 import java.nio.charset.CharsetDecoder;
+import java.util.Set;
+
+import javax.tools.JavaFileManager.Location;
+import javax.tools.JavaFileObject;
 
 import com.sun.tools.javac.file.JavacFileManager.Archive;
 import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
@@ -54,11 +55,13 @@
 public class ZipFileIndexArchive implements Archive {
 
     private final ZipFileIndex zfIndex;
-    private JavacFileManager fileManager;
+    private final JavacFileManager fileManager;
+    private final Location location;
 
-    public ZipFileIndexArchive(JavacFileManager fileManager, ZipFileIndex zdir) throws IOException {
+    public ZipFileIndexArchive(JavacFileManager fileManager, Location location, ZipFileIndex zdir) throws IOException {
         super();
         this.fileManager = fileManager;
+        this.location = location;
         this.zfIndex = zdir;
     }
 
@@ -73,7 +76,7 @@
     public JavaFileObject getFileObject(RelativeDirectory subdirectory, String file) {
         RelativeFile fullZipFileName = new RelativeFile(subdirectory, file);
         ZipFileIndex.Entry entry = zfIndex.getZipIndexEntry(fullZipFileName);
-        JavaFileObject ret = new ZipFileIndexFileObject(fileManager, zfIndex, entry, zfIndex.getZipFile());
+        JavaFileObject ret = new ZipFileIndexFileObject(fileManager, location, zfIndex, entry, zfIndex.getZipFile());
         return ret;
     }
 
@@ -116,8 +119,8 @@
         File zipName;
 
 
-        ZipFileIndexFileObject(JavacFileManager fileManager, ZipFileIndex zfIndex, ZipFileIndex.Entry entry, File zipFileName) {
-            super(fileManager);
+        ZipFileIndexFileObject(JavacFileManager fileManager, Location location, ZipFileIndex zfIndex, ZipFileIndex.Entry entry, File zipFileName) {
+            super(fileManager, location);
             this.name = entry.getFileName();
             this.zfIndex = zfIndex;
             this.entry = entry;
@@ -249,6 +252,9 @@
             else
                 return entry.getName();
         }
+        protected String inferModuleTag(String binaryName) {
+            return removeExtension(zfIndex.getZipFile().getName());
+        }
     }
 
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/javac/jigsaw/JavacCatalog.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,446 @@
+/*
+ * Copyright (c) 2009, 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.javac.jigsaw;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.module.Dependence;
+import java.lang.module.ModuleId;
+import java.lang.module.ModuleIdQuery;
+import java.lang.module.ModuleInfo;
+import java.lang.module.ModuleView;
+import java.lang.module.ServiceDependence;
+import java.lang.module.ViewDependence;
+import java.lang.module.Version;
+import java.lang.module.VersionQuery;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.lang.model.element.ModuleElement;
+
+import org.openjdk.jigsaw.Catalog;
+import org.openjdk.jigsaw.JigsawModuleSystem;
+import org.openjdk.jigsaw.Library;
+import org.openjdk.jigsaw.SimpleLibrary;
+
+import com.sun.tools.javac.code.Directive.PermitsDirective;
+import com.sun.tools.javac.code.Directive.ProvidesModuleDirective;
+import com.sun.tools.javac.code.Directive.ProvidesServiceDirective;
+import com.sun.tools.javac.code.Directive.RequiresFlag;
+import com.sun.tools.javac.code.Directive.RequiresModuleDirective;
+import com.sun.tools.javac.code.Directive.ViewDeclaration;
+import com.sun.tools.javac.code.Symbol;
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.code.Symbol.ModuleSymbol;
+import com.sun.tools.javac.jvm.ClassFile;
+import com.sun.tools.javac.util.Name;
+
+
+/*
+ * Implementation of a Jigsaw catalog providing access to the modules
+ * in a compilation found with command line options such as modulepath,
+ * classpath and sourcepath.
+ */
+public class JavacCatalog  extends Catalog {
+    final JigsawModuleSystem jigsaw;
+    final Library library;
+    
+    private Map<String, Map<Version, ModuleSymbol>> moduleMap =
+            new HashMap<String, Map<Version, ModuleSymbol>>();
+    private Version nullVersion;   // used in the moduleMap
+
+    boolean DEBUG = (System.getProperty("javac.debug.modules") != null);
+    void DEBUG(String s) {
+        if (DEBUG)
+            System.err.println(s);
+    }
+
+    JavacCatalog(File library) throws IOException/*FIXME*/ {
+        jigsaw = JigsawModuleSystem.instance();
+        nullVersion = jigsaw.parseVersion("0");
+        if (library == null)
+            this.library = Library.openSystemLibrary();
+        else
+            this.library = SimpleLibrary.open(library);
+        DEBUG("JavacCatalog: library:" + library + " this.library:" + this.library);
+    }
+
+    @Override
+    public String name() {
+        return "javac"; // can we do anything better here?
+    }
+
+    @Override
+    public Catalog parent() {
+        return library;
+    }
+    
+    void init(Iterable<? extends ModuleElement> modules) {
+        DEBUG("JavacCatalog.init: " + modules);
+        for (ModuleElement me: modules) {
+            ModuleSymbol msym = (ModuleSymbol) me;
+            DEBUG("JavacCatalog.init: msym:" + msym + " msym.fullname:" + msym.fullname + " msym.version:" + msym.version);
+            addModule(msym.fullname, msym.version, msym);
+            for (ViewDeclaration v: msym.getViews()) {
+                if (v.name != null) {
+                    addModule(v.name, msym.version, msym);
+                }
+                for (ProvidesModuleDirective d: v.getAliases()) {
+                    com.sun.tools.javac.code.ModuleId alias = d.moduleId;
+                    addModule(alias.name, alias.version, msym);
+                }
+            }
+        }
+        DEBUG("JavacCatalog.init: map:" + moduleMap);
+    }
+    
+    private void addModule(Name name, Name version, ModuleSymbol msym) {
+        String n = name.toString();
+        Version v = getVersion(version);
+        Map<Version,ModuleSymbol> map = moduleMap.get(n);
+        if (map == null)
+            moduleMap.put(n, map = new HashMap<Version,ModuleSymbol>());
+        if (v != null)
+            map.put(v, msym);
+        else
+            map.put(nullVersion, msym);
+    }
+
+    @Override
+    protected void gatherLocalModuleIds(String moduleName, Set<ModuleId> mids) throws IOException {
+        DEBUG("JavacCatalog.gatherLocalModuleIds: " + moduleName);
+        if (moduleName != null) {
+            Map<Version,ModuleSymbol> syms = moduleMap.get(moduleName);
+            if (syms == null)
+                return;
+            addModuleIds(syms, moduleName, mids);
+        } else {
+            for (String mn : moduleMap.keySet()) {
+                addModuleIds(moduleMap.get(mn), moduleName, mids);
+            }
+        }
+        DEBUG("JavacCatalog.gatherLocalModuleIds: moduleName:" + moduleName + "--" + mids);
+    }
+    
+    protected void gatherLocalDeclaringModuleIds(Set<ModuleId> mids) throws IOException {
+        DEBUG("JavacCatalog.gatherLocalDeclaringModuleIds");
+        for (Map<Version,ModuleSymbol> map : moduleMap.values()) {
+            for (ModuleSymbol sym : map.values()) {
+                ModuleId mid = getModuleId(sym);
+                mids.add(mid);
+            }
+        }
+        DEBUG("JavacCatalog.gatherLocalDeclaringModuleIds: " + "--" + mids);
+    }
+    
+    // add all ModuleIds of the given name
+    private void addModuleIds(Map<Version,ModuleSymbol> map,
+                              String mn, Set<ModuleId> mids) {
+        for (ModuleSymbol sym : map.values()) {
+            ModuleId mid = getModuleId(sym);
+            if (mn == null || mid.name().equals(mn)) {
+                mids.add(mid);
+            }
+            for (ViewDeclaration v : sym.getViews()) {
+                Name n = v.name == null ? sym.fullname : v.name;
+                if (mn == null || mn.equals(n.toString())) {
+                    mid = getModuleId(n, sym.version);
+                    if (!mids.contains(mid))
+                        mids.add(mid);
+                }
+
+                for (ProvidesModuleDirective d : v.getAliases()) {
+                    mids.add(getModuleId(d.moduleId));
+                }
+            }
+        }
+    }
+
+    @Override
+    protected ModuleInfo readLocalModuleInfo(ModuleId mid) throws IOException {
+        DEBUG("JavacCatalog.readLocalModuleInfo " + mid);
+        ModuleSymbol msym = getModuleSymbol(mid);
+        DEBUG("JavacCatalog.readLocalModuleInfo " + mid + "--" + ((msym == null) ? null : new JavacModuleInfo(msym)));
+        return (msym == null) ? null : new JavacModuleInfo(msym);
+    }
+
+//    private ModuleId getModuleId(ModuleSymbol msym) {
+//        return getModuleId(new ClassFile.ModuleId(msym.fullname, msym.version));
+//    }
+//
+//    private ModuleId getModuleId(ClassFile.ModuleId cf_mid) {
+//        ModuleId id = moduleIdCache.get(cf_mid);
+//        if (id == null) {
+//            Name name = cf_mid.name;
+//            Name version = cf_mid.version;
+//            String s = (version == null) ? name.toString() : (name + "@" + version);
+//            moduleIdCache.put(cf_mid, id = jigsaw.parseModuleId(s));
+//        }
+//        return id;
+//    }
+//
+    ModuleSymbol getModuleSymbol(ModuleId mid) {
+        Map<Version,ModuleSymbol> map = moduleMap.get(mid.name());
+        if (map == null)
+            return null;
+        return (mid.version() == null) ? map.get(nullVersion) : map.get(mid.version());
+    }
+
+    Version getVersion(Name v) {
+        return (v == null) ? null : jigsaw.parseVersion(v.toString()); // FIXME -- throws IllegalArgumentException
+    }
+
+    VersionQuery getVersionQuery(Name vq) {
+        return (vq == null) ? null : jigsaw.parseVersionQuery(vq.toString()); // FIXME -- throws IllegalArgumentException
+    }
+
+    ModuleId getModuleId(ModuleSymbol sym) {
+        return getModuleId(sym.fullname, sym.version); // FIXME -- throws IllegalArgumentException
+    }
+
+    ModuleId getModuleId(com.sun.tools.javac.code.ModuleId mid) {
+        return getModuleId(mid.name, mid.version); // FIXME -- throws IllegalArgumentException
+    }
+
+    ModuleId getModuleId(Name n, Name v) {
+        String mid = (v == null) ? n.toString() : (n + "@" + v);
+        return jigsaw.parseModuleId(mid); // FIXME -- throws IllegalArgumentException
+    }
+
+    ModuleIdQuery getModuleQuery(com.sun.tools.javac.code.ModuleQuery midq) {
+        return getModuleIdQuery(midq.name, midq.versionQuery); // FIXME -- throws IllegalArgumentException
+    }
+    
+    ModuleIdQuery getModuleIdQuery(ModuleElement.ModuleQuery midq) {
+        return getModuleIdQuery(midq.getName(), midq.getVersionQuery());
+    }
+
+    ModuleIdQuery getModuleIdQuery(Name n, Name vq) {
+        String midq = (vq == null) ? n.toString() : (n + "@" + vq);
+        return jigsaw.parseModuleIdQuery(midq); // FIXME -- throws IllegalArgumentException
+    }
+    
+    ModuleIdQuery getModuleIdQuery(CharSequence n, CharSequence vq) {
+        String q = (vq == null || vq.length() == 0) ? String.valueOf(n) : (n + "@" + vq);
+        return jigsaw.parseModuleIdQuery(q);
+    }
+
+    Dependence.Modifier getModifier(RequiresFlag f) {
+        switch (f) {
+            case LOCAL:
+                return Dependence.Modifier.LOCAL;
+            case OPTIONAL:
+                return Dependence.Modifier.OPTIONAL;
+            case REEXPORT:
+                return Dependence.Modifier.PUBLIC;
+            case SYNTHETIC:
+                return Dependence.Modifier.SYNTHETIC;
+            case SYNTHESIZED:
+                return Dependence.Modifier.SYNTHESIZED;
+	    default:
+                throw new IllegalArgumentException(f.toString());  // FIXME -- throws IllegalArgumentException
+        }
+    }
+
+    class JavacModuleInfo implements ModuleInfo {
+        ModuleSymbol msym;
+
+        ModuleId id;
+        Set<ViewDependence> requiresModules;
+        Map<ModuleId, ModuleView> views;
+
+        JavacModuleInfo(ModuleSymbol msym) {
+            msym.getClass(); // null check
+            DEBUG("JavacModuleInfo: msym: " + msym);
+
+            this.msym = msym;
+            this.views = new HashMap<ModuleId, ModuleView>();
+
+            this.id = getModuleId(msym); // FIXME -- throws IllegalArgumentException
+
+            for (ViewDeclaration v : msym.getViews()) {
+                String mainClass = null;
+
+                if (v.hasEntrypoint()) {
+                    mainClass = new String(ClassFile.externalize(v.getEntrypoint().flatname));
+                }
+
+                Set<String> permits = new LinkedHashSet<String>();
+                for (PermitsDirective d : v.getPermits()) {
+                    permits.add(d.moduleId.name.toString()); // FIXME: validate name?
+                }
+
+                Set<String> exports = new LinkedHashSet<String>();
+
+                Set<ModuleId> provides = new LinkedHashSet<ModuleId>();
+                for (ProvidesModuleDirective d : v.getAliases()) {
+                    provides.add(getModuleId(d.moduleId));
+                }
+                
+                Map<String,Set<String>> services = new LinkedHashMap<String,Set<String>>();
+                for (ProvidesServiceDirective s : v.getServices()) {
+                    String sn = new String(ClassFile.externalize(s.service.flatname));
+                    String pn = new String(ClassFile.externalize(s.impl.flatname));
+                    Set<String> providers = services.get(sn);
+                    if (providers == null) {
+                        providers = new LinkedHashSet<String>();
+                        services.put(sn, providers);
+                    }
+                    providers.add(pn);
+                }
+                
+                ModuleId vid = (v.name == null)
+                                   ? id
+                                   : getModuleId(v.name, msym.version);
+                ModuleView view = new JavacModuleView(this,
+                                                      vid,
+                                                      mainClass,
+                                                      provides,
+                                                      exports,
+                                                      permits,
+                                                      services);
+                views.put(vid, view);
+            }
+            
+            if (!views.containsKey(id)) {
+                // create the default view if not exists
+                views.put(id, new JavacModuleView(this,
+                                                  id,
+                                                  null,
+                                                  Collections.<ModuleId>emptySet(),
+                                                  Collections.<String>emptySet(),
+                                                  Collections.<String>emptySet(),
+                                                  Collections.<String,Set<String>>emptyMap()));
+            }
+
+            requiresModules = new LinkedHashSet<ViewDependence>();
+            for (RequiresModuleDirective r: msym.getRequiredModules()) {
+                DEBUG("JavacModuleInfo: require " + r);
+                ModuleIdQuery q = getModuleQuery(r.moduleQuery);
+                EnumSet<Dependence.Modifier> mods = EnumSet.noneOf(Dependence.Modifier.class);
+                for (com.sun.tools.javac.code.Directive.RequiresFlag f: r.flags) {
+                    mods.add(getModifier(f));  // FIXME -- throws IllegalArgumentException
+                }
+                requiresModules.add(new ViewDependence(mods, q));
+            }
+            DEBUG("JavacModuleInfo: msym: " + msym + "[id:" + id + " views:" + views + " requires:" + requiresModules + "]");
+        }
+
+        @Override
+        public ModuleId id() {
+            return id;
+        }
+         
+        @Override
+        public Set<ViewDependence> requiresModules() {
+            return requiresModules;
+        }
+        
+        public Set<ServiceDependence> requiresServices() {
+            return Collections.emptySet();
+        }
+
+        public ModuleView defaultView() {
+            return views.get(id);
+        }
+
+        public Set<ModuleView> views() {
+            return Collections.unmodifiableSet(new HashSet<ModuleView>(views.values()));
+        }
+    }
+    
+    class JavacModuleView
+        implements ModuleView
+    {
+        private final ModuleInfo mi;
+        private final ModuleId id;
+        private final Set<String> exports;
+        private final Set<ModuleId> aliases;
+        private final Map<String,Set<String>> services;
+        private final Set<String> permits;
+        private final String mainClass;
+
+        JavacModuleView(ModuleInfo mi,
+                        ModuleId id,
+                        String mainClass,
+                        Set<ModuleId> aliases,
+                        Set<String> exports,
+                        Set<String> permits,
+                        Map<String,Set<String>> serviceProviders) {
+            this.mi = mi;
+            this.id = id;
+            this.mainClass = mainClass;
+            this.aliases = aliases;
+            this.exports = exports;
+            this.permits = permits;
+            this.services = serviceProviders;
+        }
+
+        public ModuleInfo moduleInfo() {
+            return mi;
+        }
+
+        public ModuleId id() {
+            return id;
+        }
+
+        public Set<ModuleId> aliases() {
+            return Collections.unmodifiableSet(aliases);
+        }
+
+        public Set<String> exports() {
+            return Collections.unmodifiableSet(exports);
+        }
+        
+        public Set<String> permits() {
+            return Collections.unmodifiableSet(permits);
+        }
+
+        public Map<String,Set<String>> services() {
+            return Collections.unmodifiableMap(services);
+        }
+
+        public String mainClass() {
+            return mainClass;
+        }
+
+        @Override
+        public String toString() {
+            return "View { id: " + id
+                    + ", provides: " + aliases
+                    + ", provides service: " + services
+                    + ", permits: " + permits
+                    + ", mainClass: " + mainClass
+                    + " }";
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/javac/jigsaw/JigsawLibraryLocation.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2009, 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.javac.jigsaw;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.lang.module.ModuleId;
+import java.net.URI;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.NestingKind;
+import javax.tools.ExtendedLocation;
+import javax.tools.FileObject;
+import javax.tools.JavaFileManager.Location;
+import javax.tools.JavaFileObject;
+import javax.tools.JavaFileObject.Kind;
+
+import org.openjdk.jigsaw.Library;
+
+import com.sun.tools.javac.util.ListBuffer;
+
+/**
+ * A location to represent a Jigsaw module in a Jigsaw module library.
+ */
+public class JigsawLibraryLocation implements ExtendedLocation {
+    private Library library;
+    private ModuleId mid;
+
+    // Quick and dirty temporary debug printing;
+    // this should all be removed prior to final integration
+    boolean DEBUG = (System.getProperty("javac.debug.modules") != null);
+    void DEBUG(String s) {
+        if (DEBUG)
+            System.err.println(s);
+    }
+
+    JigsawLibraryLocation(Library library, ModuleId mid) {
+        library.getClass(); // null check
+        this.library = library;
+        mid.getClass(); // null check
+        this.mid = mid;
+    }
+
+    @Override
+    public String getName() {
+        return mid.toString();
+    }
+
+    @Override
+    public boolean isOutputLocation() {
+        // only input locations supported
+        return false;
+    }
+
+    @Override
+    public Iterable<JavaFileObject> list(String packageName, Set<Kind> kinds, boolean recurse)
+            throws IOException {
+        // only Kind.CLASS supported
+        if (!kinds.contains(Kind.CLASS))
+            return Collections.emptySet();
+        ListBuffer<JavaFileObject> results = new ListBuffer<JavaFileObject>();
+        packageName = normalize(packageName);
+        String subpackagePrefix = packageName + ".";
+        for (Library l = library; l != null; l = l.parent()) {
+            List<String> classes = l.listLocalClasses(mid, true);
+            if (classes != null) {
+                for (String cn: classes) {
+                    //DEBUG("LIST raw " + cn);
+                    cn = normalize(cn);
+                    String pn = packagePart(cn);
+                    if (pn.equals(packageName) || (recurse && pn.startsWith(subpackagePrefix))) {
+                        results.add(new LibraryFileObject(library, mid, cn));
+                    }
+                }
+            }
+        }
+        DEBUG("JigsawLibraryLocation:" + library + ":" + mid + ": list " + packageName + "," + kinds + "--" + (results.size() < 5 ? results : (results.size() + " classes")));
+        return results;
+    }
+
+    public String inferBinaryName(JavaFileObject file) {
+        if (file instanceof LibraryFileObject)
+            return ((LibraryFileObject) file).className;
+        else
+            return null;
+    }
+
+    @Override
+    public String toString() {
+        return ("JigsawLibrary[" + library + "," + mid + "]");
+    }
+
+    private static String normalize(String name) {
+        return name.replace('/', '.');
+    }
+
+    private static String packagePart(String className) {
+        int sep = className.lastIndexOf('.');
+        return (sep == -1) ? "" : className.substring(0, sep);
+    }
+
+    private static String simpleNamePart(String className) {
+        int sep = className.lastIndexOf('.');
+        return (sep == -1) ? className : className.substring(sep + 1);
+    }
+
+    class LibraryFileObject implements JavaFileObject, FileObject.Locatable {
+        Library library;
+        ModuleId mid;
+        String className;
+
+        private LibraryFileObject(Library library, ModuleId mid, String className) {
+            this.library = library;
+            this.mid = mid;
+            this.className = className;
+        }
+
+        public Kind getKind() {
+            return Kind.CLASS;
+        }
+
+        public boolean isNameCompatible(String simpleName, Kind kind) {
+            return (kind == Kind.CLASS) && simpleName.equals(simpleNamePart(className));
+        }
+
+        public NestingKind getNestingKind() {
+            return null;
+        }
+
+        public Modifier getAccessLevel() {
+            return null;
+        }
+
+        public URI toUri() {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public String getName() {
+            return library.name() + ":" + mid.toString() + ":" + className;
+        }
+
+        public InputStream openInputStream() throws IOException {
+            byte[] data;
+            if (className.endsWith(".module-info")) // FIXME?
+                data = library.readModuleInfoBytes(mid);
+            else
+                data = library.readClass(mid, className);
+            return new ByteArrayInputStream(data);
+        }
+
+        public OutputStream openOutputStream() throws IOException {
+            throw new UnsupportedOperationException();
+        }
+
+        public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
+            throw new UnsupportedOperationException();
+        }
+
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+            throw new UnsupportedOperationException();
+        }
+
+        public Writer openWriter() throws IOException {
+            throw new UnsupportedOperationException();
+        }
+
+        public long getLastModified() {
+            return 0;
+        }
+
+        public boolean delete() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public String toString() {
+            return getName();
+        }
+
+        @Override
+        public Location getLocation() {
+            return JigsawLibraryLocation.this;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (!(other instanceof LibraryFileObject))
+                return false;
+            LibraryFileObject o = (LibraryFileObject) other;
+            return (library == o.library)
+                    && mid.equals(o.mid)
+                    && className.equals(o.className);
+
+        }
+
+        @Override
+        public int hashCode() {
+            return library.hashCode() + mid.hashCode() + className.hashCode();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/javac/jigsaw/JigsawModuleResolver.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,458 @@
+/*
+ * Copyright (c) 2009, 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.javac.jigsaw;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.module.ModuleIdQuery;
+import java.lang.module.ModuleInfo;
+import java.lang.module.ModuleView;
+import java.lang.module.ServiceDependence;
+import java.lang.module.Version;
+import java.lang.module.VersionQuery;
+import java.lang.module.ViewDependence;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.openjdk.jigsaw.Configuration;
+import org.openjdk.jigsaw.ConfigurationException;
+import org.openjdk.jigsaw.Configurator;
+import org.openjdk.jigsaw.JigsawModuleSystem;
+import org.openjdk.jigsaw.PathContext;
+
+import com.sun.tools.javac.code.Directive;
+import com.sun.tools.javac.code.ModuleId;
+import com.sun.tools.javac.code.ModuleQuery;
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.code.Symbol.ModuleSymbol;
+import com.sun.tools.javac.code.Symbol.PackageSymbol;
+import com.sun.tools.javac.code.Symtab;
+import com.sun.tools.javac.comp.Modules.ModuleResolver;
+import com.sun.tools.javac.jvm.ClassReader;
+import com.sun.tools.javac.main.Option;
+import com.sun.tools.javac.util.Assert;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Debug;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Name;
+import com.sun.tools.javac.util.Names;
+import com.sun.tools.javac.util.Options;
+
+/**
+ * Jigsaw implementation of javac's simple abstraction of a module resolver.
+ */
+public class JigsawModuleResolver implements ModuleResolver {
+    JigsawModuleSystem jigsaw;
+    JavacCatalog catalog;
+    Configuration<PathContext> config;
+    ClassReader reader;
+    Names names;
+    Symtab syms;
+    Debug debug;
+    Log log;
+
+    Map<String, ModuleView> views;
+
+    public JigsawModuleResolver(Context context) throws IOException/*FIXME*/ {
+        jigsaw = JigsawModuleSystem.instance();
+
+        names = Names.instance(context);
+        syms = Symtab.instance(context);
+        reader = ClassReader.instance(context);
+
+        Options options = Options.instance(context);
+        String l = options.get(Option.L);
+        File library = (l == null ? null : new File(l));
+
+        catalog = new JavacCatalog(library);
+
+        log = Log.instance(context);
+        debug = new Debug("jigsaw", options, log);
+    }
+
+    public Iterable<? extends ModuleSymbol> resolve(
+            Iterable<? extends ModuleSymbol> roots,
+            Iterable<? extends ModuleSymbol> modules) {
+        if (debug.isEnabled())
+            debug.println("JigsawModuleResolver starting");
+
+        catalog.init(modules);
+        Collection<ModuleIdQuery> jigsawRootQueries = new LinkedHashSet<ModuleIdQuery>();
+        for (ModuleSymbol r: roots) {
+            // should use catalog here
+            CharSequence rn = r.getModuleId().getName();
+            if (rn.length() == 0) {
+                // unnamed module
+////////////                // assert r.getRequires() == default platform module
+////////////                q = getDefaultPlatformModule();
+                for (Directive.RequiresModuleDirective d: r.getRequiredModules()) {
+                    // assert mr.getFlags().isEmpty()
+                    jigsawRootQueries.add(getModuleIdQuery(d.moduleQuery)); // FIXME: handle IllegalArgumentException
+                }
+            } else {
+                jigsawRootQueries.add(getModuleIdQuery(r.getModuleId())); // FIXME: handle IllegalArgumentException
+            }
+        }
+
+        try {
+            config = Configurator.configurePaths(catalog, jigsawRootQueries);
+        } catch (IOException e) {
+            log.error("jigsaw.resolver.ioerror", e);
+            return null;
+        } catch (ConfigurationException e) {
+            log.error("jigsaw.resolver.error", e.getLocalizedMessage());
+            return null;
+        }
+
+        // have config.roots: set of root module ids
+        // have config.contexts: set of preconfigured PathContexts
+        // need to flatten the contexts graphs, using tarjan
+        // then build List<ModuleSymbol> for return.
+        // some ModuleSymbol will come from the input list
+        // other ModuleSymbol will have to come from library: create these
+        // symbols as uncompleted ModuleSymbols, with completer set to ClassReader
+        // Will need new LibraryLocation interface in ModuleFileManager
+        // for use by modules in library.    Means that FileManager.join
+        // has to be able to cope.
+        ListBuffer<PathContext> rootContexts = new ListBuffer<PathContext>();
+        for (java.lang.module.ModuleId mid: config.roots()) {
+            PathContext pcx = config.getContextForModuleName(mid.name());
+            rootContexts.add(pcx);
+        }
+
+        Tarjan<PathContext> t = new Tarjan<PathContext>(rootContexts) {
+            @Override
+            protected Iterable<? extends PathContext> getDependencies(PathContext pcx) {
+                return pcx.remoteContexts();
+            }
+        };
+
+        ListBuffer<ModuleSymbol> results = new ListBuffer<ModuleSymbol>();
+        views = new HashMap<String, ModuleView>();
+        // add the unnamed module back into the results because it was skipped as
+        // an input for the jigsaw module resolver -- yet its location field
+        // is important -- it contains sourcepath, classpath, etc
+        for (ModuleSymbol r: roots) {
+            if (r.getModuleId().getName().length() == 0) // unnamed module
+                results.add(r);
+        }
+        for (PathContext pcx: t.list()) {
+            for (ModuleInfo minfo: pcx.moduleInfos()) {
+                java.lang.module.ModuleId mid = minfo.id();
+                ModuleSymbol sym = catalog.getModuleSymbol(mid);
+                if (sym == null) {
+                    Name name = names.fromString(mid.name());
+                    sym = new ModuleSymbol(name, syms.rootModule);
+                    sym.version = names.fromString(mid.version().toString());
+                    sym.location = new JigsawLibraryLocation(catalog.library, mid);
+                    sym.directives = getDirectives(minfo); // synthesize java.base?
+                }
+                results.add(sym);
+                for (ModuleView v: minfo.views())
+                    views.put(v.id().name(), v);
+            }
+        }
+
+        if (debug.isEnabled())
+            debug.println("JigsawModuleResolver finished; results: (" + results.size() + ")");
+
+        return results;
+    }
+
+    private List<Directive> getDirectives(ModuleInfo minfo) {
+        ListBuffer<Directive> lb = new ListBuffer<Directive>();
+        for (ViewDependence vd: minfo.requiresModules()) {
+            Set<Directive.RequiresFlag> flags = Collections.emptySet(); // FIXME
+            lb.add(new Directive.RequiresModuleDirective(getModuleQuery(vd.query()), flags));
+        }
+        for (ServiceDependence sd: minfo.requiresServices()) {
+            ClassSymbol sym = reader.enterClass(names.fromString(sd.service()));
+            Set<Directive.RequiresFlag> flags = Collections.emptySet(); // FIXME
+            lb.add(new Directive.RequiresServiceDirective(sym, flags));
+        }
+        addViewDirectives(lb, minfo.defaultView());
+        for (ModuleView mview: minfo.views()) {
+            if (mview == minfo.defaultView())
+                continue;
+            ListBuffer<Directive> vl = new ListBuffer<Directive>();
+            addViewDirectives(vl, mview);
+            Name vn = names.fromString(mview.id().name());
+            lb.add(new Directive.ViewDeclaration(vn, vl.toList()));
+        }
+        return lb.toList();
+    }
+
+    private ModuleQuery getModuleQuery(ModuleIdQuery mq) {
+        String n = mq.name();
+        VersionQuery vq = mq.versionQuery();
+        return new ModuleQuery(names.fromString(n),
+                (vq == null) ? null : names.fromString(vq.toString()));
+    }
+
+    private ModuleId getModuleId(java.lang.module.ModuleId mid) {
+        String n = mid.name();
+        Version v = mid.version();
+        return new ModuleId(names.fromString(n),
+                (v == null) ? null : names.fromString(v.toString()));
+
+    }
+
+    private void addViewDirectives(ListBuffer<Directive> list, ModuleView mview) {
+        // In ModuleProvides attribute order, for benefit of javax.lang.model
+        // entry
+        String main = mview.mainClass();
+        if (main != null) {
+            ClassSymbol sym = reader.enterClass(names.fromString(main));
+            list.add(new Directive.EntrypointDirective(sym));
+        }
+        // aliases
+        for (java.lang.module.ModuleId a: mview.aliases()) {
+            list.add(new Directive.ProvidesModuleDirective(getModuleId(a)));
+        }
+        // services
+        for (Map.Entry<String,Set<String>> e: mview.services().entrySet()) {
+            ClassSymbol srvc = reader.enterClass(names.fromString(e.getKey()));
+            for (String i: e.getValue()) {
+                ClassSymbol impl = reader.enterClass(names.fromString(i));
+                list.add(new Directive.ProvidesServiceDirective(srvc, impl));
+            }
+        }
+        // exports
+        for (String e: mview.exports()) {
+            PackageSymbol pkg = reader.enterPackage(names.fromString(e));
+            list.add(new Directive.ExportsDirective(pkg));
+        }
+        // permits
+        for (String p: mview.permits()) {
+            list.add(new Directive.PermitsDirective(names.fromString(p)));
+        }
+    }
+    
+    @Override
+    public boolean isPackageVisible(ModuleSymbol msym, PackageSymbol psym) {
+        Set<PackageSymbol> set = visiblePackages.get(msym);
+        if (set == null) {
+            set = new HashSet<PackageSymbol>();
+            for (Directive.RequiresModuleDirective d: msym.getRequiredModules()) {
+                addExportsForView(set, d.moduleQuery.name.toString());
+            }
+            visiblePackages.put(msym, set);
+        }
+        return set.contains(psym);
+    }
+    
+    private void addExportsForView(Set<PackageSymbol> exports, String name) {
+        ModuleView v = views.get(name);
+        Assert.checkNonNull(v);
+        for (String e: v.exports())
+            exports.add(reader.enterPackage(names.fromString(e)));
+        for (ViewDependence vd: v.moduleInfo().requiresModules()) {
+            if (vd.modifiers().contains(ViewDependence.Modifier.PUBLIC)) {
+                addExportsForView(exports, vd.query().name());
+            }
+        }
+    }
+    
+    Map<ModuleSymbol, Set<PackageSymbol>> visiblePackages = 
+            new HashMap<ModuleSymbol, Set<PackageSymbol>>();
+
+    private ModuleIdQuery getModuleIdQuery(ModuleId mid) {
+        return getModuleIdQuery(mid.getName(), mid.getVersion());
+    }
+
+    private ModuleIdQuery getModuleIdQuery(ModuleQuery midq) {
+        return getModuleIdQuery(midq.getName(), midq.getVersionQuery());
+    }
+
+    private ModuleIdQuery getModuleIdQuery(CharSequence n, CharSequence vq) {
+        String q = (vq == null || vq.length() == 0) ? String.valueOf(n) : (n + "@" + vq);
+        return jigsaw.parseModuleIdQuery(q);
+    }
+
+
+    static abstract class Tarjan<T> {
+        protected Tarjan(Iterable<T> roots) {
+            this.roots = roots;
+        }
+
+        /**
+         * Given a set of roots defining a directed graph, return an ordered
+         * list of all the nodes in the graph, such that if node A depends on
+         * node B, and there is no cycle between A and B, then A appears before
+         * B in the list.
+         * @return
+         */
+        public Iterable<? extends T> list() {
+            List<Node> rootNodes = getNodes(roots);
+            for (Node node: rootNodes) {
+                if (node.index == -1)
+                    tarjan(node);
+            }
+            LinkedHashSet<T> results = new LinkedHashSet<T>();
+            for (Node node: rootNodes) {
+                if (!results.contains(node.t))
+                    list(node.scc, results);
+            }
+            return Collections.unmodifiableSet(results);
+        }
+
+        /**
+         * Get the set of graph nodes on which this node depends.
+         * @param t
+         * @return
+         */
+        protected abstract Iterable<? extends T> getDependencies(T t);
+
+        protected String toString(T t) {
+            return t.toString();
+        }
+
+        private void list(SCC scc, LinkedHashSet<T> results) {
+            for (Node n: scc.nodes)
+                results.add(n.t);
+            for (SCC child: scc.getChildren())
+                list(child, results);
+        }
+
+        private List<Node> getNodes(Iterable<? extends T> elems) {
+            ListBuffer<Node> lb = new ListBuffer<Node>();
+            for (T elem: elems) {
+                lb.add(getNode(elem));
+            }
+            return lb.toList();
+        }
+
+        private Node getNode(T sym) {
+            Node node = nodeMap.get(sym);
+            if (node == null)
+                nodeMap.put(sym, (node = new Node(sym)));
+            return node;
+        }
+        // where
+        private Map<T, Node> nodeMap= new HashMap<T, Node>();
+
+
+        // Tarjan's algorithm to determine strongly connected components of a
+        // directed graph in linear time.
+
+        void tarjan(Node v) {
+            v.index = index;
+            v.lowlink = index;
+            index++;
+            stack.add(0, v);
+            v.active = true;
+            for (Node n: v.getDependencies()) {
+                if (n.index == -1) {
+                    tarjan(n);
+                    v.lowlink = Math.min(v.lowlink, n.lowlink);
+                } else if (stack.contains(n)) {
+                    v.lowlink = Math.min(v.lowlink, n.index);
+                }
+            }
+            if (v.lowlink == v.index) {
+                Node n;
+                SCC scc = new SCC();
+                do {
+                    n = stack.remove(0);
+                    n.active = false;
+                    scc.add(n);
+                } while (n != v);
+            }
+        }
+
+        private final Iterable<T> roots;
+        private int index = 0;
+        private ArrayList<Node> stack = new ArrayList<Node>();
+
+        private class Node implements Comparable<Node> {
+            final T t;
+            SCC scc;
+            int index = -1;
+            int lowlink;
+            boolean active;
+
+            Node(T t) {
+                this.t = t;
+            }
+
+            Iterable<Node> getDependencies() {
+                ListBuffer<Node> nodes = new ListBuffer<Node>();
+                for (T dep: Tarjan.this.getDependencies(this.t))
+                    nodes.add(getNode(dep));
+                return nodes.toList();
+            }
+
+            @Override
+            public String toString() {
+                return Tarjan.this.toString(t) + "(index:" + index +",low:" + lowlink + ",active:" + active + ")" ;
+            }
+
+            public int compareTo(Node o) {
+                return (index < o.index) ? -1 : (index == o.index) ? 0 : 1;
+            }
+        }
+
+        private class SCC {
+            void add(Node node) {
+                nodes.add(node);
+                node.scc = this;
+            }
+
+            Set<SCC> getChildren() {
+                if (children == null) {
+                    children = new LinkedHashSet<SCC>();
+                    for (Node node: nodes) {
+                        for (Node n: node.getDependencies()) {
+                            n.scc.getClass(); // nullcheck
+                            if (n.scc != this)
+                                children.add(n.scc);
+                        }
+                    }
+                }
+                return children;
+            }
+
+            @Override
+            public String toString() {
+                return nodes.toString();
+            }
+
+            private SortedSet<Node> nodes = new TreeSet<Node>();
+            private Set<SCC> children;
+        }
+    }
+
+}
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassFile.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassFile.java	Tue May 07 17:14:17 2013 -0700
@@ -85,6 +85,8 @@
     public final static int CONSTANT_MethodHandle = 15;
     public final static int CONSTANT_MethodType = 16;
     public final static int CONSTANT_InvokeDynamic = 18;
+    public final static int CONSTANT_ModuleId = 19;
+    public final static int CONSTANT_ModuleQuery = 20;
 
     public final static int REF_getField = 1;
     public final static int REF_getStatic = 2;
@@ -106,8 +108,9 @@
         V45_3(45, 3), // base level for all attributes
         V49(49, 0),   // JDK 1.5: enum, generics, annotations
         V50(50, 0),   // JDK 1.6: stackmaps
-        V51(51, 0),   // JDK 1.7
-        V52(52, 0);   // JDK 1.8: lambda, type annos, param names
+        V51(51, 0),   // JDK 1.7: invokedynamic
+        V52(52, 0),   // JDK 1.8: lambda, type annos, param names
+        V53(52, 0);   // JDK 1.9: Jigsaw !!! FIXME -- the 52 is deliberate but temporary and should be corrected eventually
         Version(int major, int minor) {
             this.major = major;
             this.minor = minor;
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Tue May 07 17:14:17 2013 -0700
@@ -29,37 +29,53 @@
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.nio.CharBuffer;
-import java.util.Arrays;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
+
 import javax.lang.model.SourceVersion;
-import javax.tools.JavaFileObject;
 import javax.tools.JavaFileManager;
 import javax.tools.JavaFileManager.Location;
+import javax.tools.JavaFileObject;
 import javax.tools.StandardJavaFileManager;
 
 import static javax.tools.StandardLocation.*;
 
-import com.sun.tools.javac.comp.Annotate;
 import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Directive.EntrypointDirective;
+import com.sun.tools.javac.code.Directive.ExportsDirective;
+import com.sun.tools.javac.code.Directive.PermitsDirective;
+import com.sun.tools.javac.code.Directive.ProvidesModuleDirective;
+import com.sun.tools.javac.code.Directive.ProvidesServiceDirective;
+import com.sun.tools.javac.code.Directive.RequiresFlag;
+import com.sun.tools.javac.code.Directive.RequiresModuleDirective;
+import com.sun.tools.javac.code.Directive.RequiresServiceDirective;
+import com.sun.tools.javac.code.Directive.ViewDeclaration;
 import com.sun.tools.javac.code.Lint.LintCategory;
-import com.sun.tools.javac.code.Type.*;
-import com.sun.tools.javac.code.Symbol.*;
-import com.sun.tools.javac.code.Symtab;
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.code.Symbol.Completer;
+import com.sun.tools.javac.code.Symbol.CompletionFailure;
+import com.sun.tools.javac.code.Symbol.MethodSymbol;
+import com.sun.tools.javac.code.Symbol.ModuleSymbol;
+import com.sun.tools.javac.code.Symbol.PackageSymbol;
+import com.sun.tools.javac.code.Symbol.TypeSymbol;
+import com.sun.tools.javac.code.Symbol.VarSymbol;
+import com.sun.tools.javac.code.Type.ArrayType;
+import com.sun.tools.javac.code.Type.ClassType;
+import com.sun.tools.javac.code.Type.ForAll;
+import com.sun.tools.javac.code.Type.MethodType;
+import com.sun.tools.javac.code.Type.TypeVar;
+import com.sun.tools.javac.code.Type.WildcardType;
+import com.sun.tools.javac.comp.Annotate;
 import com.sun.tools.javac.file.BaseFileObject;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
+import com.sun.tools.javac.util.List;
 
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Kinds.*;
 import static com.sun.tools.javac.code.TypeTag.CLASS;
 import static com.sun.tools.javac.jvm.ClassFile.*;
 import static com.sun.tools.javac.jvm.ClassFile.Version.*;
-
-import static com.sun.tools.javac.main.Option.*;
+import static com.sun.tools.javac.main.Option.VERBOSE;
 
 /** This class provides operations to read a classfile into an internal
  *  representation. The internal representation is anchored in a
@@ -119,6 +135,10 @@
      */
     boolean allowDefaultMethods;
 
+    /** Switch: allow modules
+     */
+    boolean allowModules;
+
     /** Switch: preserve parameter names from the variable table.
      */
     public boolean saveParameterNames;
@@ -178,6 +198,11 @@
      */
     private Map<Name, PackageSymbol> packages;
 
+    /** A hashtable giving the module for each module location.
+     *
+     */
+    private Map<Location, ModuleSymbol> allModules;
+
     /** The current scope where type variables are entered.
      */
     protected Scope typevars;
@@ -258,9 +283,11 @@
             packages = syms.packages;
             Assert.check(classes == null || classes == syms.classes);
             classes = syms.classes;
+            allModules = syms.allModules;
         } else {
             packages = new HashMap<Name, PackageSymbol>();
             classes = new HashMap<Name, ClassSymbol>();
+            allModules = new HashMap<Location, ModuleSymbol>();
         }
 
         packages.put(names.empty, syms.rootPackage);
@@ -295,6 +322,7 @@
         allowVarargs     = source.allowVarargs();
         allowAnnotations = source.allowAnnotations();
         allowSimplifiedVarargs = source.allowSimplifiedVarargs();
+        allowModules     = source.allowModules();
         allowDefaultMethods = source.allowDefaultMethods();
 
         saveParameterNames = options.isSet("save-parameter-names");
@@ -324,6 +352,7 @@
             c.members_field.enter(sym);
     }
 
+    // <editor-fold defaultstate="collapsed" desc="Error diagnoses">
 /************************************************************************
  * Error Diagnoses
  ***********************************************************************/
@@ -349,7 +378,9 @@
             currentClassFile,
             diagFactory.fragment(key, args));
     }
-
+    // </editor-fold>
+
+    // <editor-fold defaultstate="collapsed" desc="Buffer access">
 /************************************************************************
  * Buffer Access
  ***********************************************************************/
@@ -429,6 +460,9 @@
             throw new AssertionError(e);
         }
     }
+    // </editor-fold>
+
+    // <editor-fold defaultstate="collapsed" desc="Constant Pool Access">
 
 /************************************************************************
  * Constant Pool Access
@@ -465,6 +499,8 @@
             case CONSTANT_Integer:
             case CONSTANT_Float:
             case CONSTANT_InvokeDynamic:
+            case CONSTANT_ModuleId:
+            case CONSTANT_ModuleQuery:
                 bp = bp + 4;
                 break;
             case CONSTANT_Long:
@@ -542,6 +578,16 @@
         case CONSTANT_InvokeDynamic:
             skipBytes(5);
             break;
+        case CONSTANT_ModuleId:
+            poolObj[i] = new ModuleId(
+                readInternalName(getChar(index + 1)),
+                readName(getChar(index + 3)));
+            break;
+        case CONSTANT_ModuleQuery:
+            poolObj[i] = new ModuleQuery(
+                readInternalName(getChar(index + 1)),
+                readName(getChar(index + 3)));
+            break;
         default:
             throw badClassFile("bad.const.pool.tag", Byte.toString(tag));
         }
@@ -590,6 +636,49 @@
         return (Name) (readPool(i));
     }
 
+    /** Read module id.
+     */
+    ModuleId readModuleId(int i) {
+        return (ModuleId) (readPool(i));
+    }
+
+    /** Read module id query.
+     */
+    ModuleQuery readModuleQuery(int i) {
+        return (ModuleQuery) (readPool(i));
+    }
+
+    /** Read requires_flags.
+     */
+    Set<RequiresFlag> readRequiresFlags(int flags) {
+        Set<RequiresFlag> set = EnumSet.noneOf(RequiresFlag.class);
+        for (RequiresFlag f: RequiresFlag.values()) {
+            if ((flags & f.value) != 0)
+                set.add(f);
+        }
+        return set;
+    }
+
+    Name readInternalName(int i) {
+        int index = poolIdx[i];
+        return names.fromUtf(internalize(buf, index + 3, getChar(index + 1)));
+    }
+
+    /** Read module name.
+     * The module name is in a CONSTANT_Class_info, but we don't want to
+     * enter a class for it, so can't use readClassSymbol.
+     */
+    Name readModuleInfoName(int i) {
+        int index = poolIdx[i];
+        assert index != 0;
+        byte tag = buf[index];
+        assert tag == CONSTANT_Class;
+        return readInternalName(getChar(index+1));
+    }
+    // </editor-fold>
+
+    // <editor-fold defaultstate="collapsed" desc="Reading Types">
+
 /************************************************************************
  * Reading Types
  ***********************************************************************/
@@ -905,6 +994,9 @@
             throw badClassFile("undecl.type.var", name);
         }
     }
+    // </editor-fold>
+
+    // <editor-fold defaultstate="collapsed" desc="Reading Attributes">
 
 /************************************************************************
  * Reading Attributes
@@ -1183,6 +1275,8 @@
                 }
             },
 
+            //  v52 module attributes
+
             new AttributeReader(names.RuntimeVisibleTypeAnnotations, V52, CLASS_OR_MEMBER_ATTRIBUTE) {
                 protected void read(Symbol sym, int attrLen) {
                     attachTypeAnnotations(sym);
@@ -1195,6 +1289,105 @@
                 }
             },
 
+            new AttributeReader(names.Module, V52, CLASS_ATTRIBUTE) {
+                @Override
+                protected boolean accepts(AttributeKind kind) {
+                    return super.accepts(kind) && allowModules;
+                }
+                protected void read(Symbol sym, int attrLen) {
+                    if (sym.kind == TYP && sym.owner.kind == MDL) {
+                        ModuleSymbol msym = (ModuleSymbol) sym.owner;
+                        ModuleId mid = readModuleId(nextChar());
+                        msym.name = msym.fullname = mid.name;
+                        msym.version = mid.version;
+                    }
+                }
+            },
+
+            new AttributeReader(names.ModuleProvides, V52, CLASS_ATTRIBUTE) {
+                @Override
+                protected boolean accepts(AttributeKind kind) {
+                    return super.accepts(kind) && allowModules;
+                }
+                protected void read(Symbol sym, int attrLen) {
+                    if (sym.kind == TYP && sym.owner.kind == MDL) {
+                        ModuleSymbol msym = (ModuleSymbol) sym.owner;
+                        int numViews = nextChar();
+                        for (int v = 0; v < numViews; v++) {
+                            Name viewName = readName(nextChar());
+                            List<Directive> directives =
+                                (viewName == null) ? msym.directives : List.<Directive>nil();
+
+                            ClassSymbol entrypoint = readClassSymbol(nextChar());
+                            if (entrypoint != null) {
+                                EntrypointDirective d = new EntrypointDirective(entrypoint);
+                                directives = directives.prepend(d);
+                            }
+
+                            int numAliases = nextChar();
+                            for (int i = 0; i < numAliases; i++) {
+                                ModuleId id = readModuleId(nextChar());
+                                ProvidesModuleDirective d = new ProvidesModuleDirective(id);
+                                directives = directives.prepend(d);
+                            }
+
+                            int numServices = nextChar();
+                            for (int i = 0; i < numServices; i++) {
+                                ClassSymbol svcSym = readClassSymbol(nextChar());
+                                ClassSymbol implSym = readClassSymbol(nextChar());
+                                ProvidesServiceDirective d = new ProvidesServiceDirective(svcSym, implSym);
+                                directives = directives.prepend(d);
+                            }
+
+                            int numExports = nextChar();
+                            for (int i = 0; i < numExports; i++) {
+                                Name export = readName(nextChar());
+                                PackageSymbol psym = enterPackage(export);
+                                ExportsDirective d = new ExportsDirective(psym);
+                                directives = directives.prepend(d);
+                            }
+
+                            int numPermits = nextChar();
+                            for (int i = 0; i < numPermits; i++) {
+                                ModuleId id = readModuleId(nextChar());
+                                PermitsDirective d = new PermitsDirective(id);
+                                directives = directives.prepend(d);
+                            }
+
+                            if (viewName != null) {
+                                ViewDeclaration d = new ViewDeclaration(viewName, directives.reverse());
+                                msym.directives = msym.directives.prepend(d);
+                            }
+                        }
+                    }
+                }
+            },
+
+            new AttributeReader(names.ModuleRequires, V52, CLASS_ATTRIBUTE) {
+                @Override
+                protected boolean accepts(AttributeKind kind) {
+                    return super.accepts(kind) && allowModules;
+                }
+                protected void read(Symbol sym, int attrLen) {
+                    if (sym.kind == TYP && sym.owner.kind == MDL) {
+                        ModuleSymbol msym = (ModuleSymbol) sym.owner;
+                        int numModules = nextChar();
+                        for (int r = 0; r < numModules; r++) {
+                            ModuleQuery q = readModuleQuery(nextChar());
+                            Set<RequiresFlag> flags = readRequiresFlags(nextInt());
+                            RequiresModuleDirective d = new RequiresModuleDirective(q, flags);
+                            msym.directives = msym.directives.prepend(d);
+                        }
+                        int numServices = nextChar();
+                        for (int r = 0; r < numServices; r++) {
+                            ClassSymbol csym = readClassSymbol(nextChar());
+                            Set<RequiresFlag> flags = readRequiresFlags(nextInt());
+                            RequiresServiceDirective d = new RequiresServiceDirective(csym, flags);
+                            msym.directives = msym.directives.prepend(d);
+                        }
+                    }
+                }
+            },
 
             // The following attributes for a Code attribute are not currently handled
             // StackMapTable
@@ -1214,8 +1407,6 @@
             printCCF("ccf.unrecognized.attribute", attrName);
     }
 
-
-
     protected void readEnclosingMethodAttr(Symbol sym) {
         // sym is a nested class with an "Enclosing Method" attribute
         // remove sym from it's current owners scope and place it in
@@ -1365,6 +1556,9 @@
         readMemberAttrs(owner);
         return null;
     }
+    // </editor-fold>
+
+    // <editor-fold defaultstate="collapsed" desc="Reading Java-language annotations">
 
 /************************************************************************
  * Reading Java-language annotations
@@ -1908,6 +2102,7 @@
             }
         }
     }
+    // </editor-fold>
 
     class TypeAnnotationCompleter extends AnnotationCompleter {
 
@@ -1942,6 +2137,7 @@
         }
     }
 
+    // <editor-fold defaultstate="collapsed" desc="Reading Symbols">
 
 /************************************************************************
  * Reading Symbols
@@ -2157,11 +2353,20 @@
         long flags = adjustClassFlags(nextChar());
         if (c.owner.kind == PCK) c.flags_field = flags;
 
-        // read own class name and check that it matches
-        ClassSymbol self = readClassSymbol(nextChar());
-        if (c != self)
-            throw badClassFile("class.file.wrong.class",
-                               self.flatname);
+        if (c.owner.kind == MDL) {
+            //System.err.println("ClassReader.readClass getModuleInfoName");
+            c.fullname = c.flatname = readModuleInfoName(nextChar());
+            c.name = Convert.shortName(c.fullname);
+            assert c.name == names.module_info;
+        } else {
+            // read own class name and check that it matches
+            ClassSymbol self = readClassSymbol(nextChar());
+            if (c != self) {
+                //System.err.println("ClassReader.readClass c=" + c + " self=" + self);
+                throw badClassFile("class.file.wrong.class",
+                                   self.flatname);
+            }
+        }
 
         // class attributes must be read before class
         // skip ahead to read class attributes
@@ -2273,6 +2478,9 @@
         }
         readClass(c);
     }
+    // </editor-fold>
+
+    // <editor-fold defaultstate="collapsed" desc="Adjusting flags">
 
 /************************************************************************
  * Adjusting flags
@@ -2297,6 +2505,9 @@
     long adjustClassFlags(long flags) {
         return flags & ~ACC_SUPER; // SUPER and SYNCHRONIZED bits overloaded
     }
+    // </editor-fold>
+
+    // <editor-fold defaultstate="collapsed" desc="Loading Classes">
 
 /************************************************************************
  * Loading Classes
@@ -2398,6 +2609,15 @@
             } catch (IOException ex) {
                 throw new CompletionFailure(sym, ex.getLocalizedMessage()).initCause(ex);
             }
+        } else if (sym.kind == MDL) {
+            //System.err.println("ClassReader.complete module " + sym + " " + sym.name);
+            ModuleSymbol msym = (ModuleSymbol) sym;
+            msym.module_info.members_field = new Scope(sym); // or Scope.empty?
+            msym.directives = List.nil();
+            fillIn(msym.module_info);
+            msym.directives = msym.directives.reverse();
+            assert msym.name != null;
+            //System.err.println("ClassReader.completed module " + sym + " " + sym.name);
         }
         if (!filling && !suppressFlush)
             annotate.flush(); // finish attaching annotations
@@ -2481,6 +2701,15 @@
                         foundTypeVariables = List.nil();
                         filling = false;
                     }
+
+                    if (allowModules) {
+                        if (!(classfile instanceof JavaFileObject.Locatable))
+                            throw new CompletionFailure(c, "cannot determine module");
+                        Location l = ((JavaFileObject.Locatable) classfile).getLocation();
+                        c.modle = enterModule(l);
+                    } else {
+                        c.modle = syms.noModule;
+                    }
                 } else {
                     if (sourceCompleter != null) {
                         sourceCompleter.complete(c);
@@ -2489,6 +2718,7 @@
                                                         + classfile.toUri());
                     }
                 }
+                Assert.checkNonNull(c.modle);
                 return;
             } catch (IOException ex) {
                 throw badClassFile("unable.to.access.file", ex.getMessage());
@@ -2579,6 +2809,9 @@
         }
         return c;
     }
+    // </editor-fold>
+
+    // <editor-fold defaultstate="collapsed" desc="Loading Packages">
 
 /************************************************************************
  * Loading Packages
@@ -2616,7 +2849,9 @@
      *         (2) we have one of the other kind, and the given class file
      *             is older.
      */
-    protected void includeClassFile(PackageSymbol p, JavaFileObject file) {
+    protected void includeClassFile(PackageSymbol p, JavaFileObject file, Name simpleName) {
+        boolean isPackageInfo = simpleName == names.package_info;
+
         if ((p.flags_field & EXISTS) == 0)
             for (Symbol q = p; q != null && q.kind == PCK; q = q.owner)
                 q.flags_field |= EXISTS;
@@ -2626,18 +2861,14 @@
             seen = CLASS_SEEN;
         else
             seen = SOURCE_SEEN;
-        String binaryName = fileManager.inferBinaryName(currentLoc, file);
-        int lastDot = binaryName.lastIndexOf(".");
-        Name classname = names.fromString(binaryName.substring(lastDot + 1));
-        boolean isPkgInfo = classname == names.package_info;
-        ClassSymbol c = isPkgInfo
-            ? p.package_info
-            : (ClassSymbol) p.members_field.lookup(classname).sym;
+        ClassSymbol c =
+            isPackageInfo ? p.package_info
+            : (ClassSymbol) p.members_field.lookup(simpleName).sym;
         if (c == null) {
-            c = enterClass(classname, p);
+            c = enterClass(simpleName, p);
             if (c.classfile == null) // only update the file if's it's newly created
                 c.classfile = file;
-            if (isPkgInfo) {
+            if (isPackageInfo) {
                 p.package_info = c;
             } else {
                 if (c.owner == p)  // it might be an inner class
@@ -2658,7 +2889,7 @@
      *  file or a class file when both are present.  May be overridden
      *  by subclasses.
      */
-    protected JavaFileObject preferredFileObject(JavaFileObject a,
+    public JavaFileObject preferredFileObject(JavaFileObject a,
                                            JavaFileObject b) {
 
         if (preferSource)
@@ -2685,17 +2916,29 @@
     protected void extraFileActions(PackageSymbol pack, JavaFileObject fe) {
     }
 
-    protected Location currentLoc; // FIXME
-
+    public void setPathLocation(Location pathLocation) {
+        this.pathLocation = pathLocation;
+    }
+
+    private Location pathLocation;
     private boolean verbosePath = true;
 
+
     /** Load directory of package into members scope.
      */
     private void fillIn(PackageSymbol p) throws IOException {
         if (p.members_field == null) p.members_field = new Scope(p);
         String packageName = p.fullname.toString();
 
-        Set<JavaFileObject.Kind> kinds = getPackageFileKinds();
+        //System.err.println("ClassReader.fillIn using pathLocation " + (pathLocation != null));
+        if (pathLocation != null) {
+            fillIn(p, pathLocation,
+                    fileManager.list(pathLocation,
+                                    packageName,
+                                    EnumSet.allOf(JavaFileObject.Kind.class),
+                                    false));
+            return;
+        }
 
         fillIn(p, PLATFORM_CLASS_PATH,
                fileManager.list(PLATFORM_CLASS_PATH,
@@ -2703,6 +2946,8 @@
                                 EnumSet.of(JavaFileObject.Kind.CLASS),
                                 false));
 
+        Set<JavaFileObject.Kind> kinds = getPackageFileKinds();
+
         Set<JavaFileObject.Kind> classKinds = EnumSet.copyOf(kinds);
         classKinds.remove(JavaFileObject.Kind.SOURCE);
         boolean wantClassFiles = !classKinds.isEmpty();
@@ -2769,17 +3014,16 @@
                             Location location,
                             Iterable<JavaFileObject> files)
         {
-            currentLoc = location;
             for (JavaFileObject fo : files) {
                 switch (fo.getKind()) {
                 case CLASS:
                 case SOURCE: {
-                    // TODO pass binaryName to includeClassFile
-                    String binaryName = fileManager.inferBinaryName(currentLoc, fo);
+                    String binaryName = fileManager.inferBinaryName(location, fo);
                     String simpleName = binaryName.substring(binaryName.lastIndexOf(".") + 1);
                     if (SourceVersion.isIdentifier(simpleName) ||
-                        simpleName.equals("package-info"))
-                        includeClassFile(p, fo);
+                        simpleName.contentEquals(names.package_info)) {
+                        includeClassFile(p, fo, names.fromString(simpleName));
+                    }
                     break;
                 }
                 default:
@@ -2787,6 +3031,64 @@
                 }
             }
         }
+    // </editor-fold>
+
+    // <editor-fold defaultstate="collapsed" desc="Loading Modules">
+
+/************************************************************************
+ * Loading Modules
+ ***********************************************************************/
+
+    public ModuleSymbol enterModule(Location locn) {
+        ModuleSymbol sym = allModules.get(locn);
+        if (sym == null) {
+            sym = new ModuleSymbol(null, syms.rootModule);
+            sym.location = locn;
+            sym.module_info = new ClassSymbol(0, names.module_info, sym);
+            sym.module_info.modle = sym;
+            sym.completer = new Symbol.Completer() {
+                public void complete(Symbol sym) throws CompletionFailure {
+                    readModule((ModuleSymbol) sym);
+                }
+
+                void readModule(ModuleSymbol sym) {
+                    Location locn = sym.location;
+                    JavaFileObject srcFile = getModuleInfo(locn, JavaFileObject.Kind.SOURCE);
+                    JavaFileObject classFile = getModuleInfo(locn, JavaFileObject.Kind.CLASS);
+                    JavaFileObject file;
+                    if (srcFile == null) {
+                        if (classFile == null) {
+                            sym.name = sym.fullname = names.empty; // unnamed module
+                            RequiresModuleDirective d = new RequiresModuleDirective(syms.jdkLegacyQuery,
+                                    EnumSet.of(Directive.RequiresFlag.SYNTHESIZED));
+                            sym.directives = List.<Directive>of(d);
+                            return;
+                        }
+                        file = classFile;
+                    } else if (classFile == null)
+                        file = srcFile;
+                    else
+                        file = preferredFileObject(srcFile, classFile);
+
+                    sym.module_info.classfile = file;
+                    ClassReader.this.complete(sym);
+                    assert sym.name != null;
+                }
+
+                JavaFileObject getModuleInfo(Location locn, JavaFileObject.Kind kind) {
+                    try {
+                        return fileManager.getJavaFileForInput(locn, "module-info", kind);
+                    } catch (IOException e) {
+                        return null;
+                    }
+                }
+            };
+            allModules.put(locn, sym);
+        }
+        return sym;
+    }
+
+    // </editor-fold>
 
     /** Output for "-checkclassfile" option.
      *  @param key The key to look up the correct internationalized string.
@@ -2802,6 +3104,8 @@
             throws CompletionFailure;
     }
 
+    // <editor-fold defaultstate="collapsed" desc="SourceFileObject">
+
     /**
      * A subclass of JavaFileObject for the sourcefile attribute found in a classfile.
      * The attribute is only the last component of the original filename, so is unlikely
@@ -2816,7 +3120,7 @@
         private Name flatname;
 
         public SourceFileObject(Name name, Name flatname) {
-            super(null); // no file manager; never referenced for this file object
+            super(null, null); // no file manager or location; never referenced for this file object
             this.name = name;
             this.flatname = flatname;
         }
@@ -2886,6 +3190,11 @@
         }
 
         @Override
+        protected String inferModuleTag(String binaryName) {
+            return null;
+        }
+
+        @Override
         public boolean isNameCompatible(String simpleName, JavaFileObject.Kind kind) {
             return true; // fail-safe mode
         }
@@ -2913,4 +3222,5 @@
             return name.hashCode();
         }
     }
+    // </editor-fold>
 }
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Tue May 07 17:14:17 2013 -0700
@@ -31,14 +31,16 @@
 import java.util.Set;
 import java.util.HashSet;
 
-import javax.lang.model.type.TypeKind;
+import javax.tools.FileObject;
 import javax.tools.JavaFileManager;
-import javax.tools.FileObject;
+import javax.tools.JavaFileManager.Location;
 import javax.tools.JavaFileObject;
+import javax.tools.ModuleFileManager;
 
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Attribute.RetentionPolicy;
 import com.sun.tools.javac.code.Attribute.TypeCompound;
+import com.sun.tools.javac.code.Directive.*;
 import static com.sun.tools.javac.code.BoundKind.EXTENDS;
 import static com.sun.tools.javac.code.BoundKind.SUPER;
 import static com.sun.tools.javac.code.BoundKind.UNBOUND;
@@ -475,6 +477,21 @@
                     poolbuf.appendByte(CONSTANT_Class);
                     poolbuf.appendChar(pool.put(xClassName(type)));
                 }
+            } else if (value instanceof ModuleSymbol) {
+                ModuleSymbol sym = (ModuleSymbol) value;
+                poolbuf.appendByte(CONSTANT_ModuleId);
+                poolbuf.appendChar(pool.put(names.fromUtf(externalize(sym.flatName()))));
+                poolbuf.appendChar(sym.version == null ? 0 : pool.put(sym.version));
+            } else if (value instanceof ModuleId) {
+                ModuleId mid = (ModuleId)value;
+                poolbuf.appendByte(CONSTANT_ModuleId);
+                poolbuf.appendChar(pool.put(names.fromUtf(externalize(mid.name))));
+                poolbuf.appendChar(mid.version == null ? 0 : pool.put(mid.version));
+            } else if (value instanceof ModuleQuery) {
+                ModuleQuery mid = (ModuleQuery)value;
+                poolbuf.appendByte(CONSTANT_ModuleQuery);
+                poolbuf.appendChar(pool.put(names.fromUtf(externalize(mid.name))));
+                poolbuf.appendChar(mid.versionQuery == null ? 0 : pool.put(mid.versionQuery));
             } else if (value instanceof MethodHandle) {
                 MethodHandle ref = (MethodHandle)value;
                 poolbuf.appendByte(CONSTANT_MethodHandle);
@@ -994,6 +1011,95 @@
     }
 
 /**********************************************************************
+ * Writing module attributes
+ **********************************************************************/
+
+    /** Write the Module attribute if needed.
+     *  Returns the number of attributes written (0 or 1).
+     */
+    int writeModuleAttribute(ClassSymbol c) {
+        if (c.modle == null)
+            return 0;
+
+        int alenIdx = writeAttr(names.Module);
+        databuf.appendChar(pool.put(c.modle));
+        endAttr(alenIdx);
+        return 1;
+    }
+
+    int writeModuleMetadata(ModuleSymbol sym) {
+        int n = 0;
+
+        if (sym.hasRequires()) {
+            int alenIdx = writeAttr(names.ModuleRequires);
+                // modules
+                List<RequiresModuleDirective> modules = sym.getRequiredModules();
+                databuf.appendChar(modules.size());
+                for (RequiresModuleDirective m: modules) {
+                    databuf.appendChar(pool.put(m.moduleQuery));
+                    databuf.appendInt(RequiresFlag.value(m.flags));
+                }
+                // services
+                List<RequiresServiceDirective> services = sym.getRequiredServices();
+                databuf.appendChar(services.size());
+                for (RequiresServiceDirective s: services) {
+                    databuf.appendChar(pool.put(s.sym));
+                    databuf.appendInt(RequiresFlag.value(s.flags));
+                }
+            endAttr(alenIdx);
+            n++;
+        }
+
+        if (sym.hasViews()) {
+            int alenIdx = writeAttr(names.ModuleProvides);
+            List<ViewDeclaration> views = sym.getViews();
+            databuf.appendChar(views.size());
+            for (ViewDeclaration v: views) {
+                // name
+                databuf.appendChar(v.isDefault() ? 0 : pool.put(names.fromUtf(externalize(v.name))));
+                // entrypoint, if any
+                ClassSymbol esym = v.getEntrypoint();
+                databuf.appendChar(esym == null ? 0 : pool.put(esym));
+                // aliases
+                List<ProvidesModuleDirective> aliases = v.getAliases();
+                databuf.appendChar(aliases.size());
+                for (ProvidesModuleDirective a: aliases)
+                    databuf.appendChar(pool.put(a.moduleId));
+                // services
+                List<ProvidesServiceDirective> services = v.getServices();
+                databuf.appendChar(services.size());
+                for (ProvidesServiceDirective s: services) {
+                    databuf.appendChar(pool.put(s.service));
+                    databuf.appendChar(pool.put(s.impl));
+                }
+                // exports
+                Set<PackageSymbol> exports = sym.getExports(v);
+                databuf.appendChar(exports.size());
+                for (PackageSymbol e: exports) {
+                    databuf.appendChar(pool.put(names.fromUtf(externalize(e.flatName()))));
+                }
+                // permits
+                List<PermitsDirective> permits = v.getPermits();
+                databuf.appendChar(permits.size());
+                for (PermitsDirective p: permits) {
+                    databuf.appendChar(pool.put(p.moduleId));
+                }
+            }
+            endAttr(alenIdx);
+            n++;
+        }
+
+        if (sym.hasExtendedMetadata()) {
+            int alenIdx = writeAttr(names.ModuleData);
+            databuf.appendChar(pool.put(sym.extendedMetadata));
+            endAttr(alenIdx);
+            n++;
+        }
+
+        return n;
+    }
+
+/**********************************************************************
  * Writing Objects
  **********************************************************************/
 
@@ -1012,6 +1118,7 @@
         if (!c.type.hasTag(CLASS)) return; // arrays
         if (pool != null && // pool might be null if called from xClassName
             c.owner.enclClass() != null &&
+            c.owner.kind != MDL &&
             (innerClasses == null || !innerClasses.contains(c))) {
 //          log.errWriter.println("enter inner " + c);//DEBUG
             enterInner(c.owner.enclClass());
@@ -1613,9 +1720,25 @@
     public JavaFileObject writeClass(ClassSymbol c)
         throws IOException, PoolOverflow, StringOverflow
     {
+        String name = (c.owner.kind == MDL ? c.name : c.flatname).toString();
+
+        Location outLocn;
+        if (fileManager instanceof ModuleFileManager && fileManager.hasLocation(CLASS_OUTPUT)) {
+            ModuleFileManager mfm = (ModuleFileManager) fileManager;
+            String pkgName = c.owner.kind == MDL ? "" : c.packge().fullname.toString();
+            try {
+                outLocn = mfm.getModuleLocation(CLASS_OUTPUT, c.sourcefile, pkgName);
+            } catch (IllegalArgumentException e) {
+                throw new AssertionError();
+            }
+        } else
+            // Note: when CLASS_OUTPUT is not set, getJavaFileForOutput will
+            // default to writing the output in the same directory as the sourcefile
+            outLocn = CLASS_OUTPUT;
+
         JavaFileObject outFile
-            = fileManager.getJavaFileForOutput(CLASS_OUTPUT,
-                                               c.flatname.toString(),
+            = fileManager.getJavaFileForOutput(outLocn,
+                                               name,
                                                JavaFileObject.Kind.CLASS,
                                                c.sourcefile);
         OutputStream out = outFile.openOutputStream();
@@ -1743,6 +1866,10 @@
         acount += writeJavaAnnotations(c.getRawAttributes());
         acount += writeTypeAnnotations(c.getRawTypeAttributes());
         acount += writeEnclosingMethodAttribute(c);
+        if (c.owner.kind == MDL) {
+            acount += writeModuleAttribute(c);
+            acount += writeModuleMetadata(c.modle);
+        }
         acount += writeExtraClassAttributes(c);
 
         poolbuf.appendInt(JAVA_MAGIC);
--- a/src/share/classes/com/sun/tools/javac/jvm/Pool.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/Pool.java	Tue May 07 17:14:17 2013 -0700
@@ -39,6 +39,7 @@
 
 import java.util.*;
 
+import com.sun.tools.javac.util.Assert;
 /** An internal structure that corresponds to the constant pool of a classfile.
  *
  *  <p><b>This is NOT part of any supported API.
@@ -101,6 +102,7 @@
      *  package.  Return the object's index in the pool.
      */
     public int put(Object value) {
+        Assert.checkNonNull(value);
         value = makePoolValue(value);
 //      assert !(value instanceof Type.TypeVar);
         Integer index = indices.get(value);
--- a/src/share/classes/com/sun/tools/javac/jvm/Target.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/Target.java	Tue May 07 17:14:17 2013 -0700
@@ -295,4 +295,8 @@
     public boolean hasEnclosingMethodAttribute() {
         return compareTo(JDK1_5) >= 0;
     }
+
+    public boolean useModules() {
+        return compareTo(JDK1_7) >= 0;
+    }
 }
--- a/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Tue May 07 17:14:17 2013 -0700
@@ -44,9 +44,9 @@
 import javax.lang.model.SourceVersion;
 import javax.tools.DiagnosticListener;
 import javax.tools.JavaFileManager;
+import javax.tools.JavaFileManager.Location;
 import javax.tools.JavaFileObject;
 import javax.tools.StandardLocation;
-
 import static javax.tools.StandardLocation.CLASS_OUTPUT;
 
 import com.sun.source.util.TaskEvent;
@@ -64,7 +64,6 @@
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.comp.CompileStates.CompileState;
 import com.sun.tools.javac.util.Log.WriterKind;
-
 import static com.sun.tools.javac.code.TypeTag.CLASS;
 import static com.sun.tools.javac.main.Option.*;
 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
@@ -81,7 +80,7 @@
  *  This code and its internal interfaces are subject to change or
  *  deletion without notice.</b>
  */
-public class JavaCompiler implements ClassReader.SourceCompleter {
+public class JavaCompiler {
     /** The context key for the compiler. */
     protected static final Context.Key<JavaCompiler> compilerKey =
         new Context.Key<JavaCompiler>();
@@ -374,7 +373,7 @@
         types = Types.instance(context);
         taskListener = MultiTaskListener.instance(context);
 
-        reader.sourceCompleter = this;
+        reader.sourceCompleter = new Completer();
 
         options = Options.instance(context);
 
@@ -589,8 +588,7 @@
      */
     protected JCCompilationUnit parse(JavaFileObject filename, CharSequence content) {
         long msec = now();
-        JCCompilationUnit tree = make.TopLevel(List.<JCTree.JCAnnotation>nil(),
-                                      null, List.<JCTree>nil());
+        JCCompilationUnit tree = make.TopLevel(List.<JCTree>nil());
         if (content != null) {
             if (verbose) {
                 log.printVerbose("parsing.started", filename);
@@ -676,8 +674,7 @@
                 tree = (tree == null) ? make.Ident(names.fromString(s))
                                       : make.Select(tree, names.fromString(s));
             }
-            JCCompilationUnit toplevel =
-                make.TopLevel(List.<JCTree.JCAnnotation>nil(), null, List.<JCTree>nil());
+            JCCompilationUnit toplevel = make.TopLevel(List.<JCTree>nil());
             toplevel.packge = syms.unnamedPackage;
             return attr.attribIdent(tree, toplevel);
         } finally {
@@ -736,56 +733,83 @@
      *  by the class file reader.
      *  @param c          The class the source file of which needs to be compiled.
      */
-    public void complete(ClassSymbol c) throws CompletionFailure {
-//      System.err.println("completing " + c);//DEBUG
-        if (completionFailureName == c.fullname) {
-            throw new CompletionFailure(c, "user-selected completion failure by class name");
-        }
-        JCCompilationUnit tree;
-        JavaFileObject filename = c.classfile;
-        JavaFileObject prev = log.useSource(filename);
+    protected class Completer implements ClassReader.SourceCompleter {
+        final boolean allowModules;
 
-        try {
-            tree = parse(filename, filename.getCharContent(false));
-        } catch (IOException e) {
-            log.error("error.reading.file", filename, JavacFileManager.getMessage(e));
-            tree = make.TopLevel(List.<JCTree.JCAnnotation>nil(), null, List.<JCTree>nil());
-        } finally {
-            log.useSource(prev);
-        }
-
-        if (!taskListener.isEmpty()) {
-            TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, tree);
-            taskListener.started(e);
+        public Completer() {
+            allowModules = source.allowModules();
         }
 
-        enter.complete(List.of(tree), c);
+        public void complete(ClassSymbol c) throws CompletionFailure {
+            if (completionFailureName == c.fullname) {
+                throw new CompletionFailure(c, "user-selected completion failure by class name");
+            }
+            JCCompilationUnit tree;
+            JavaFileObject filename = c.classfile;
+            JavaFileObject prev = log.useSource(filename);
 
-        if (!taskListener.isEmpty()) {
-            TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, tree);
-            taskListener.finished(e);
-        }
+            try {
+                tree = parse(filename, filename.getCharContent(false));
+            } catch (IOException e) {
+                log.error("error.reading.file", filename, JavacFileManager.getMessage(e));
+                tree = make.TopLevel(List.<JCTree>nil());
+            } finally {
+                log.useSource(prev);
+            }
+
+            if (allowModules) {
+                if (!(filename instanceof JavaFileObject.Locatable))
+                    throw new CompletionFailure(c, "cannot determine module");
+                Location l = ((JavaFileObject.Locatable) filename).getLocation();
+                tree.modle = reader.enterModule(l);
+            } else {
+                tree.modle = syms.noModule;
+            }
+
+            if (!taskListener.isEmpty()) {
+                TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, tree);
+                taskListener.started(e);
+            }
 
-        if (enter.getEnv(c) == null) {
-            boolean isPkgInfo =
-                tree.sourcefile.isNameCompatible("package-info",
-                                                 JavaFileObject.Kind.SOURCE);
-            if (isPkgInfo) {
-                if (enter.getEnv(tree.packge) == null) {
+            enter.complete(List.of(tree), c);
+
+            if (!taskListener.isEmpty()) {
+                TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, tree);
+                taskListener.finished(e);
+            }
+
+            if (enter.getEnv(c) == null) {
+                boolean isPackageInfo =
+                    tree.sourcefile.isNameCompatible("package-info",
+                                                     JavaFileObject.Kind.SOURCE);
+                boolean isModuleInfo =
+                    tree.sourcefile.isNameCompatible("module-info",
+                                                     JavaFileObject.Kind.SOURCE);
+                if (isPackageInfo) {
+                    if (enter.getEnv(tree.packge) == null) {
+                        JCDiagnostic diag =
+                            diagFactory.fragment("file.does.not.contain.package",
+                                                     c.location());
+                        throw reader.new BadClassFile(c, filename, diag);
+                    }
+                } else if (isModuleInfo) {
+                    if (enter.getEnv(tree.modle) == null) {
+                        JCDiagnostic diag =
+                            diagFactory.fragment("file.does.not.contain.module",
+                                                     c.location());
+                        throw reader.new BadClassFile(c, filename, diag);
+                    }
+                }
+                else {
                     JCDiagnostic diag =
-                        diagFactory.fragment("file.does.not.contain.package",
-                                                 c.location());
+                            diagFactory.fragment("file.doesnt.contain.class",
+                                                c.getQualifiedName());
                     throw reader.new BadClassFile(c, filename, diag);
                 }
-            } else {
-                JCDiagnostic diag =
-                        diagFactory.fragment("file.doesnt.contain.class",
-                                            c.getQualifiedName());
-                throw reader.new BadClassFile(c, filename, diag);
             }
+
+            implicitSourceFilesRead = true;
         }
-
-        implicitSourceFilesRead = true;
     }
 
     /** Track when the JavaCompiler has been used to compile something. */
@@ -812,6 +836,7 @@
     {
         if (processors != null && processors.iterator().hasNext())
             explicitAnnotationProcessingRequested = true;
+
         // as a JavaCompiler can only be used once, throw an exception if
         // it has been used before.
         if (hasBeenUsed)
@@ -1404,7 +1429,7 @@
             make.at(Position.FIRSTPOS);
             TreeMaker localMake = make.forToplevel(env.toplevel);
 
-            if (env.tree instanceof JCCompilationUnit) {
+            if (env.tree.hasTag(JCTree.Tag.TOPLEVEL) || env.tree.hasTag(JCTree.Tag.MODULE)) {
                 if (!(stubOutput || sourceOutput || printFlat)) {
                     if (shouldStop(CompileState.LOWER))
                         return;
--- a/src/share/classes/com/sun/tools/javac/main/Main.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/main/Main.java	Tue May 07 17:14:17 2013 -0700
@@ -309,6 +309,37 @@
             }
         }
 
+
+        Option[] bootclasspathOptions = {
+//            XBOOTCLASSPATH_PREPEND,
+            ENDORSEDDIRS,
+//            BOOTCLASSPATH,
+//            XBOOTCLASSPATH_APPEND,
+            EXTDIRS
+        };
+        Option[] moduleOptions = {
+            L,
+            MODULEPATH
+        };
+        List<Option> bcpOpts = List.nil();
+        List<Option> mOpts = List.nil();
+        for (Option n: bootclasspathOptions) {
+            if (options.get(n) != null)
+                bcpOpts = bcpOpts.prepend(n);
+        }
+        for (Option n: moduleOptions) {
+            if (options.get(n) != null)
+                mOpts = mOpts.prepend(n);
+        }
+        if (bcpOpts.nonEmpty() && mOpts.nonEmpty()) {
+            error("err.conficting.options", bcpOpts.head.text, mOpts.head.text);
+            return null;
+        }
+        if (mOpts.nonEmpty() && !source.allowModules()) {
+            error("err.option.not.supported.in.source", mOpts.head.text, source.name);
+            return null;
+        }
+
         String profileString = options.get(PROFILE);
         if (profileString != null) {
             Profile profile = Profile.lookup(profileString);
--- a/src/share/classes/com/sun/tools/javac/main/Option.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/main/Option.java	Tue May 07 17:14:17 2013 -0700
@@ -153,6 +153,10 @@
         }
     },
 
+    MODULEPATH("-modulepath", "opt.arg.path", "opt.modulepath", STANDARD, FILEMANAGER),
+    
+    L("-L", "opt.arg.library", "opt.L", STANDARD, FILEMANAGER),
+
     EXTDIRS("-extdirs", "opt.arg.dirs", "opt.extdirs", STANDARD, FILEMANAGER),
 
     DJAVA_EXT_DIRS("-Djava.ext.dirs=", "opt.arg.dirs", "opt.extdirs", EXTENDED, FILEMANAGER) {
--- a/src/share/classes/com/sun/tools/javac/model/JavacElements.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/model/JavacElements.java	Tue May 07 17:14:17 2013 -0700
@@ -181,8 +181,8 @@
         Symbol sym = cast(Symbol.class, e);
         class Vis extends JCTree.Visitor {
             List<JCAnnotation> result = null;
-            public void visitTopLevel(JCCompilationUnit tree) {
-                result = tree.packageAnnotations;
+            public void visitPackage(JCPackageDecl tree) {
+                result = tree.annots;
             }
             public void visitClassDef(JCClassDecl tree) {
                 result = tree.mods.annotations;
--- a/src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java	Tue May 07 17:14:17 2013 -0700
@@ -101,6 +101,8 @@
         }
     }
 
+    protected boolean allowVersionLiteral;
+
     /**
      * Create a scanner from the input array.  This method might
      * modify the array.  To avoid copying the input array, ensure
@@ -130,6 +132,14 @@
         this.allowUnderscoresInLiterals = source.allowUnderscoresInLiterals();
     }
 
+    protected boolean allowVersionLiteral() {
+        return allowVersionLiteral;
+    }
+
+    protected void allowVersionLiteral(boolean allow) {
+        allowVersionLiteral = allow;
+    }
+
     /** Report an error at the given position using the provided arguments.
      */
     protected void lexError(int pos, String key, Object... args) {
@@ -445,6 +455,70 @@
         }
     }
 
+    /* same as scanIdent, except
+     * 1. '.' and '-' included
+     * 2. set tk to VERSION_LITERAL
+     */
+    private void scanVersionLiteral() {
+        boolean isJavaIdentifierPart;
+        char high;
+        do {
+            reader.putChar(true);
+            switch (reader.ch) {
+            case '-': case '.': // specific to version literals
+            case 'A': case 'B': case 'C': case 'D': case 'E':
+            case 'F': case 'G': case 'H': case 'I': case 'J':
+            case 'K': case 'L': case 'M': case 'N': case 'O':
+            case 'P': case 'Q': case 'R': case 'S': case 'T':
+            case 'U': case 'V': case 'W': case 'X': case 'Y':
+            case 'Z':
+            case 'a': case 'b': case 'c': case 'd': case 'e':
+            case 'f': case 'g': case 'h': case 'i': case 'j':
+            case 'k': case 'l': case 'm': case 'n': case 'o':
+            case 'p': case 'q': case 'r': case 's': case 't':
+            case 'u': case 'v': case 'w': case 'x': case 'y':
+            case 'z':
+            case '$': case '_':
+            case '0': case '1': case '2': case '3': case '4':
+            case '5': case '6': case '7': case '8': case '9':
+            case '\u0000': case '\u0001': case '\u0002': case '\u0003':
+            case '\u0004': case '\u0005': case '\u0006': case '\u0007':
+            case '\u0008': case '\u000E': case '\u000F': case '\u0010':
+            case '\u0011': case '\u0012': case '\u0013': case '\u0014':
+            case '\u0015': case '\u0016': case '\u0017':
+            case '\u0018': case '\u0019': case '\u001B':
+            case '\u007F':
+                break;
+            case '\u001A': // EOI is also a legal identifier part
+                if (reader.bp >= reader.buflen) {
+                    name = reader.name();
+                    tk = TokenKind.VERSIONLITERAL;
+                    return;
+                }
+                break;
+            default:
+                if (reader.ch < '\u0080') {
+                    // all ASCII range chars already handled, above
+                    isJavaIdentifierPart = false;
+                } else {
+                    high = reader.scanSurrogates();
+                    if (high != 0) {
+                        reader.putChar(high);
+                        isJavaIdentifierPart = Character.isJavaIdentifierPart(
+                            Character.toCodePoint(high, reader.ch));
+                    } else {
+                        isJavaIdentifierPart = Character.isJavaIdentifierPart(reader.ch);
+                    }
+                }
+                if (!isJavaIdentifierPart) {
+                    name = reader.name();
+                    tk = TokenKind.VERSIONLITERAL;
+                    return;
+                }
+            }
+        } while (true);
+    }
+
     /** Read token.
      */
     public Token readToken() {
@@ -496,6 +570,10 @@
                     scanIdent();
                     break loop;
                 case '0':
+                    if (allowVersionLiteral) {
+                        scanVersionLiteral();
+                        break loop;
+                    }
                     reader.scanChar();
                     if (reader.ch == 'x' || reader.ch == 'X') {
                         reader.scanChar();
@@ -535,6 +613,10 @@
                     break loop;
                 case '1': case '2': case '3': case '4':
                 case '5': case '6': case '7': case '8': case '9':
+                    if (allowVersionLiteral) {
+                        scanVersionLiteral();
+                        break loop;
+                    }
                     scanNumber(pos, 10);
                     break loop;
                 case '.':
--- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Tue May 07 17:14:17 2013 -0700
@@ -28,6 +28,7 @@
 import java.util.*;
 
 import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
+import com.sun.source.tree.RequiresFlag;
 
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.parser.Tokens.*;
@@ -47,6 +48,7 @@
 import static com.sun.tools.javac.parser.Tokens.TokenKind.GT;
 import static com.sun.tools.javac.parser.Tokens.TokenKind.IMPORT;
 import static com.sun.tools.javac.parser.Tokens.TokenKind.LT;
+import static com.sun.tools.javac.parser.Tokens.TokenKind.PACKAGE;
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
 import static com.sun.tools.javac.util.ListBuffer.lb;
 
@@ -162,6 +164,7 @@
         this.allowStaticInterfaceMethods = source.allowStaticInterfaceMethods();
         this.allowIntersectionTypesInCast = source.allowIntersectionTypesInCast();
         this.allowTypeAnnotations = source.allowTypeAnnotations();
+        this.allowModules = source.allowModules();
         this.keepDocComments = keepDocComments;
         docComments = newDocCommentTable(keepDocComments, fac);
         this.keepLineMap = keepLineMap;
@@ -231,6 +234,10 @@
      */
     boolean allowMethodReferences;
 
+    /** Switch: should we recognize modules?
+     */
+    boolean allowModules;
+
     /** Switch: should we allow default methods in interfaces?
      */
     boolean allowDefaultMethods;
@@ -656,6 +663,20 @@
     }
 
     /**
+     * Qualident = Ident { DOT Ident }
+     * (used when we've had to lookahead at the first identifier)
+     */
+    public JCExpression qualident(JCExpression head) {
+        JCExpression t = head;
+        while (token.kind == DOT) {
+            int pos = token.pos;
+            nextToken();
+            t = toP(F.at(pos).Select(t, ident()));
+        }
+        return t;
+    }
+
+    /**
      * Literal =
      *     INTLITERAL
      *   | LONGLITERAL
@@ -3035,51 +3056,63 @@
         boolean consumedToplevelDoc = false;
         boolean seenImport = false;
         boolean seenPackage = false;
-        List<JCAnnotation> packageAnnotations = List.nil();
-        if (token.kind == MONKEYS_AT)
+        ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
+
+        if (token.kind == IDENTIFIER && token.name() == names.module) {
+            defs.append(moduleDecl(mods, token.comment(CommentStyle.JAVADOC)));
+            consumedToplevelDoc = true;
+        } else {
+            List<JCAnnotation> packageAnnotations = List.nil();
+            if (token.kind == MONKEYS_AT)
             mods = modifiersOpt();
 
-        if (token.kind == PACKAGE) {
-            seenPackage = true;
-            if (mods != null) {
-                checkNoMods(mods.flags);
-                packageAnnotations = mods.annotations;
-                mods = null;
+            if (token.kind == PACKAGE) {
+                seenPackage = true;
+                if (mods != null) {
+                    checkNoMods(mods.flags);
+                    packageAnnotations = mods.annotations;
+                    mods = null;
+                }
+                nextToken();
+                pid = qualident(false);
+                accept(SEMI);
+                JCPackageDecl pd = F.at(firstToken.pos).Package(packageAnnotations, pid);
+                Comment docComment = firstToken.comment(CommentStyle.JAVADOC);
+                consumedToplevelDoc = true;
+                attach(pd, docComment);
+                defs.append(pd);
             }
-            nextToken();
-            pid = qualident(false);
-            accept(SEMI);
-        }
-        ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
-        boolean checkForImports = true;
-        boolean firstTypeDecl = true;
-        while (token.kind != EOF) {
-            if (token.pos > 0 && token.pos <= endPosTable.errorEndPos) {
-                // error recovery
-                skip(checkForImports, false, false, false);
-                if (token.kind == EOF)
-                    break;
-            }
-            if (checkForImports && mods == null && token.kind == IMPORT) {
-                seenImport = true;
-                defs.append(importDeclaration());
-            } else {
-                Comment docComment = token.comment(CommentStyle.JAVADOC);
-                if (firstTypeDecl && !seenImport && !seenPackage) {
-                    docComment = firstToken.comment(CommentStyle.JAVADOC);
-                    consumedToplevelDoc = true;
+
+            boolean checkForImports = true;
+            boolean firstTypeDecl = true;
+            while (token.kind != EOF) {
+                if (token.pos <= endPosTable.errorEndPos) {
+                    // error recovery
+                    skip(checkForImports, false, false, false);
+                    if (token.kind == EOF)
+                        break;
                 }
-                JCTree def = typeDeclaration(mods, docComment);
-                if (def instanceof JCExpressionStatement)
-                    def = ((JCExpressionStatement)def).expr;
-                defs.append(def);
-                if (def instanceof JCClassDecl)
-                    checkForImports = false;
-                mods = null;
-                firstTypeDecl = false;
+                if (checkForImports && mods == null && token.kind == IMPORT) {
+                    seenImport = true;
+                    defs.append(importDeclaration());
+                } else {
+                    Comment docComment = token.comment(CommentStyle.JAVADOC);
+                    if (firstTypeDecl && !seenImport && !seenPackage) {
+                        docComment = firstToken.comment(CommentStyle.JAVADOC);
+                        consumedToplevelDoc = true;
+                    }
+                    JCTree def = typeDeclaration(mods, docComment);
+                    if (def instanceof JCExpressionStatement)
+                        def = ((JCExpressionStatement)def).expr;
+                    defs.append(def);
+                    if (def instanceof JCClassDecl)
+                        checkForImports = false;
+                    mods = null;
+                    firstTypeDecl = false;
+                }
             }
         }
-        JCTree.JCCompilationUnit toplevel = F.at(firstToken.pos).TopLevel(packageAnnotations, pid, defs.toList());
+        JCTree.JCCompilationUnit toplevel = F.at(firstToken.pos).TopLevel(defs.toList());
         if (!consumedToplevelDoc)
             attach(toplevel, firstToken.comment(CommentStyle.JAVADOC));
         if (defs.isEmpty())
@@ -3093,6 +3126,220 @@
         return toplevel;
     }
 
+    /**
+     * ModuleDecl = { "@" Annotation } MODULE ModuleId [ ModuleProvides ] '{' { ModuleMetadata } '}'
+     * ModuleProvides = PROVIDES ModuleIdList
+     *
+     * called after MODULE has been seen
+     */
+    JCModuleDecl moduleDecl(JCModifiers mods, Comment dc) {
+        int pos = token.pos;
+        if (!allowModules) {
+            log.error(pos, "modules.not.supported.in.source", source.name);
+            allowModules = true;
+        }
+        S.allowVersionLiteral(true);
+        // FIXME: unimpl annots
+        List<JCAnnotation> annots = List.nil();
+        if (mods != null) {
+            checkNoMods(mods.flags);
+            annots = mods.annotations;
+            mods = null;
+        }
+        nextToken();
+        JCModuleId mid = moduleId();
+        List<JCModuleDirective> directives = null;
+
+        accept(LBRACE);
+        directives = moduleDirectiveList();
+        if (token.kind != RBRACE) {
+            setErrorEndPos(token.pos);
+            reportSyntaxError(S.prevToken().endPos, "expected", RBRACE);
+        }
+
+        // The extended metadata is all of the textual content that follows the
+        // module declaration.
+        UnicodeReader reader = S.getReader();
+        while (reader.bp < reader.buflen && Character.isWhitespace(reader.ch))
+            reader.scanChar();
+        while (reader.bp < reader.buflen)
+            reader.putChar(true);
+        Name moduleData = (reader.sp == 0) ? null : reader.name();
+
+        JCModuleDecl result = toP(F.at(pos).Module(mid, directives, moduleData));
+        attach(result, dc);
+        return result;
+    }
+
+    /**
+     * ModuleMetadataList = ModuleMetadata*
+     * ModuleMetadata = ModuleRequires | ModulePermits | ModuleProvides
+     * ModuleRequires = REQUIRES Identifier* ModuleId {',' ModuleId}
+     * ModulePermits  = PERMITS  QualifiedIdentifier {',' QualifiedIdentifier}
+     */
+    List<JCModuleDirective> moduleDirectiveList() {
+        ListBuffer<JCModuleDirective> defs = new ListBuffer<JCModuleDirective>();
+
+        while (token.kind == IDENTIFIER || token.kind == CLASS) {
+            int pos = token.pos;
+            if (token.kind == CLASS) {
+                nextToken();
+                JCExpression qualId = qualident(false);
+                accept(SEMI);
+                defs.append(toP(F.at(pos).Entrypoint(qualId)));
+            } else if (token.name() == names.exports) {
+                // FIXME, unimpl .**?
+                nextToken();
+                JCExpression exportId = toP(F.at(token.pos).Ident(ident()));
+                while (token.kind == DOT) {
+                    int pos1 = token.pos;
+                    accept(DOT);
+                    if (token.kind == STAR || token.kind == STARSTAR) {
+                        Name tname = (token.kind == STAR ? names.asterisk : names.double_asterisk);
+                        exportId = to(F.at(pos1).Select(exportId, tname));
+                        nextToken();
+                        break;
+                    } else {
+                        exportId = toP(F.at(pos1).Select(exportId, ident()));
+                    }
+                }
+                accept(SEMI);
+                defs.append(toP(F.at(pos).Exports(exportId)));
+            } else if (token.name() == names.requires) {
+                ListBuffer<RequiresFlag> flags = new ListBuffer<RequiresFlag>();
+                nextToken();
+                if (token.kind == IDENTIFIER && token.name() == names.optional) {
+                    flags.add(RequiresFlag.OPTIONAL);
+                    nextToken();
+                }
+                if (token.kind == IDENTIFIER && token.name() == names.service) {
+                    nextToken();
+                    JCExpression qualId = qualident(false);
+                    accept(SEMI);
+                    defs.append(toP(F.at(pos).RequiresService(flags.toList(), qualId)));
+                } else {
+                    while ((token.kind == PUBLIC)
+                            || (token.kind == IDENTIFIER && token.name() == names.local)) {
+                        RequiresFlag flag = (token.kind == PUBLIC)
+                                ? RequiresFlag.REEXPORT : RequiresFlag.LOCAL;
+                        // FIXME: check duplicates
+                        flags.append(flag);
+                        nextToken();
+                    }
+                    JCModuleQuery moduleQuery = moduleQuery();
+                    accept(SEMI);
+                    defs.append(toP(F.at(pos).RequiresModule(flags.toList(), moduleQuery)));
+                }
+            } else if (token.name() == names.permits) {
+                nextToken();
+                JCExpression qualId = qualident(false);
+                accept(SEMI);
+                defs.append(toP(F.at(pos).Permits(qualId)));
+            } else if (token.name() == names.provides) {
+                nextToken();
+                if (token.kind == IDENTIFIER && token.name() == names.service) {
+                    nextToken();
+                    JCExpression serviceName = qualident(false);
+                    if (token.kind == IDENTIFIER && token.name() == names.with) {
+                        nextToken();
+                        JCExpression implName = qualident(false);
+                        accept(SEMI);
+                        defs.append(toP(F.at(pos).ProvidesService(serviceName, implName)));
+                    } else {
+                        log.error("with.expected");
+                    }
+                } else {
+                    JCModuleId moduleId = moduleId();
+                    accept(SEMI);
+                    defs.append(toP(F.at(pos).ProvidesModule(moduleId)));
+                }
+            } else if (token.name() == names.view) {
+                nextToken();
+                JCExpression qualId = qualident(false);
+                accept(LBRACE);
+                List<JCModuleDirective> directives = moduleDirectiveList();
+                accept(RBRACE);
+                defs.append(toP(F.at(pos).View(qualId, directives)));
+            } else
+                break;
+        }
+
+        return defs.toList();
+    }
+
+    /** ModuleIdList = ModuleId {"," ModuleId}
+     */
+    List<JCModuleId> moduleIdList() {
+        ListBuffer<JCModuleId> ts = new ListBuffer<JCModuleId>();
+        ts.append(moduleId());
+        while (token.kind == COMMA) {
+            nextToken();
+            ts.append(moduleId());
+        }
+        return ts.toList();
+    }
+
+    /** ModuleIdList = ModuleId {"," ModuleId}
+     *  used when we've peeked ahead at the first identifier
+     */
+    List<JCModuleId> moduleIdList(JCExpression head) {
+        ListBuffer<JCModuleId> ts = new ListBuffer<JCModuleId>();
+        ts.append(moduleId(head));
+        while (token.kind == COMMA) {
+            nextToken();
+            ts.append(moduleId());
+        }
+        return ts.toList();
+    }
+
+    JCModuleId moduleId() {
+        return moduleId(toP(F.at(token.pos).Ident(ident())));
+    }
+
+    JCModuleId moduleId(JCExpression head) {
+        int pos = token.pos;
+        JCTree qualId = qualident(head);
+        Name version = null;
+        if (token.kind == MONKEYS_AT) {
+            nextToken();
+            if (token.kind == VERSIONLITERAL) {
+                version = token.name();
+            } else
+               log.error(pos, "module.version.literal.expected");
+            nextToken();
+        }
+        return toP(F.at(pos).ModuleId(qualId, version));
+    }
+
+    JCModuleQuery moduleQuery() {
+        return moduleQuery(toP(F.at(token.pos).Ident(ident())));
+    }
+
+    JCModuleQuery moduleQuery(JCExpression head) {
+        int pos = token.pos;
+        JCTree qualId = qualident(head);
+        Name query = null;
+        if (token.kind == MONKEYS_AT) {
+            nextToken();
+            if (token.kind == VERSIONLITERAL) {
+                query = token.name();
+                nextToken();
+            } else if (optag(token.kind) != Tag.NO_TAG) { // FIXME: close, but not close enough
+                Token op = token;
+                nextToken();
+                if (token.kind == VERSIONLITERAL) {
+                    query = names.fromString(op.kind.name + token.name());
+                    nextToken();
+                } else {
+                    log.error(token.pos, "module.version.literal.expected");
+                }
+            } else {
+               log.error(pos, "module.version.query.expected");
+            }
+        }
+        return toP(F.at(pos).ModuleQuery(qualId, query));
+    }
+
     /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";"
      */
     JCTree importDeclaration() {
--- a/src/share/classes/com/sun/tools/javac/parser/Lexer.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/parser/Lexer.java	Tue May 07 17:14:17 2013 -0700
@@ -25,7 +25,7 @@
 
 package com.sun.tools.javac.parser;
 
-import com.sun.tools.javac.parser.Tokens.*;
+import com.sun.tools.javac.parser.Tokens.Token;
 import com.sun.tools.javac.util.Position.LineMap;
 
 /**
@@ -84,4 +84,9 @@
      * @return a LineMap
      */
     LineMap getLineMap();
+
+    boolean allowVersionLiteral();
+    void allowVersionLiteral(boolean allow);
+
+    UnicodeReader getReader();
 }
--- a/src/share/classes/com/sun/tools/javac/parser/Scanner.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/parser/Scanner.java	Tue May 07 17:14:17 2013 -0700
@@ -134,4 +134,16 @@
     public void errPos(int pos) {
         tokenizer.errPos(pos);
     }
+
+    public boolean allowVersionLiteral() {
+        return tokenizer.allowVersionLiteral();
+    }
+
+    public void allowVersionLiteral(boolean allow) {
+        tokenizer.allowVersionLiteral(allow);
+    }
+
+    public UnicodeReader getReader() {
+        return tokenizer.reader;
+    }
 }
--- a/src/share/classes/com/sun/tools/javac/parser/Tokens.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/parser/Tokens.java	Tue May 07 17:14:17 2013 -0700
@@ -173,6 +173,7 @@
         DOUBLELITERAL(Tag.NUMERIC),
         CHARLITERAL(Tag.NUMERIC),
         STRINGLITERAL(Tag.STRING),
+        VERSIONLITERAL(Tag.NAMED),
         TRUE("true", Tag.NAMED),
         FALSE("false", Tag.NAMED),
         NULL("null", Tag.NAMED),
@@ -207,6 +208,7 @@
         PLUS("+"),
         SUB("-"),
         STAR("*"),
+        STARSTAR("**"),
         SLASH("/"),
         AMP("&"),
         BAR("|"),
@@ -230,14 +232,15 @@
         CUSTOM;
 
         public final String name;
-        public final Tag tag;
+        final Tag tag;
 
         TokenKind() {
             this(null, Tag.DEFAULT);
         }
 
         TokenKind(String name) {
-            this(name, Tag.DEFAULT);
+            // TEMP HACK
+            this(name, Character.isLetter(name.charAt(0)) ? Tag.NAMED : Tag.DEFAULT);
         }
 
         TokenKind(Tag tag) {
@@ -249,6 +252,7 @@
             this.tag = tag;
         }
 
+        @Override
         public String toString() {
             switch (this) {
             case IDENTIFIER:
@@ -265,6 +269,8 @@
                 return "token.float";
             case DOUBLELITERAL:
                 return "token.double";
+            case VERSIONLITERAL:
+                return "token.version";
             case ERROR:
                 return "token.bad-symbol";
             case EOF:
@@ -422,6 +428,7 @@
             this.name = name;
         }
 
+        @Override
         protected void checkKind() {
             if (kind.tag != Tag.NAMED) {
                 throw new AssertionError("Bad token kind - expected " + Tag.NAMED);
@@ -443,6 +450,7 @@
             this.stringVal = stringVal;
         }
 
+        @Override
         protected void checkKind() {
             if (kind.tag != Tag.STRING) {
                 throw new AssertionError("Bad token kind - expected " + Tag.STRING);
@@ -464,6 +472,7 @@
             this.radix = radix;
         }
 
+        @Override
         protected void checkKind() {
             if (kind.tag != Tag.NUMERIC) {
                 throw new AssertionError("Bad token kind - expected " + Tag.NUMERIC);
--- a/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Tue May 07 17:14:17 2013 -0700
@@ -1332,9 +1332,19 @@
                     node.type = null;
             }
             public void visitTopLevel(JCCompilationUnit node) {
+                node.locn = null;
+                node.modle = null;
                 node.packge = null;
                 super.visitTopLevel(node);
             }
+            public void visitModuleDef(JCModuleDecl node) {
+                node.sym = null;
+                super.visitModuleDef(node);
+            }
+            public void visitPackageDef(JCPackageDecl node) {
+                node.sym = null;
+                super.visitPackageDef(node);
+            }
             public void visitClassDef(JCClassDecl node) {
                 node.sym = null;
                 super.visitClassDef(node);
--- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue May 07 17:14:17 2013 -0700
@@ -1082,6 +1082,100 @@
 compiler.misc.inaccessible.varargs.type=\
     formal varargs element type {0} is not accessible from {1} {2}
 
+compiler.err.mdl.no.version.available=\
+    no version available for module {0}
+compiler.err.mdl.no.unique.version.available=\
+    no unique version available for module {0}
+compiler.err.mdl.required.version.not.available=\
+    required version not available for module {0}
+compiler.err.mdl.duplicate.definition=\
+    duplicate definition of module {0}
+compiler.err.mdl.file.in.wrong.directory=\
+    file is not in the expected subdirectory within its package hierarchy
+compiler.err.module.library.not.found=\
+    module library not found: {0}
+compiler.err.module.decl.not.permitted=\
+    module declaration not permitted
+compiler.misc.cant.resolve.modules=\
+    cannot resolve module dependencies
+compiler.err.jigsaw.resolver.error=\
+    Cannot resolve module dependencies using Jigsaw module resolver\n{0}
+compiler.err.jigsaw.resolver.ioerror=\
+    IO error while resolving modules using Jigsaw module resolver\n{0}
+
+# 0: string
+compiler.err.cannot.open.module.library=\
+    cannot open module library: {0}
+
+compiler.err.dupl.entrypoint=\
+    entry point already specified for module or view.
+
+# 0: symbol
+compiler.err.dupl.exports=\
+    ''export'' directive for package {0} already specified
+
+# 0: symbol
+compiler.err.dupl.permits=\
+    ''permits'' directive for module {0} already specified
+
+# 0: symbol
+compiler.err.dupl.provides=\
+    ''provides'' directive for module {0} already specified
+
+# 0: symbol
+compiler.err.dupl.provides.service=\
+    ''provides'' directive service {0} with {1} already specified
+
+# 0: symbol
+compiler.err.dupl.requires=\
+    ''requires'' directive for module {0} already specified
+
+# 0: symbol
+compiler.err.dupl.requires.service=\
+    ''requires'' directive for service {0} already specified
+
+# 0: string
+compiler.err.dupl.view=\
+    view {0} already defined in this module
+
+# 0: symbol
+compiler.err.mdl.already.defined=\
+    module {0} already defined
+
+compiler.err.mdl.module.file.manager.required=\
+    module file manager required
+
+compiler.err.module.version.literal.expected=\
+    version literal expected
+
+compiler.err.module.version.query.expected=\
+    version query expected
+
+compiler.err.nested.view.not.allowed=\
+    nested view not permitted
+
+compiler.err.requires.not.allowed.in.view=\
+    ''requires'' directive not permitted in view
+
+compiler.err.with.expected=\
+    ''with'' expected
+
+# 0: symbol
+compiler.err.no.psv.main=\
+    class {0} does not define public static void main(String[])
+
+# 0: symbol
+compiler.err.service.impl.is.abstract=\
+    service implementation class {0} is abstract
+
+# 0: symbol
+compiler.err.service.impl.no.default.constr=\
+    class {0} does not define a public no-args constructor
+
+# 0: symbol
+compiler.err.service.impl.is.inner=\
+    service implemention class {0} is an inner class
+
 # In the following string, {1} will always be the detail message from
 # java.io.IOException.
 # 0: symbol, 1: string
@@ -1588,6 +1682,9 @@
 compiler.misc.token.double=\
     <double>
 
+compiler.misc.token.version=\
+    <version>
+
 compiler.misc.token.bad-symbol=\
     <bad symbol>
 
@@ -1644,6 +1741,9 @@
 compiler.misc.unnamed.package=\
     unnamed package
 
+compiler.misc.unnamed.module=\
+    unnamed module
+
 #####
 
 # 0: symbol, 1: message segment
@@ -1700,9 +1800,14 @@
 compiler.misc.file.doesnt.contain.class=\
     file does not contain class {0}
 
+# 0: symbol
 compiler.misc.file.does.not.contain.package=\
     file does not contain package {0}
 
+# 0: symbol
+compiler.misc.file.does.not.contain.module=\
+    file does not contain module {0}
+
 compiler.misc.illegal.start.of.class.file=\
     illegal start of class file
 
@@ -2045,6 +2150,9 @@
 compiler.misc.kindname.instance.init=\
     instance initializer
 
+compiler.misc.kindname.module=\
+    module
+
 #####
 
 compiler.misc.no.args=\
@@ -2259,6 +2367,11 @@
     (use -source 8 or higher to enable method references)
 
 # 0: string
+compiler.err.modules.not.supported.in.source=\
+    modules are not supported in -source {0}\n\
+(use -source 8 or higher to enable modules)
+
+# 0: string
 compiler.err.default.methods.not.supported.in.source=\
     default methods are not supported in -source {0}\n\
     (use -source 8 or higher to enable default methods)
--- a/src/share/classes/com/sun/tools/javac/resources/javac.properties	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/resources/javac.properties	Tue May 07 17:14:17 2013 -0700
@@ -41,6 +41,8 @@
     Specify where to find user class files and annotation processors
 javac.opt.sourcepath=\
     Specify where to find input source files
+javac.opt.modulepath=\
+    Specify where to find module source and class files
 javac.opt.bootclasspath=\
     Override location of bootstrap class files
 javac.opt.Xbootclasspath.p=\
@@ -83,12 +85,16 @@
     Specify whether or not to generate class files for implicitly referenced files
 javac.opt.pkginfo=\
     Specify handling of package-info files
+javac.opt.L=\
+    Specify location of module library
 javac.opt.arg.class=\
     <class>
 javac.opt.arg.class.list=\
     <class1>[,<class2>,<class3>...]
 javac.opt.arg.flag=\
     <flag>
+javac.opt.arg.library=\
+    <library>
 javac.opt.arg.key.equals.value=\
     key[=value]
 javac.opt.arg.path=\
@@ -207,6 +213,11 @@
     not a directory: {0}
 javac.err.file.not.file=\
     not a file: {0}
+javac.err.conficting.options=\
+    cannot specify both {0} and {1}
+javac.err.option.not.supported.in.source=\
+    option {0} not supported with -source {1}\n\
+(use -source 7 or higher to enable module options)
 javac.msg.plugin.not.found=\
     plug-in not found: {0}
 ## messages
--- a/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Tue May 07 17:14:17 2013 -0700
@@ -31,6 +31,7 @@
 
 import javax.lang.model.element.Modifier;
 import javax.lang.model.type.TypeKind;
+import javax.tools.JavaFileManager.Location;
 import javax.tools.JavaFileObject;
 
 import com.sun.source.tree.*;
@@ -342,6 +343,19 @@
         DIV_ASG(DIV),                    // /=
         MOD_ASG(MOD),                    // %=
 
+        MODULE,
+        MODULE_ID,
+        MODULE_QUERY,
+        VIEW_DECLARATION,
+        ENTRYPOINT_DIRECTIVE,
+        EXPORT_DIRECTIVE,
+        PERMITS_DIRECTIVE,
+        PROVIDES_MODULE_DIRECTIVE,
+        PROVIDES_SERVICE_DIRECTIVE,
+        REQUIRES_MODULE_DIRECTIVE,
+        REQUIRES_SERVICE_DIRECTIVE,
+        PACKAGE,
+
         /** A synthetic let expression, of type LetExpr.
          */
         LETEXPR;                         // ala scheme
@@ -385,6 +399,7 @@
         }
     }
 
+
     /* The (encoded) position in the source file. @see util.Position.
      */
     public int pos;
@@ -444,7 +459,7 @@
     public Object clone() {
         try {
             return super.clone();
-        } catch(CloneNotSupportedException e) {
+        } catch (CloneNotSupportedException e) {
             throw new RuntimeException(e);
         }
     }
@@ -479,13 +494,14 @@
      * Everything in one source file is kept in a {@linkplain JCCompilationUnit} structure.
      */
     public static class JCCompilationUnit extends JCTree implements CompilationUnitTree {
-        public List<JCAnnotation> packageAnnotations;
-        /** The tree representing the package clause. */
-        public JCExpression pid;
-        /** All definitions in this file (ClassDef, Import, and Skip) */
+        /** All definitions in this file (Package, Import, ClassDef, and Skip) */
         public List<JCTree> defs;
-        /* The source file name. */
+        /** The source file name. */
         public JavaFileObject sourcefile;
+        /** The module to which this compilation unit belongs. */
+        public ModuleSymbol modle;
+        /** The location in which this compilation unit was found. */
+        public Location locn;
         /** The package to which this compilation unit belongs. */
         public PackageSymbol packge;
         /** A scope for all named imports. */
@@ -500,15 +516,11 @@
         /* An object encapsulating ending positions of source ranges indexed by
          * the tree nodes they belong to. Defined only if option -Xjcov is set. */
         public EndPosTable endPositions = null;
-        protected JCCompilationUnit(List<JCAnnotation> packageAnnotations,
-                        JCExpression pid,
-                        List<JCTree> defs,
+        protected JCCompilationUnit(List<JCTree> defs,
                         JavaFileObject sourcefile,
                         PackageSymbol packge,
                         ImportScope namedImportScope,
                         StarImportScope starImportScope) {
-            this.packageAnnotations = packageAnnotations;
-            this.pid = pid;
             this.defs = defs;
             this.sourcefile = sourcefile;
             this.packge = packge;
@@ -520,7 +532,8 @@
 
         public Kind getKind() { return Kind.COMPILATION_UNIT; }
         public List<JCAnnotation> getPackageAnnotations() {
-            return packageAnnotations;
+            JCPackageDecl pd = TreeInfo.getPackage(this);
+            return pd == null ? List.<JCAnnotation>nil() : pd.getAnnotations();
         }
         public List<JCImport> getImports() {
             ListBuffer<JCImport> imports = new ListBuffer<JCImport>();
@@ -532,7 +545,10 @@
             }
             return imports.toList();
         }
-        public JCExpression getPackageName() { return pid; }
+        public JCExpression getPackageName() {
+            JCPackageDecl pd = TreeInfo.getPackage(this);
+            return pd == null ? null : pd.getPackageId();
+        }
         public JavaFileObject getSourceFile() {
             return sourcefile;
         }
@@ -2347,6 +2363,446 @@
         }
     }
 
+    public static class JCModuleId extends JCTree implements ModuleIdTree {
+        public JCTree qualId;
+        public Name version;
+        protected JCModuleId(JCTree qualId, Name version) {
+            this.qualId = qualId;
+            this.version = version;
+        }
+
+        @Override
+        public void accept(Visitor v) { v.visitModuleId(this); }
+
+        @Override
+        public Kind getKind() {
+            return Kind.MODULE_ID;
+        }
+
+        @Override
+        public JCTree getName() {
+            return qualId;
+        }
+
+        @Override
+        public Name getVersion() {
+            return version;
+        }
+
+        @Override
+        public <R, D> R accept(TreeVisitor<R, D> v, D d) {
+            return v.visitModuleId(this, d);
+        }
+
+        @Override
+        public Tag getTag() {
+            return MODULE_ID;
+        }
+    }
+
+    public static class JCModuleQuery extends JCTree implements ModuleQueryTree {
+        public JCTree qualId;
+        public Name versionQuery;
+        protected JCModuleQuery(JCTree qualId, Name versionQuery) {
+            this.qualId = qualId;
+            this.versionQuery = versionQuery;
+        }
+
+        @Override
+        public void accept(Visitor v) { v.visitModuleQuery(this); }
+
+        @Override
+        public Kind getKind() {
+            return Kind.MODULE_QUERY;
+        }
+
+        @Override
+        public JCTree getName() {
+            return qualId;
+        }
+
+        @Override
+        public Name getVersionQuery() {
+            return versionQuery;
+        }
+
+        @Override
+        public <R, D> R accept(TreeVisitor<R, D> v, D d) {
+            return v.visitModuleQuery(this, d);
+        }
+
+        @Override
+        public Tag getTag() {
+            return MODULE_QUERY;
+        }
+    }
+
+    public static class JCModuleDecl extends JCTree implements ModuleTree {
+        public JCModuleId id;
+        public List<JCModuleDirective> directives;
+        public Name metadata;
+        public ModuleSymbol sym;
+
+        protected JCModuleDecl(JCModuleId id,
+                List<JCModuleDirective> directives, Name metadata) {
+            this.id = id;
+            this.directives = directives;
+            this.metadata = metadata;
+        }
+
+        @Override
+        public void accept(Visitor v) { v.visitModuleDef(this); }
+
+        @Override
+        public Kind getKind() {
+            return Kind.MODULE;
+        }
+
+        @Override
+        public JCModuleId getId() {
+            return id;
+        }
+
+        @Override
+        public List<JCModuleDirective> getDirectives() {
+            return directives;
+        }
+
+        @Override
+        public Name getExtendedMetadata() {
+            return metadata;
+        }
+
+        @Override
+        public <R, D> R accept(TreeVisitor<R, D> v, D d) {
+            return v.visitModule(this, d);
+        }
+
+        @Override
+        public Tag getTag() {
+            return MODULE;
+        }
+    }
+
+    public static abstract class JCModuleDirective extends JCTree implements ModuleDirectiveTree {
+    }
+
+    public static class JCViewDecl extends JCModuleDirective implements ViewDeclarationTree {
+        public JCExpression name;
+        public List<JCModuleDirective> directives;
+
+        protected JCViewDecl(JCExpression name, List<JCModuleDirective> directives) {
+            this.name = name;
+            this.directives = directives;
+        }
+
+        @Override
+        public void accept(Visitor v) { v.visitView(this); }
+
+        @Override
+        public Kind getKind() {
+            return Kind.VIEW_DECLARATION;
+        }
+
+        @Override
+        public JCExpression getName() {
+            return name;
+        }
+
+        @Override
+        public List<JCModuleDirective> getDirectives() {
+            return directives;
+        }
+
+        @Override
+        public <R, D> R accept(TreeVisitor<R, D> v, D d) {
+            return v.visitView(this, d);
+        }
+
+        @Override
+        public Tag getTag() {
+            return VIEW_DECLARATION;
+        }
+    }
+
+    public static class JCEntrypointDirective extends JCModuleDirective
+            implements EntrypointDirectiveTree {
+        public JCExpression qualId;
+        protected JCEntrypointDirective(JCExpression qualId) {
+            this.qualId = qualId;
+        }
+
+        @Override
+        public void accept(Visitor v) { v.visitEntrypoint(this); }
+
+        @Override
+        public Kind getKind() {
+            return Kind.ENTRYPOINT_DIRECTIVE;
+        }
+
+        @Override
+        public JCExpression getClassName() {
+            return qualId;
+        }
+
+        @Override
+        public <R, D> R accept(TreeVisitor<R, D> v, D d) {
+            return v.visitEntrypoint(this, d);
+        }
+
+        @Override
+        public Tag getTag() {
+            return ENTRYPOINT_DIRECTIVE;
+        }
+    }
+
+    public static class JCExportDirective extends JCModuleDirective
+            implements ExportDirectiveTree {
+        public JCExpression qualid;
+
+        protected JCExportDirective(JCExpression qualId) {
+            this.qualid = qualId;
+        }
+
+        @Override
+        public void accept(Visitor v) { v.visitExports(this); }
+
+        @Override
+        public Kind getKind() {
+            return Kind.EXPORT_DIRECTIVE;
+        }
+
+        @Override
+        public JCExpression getExportName() {
+            return qualid;
+        }
+
+        @Override
+        public <R, D> R accept(TreeVisitor<R, D> v, D d) {
+            return v.visitExport(this, d);
+        }
+
+        @Override
+        public Tag getTag() {
+            return EXPORT_DIRECTIVE;
+        }
+    }
+
+    public static class JCPermitsDirective extends JCModuleDirective
+            implements PermitsDirectiveTree {
+        public JCExpression moduleName;
+
+        protected JCPermitsDirective(JCExpression moduleName) {
+            this.moduleName = moduleName;
+        }
+
+        @Override
+        public void accept(Visitor v) { v.visitPermits(this); }
+
+        @Override
+        public Kind getKind() {
+            return Kind.PERMITS_DIRECTIVE;
+        }
+
+        @Override
+        public <R, D> R accept(TreeVisitor<R, D> v, D d) {
+            return v.visitPermits(this, d);
+        }
+
+        @Override
+        public JCExpression getModuleName() {
+            return moduleName;
+        }
+
+        @Override
+        public Tag getTag() {
+            return PERMITS_DIRECTIVE;
+        }
+    }
+
+    public static class JCRequiresModuleDirective extends JCModuleDirective
+            implements RequiresModuleDirectiveTree {
+        public List<RequiresFlag> flags;
+        public JCModuleQuery moduleQuery;
+
+        protected JCRequiresModuleDirective(List<RequiresFlag> flags, JCModuleQuery moduleQuery) {
+            this.flags = flags;
+            this.moduleQuery = moduleQuery;
+        }
+
+        @Override
+        public void accept(Visitor v) { v.visitRequiresModule(this); }
+
+        @Override
+        public Kind getKind() {
+            return Kind.REQUIRES_MODULE_DIRECTIVE;
+        }
+
+        @Override
+        public <R, D> R accept(TreeVisitor<R, D> v, D d) {
+            return v.visitRequiresModule(this, d);
+        }
+
+        @Override
+        public List<RequiresFlag> getFlags() {
+            return flags;
+        }
+
+        @Override
+        public JCModuleQuery getModuleQuery() {
+            return moduleQuery;
+        }
+
+        @Override
+        public Tag getTag() {
+            return REQUIRES_MODULE_DIRECTIVE;
+        }
+    }
+
+    public static class JCRequiresServiceDirective extends JCModuleDirective
+            implements RequiresServiceDirectiveTree {
+        public List<RequiresFlag> flags;
+        public JCExpression serviceName;
+
+        protected JCRequiresServiceDirective(List<RequiresFlag> flags, JCExpression serviceName) {
+            this.flags = flags;
+            this.serviceName = serviceName;
+        }
+
+        @Override
+        public void accept(Visitor v) { v.visitRequiresService(this); }
+
+        @Override
+        public Kind getKind() {
+            return Kind.REQUIRES_SERVICE_DIRECTIVE;
+        }
+
+        @Override
+        public <R, D> R accept(TreeVisitor<R, D> v, D d) {
+            return v.visitRequiresService(this, d);
+        }
+
+        @Override
+        public List<RequiresFlag> getFlags() {
+            return flags;
+        }
+
+        @Override
+        public JCExpression getServiceName() {
+            return serviceName;
+        }
+
+        @Override
+        public Tag getTag() {
+            return REQUIRES_SERVICE_DIRECTIVE;
+        }
+    }
+
+    public static class JCProvidesModuleDirective extends JCModuleDirective
+            implements ProvidesModuleDirectiveTree {
+        public JCModuleId moduleId;
+
+        protected JCProvidesModuleDirective(JCModuleId moduleId) {
+            this.moduleId = moduleId;
+        }
+
+        @Override
+        public void accept(Visitor v) { v.visitProvidesModule(this); }
+
+        @Override
+        public Kind getKind() {
+            return Kind.PROVIDES_MODULE_DIRECTIVE;
+        }
+
+        @Override
+        public <R, D> R accept(TreeVisitor<R, D> v, D d) {
+            return v.visitProvidesModule(this, d);
+        }
+
+        @Override
+        public JCModuleId getModuleId() {
+            return moduleId;
+        }
+
+        @Override
+        public Tag getTag() {
+            return PROVIDES_MODULE_DIRECTIVE;
+        }
+    }
+
+    public static class JCProvidesServiceDirective extends JCModuleDirective
+            implements ProvidesServiceDirectiveTree {
+        public JCExpression serviceName;
+        public JCExpression implName;
+
+        protected JCProvidesServiceDirective(JCExpression serviceName, JCExpression implName) {
+            this.serviceName = serviceName;
+            this.implName = implName;
+        }
+
+        @Override
+        public void accept(Visitor v) { v.visitProvidesService(this); }
+
+        @Override
+        public Kind getKind() {
+            return Kind.PROVIDES_SERVICE_DIRECTIVE;
+        }
+
+        @Override
+        public <R, D> R accept(TreeVisitor<R, D> v, D d) {
+            return v.visitProvidesService(this, d);
+        }
+
+        @Override
+        public JCExpression getServiceName() {
+            return serviceName;
+        }
+
+        @Override
+        public JCExpression getImplementationName() {
+            return implName;
+        }
+
+        @Override
+        public Tag getTag() {
+            return PROVIDES_SERVICE_DIRECTIVE;
+        }
+    }
+
+    public static class JCPackageDecl extends JCTree implements com.sun.source.tree.PackageTree {
+        public List<JCAnnotation> annots;
+        public JCExpression packageId;
+        public PackageSymbol sym;
+        protected JCPackageDecl(List<JCAnnotation> annots, JCExpression packageId) {
+            this.annots = annots;
+            this.packageId = packageId;
+        }
+        @Override
+        public void accept(Visitor v) { v.visitPackageDef(this); }
+
+        public Kind getKind() {
+            return Kind.PACKAGE;
+        }
+
+        public List<JCAnnotation> getAnnotations() {
+            return annots;
+        }
+
+        public JCExpression getPackageId() {
+            return packageId;
+        }
+
+        @Override
+        public <R, D> R accept(TreeVisitor<R, D> v, D d) {
+            return v.visitPackage(this, d);
+        }
+
+        @Override
+        public Tag getTag() {
+            return PACKAGE;
+        }
+    }
+
     public static class JCErroneous extends JCExpression
             implements com.sun.source.tree.ErroneousTree {
         public List<? extends JCTree> errs;
@@ -2399,9 +2855,7 @@
     /** An interface for tree factories
      */
     public interface Factory {
-        JCCompilationUnit TopLevel(List<JCAnnotation> packageAnnotations,
-                                   JCExpression pid,
-                                   List<JCTree> defs);
+        JCCompilationUnit TopLevel(List<JCTree> defs);
         JCImport Import(JCTree qualid, boolean staticImport);
         JCClassDecl ClassDef(JCModifiers mods,
                           Name name,
@@ -2482,6 +2936,17 @@
         JCAnnotation Annotation(JCTree annotationType, List<JCExpression> args);
         JCModifiers Modifiers(long flags, List<JCAnnotation> annotations);
         JCErroneous Erroneous(List<? extends JCTree> errs);
+        JCModuleDecl Module(JCModuleId moduleId, List<JCModuleDirective> directives, Name metadata);
+        JCViewDecl View(JCExpression name, List<JCModuleDirective> directives);
+        JCModuleId ModuleId(JCTree qualId, Name version);
+        JCModuleQuery ModuleQuery(JCTree qualId, Name versionQuery);
+        JCEntrypointDirective Entrypoint(JCExpression qualId);
+        JCExportDirective Exports(JCExpression qualId);
+        JCPermitsDirective Permits(JCExpression qualId);
+        JCProvidesModuleDirective ProvidesModule(JCModuleId moduleId);
+        JCProvidesServiceDirective ProvidesService(JCExpression serviceName, JCExpression implementationName);
+        JCRequiresModuleDirective RequiresModule(List<RequiresFlag> flags, JCModuleQuery moduleQuery);
+        JCRequiresServiceDirective RequiresService(List<RequiresFlag> flags, JCExpression serviceName);
         LetExpr LetExpr(List<JCVariableDecl> defs, JCTree expr);
     }
 
@@ -2541,6 +3006,18 @@
         public void visitModifiers(JCModifiers that)         { visitTree(that); }
         public void visitAnnotatedType(JCAnnotatedType that) { visitTree(that); }
         public void visitErroneous(JCErroneous that)         { visitTree(that); }
+        public void visitModuleDef(JCModuleDecl that)        { visitTree(that); }
+        public void visitEntrypoint(JCEntrypointDirective that) { visitTree(that); }
+        public void visitExports(JCExportDirective that)   { visitTree(that); }
+        public void visitModuleId(JCModuleId that)           { visitTree(that); }
+        public void visitModuleQuery(JCModuleQuery that) { visitTree(that); }
+        public void visitPermits(JCPermitsDirective that) { visitTree(that); }
+        public void visitProvidesModule(JCProvidesModuleDirective that) { visitTree(that); }
+        public void visitProvidesService(JCProvidesServiceDirective that) { visitTree(that); }
+        public void visitRequiresModule(JCRequiresModuleDirective that) { visitTree(that); }
+        public void visitRequiresService(JCRequiresServiceDirective that) { visitTree(that); }
+        public void visitView(JCViewDecl that) { visitTree(that); }
+        public void visitPackageDef(JCPackageDecl that)      { visitTree(that); }
         public void visitLetExpr(LetExpr that)               { visitTree(that); }
 
         public void visitTree(JCTree that)                   { Assert.error(); }
--- a/src/share/classes/com/sun/tools/javac/tree/Pretty.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/tree/Pretty.java	Tue May 07 17:14:17 2013 -0700
@@ -25,6 +25,7 @@
 
 package com.sun.tools.javac.tree;
 
+import com.sun.source.tree.RequiresFlag;
 import java.io.*;
 
 import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
@@ -366,33 +367,40 @@
      *  @param cdef     The class definition, which is assumed to be part of the
      *                  toplevel tree.
      */
+    @SuppressWarnings("fallthrough")
     public void printUnit(JCCompilationUnit tree, JCClassDecl cdef) throws IOException {
         docComments = tree.docComments;
         printDocComment(tree);
-        if (tree.pid != null) {
-            print("package ");
-            printExpr(tree.pid);
-            print(";");
-            println();
-        }
-        boolean firstImport = true;
-        for (List<JCTree> l = tree.defs;
-        l.nonEmpty() && (cdef == null || l.head.hasTag(IMPORT));
-        l = l.tail) {
-            if (l.head.hasTag(IMPORT)) {
-                JCImport imp = (JCImport)l.head;
-                Name name = TreeInfo.name(imp.qualid);
-                if (name == name.table.names.asterisk ||
-                        cdef == null ||
-                        isUsed(TreeInfo.symbol(imp.qualid), cdef)) {
-                    if (firstImport) {
-                        firstImport = false;
+        boolean inImports = false;
+        for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
+            switch (l.head.getTag()) {
+                case IMPORT:
+                    JCImport imp = (JCImport)l.head;
+                    Name name = TreeInfo.name(imp.qualid);
+                    if (name == name.table.names.asterisk ||
+                            cdef == null ||
+                            isUsed(TreeInfo.symbol(imp.qualid), cdef)) {
+                        if (!inImports) {
+                            inImports = true;
+                            println();
+                        }
+                        printStat(imp);
+                    }
+                    break;
+
+                default:
+                    if (cdef != null)
+                        break;
+                    // fall-through
+
+                case MODULE:
+                case PACKAGE:
+                    if (inImports) {
+                        inImports = false;
                         println();
                     }
-                    printStat(imp);
-                }
-            } else {
-                printStat(l.head);
+                    printStat(l.head);
+                    break;
             }
         }
         if (cdef != null) {
@@ -428,6 +436,159 @@
         }
     }
 
+    @Override
+    public void visitModuleDef(JCModuleDecl tree) {
+        try {
+            print("module ");
+            printExpr(tree.id);
+            if (tree.directives == null) {
+                print(";");
+            } else {
+                printBlock(tree.directives);
+            }
+            println();
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    @Override
+    public void visitModuleId(JCModuleId tree) {
+        try {
+            printExpr(tree.qualId);
+            if (tree.version != null) {
+                print(" @ ");
+                print(tree.version);  // JIGSAW FIXME -- CHECK IF QUOTES REQUIRED
+            }
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    @Override
+    public void visitModuleQuery(JCModuleQuery tree) {
+        try {
+            printExpr(tree.qualId);
+            if (tree.versionQuery != null) {
+                print(" @ ");
+                print(tree.versionQuery);  // JIGSAW FIXME -- CHECK IF QUOTES REQUIRED
+            }
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    @Override
+    public void visitEntrypoint(JCEntrypointDirective tree) {
+        try {
+            print("class ");
+            printExpr(tree.qualId);
+            print(";");
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    @Override
+    public void visitExports(JCExportDirective tree) {
+        try {
+            print("export ");
+            printExpr(tree.qualid);
+            print(";");
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    @Override
+    public void visitPermits(JCPermitsDirective tree) {
+        try {
+            print("permits ");
+            printExpr(tree.moduleName);
+            print(";");
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    @Override
+    public void visitProvidesModule(JCProvidesModuleDirective tree) {
+        try {
+            print("provides ");
+            printExpr(tree.moduleId);
+            print(";");
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    @Override
+    public void visitProvidesService(JCProvidesServiceDirective tree) {
+        try {
+            print("provides service ");
+            printExpr(tree.serviceName);
+            print(" with ");
+            printExpr(tree.implName);
+            print(";");
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    @Override
+    public void visitRequiresModule(JCRequiresModuleDirective tree) {
+        try {
+            print("requires ");
+            for (List<RequiresFlag> l = tree.flags; l.nonEmpty(); l = l.tail ) {
+                print(l.head);
+                print(" ");
+            }
+            printExpr(tree.moduleQuery);
+            print(";");
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    @Override
+    public void visitRequiresService(JCRequiresServiceDirective tree) {
+        try {
+            print("requires service ");
+            for (List<RequiresFlag> l = tree.flags; l.nonEmpty(); l = l.tail ) {
+                print(l.head);
+                print(" ");
+            }
+            printExpr(tree.serviceName);
+            print(";");
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    @Override
+    public void visitView(JCViewDecl tree) {
+        try {
+            print("module ");
+            printExpr(tree.name);
+            printBlock(tree.directives);
+            println();
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    public void visitPackageDef(JCPackageDecl tree) {
+        try {
+            printAnnotations(tree.annots);
+            print("package ");
+            printExpr(tree.packageId);
+            print(";");
+            println();
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
     public void visitImport(JCImport tree) {
         try {
             print("import ");
--- a/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java	Tue May 07 17:14:17 2013 -0700
@@ -29,6 +29,7 @@
 import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.Name;
 
 /**
  * Creates a copy of a tree, using a given TreeMaker.
@@ -346,10 +347,8 @@
 
     public JCTree visitCompilationUnit(CompilationUnitTree node, P p) {
         JCCompilationUnit t = (JCCompilationUnit) node;
-        List<JCAnnotation> packageAnnotations = copy(t.packageAnnotations, p);
-        JCExpression pid = copy(t.pid, p);
         List<JCTree> defs = copy(t.defs, p);
-        return M.at(t.pos).TopLevel(packageAnnotations, pid, defs);
+        return M.at(t.pos).TopLevel(defs);
     }
 
     public JCTree visitTry(TryTree node, P p) {
@@ -440,6 +439,97 @@
         return M.at(t.pos).Wildcard(kind, inner);
     }
 
+    @Override
+    public JCTree visitModule(ModuleTree node, P p) {
+        JCModuleDecl t = (JCModuleDecl) node;
+        JCModuleId moduleId = copy(t.id);
+        List<JCModuleDirective> directives = copy(t.directives);
+        return M.at(t.pos).Module(moduleId, directives, t.metadata);
+    }
+
+    @Override
+    public JCTree visitView(ViewDeclarationTree node, P p) {
+        JCViewDecl t = (JCViewDecl) node;
+        JCExpression name = copy(t.name);
+        List<JCModuleDirective> directives = copy(t.directives);
+        return M.at(t.pos).View(name, directives);
+    }
+
+    @Override
+    public JCEntrypointDirective visitEntrypoint(EntrypointDirectiveTree node, P p) {
+        JCEntrypointDirective t = (JCEntrypointDirective) node;
+        JCExpression qualId = copy(t.qualId, p);
+        return M.at(t.pos).Entrypoint(qualId);
+    }
+
+    @Override
+    public JCExportDirective visitExport(ExportDirectiveTree node, P p) {
+        JCExportDirective t = (JCExportDirective) node;
+        JCExpression qualId = copy(t.qualid, p);
+        return M.at(t.pos).Exports(qualId);
+    }
+
+    @Override
+    public JCModuleId visitModuleId(ModuleIdTree node, P p) {
+        JCModuleId t = (JCModuleId) node;
+        JCTree qualId = copy(t.qualId, p);
+        Name version = t.version;
+        return M.at(t.pos).ModuleId(qualId, version);
+    }
+
+    @Override
+    public JCModuleQuery visitModuleQuery(ModuleQueryTree node, P p) {
+        JCModuleQuery t = (JCModuleQuery) node;
+        JCTree qualId = copy(t.qualId, p);
+        Name versionQuery = t.versionQuery;
+        return M.at(t.pos).ModuleQuery(qualId, versionQuery);
+    }
+
+    @Override
+    public JCPermitsDirective visitPermits(PermitsDirectiveTree node, P p) {
+        JCPermitsDirective t = (JCPermitsDirective) node;
+        JCExpression moduleName = copy(t.moduleName, p);
+        return M.at(t.pos).Permits(moduleName);
+    }
+
+    @Override
+    public JCProvidesModuleDirective visitProvidesModule(ProvidesModuleDirectiveTree node, P p) {
+        JCProvidesModuleDirective t = (JCProvidesModuleDirective) node;
+        JCModuleId moduleId = copy(t.moduleId, p);
+        return M.at(t.pos).ProvidesModule(moduleId);
+    }
+
+    @Override
+    public JCProvidesServiceDirective visitProvidesService(ProvidesServiceDirectiveTree node, P p) {
+        JCProvidesServiceDirective t = (JCProvidesServiceDirective) node;
+        JCExpression serviceName = copy(t.serviceName, p);
+        JCExpression implName = copy(t.implName, p);
+        return M.at(t.pos).ProvidesService(serviceName, implName);
+    }
+
+    @Override
+    public JCRequiresModuleDirective visitRequiresModule(RequiresModuleDirectiveTree node, P p) {
+        JCRequiresModuleDirective t = (JCRequiresModuleDirective) node;
+        List<RequiresFlag> flags = t.flags;
+        JCModuleQuery moduleQuery = copy(t.moduleQuery, p);
+        return M.at(t.pos).RequiresModule(flags, moduleQuery);
+    }
+
+    @Override
+    public JCRequiresServiceDirective visitRequiresService(RequiresServiceDirectiveTree node, P p) {
+        JCRequiresServiceDirective t = (JCRequiresServiceDirective) node;
+        List<RequiresFlag> flags = t.flags;
+        JCExpression serviceName = copy(t.serviceName, p);
+        return M.at(t.pos).RequiresService(flags, serviceName);
+    }
+
+    public JCTree visitPackage(PackageTree node, P p) {
+        JCPackageDecl t = (JCPackageDecl) node;
+        List<JCAnnotation> annots = copy(t.annots, p);
+        JCExpression packageId = copy(t.packageId);
+        return M.at(t.pos).Package(annots, packageId);
+    }
+
     public JCTree visitOther(Tree node, P p) {
         JCTree tree = (JCTree) node;
         switch (tree.getTag()) {
--- a/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Tue May 07 17:14:17 2013 -0700
@@ -35,6 +35,7 @@
 import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
+import javax.tools.JavaFileObject;
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.TypeTag.BOT;
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
@@ -470,6 +471,16 @@
                     return getStartPos(node.vartype);
                 }
             }
+        case PACKAGE: {
+            JCPackageDecl node = (JCPackageDecl)tree;
+            if (node.annots.nonEmpty())
+                return getStartPos(node.annots.head);
+            break;
+        }
+        case MODULE_ID: {
+            JCModuleId node = (JCModuleId)tree;
+            return getStartPos(node.qualId);
+        }
             case ERRONEOUS: {
                 JCErroneous node = (JCErroneous)tree;
                 if (node.errs != null && node.errs.nonEmpty())
@@ -620,26 +631,32 @@
     public static JCTree declarationFor(final Symbol sym, final JCTree tree) {
         class DeclScanner extends TreeScanner {
             JCTree result = null;
+            @Override
             public void scan(JCTree tree) {
                 if (tree!=null && result==null)
                     tree.accept(this);
             }
+            @Override
             public void visitTopLevel(JCCompilationUnit that) {
                 if (that.packge == sym) result = that;
                 else super.visitTopLevel(that);
             }
+            @Override
             public void visitClassDef(JCClassDecl that) {
                 if (that.sym == sym) result = that;
                 else super.visitClassDef(that);
             }
+            @Override
             public void visitMethodDef(JCMethodDecl that) {
                 if (that.sym == sym) result = that;
                 else super.visitMethodDef(that);
             }
+            @Override
             public void visitVarDef(JCVariableDecl that) {
                 if (that.sym == sym) result = that;
                 else super.visitVarDef(that);
             }
+            @Override
             public void visitTypeParameter(JCTypeParameter that) {
                 if (that.type != null && that.type.tsym == sym) result = that;
                 else super.visitTypeParameter(that);
@@ -669,6 +686,7 @@
         }
         class PathFinder extends TreeScanner {
             List<JCTree> path = List.nil();
+            @Override
             public void scan(JCTree tree) {
                 if (tree != null) {
                     path = path.prepend(tree);
@@ -1115,4 +1133,40 @@
         finder.scan(e);
         return finder.foundTypeAnno;
     }
+
+    public static boolean isModuleInfo(JCCompilationUnit tree) {
+        return tree.sourcefile.isNameCompatible("module-info", JavaFileObject.Kind.SOURCE);
+    }
+
+    public static JCModuleDecl getModule(JCCompilationUnit t) {
+        for (JCTree def: t.defs) {
+            switch (def.getTag()) {
+                case IMPORT:
+                    continue;
+                case MODULE:
+                    return (JCModuleDecl) def;
+                default:
+                    break;
+            }
+        }
+        return null;
+    }
+
+    public static boolean isPackageInfo(JCCompilationUnit tree) {
+        return tree.sourcefile.isNameCompatible("package-info", JavaFileObject.Kind.SOURCE);
+    }
+
+    public static JCPackageDecl getPackage(JCCompilationUnit t) {
+        for (JCTree def: t.defs) {
+            switch (def.getTag()) {
+                case IMPORT:
+                    continue;
+                case PACKAGE:
+                    return (JCPackageDecl) def;
+                default:
+                    break;
+            }
+        }
+        return null;
+    }
 }
--- a/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java	Tue May 07 17:14:17 2013 -0700
@@ -25,12 +25,13 @@
 
 package com.sun.tools.javac.tree;
 
+import com.sun.source.tree.RequiresFlag;
+
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.code.Type.*;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
-
 import com.sun.tools.javac.tree.JCTree.*;
 
 import static com.sun.tools.javac.code.Flags.*;
@@ -119,19 +120,18 @@
      * Create given tree node at current position.
      * @param defs a list of ClassDef, Import, and Skip
      */
-    public JCCompilationUnit TopLevel(List<JCAnnotation> packageAnnotations,
-                                      JCExpression pid,
-                                      List<JCTree> defs) {
-        Assert.checkNonNull(packageAnnotations);
+    public JCCompilationUnit TopLevel(List<JCTree> defs) {
         for (JCTree node : defs)
             Assert.check(node instanceof JCClassDecl
                 || node instanceof JCImport
+                || node instanceof JCPackageDecl
+                || node instanceof JCModuleDecl
                 || node instanceof JCSkip
                 || node instanceof JCErroneous
                 || (node instanceof JCExpressionStatement
                     && ((JCExpressionStatement)node).expr instanceof JCErroneous),
                 node.getClass().getSimpleName());
-        JCCompilationUnit tree = new JCCompilationUnit(packageAnnotations, pid, defs,
+        JCCompilationUnit tree = new JCCompilationUnit(defs,
                                      null, null, null, null);
         tree.pos = pos;
         return tree;
@@ -523,6 +523,91 @@
         return Modifiers(flags, List.<JCAnnotation>nil());
     }
 
+    @Override
+    public JCModuleDecl Module(JCModuleId moduleId,
+            List<JCModuleDirective> directives, Name metadata) {
+        JCModuleDecl tree = new JCModuleDecl(moduleId, directives, metadata);
+        tree.pos = pos;
+        return tree;
+    }
+
+    @Override
+    public JCViewDecl View(JCExpression name,
+            List<JCModuleDirective> directives) {
+        JCViewDecl tree = new JCViewDecl(name, directives);
+        tree.pos = pos;
+        return tree;
+    }
+
+    @Override
+    public JCEntrypointDirective Entrypoint(JCExpression qualId) {
+        JCEntrypointDirective tree = new JCEntrypointDirective(qualId);
+        tree.pos = pos;
+        return tree;
+    }
+
+    @Override
+    public JCExportDirective Exports(JCExpression qualId) {
+        JCExportDirective tree = new JCExportDirective(qualId);
+        tree.pos = pos;
+        return tree;
+    }
+
+    @Override
+    public JCModuleId ModuleId(JCTree qualId, Name version) {
+        JCModuleId tree = new JCModuleId(qualId, version);
+        tree.pos = pos;
+        return tree;
+    }
+
+    @Override
+    public JCModuleQuery ModuleQuery(JCTree qualId, Name versionQuery) {
+        JCModuleQuery tree = new JCModuleQuery(qualId, versionQuery);
+        tree.pos = pos;
+        return tree;
+    }
+
+    @Override
+    public JCPermitsDirective Permits(JCExpression qualId) {
+        JCPermitsDirective tree = new JCPermitsDirective(qualId);
+        tree.pos = pos;
+        return tree;
+    }
+
+    @Override
+    public JCProvidesModuleDirective ProvidesModule(JCModuleId moduleId) {
+        JCProvidesModuleDirective tree = new JCProvidesModuleDirective(moduleId);
+        tree.pos = pos;
+        return tree;
+    }
+
+    @Override
+    public JCProvidesServiceDirective ProvidesService(JCExpression service, JCExpression impl) {
+        JCProvidesServiceDirective tree = new JCProvidesServiceDirective(service, impl);
+        tree.pos = pos;
+        return tree;
+    }
+
+    @Override
+    public JCRequiresModuleDirective RequiresModule(List<RequiresFlag> flags, JCModuleQuery moduleQuery) {
+        JCRequiresModuleDirective tree = new JCRequiresModuleDirective(flags, moduleQuery);
+        tree.pos = pos;
+        return tree;
+    }
+
+    @Override
+    public JCRequiresServiceDirective RequiresService(List<RequiresFlag> flags, JCExpression serviceName) {
+        JCRequiresServiceDirective tree = new JCRequiresServiceDirective(flags, serviceName);
+        tree.pos = pos;
+        return tree;
+    }
+
+    public JCPackageDecl Package(List<JCAnnotation> annots, JCExpression packageId) {
+        JCPackageDecl tree = new JCPackageDecl(annots, packageId);
+        tree.pos = pos;
+        return tree;
+    }
+
     public JCAnnotatedType AnnotatedType(List<JCAnnotation> annotations, JCExpression underlyingType) {
         JCAnnotatedType tree = new JCAnnotatedType(annotations, underlyingType);
         tree.pos = pos;
--- a/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java	Tue May 07 17:14:17 2013 -0700
@@ -46,7 +46,8 @@
     /** Visitor method: Scan a single node.
      */
     public void scan(JCTree tree) {
-        if(tree!=null) tree.accept(this);
+        if (tree != null)
+            tree.accept(this);
     }
 
     /** Visitor method: scan a list of nodes.
@@ -62,12 +63,73 @@
  * Visitor methods
  ****************************************************************************/
 
+    @Override
     public void visitTopLevel(JCCompilationUnit tree) {
-        scan(tree.packageAnnotations);
-        scan(tree.pid);
         scan(tree.defs);
     }
 
+    @Override
+    public void visitModuleDef(JCModuleDecl tree) {
+        scan(tree.id);
+        scan(tree.directives);
+    }
+
+    @Override
+    public void visitModuleId(JCModuleId tree) {
+        scan(tree.qualId);
+    }
+
+    @Override
+    public void visitModuleQuery(JCModuleQuery tree) {
+        scan(tree.qualId);
+    }
+
+    @Override
+    public void visitEntrypoint(JCEntrypointDirective tree) {
+        scan(tree.qualId);
+    }
+
+    @Override
+    public void visitExports(JCExportDirective tree) {
+        scan(tree.qualid);
+    }
+
+    @Override
+    public void visitPermits(JCPermitsDirective tree) {
+        scan(tree.moduleName);
+    }
+
+    @Override
+    public void visitProvidesModule(JCProvidesModuleDirective tree) {
+        scan(tree.moduleId);
+    }
+
+    @Override
+    public void visitProvidesService(JCProvidesServiceDirective tree) {
+        scan(tree.serviceName);
+        scan(tree.implName);
+    }
+
+    @Override
+    public void visitRequiresModule(JCRequiresModuleDirective tree) {
+        scan(tree.moduleQuery);
+    }
+
+    @Override
+    public void visitRequiresService(JCRequiresServiceDirective tree) {
+        scan(tree.serviceName);
+    }
+
+    @Override
+    public void visitView(JCViewDecl tree) {
+        scan(tree.directives);
+    }
+
+    public void visitPackageDef(JCPackageDecl tree) {
+        scan(tree.annots);
+        scan(tree.packageId);
+    }
+
     public void visitImport(JCImport tree) {
         scan(tree.qualid);
     }
--- a/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java	Tue May 07 17:14:17 2013 -0700
@@ -116,11 +116,15 @@
  ****************************************************************************/
 
     public void visitTopLevel(JCCompilationUnit tree) {
-        tree.pid = translate(tree.pid);
         tree.defs = translate(tree.defs);
         result = tree;
     }
 
+    public void visitPackageDef(JCPackageDecl tree) {
+        tree.packageId = translate(tree.packageId);
+        result = tree;
+    }
+
     public void visitImport(JCImport tree) {
         tree.qualid = translate(tree.qualid);
         result = tree;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/javac/util/Debug.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2010, 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.javac.util;
+
+import java.io.PrintWriter;
+import java.util.HashSet;
+import java.util.Set;
+
+public class Debug {
+    static final boolean ALLOW_OPTION = true;
+    static final boolean ALLOW_SYSPROP = true;
+    static final boolean ALLOW_ENVVAR = true;
+
+    public final PrintWriter out;
+    Set<String> opts;
+
+    public Debug(String name, Options options, Log log) {
+        this(name, options, log.noticeWriter);
+    }
+
+    public Debug(String name, Options options, PrintWriter out) {
+        if (out == null) out = new PrintWriter(System.err);
+        this.out = new DebugPrinter(name, out);
+
+        if (ALLOW_OPTION && options != null) {
+            String v = options.get(name + ".debug");
+            if (v != null)
+                setOpts("all");
+            String prefix = name + ".debug:";
+            for (String k: options.keySet()) {
+                if (k.startsWith(prefix))
+                    setOpts(k.substring(prefix.length()));
+            }
+        }
+
+        try {
+            if (opts == null && ALLOW_SYSPROP)
+                setOpts(System.getProperty("javac." + name + ".debug"));
+        } catch (SecurityException e) {
+            // ignore
+        }
+
+        try {
+            if (opts == null && ALLOW_ENVVAR)
+                setOpts(System.getenv("_JAVAC_" + name.toUpperCase() + "_DEBUG"));
+        } catch (SecurityException e) {
+            // ignore
+        }
+    }
+
+    public boolean isEnabled() {
+        return (opts != null);
+    }
+
+    public boolean isEnabled(String opt) {
+        if (opts == null)
+            return false;
+
+        return opts.contains(opt) ||
+                (opts.contains("all") && !opts.contains("-" + opt));
+    }
+
+    public void print(Object o) {
+        out.print(o);
+    }
+
+    public void print(String s) {
+        out.print(s);
+    }
+
+    public void println(Object o) {
+        out.println(o);
+        out.flush();
+    }
+
+    public void println(String s) {
+        out.println(s);
+        out.flush();
+    }
+
+    public void println() {
+        out.println();
+        out.flush();
+    }
+
+    void setOpts(String list) {
+        if (list == null)
+            return;
+        if (list.equals("true")) // common value for sys props and env vars
+            list = "all";
+        for (String opt: list.split("[\\s,]+")) {
+            if (opt.isEmpty())
+                continue;
+            if (opts == null)
+                opts = new HashSet<String>();
+            opts.add(opt);
+        }
+    }
+
+    static class DebugPrinter extends PrintWriter {
+        final String name;
+        boolean needLinePrefix = true;
+
+        DebugPrinter(String name, PrintWriter out) {
+            super(out);
+            this.name = name;
+        }
+
+        @Override
+        public void write(int c) {
+            checkLinePrefix();
+            super.write(c);
+        }
+
+        @Override
+        public void write(String s, int off, int len) {
+            if (len > 0) {
+                checkLinePrefix();
+                super.write(s, off, len);
+            }
+        }
+
+        @Override
+        public void println() {
+            super.println();
+            needLinePrefix = true;
+        }
+
+        private void checkLinePrefix() {
+            if (needLinePrefix) {
+                needLinePrefix = false;
+                write("[" + name + "] ");
+            }
+        }
+    }
+}
--- a/src/share/classes/com/sun/tools/javac/util/Names.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/util/Names.java	Tue May 07 17:14:17 2013 -0700
@@ -50,6 +50,7 @@
     // operators and punctuation
     public final Name asterisk;
     public final Name comma;
+    public final Name double_asterisk;
     public final Name empty;
     public final Name hyphen;
     public final Name one;
@@ -61,8 +62,20 @@
     // keywords
     public final Name _class;
     public final Name _default;
+    public final Name _public;
     public final Name _super;
     public final Name _this;
+    public final Name exports;
+    public final Name local;
+    public final Name main;
+    public final Name module;
+    public final Name optional;
+    public final Name permits;
+    public final Name provides;
+    public final Name requires;
+    public final Name service;
+    public final Name view;
+    public final Name with;
 
     // field and method names
     public final Name _name;
@@ -116,6 +129,10 @@
     // package names
     public final Name java_lang;
 
+    // module names
+    public final Name java_base;
+    public final Name jdk_legacy;
+
     // attribute names
     public final Name Annotation;
     public final Name AnnotationDefault;
@@ -134,6 +151,10 @@
     public final Name LocalVariableTable;
     public final Name LocalVariableTypeTable;
     public final Name MethodParameters;
+    public final Name Module;
+    public final Name ModuleData;
+    public final Name ModuleProvides;
+    public final Name ModuleRequires;
     public final Name RuntimeInvisibleAnnotations;
     public final Name RuntimeInvisibleParameterAnnotations;
     public final Name RuntimeInvisibleTypeAnnotations;
@@ -170,6 +191,7 @@
     public final Name T;
     public final Name deprecated;
     public final Name ex;
+    public final Name module_info;
     public final Name package_info;
 
     //lambda-related
@@ -186,6 +208,7 @@
         // operators and punctuation
         asterisk = fromString("*");
         comma = fromString(",");
+        double_asterisk = fromString("**");
         empty = fromString("");
         hyphen = fromString("-");
         one = fromString("1");
@@ -197,8 +220,20 @@
         // keywords
         _class = fromString("class");
         _default = fromString("default");
+        _public = fromString("public");
         _super = fromString("super");
         _this = fromString("this");
+        exports = fromString("exports");
+        local = fromString("local");
+        main = fromString("main");
+        module = fromString("module");
+        optional = fromString("optional");
+        permits = fromString("permits");
+        provides = fromString("provides");
+        requires = fromString("requires");
+        service = fromString("service");
+        view = fromString("view");
+        with = fromString("with");
 
         // field and method names
         _name = fromString("name");
@@ -252,6 +287,10 @@
         // package names
         java_lang = fromString("java.lang");
 
+        // module names
+        java_base = fromString("java.base");
+        jdk_legacy = fromString("jdk");       // FIXME: update when alias support working
+
         // attribute names
         Annotation = fromString("Annotation");
         AnnotationDefault = fromString("AnnotationDefault");
@@ -270,6 +309,10 @@
         LocalVariableTable = fromString("LocalVariableTable");
         LocalVariableTypeTable = fromString("LocalVariableTypeTable");
         MethodParameters = fromString("MethodParameters");
+        Module = fromString("Module");
+        ModuleData = fromString("ModuleData");
+        ModuleProvides = fromString("ModuleProvides");
+        ModuleRequires = fromString("ModuleRequires");
         RuntimeInvisibleAnnotations = fromString("RuntimeInvisibleAnnotations");
         RuntimeInvisibleParameterAnnotations = fromString("RuntimeInvisibleParameterAnnotations");
         RuntimeInvisibleTypeAnnotations = fromString("RuntimeInvisibleTypeAnnotations");
@@ -306,6 +349,7 @@
         T = fromString("T");
         deprecated = fromString("deprecated");
         ex = fromString("ex");
+        module_info = fromString("module-info");
         package_info = fromString("package-info");
 
         //lambda-related
--- a/src/share/classes/com/sun/tools/javadoc/JavadocTool.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javadoc/JavadocTool.java	Tue May 07 17:14:17 2013 -0700
@@ -134,7 +134,7 @@
         docenv.setEncoding(encoding);
         docenv.docClasses = docClasses;
         docenv.legacyDoclet = legacyDoclet;
-        javadocReader.sourceCompleter = docClasses ? null : this;
+        javadocReader.sourceCompleter = docClasses ? null : new Completer();
 
         ListBuffer<String> names = new ListBuffer<String>();
         ListBuffer<JCCompilationUnit> classTrees = new ListBuffer<JCCompilationUnit>();
--- a/src/share/classes/com/sun/tools/javap/AttributeWriter.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javap/AttributeWriter.java	Tue May 07 17:14:17 2013 -0700
@@ -47,6 +47,10 @@
 import com.sun.tools.classfile.LocalVariableTable_attribute;
 import com.sun.tools.classfile.LocalVariableTypeTable_attribute;
 import com.sun.tools.classfile.MethodParameters_attribute;
+import com.sun.tools.classfile.ModuleData_attribute;
+import com.sun.tools.classfile.ModuleProvides_attribute;
+import com.sun.tools.classfile.ModuleRequires_attribute;
+import com.sun.tools.classfile.Module_attribute;
 import com.sun.tools.classfile.RuntimeInvisibleAnnotations_attribute;
 import com.sun.tools.classfile.RuntimeInvisibleParameterAnnotations_attribute;
 import com.sun.tools.classfile.RuntimeInvisibleTypeAnnotations_attribute;
@@ -389,6 +393,109 @@
         return null;
     }
 
+    public Void visitModule(Module_attribute attr, Void ignore) {
+        println("Module: " + constantWriter.stringValue(attr.module_id_index));
+        return null;
+    }
+
+    String getModuleName(Module_attribute attr) {
+        try {
+            return attr.getModuleName(constant_pool);
+        } catch (ConstantPoolException e) {
+            return report(e);
+        }
+    }
+
+    public Void visitModuleData(ModuleData_attribute attr, Void ignore) {
+        println("ModuleData: ");
+        indent(+1);
+        println("#" + attr.data_index
+                + "\t// " + constantWriter.stringValue(attr.data_index));
+        indent(-1);
+        return null;
+    }
+
+    public Void visitModuleProvides(ModuleProvides_attribute attr, Void ignore) {
+        println("ModuleProvides: ");
+        indent(+1);
+        for (int i = 0; i < attr.view_table.length; i++) {
+            println("View " + i);
+            indent(+1);
+            ModuleProvides_attribute.View v = attr.view_table[i];
+            String view_name = (v.view_name_index == 0)
+                    ? "(default)" : constantWriter.stringValue(v.view_name_index);
+            println("#" + v.view_name_index + "\t// view " + view_name);
+            String entrypoint_name = (v.entrypoint_index == 0)
+                    ? "(none)" : constantWriter.stringValue(v.entrypoint_index);
+            println("#" + v.entrypoint_index + "\t// class " + entrypoint_name);
+            println(v.alias_length + "\t// aliases ");
+            indent(+1);
+            for (int ai = 0; ai < v.alias_length; ai++) {
+                int a = v.alias_table[ai];
+                println(a + "\t// provides " + constantWriter.stringValue(a));
+            }
+            indent(-1);
+            println(v.service_length + "\t// services ");
+            indent(+1);
+            for (int si = 0; si < v.service_length; si++) {
+                ModuleProvides_attribute.Service s = v.service_table[si];
+                println("#" + s.service_index + ", " + "#" + s.impl_index
+                        +"\t// provides service " + constantWriter.stringValue(s.service_index)
+                        + " with " + constantWriter.stringValue(s.impl_index));
+            }
+            indent(-1);
+            println(v.export_length + "\t// exports ");
+            indent(+1);
+            for (int ei = 0; ei < v.export_length; ei++) {
+                int e = v.export_table[ei];
+                println("#" + e + "\t// exports " + constantWriter.stringValue(e));
+            }
+            indent(-1);
+            println(v.permit_length + "\t// permits ");
+            indent(+1);
+            for (int pi = 0; pi < v.permit_length; pi++) {
+                int p = v.permit_table[pi];
+                println("#" + p +"\t// permits " + constantWriter.stringValue(p));
+            }
+            indent(-1); // end of permits
+            indent(-1); // end of ModuleProvides
+        }
+        indent(-1);
+        return null;
+    }
+
+    public Void visitModuleRequires(ModuleRequires_attribute attr, Void ignore) {
+        println("ModuleRequires: ");
+        indent(+1);
+        writeRequiresTable(attr.module_table, false);
+        writeRequiresTable(attr.service_table, true);
+        indent(-1);
+        return null;
+    }
+
+    protected void writeRequiresTable(ModuleRequires_attribute.Entry[] entries,
+            boolean service) {
+        println(entries.length + "\t// " + (service ? "services" : "modules"));
+        indent(+1);
+        for (ModuleRequires_attribute.Entry e: entries) {
+            print("#" + e.index + "," + String.format("%x", e.flags)+ "\t// requires");
+            if ((e.flags & ModuleRequires_attribute.ACC_OPTIONAL) != 0)
+                print(" optional");
+            if ((e.flags & ModuleRequires_attribute.ACC_LOCAL) != 0)
+                print(" local");
+            if ((e.flags & ModuleRequires_attribute.ACC_REEXPORT) != 0)
+                print(" public");
+            if ((e.flags & ModuleRequires_attribute.ACC_SYNTHETIC) != 0)
+                print(" synthetic");
+            if ((e.flags & ModuleRequires_attribute.ACC_SYNTHESIZED) != 0)
+                print(" synthesized");
+            if (service)
+                print(" service");
+            println(" " + constantWriter.stringValue(e.index));
+        }
+        indent(-1);
+    }
+
     private static final String format = "%-31s%s";
 
     public Void visitMethodParameters(MethodParameters_attribute attr,
--- a/src/share/classes/com/sun/tools/javap/ClassWriter.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javap/ClassWriter.java	Tue May 07 17:14:17 2013 -0700
@@ -202,13 +202,16 @@
         if (options.verbose) {
             println();
             indent(+1);
-            attrWriter.write(cf, cf.attributes, constant_pool);
+            if (options.compat)
+                attrWriter.write(cf, cf.attributes, constant_pool);
             println("minor version: " + cf.minor_version);
             println("major version: " + cf.major_version);
             if (!options.compat)
               writeList("flags: ", flags.getClassFlags(), "\n");
             indent(-1);
             constantWriter.writeConstantPool();
+            if (!options.compat)
+                attrWriter.write(cf, cf.attributes, constant_pool);
         } else {
             print(" ");
         }
--- a/src/share/classes/com/sun/tools/javap/ConstantWriter.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javap/ConstantWriter.java	Tue May 07 17:14:17 2013 -0700
@@ -51,7 +51,6 @@
         super(context);
         context.put(ConstantWriter.class, this);
         classWriter = ClassWriter.instance(context);
-        options = Options.instance(context);
     }
 
     protected void writeConstantPool() {
@@ -109,6 +108,20 @@
                 return 2;
             }
 
+            public Integer visitModuleId(CONSTANT_ModuleId_info info, Void p) {
+                print("#" + info.name_index + ":#" + info.version_index);
+                tab();
+                println("//  " + stringValue(info));
+                return 1;
+            }
+
+            public Integer visitModuleQuery(CONSTANT_ModuleQuery_info info, Void p) {
+                print("#" + info.name_index + ":#" + info.version_index);
+                tab();
+                println("//  " + stringValue(info));
+                return 1;
+            }
+
             public Integer visitNameAndType(CONSTANT_NameAndType_info info, Void p) {
                 print("#" + info.name_index + ":#" + info.type_index);
                 tab();
@@ -234,6 +247,8 @@
                 return "InvokeDynamic";
             case CONSTANT_NameAndType:
                 return "NameAndType";
+            case CONSTANT_ModuleId:
+                return "ModuleId";
             default:
                 return "(unknown tag " + tag + ")";
         }
@@ -248,6 +263,16 @@
         }
     }
 
+    String stringValues(int[] constant_pool_indices, String sep) {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < constant_pool_indices.length; i++) {
+            if (i > 0)
+                sb.append(sep);
+            sb.append(stringValue(constant_pool_indices[i]));
+        }
+        return sb.toString();
+    }
+
     String stringValue(CPInfo cpInfo) {
         return stringValueVisitor.visit(cpInfo);
     }
@@ -304,6 +329,52 @@
             return info.value + "l";
         }
 
+        public String visitModuleId(CONSTANT_ModuleId_info info, Void p) {
+            if (info.version_index == 0)
+                return getCheckedName(info);
+            else
+                return getCheckedName(info) + "@" + getCheckedVersion(info);
+        }
+
+        String getCheckedName(CONSTANT_ModuleId_info info) {
+            try {
+                return checkName(info.getName());
+            } catch (ConstantPoolException e) {
+                return report(e);
+            }
+        }
+
+        String getCheckedVersion(CONSTANT_ModuleId_info info) {
+            try {
+                return info.getVersion();
+            } catch (ConstantPoolException e) {
+                return report(e);
+            }
+        }
+
+        public String visitModuleQuery(CONSTANT_ModuleQuery_info info, Void p) {
+            if (info.version_index == 0)
+                return getCheckedName(info);
+            else
+                return getCheckedName(info) + "@" + getCheckedVersion(info);
+        }
+
+        String getCheckedName(CONSTANT_ModuleQuery_info info) {
+            try {
+                return checkName(info.getName());
+            } catch (ConstantPoolException e) {
+                return report(e);
+            }
+        }
+
+        String getCheckedVersion(CONSTANT_ModuleQuery_info info) {
+            try {
+                return info.getVersion();
+            } catch (ConstantPoolException e) {
+                return report(e);
+            }
+        }
+
         public String visitNameAndType(CONSTANT_NameAndType_info info, Void p) {
             return getCheckedName(info) + ":" + getType(info);
         }
@@ -450,5 +521,4 @@
     }
 
     private ClassWriter classWriter;
-    private Options options;
 }
--- a/src/share/classes/com/sun/tools/javap/JavapTask.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javap/JavapTask.java	Tue May 07 17:14:17 2013 -0700
@@ -444,7 +444,7 @@
             handleOptions(args);
 
             // the following gives consistent behavior with javac
-            if (classes == null || classes.size() == 0) {
+            if (classes == null || classes.isEmpty()) {
                 if (options.help || options.version || options.fullVersion)
                     return EXIT_OK;
                 else
@@ -531,7 +531,7 @@
             throw new BadArgs("err.incompatible.options", sb);
         }
 
-        if ((classes == null || classes.size() == 0) &&
+        if ((classes == null || classes.isEmpty()) &&
                 !(noArgs || options.help || options.version || options.fullVersion)) {
             throw new BadArgs("err.no.classes.specified");
         }
@@ -573,7 +573,7 @@
     }
 
     public boolean run() {
-        if (classes == null || classes.size() == 0)
+        if (classes == null || classes.isEmpty())
             return false;
 
         context.put(PrintWriter.class, log);
--- a/src/share/classes/com/sun/tools/javap/resources/javap.properties	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/com/sun/tools/javap/resources/javap.properties	Tue May 07 17:14:17 2013 -0700
@@ -1,5 +1,5 @@
 
-err.prefix=Error: 
+err.prefix=Error:
 
 err.bad.constant.pool=error while reading constant pool for {0}: {1}
 err.class.not.found=class not found: {0}
--- a/src/share/classes/javax/lang/model/element/Modifier.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/javax/lang/model/element/Modifier.java	Tue May 07 17:14:17 2013 -0700
@@ -64,7 +64,8 @@
     /** The modifier {@code volatile} */        VOLATILE,
     /** The modifier {@code synchronized} */    SYNCHRONIZED,
     /** The modifier {@code native} */          NATIVE,
-    /** The modifier {@code strictfp} */        STRICTFP;
+    /** The modifier {@code strictfp} */        STRICTFP,
+    /** The modifier {@code module} */          MODULE;
 
     /**
      * Returns this modifier's name in lowercase.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/javax/lang/model/element/ModuleElement.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javax.lang.model.element;
+
+/** Interim API. */
+public interface ModuleElement extends Element {
+
+    // consider using java.lang.module.ModuleId
+    interface ModuleId {
+        CharSequence getName();
+        CharSequence getVersion();
+    }
+
+    // consider using java.lang.module.ModuleIdQuery
+    interface ModuleQuery {
+        CharSequence getName();
+        CharSequence getVersionQuery();
+    }
+
+    ModuleId getModuleId();
+
+}
--- a/src/share/classes/javax/lang/model/type/TypeKind.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/javax/lang/model/type/TypeKind.java	Tue May 07 17:14:17 2013 -0700
@@ -134,6 +134,12 @@
     EXECUTABLE,
 
     /**
+     * A pseudo-type corresponding to a module element.
+     * @see NoType
+     */
+    MODULE,
+
+    /**
      * An implementation-reserved type.
      * This is not the type you are looking for.
      */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/javax/tools/ExtendedLocation.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2009, 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 javax.tools;
+
+import java.io.IOException;
+import java.util.Set;
+
+/**
+ * A location that can list its contents.
+ * @author jjg
+ */
+public interface ExtendedLocation extends JavaFileManager.Location {
+
+
+    /**
+     * List the contents of this location.
+     * @param packageName  a package name
+     * @param kinds        return objects only of these kinds
+     * @param recurse      if true include "subpackages"
+     * @return an Iterable of file objects matching the given criteria
+     * @throws IOException if an I/O error occurred
+     * @see JavaFileManager#list
+     */
+    Iterable<JavaFileObject> list(String packageName,
+                                  Set<JavaFileObject.Kind> kinds,
+                                  boolean recurse)
+        throws IOException;
+
+    /**
+     * Infers a binary name of a file object returned from this location.
+     *
+     * @param file a file object
+     * @return a binary name or {@code null} if the file object is not
+     * found in this location
+     * @see JavaFileManager#inferBinaryName
+     */
+    String inferBinaryName(JavaFileObject file);
+}
--- a/src/share/classes/javax/tools/FileObject.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/javax/tools/FileObject.java	Tue May 07 17:14:17 2013 -0700
@@ -32,6 +32,8 @@
 import java.io.Writer;
 import java.net.URI;
 
+import javax.tools.JavaFileManager.Location;
+
 /**
  * File abstraction for tools.  In this context, <em>file</em> means
  * an abstraction of regular files and other sources of data.  For
@@ -49,6 +51,12 @@
  * @since 1.6
  */
 public interface FileObject {
+    /**
+     * Interface to be provided by file objects that can return their location.
+     */
+    interface Locatable {
+        Location getLocation();
+    }
 
     /**
      * Returns a URI identifying this file object.
--- a/src/share/classes/javax/tools/JavaFileManager.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/javax/tools/JavaFileManager.java	Tue May 07 17:14:17 2013 -0700
@@ -177,7 +177,7 @@
      *
      * @param location a location
      * @param file a file object
-     * @return a binary name or {@code null} the file object is not
+     * @return a binary name or {@code null} if the file object is not
      * found in the given location
      * @throws IllegalStateException if {@link #close} has been called
      * and this file manager cannot be reopened
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/javax/tools/ModuleFileManager.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2009, 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 javax.tools;
+
+public interface ModuleFileManager extends JavaFileManager {
+    class InvalidLocationException extends IllegalArgumentException {
+        private static final long serialVersionUID = 2115919242510692026L;
+    }
+
+    class InvalidFileObjectException extends IllegalArgumentException {
+        private static final long serialVersionUID = 1234906668846471087L;
+    }
+
+    enum ModuleMode { SINGLE, MULTIPLE };
+
+    /**
+     * Determine if the file manager is running in "single module mode"
+     * or "multiple module mode". This affects how files are written to
+     * the class output directory.
+     * Multiple module mode is active if a module path has been set,
+     * but not a class path.
+     */
+    ModuleMode getModuleMode();
+
+    /**
+     * Get a location representing the "container" for a file object
+     * for a compilation unit in a given package.
+     */
+    Location getModuleLocation(Location location, JavaFileObject fo, String packageName)
+            throws IllegalArgumentException;
+
+    /**
+     * Get the set of "module locations" available on a "module path",
+     * where each "module location" is determined by the existence of
+     * a subdirectory on the path containing a module-info file.
+     */
+    Iterable<? extends Location> getModuleLocations(Location location);
+
+    /**
+     * Join a set of locations into a "search path".
+     */
+    Location join(Iterable<? extends Location> locations);
+}
--- a/src/share/classes/javax/tools/StandardLocation.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/src/share/classes/javax/tools/StandardLocation.java	Tue May 07 17:14:17 2013 -0700
@@ -72,7 +72,12 @@
      * Location of new native header files.
      * @since 1.8
      */
-    NATIVE_HEADER_OUTPUT;
+    NATIVE_HEADER_OUTPUT,
+
+    /**
+     * Location to search for existing module class files.
+     */
+    MODULE_PATH;
 
     /**
      * Gets a location object with the given name.  The following
--- a/test/Makefile	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/Makefile	Tue May 07 17:14:17 2013 -0700
@@ -225,6 +225,17 @@
 JCK_COMPILER_OUTPUT_DIR = $(ABS_TEST_OUTPUT_DIR)/jck-compiler
 JCK_RUNTIME_OUTPUT_DIR = $(ABS_TEST_OUTPUT_DIR)/jck-runtime-Xcompile
 
+PROBLEM_LISTS=ModulesProblemList.txt
+EXCLUDELIST=$(ABS_TEST_OUTPUT_DIR)/excludelist.txt
+
+ifdef NO_EXCLUDES
+$(EXCLUDELIST): $(PROBLEM_LISTS)
+	@echo "NOTHING_EXCLUDED" > $@
+else
+$(EXCLUDELIST): $(PROBLEM_LISTS)
+	@cat $(PROBLEM_LISTS) > $@
+endif
+
 # Default make rule -- warning, may take a while
 all: $(JPRT_CLEAN) jtreg-tests jck-compiler-tests jck-runtime-tests $(JPRT_ARCHIVE_BUNDLE) all-summary
 	@echo "Testing completed successfully"
@@ -266,7 +277,7 @@
 #	(Optional) reference results (e.g. work, report or summary.txt)
 #
 jtreg_tests: jtreg-tests
-jtreg-tests: check-jtreg FRC
+jtreg-tests: check-jtreg $(EXCLUDELIST) FRC
 	@rm -f -r $(JTREG_OUTPUT_DIR)/JTwork $(JTREG_OUTPUT_DIR)/JTreport \
 	    $(JTREG_OUTPUT_DIR)/diff.html $(JTREG_OUTPUT_DIR)/status.txt
 	@mkdir -p $(JTREG_OUTPUT_DIR)
@@ -277,6 +288,7 @@
           -r:$(JTREG_OUTPUT_DIR)/JTreport \
           -w:$(JTREG_OUTPUT_DIR)/JTwork \
           -jdk:$(TESTJAVA) \
+	  -exclude:$(EXCLUDELIST) \
           $(JAVA_ARGS:%=-vmoption:%) \
 	  $(JTREG_OPTIONS) \
           $(JTREG_TESTDIRS) \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/ModulesProblemList.txt	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,135 @@
+###########################################################################
+#
+# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+############################################################################
+# jigsaw legacy image
+tools/javac/6302184/T6302184.sh				generic-all
+
+# AsssertionError - package-info.class not found
+tools/javac/TestPkgInfo.java				generic-all
+
+# new module-compilation-related message keys are not in the resource bundle
+tools/javac/diags/CheckExamples.java			generic-all
+tools/javac/diags/CheckResourceKeys.java		generic-all
+tools/javac/diags/MessageInfo.java			generic-all
+
+# wrong size found: 8340; expected: 6655
+tools/javac/nio/compileTest/CompileTest.java		generic-all
+
+# AssertionError - unexpected empty block found
+tools/javac/parser/ExtraSemiTest.java			generic-all
+
+# Failures in jdk-module-image
+
+# rt.jar not found
+tools/javadoc/6942366/T6942366.java			generic-all
+
+# error - Locale not available: ja
+com/sun/javadoc/testHtmlTag/TestHtmlTag.java		generic-all
+
+# bootclasspath and module content (classes)
+tools/javac/api/T6430241.java				generic-all
+tools/javac/Paths/Diagnostics.sh			generic-all
+
+# sun.misc.Lock is in compat module
+tools/javac/warnings/6594914/T6594914b.java		generic-all
+
+############################################################################
+# Following test failures need further investigation
+
+# Tests timeout
+
+tools/javac/T7093325.java                                           generic-all
+tools/javac/TryWithResources/InterruptedExceptionTest.java          generic-all
+tools/javac/api/TestContainTypes.java                               generic-all
+tools/javac/failover/CheckAttributedTree.java                       generic-all
+tools/javac/generics/diamond/7030150/GenericConstructorAndDiamondTest.java   generic-all
+tools/javac/generics/diamond/7046778/DiamondAndInnerClassTest.java           generic-all
+tools/javac/generics/inference/7086601/T7086601b.java                        generic-all
+tools/javac/generics/rawOverride/7062745/GenericOverrideTest.java            generic-all
+tools/javac/multicatch/7030606/DisjunctiveTypeWellFormednessTest.java        generic-all
+tools/javac/processing/TestWarnErrorCount.java               generic-all
+tools/javac/varargs/6199075/T6199075.java                    generic-all
+tools/javac/varargs/7042566/T7042566.java                    generic-all
+tools/javac/varargs/warning/Warn4.java                       generic-all
+tools/javac/varargs/warning/Warn5.java                       generic-all
+tools/javac/versions/check.sh                                generic-all
+
+############################################################################
+
+# Need to investigate what javac needs to do for classpath mode
+
+com/sun/javadoc/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java generic-all
+com/sun/javadoc/testPackageDeprecation/TestPackageDeprecation.java generic-all
+tools/javac/4846262/Test.sh                                  generic-all
+tools/javac/6589361/T6589361.java                            generic-all
+tools/javac/EarlyAssert.java                                 generic-all
+tools/javac/Paths/MineField.sh                               generic-all
+tools/javac/T6351767.java                                    generic-all
+tools/javac/T6705935.java                                    generic-all
+tools/javac/T6725036.java                                    generic-all
+tools/javac/T6993301.java                                    generic-all
+tools/javac/annotations/TestAnnotationPackageInfo.java       generic-all
+tools/javac/api/6411310/T6411310.java                        generic-all
+tools/javac/api/6411333/T6411333.java                        generic-all
+tools/javac/api/6431257/T6431257.java                        generic-all
+tools/javac/api/6437349/T6437349.java                        generic-all
+tools/javac/api/6598108/T6598108.java                        generic-all
+tools/javac/api/6608214/T6608214.java                        generic-all
+tools/javac/api/TestClientCodeWrapper.java                   generic-all
+tools/javac/api/TestEvalExpression.java                      generic-all
+tools/javac/api/guide/Test.java                              generic-all
+tools/javac/modules/RequiresModuleTest02.java                generic-all
+tools/javac/parser/JavacParserTest.java                      generic-all
+tools/javac/processing/6348193/T6348193.java                 generic-all
+tools/javac/processing/6378728/T6378728.java                 generic-all
+tools/javac/processing/T6920317.java                         generic-all
+tools/javac/processing/errors/TestReturnCode.java            generic-all
+tools/javac/processing/messager/MessagerDiags.java           generic-all
+tools/javac/processing/model/TestSymtabItems.java            generic-all
+tools/javac/processing/model/testgetallmembers/Main.java     generic-all
+tools/javac/tree/DocCommentToplevelTest.java                 generic-all
+tools/javac/tree/MakeLiteralTest.java                        generic-all
+tools/javac/tree/TreeKindTest.java                           generic-all
+tools/javac/tree/TreePosTest.java                            generic-all
+tools/javac/types/BoxingConversionTest.java                  generic-all
+tools/javac/types/CastTest.java                              generic-all
+tools/javac/types/GenericTypeWellFormednessTest.java         generic-all
+tools/javac/types/PrimitiveConversionTest.java               generic-all
+tools/javadoc/6227454/Test.java                              generic-all
+tools/javadoc/6964914/Test.java                              generic-all
+tools/javadoc/6964914/TestStdDoclet.java                     generic-all
+tools/javadoc/6964914/TestUserDoclet.java                    generic-all
+tools/javadoc/annotations/annotatePackage/Main.java          generic-all
+tools/javah/T6893943.java                                    generic-all
+tools/javap/6937244/T6937244.java                            generic-all
+tools/javap/T4880672.java                                    generic-all
+tools/javap/T4884240.java                                    generic-all
+tools/javap/T4975569.java                                    generic-all
+tools/javap/T6729471.java                                    generic-all
+tools/javap/T6863746.java                                    generic-all
+tools/javap/T6866657.java                                    generic-all
+tools/javap/T6980017.java                                    generic-all
--- a/test/TEST.ROOT	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/TEST.ROOT	Tue May 07 17:14:17 2013 -0700
@@ -3,4 +3,4 @@
 # DO NOT EDIT without first contacting jdk-regtest@sun.com.
 
 # The list of keywords supported in the entire test suite
-keys=2d dnd i18n
+keys=jigsaw
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/4846262/Test.sh	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,81 @@
+#!/bin/sh -f
+
+#
+# Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# 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.
+#
+
+#
+# @test
+# @bug 4846262
+# @summary check that javac operates correctly in EBCDIC locale
+
+set -x
+
+if [ "${TESTSRC}" = "" ]
+then
+  echo "TESTSRC not set.  Test cannot execute.  Failed."
+  exit 1
+fi
+echo "TESTSRC=${TESTSRC}"
+if [ "${TESTJAVA}" = "" ]
+then
+  echo "TESTJAVA not set.  Test cannot execute.  Failed."
+  exit 1
+fi
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+  SunOS | Linux | Darwin )
+    FS="/"
+    ;;
+  CYGWIN* )
+    FS="/"
+    DIFFOPTS="--strip-trailing-cr"
+    ;;
+  Windows* )
+    FS="\\"
+    ;;
+  * )
+    echo "Unrecognized system!"
+    exit 1;
+    ;;
+esac
+
+rm -f Test.java Test.out
+
+"${TESTJAVA}${FS}bin${FS}native2ascii" ${TESTTOOLVMOPTS} -reverse -encoding IBM1047 ${TESTSRC}${FS}Test.java Test.java
+
+"${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -J-Duser.language=en -J-Duser.region=US -J-Dfile.encoding=IBM1047 Test.java 2>Test.tmp
+
+"${TESTJAVA}${FS}bin${FS}native2ascii" ${TESTTOOLVMOPTS} -encoding IBM1047 Test.tmp Test.out
+
+diff ${DIFFOPTS} -c "${TESTSRC}${FS}Test.out" Test.out
+result=$?
+
+if [ $result -eq 0 ]
+then
+  echo "Passed"
+else
+  echo "Failed"
+fi
+exit $result
--- a/test/tools/javac/4880220/T4880220.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javac/4880220/T4880220.java	Tue May 07 17:14:17 2013 -0700
@@ -3,11 +3,11 @@
  * @bug 4880220
  * @summary Add a warning when accessing a static method via an reference
  *
- * @compile/ref=T4880220.empty.out                                                   T4880220.java
- * @compile/ref=T4880220.warn.out       -XDrawDiagnostics         -Xlint:static      T4880220.java
- * @compile/ref=T4880220.warn.out       -XDrawDiagnostics         -Xlint:all         T4880220.java
- * @compile/ref=T4880220.empty.out      -XDrawDiagnostics         -Xlint:all,-static T4880220.java
- * @compile/ref=T4880220.error.out/fail -XDrawDiagnostics -Werror -Xlint:all         T4880220.java
+ * @compile/ref=T4880220.empty.out                                                         T4880220.java
+ * @compile/ref=T4880220.warn.out       -XDrawDiagnostics         -Xlint:static            T4880220.java
+ * @compile/ref=T4880220.warn.out       -XDrawDiagnostics         -Xlint:all,-path         T4880220.java
+ * @compile/ref=T4880220.empty.out      -XDrawDiagnostics         -Xlint:all,-path,-static T4880220.java
+ * @compile/ref=T4880220.error.out/fail -XDrawDiagnostics -Werror -Xlint:all,-path         T4880220.java
  */
 
 public class T4880220 {
--- a/test/tools/javac/6508981/TestInferBinaryName.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javac/6508981/TestInferBinaryName.java	Tue May 07 17:14:17 2013 -0700
@@ -32,6 +32,8 @@
 
 import java.io.*;
 import java.util.*;
+import java.util.jar.*;
+import java.util.zip.*;
 import javax.tools.*;
 
 import com.sun.tools.javac.file.JavacFileManager;
@@ -58,8 +60,15 @@
     }
 
     void run() throws Exception {
+        javaHome = new File(System.getProperty("java.home"));
+        if (javaHome.getName().equals("jre"))
+            javaHome = javaHome.getParentFile();
+        modularJDK = file(javaHome, "lib", "modules", "%jigsaw-library").exists();
+
         //System.err.println(System.getProperties());
         testDirectory();
+        testUserJar_ZipArchive();
+        testUserJar_ZipFileIndex();
         testSymbolArchive();
         testZipArchive();
         testZipFileIndexArchive();
@@ -69,42 +78,91 @@
     }
 
     void testDirectory() throws IOException {
+        String testName = "testDirectory";
         String testClassName = "p.A";
         JavaFileManager fm =
             getFileManager("test.classes", USE_SYMBOL_FILE, USE_ZIP_FILE_INDEX);
-        test("testDirectory",
+        test(testName,
              fm, testClassName, "com.sun.tools.javac.file.RegularFileObject");
     }
 
+    void testUserJar_ZipArchive() throws IOException {
+        String testName = "testUserJar_ZipArchive";
+        String testClassName = "p.A";
+        File my_jar = createJar("my.jar", getClasses(p.A.class));
+        System.setProperty("my.jar", my_jar.getPath());
+
+        JavaFileManager fm =
+            getFileManager("my.jar", USE_SYMBOL_FILE, DONT_USE_ZIP_FILE_INDEX);
+        test(testName,
+             fm, testClassName, "com.sun.tools.javac.file.ZipArchive$ZipFileObject");
+    }
+
+    void testUserJar_ZipFileIndex() throws IOException {
+        String testName = "testUserJar_ZipFileIndex";
+        String testClassName = "p.A";
+        File my_jar = createJar("my.jar", getClasses(p.A.class));
+        System.setProperty("my.jar", my_jar.getPath());
+
+        JavaFileManager fm =
+            getFileManager("my.jar", USE_SYMBOL_FILE, USE_ZIP_FILE_INDEX);
+        test(testName,
+             fm, testClassName, "com.sun.tools.javac.file.ZipFileIndexArchive$ZipFileIndexFileObject");
+    }
+
     void testSymbolArchive() throws IOException {
+        String testName = "testSymbolArchive";
+        if (modularJDK && !file(javaHome, "lib", "ct.sym").exists()) {
+            skip(testName, "modular JDK found with no ct.sym");
+            return;
+        }
+
         String testClassName = "java.lang.String";
         JavaFileManager fm =
             getFileManager("sun.boot.class.path", USE_SYMBOL_FILE, DONT_USE_ZIP_FILE_INDEX);
-        test("testSymbolArchive",
+        test(testName,
              fm, testClassName, "com.sun.tools.javac.file.SymbolArchive$SymbolFileObject");
     }
 
     void testZipArchive() throws IOException {
+        String testName = "testZipArchive";
+        if (modularJDK) {
+            skip(testName, "assumes impl for platform classes");
+            return;
+        }
+
         String testClassName = "java.lang.String";
         JavaFileManager fm =
             getFileManager("sun.boot.class.path", IGNORE_SYMBOL_FILE, DONT_USE_ZIP_FILE_INDEX);
-        test("testZipArchive",
+        test(testName,
              fm, testClassName, "com.sun.tools.javac.file.ZipArchive$ZipFileObject");
     }
 
     void testZipFileIndexArchive() throws IOException {
+        String testName = "testZipFileIndexArchive";
+        if (modularJDK) {
+            skip(testName, " assumes impl for platform classes");
+            return;
+        }
+
         String testClassName = "java.lang.String";
         JavaFileManager fm =
             getFileManager("sun.boot.class.path", USE_SYMBOL_FILE, USE_ZIP_FILE_INDEX);
-        test("testZipFileIndexArchive",
+        test(testName,
              fm, testClassName, "com.sun.tools.javac.file.ZipFileIndexArchive$ZipFileIndexFileObject");
     }
 
     void testZipFileIndexArchive2() throws IOException {
+        String testName = "testZipFileIndexArchive2";
+        if (modularJDK) {
+            skip(testName, "assumes impl for platform classes");
+            return;
+        }
+
         String testClassName = "java.lang.String";
         JavaFileManager fm =
             getFileManager("sun.boot.class.path", IGNORE_SYMBOL_FILE, USE_ZIP_FILE_INDEX);
-        test("testZipFileIndexArchive2",
+        test(testName,
              fm, testClassName, "com.sun.tools.javac.file.ZipFileIndexArchive$ZipFileIndexFileObject");
     }
 
@@ -168,7 +226,64 @@
         }
     }
 
+    Map<String,byte[]> getClasses(Class... classes) throws IOException {
+        ClassLoader cl = getClass().getClassLoader();
+        Map<String,byte[]> results = new HashMap<String, byte[]>();
+        for (Class c: classes) {
+            String name = c.getName().replace(".", "/") + ".class";
+            byte[] data = read(cl.getResourceAsStream(name));
+            results.put(name, data);
+        }
+        return results;
+    }
+
+    byte[] read(InputStream in) throws IOException {
+        try {
+            byte[] data = new byte[8192];
+            int offset = 0;
+            int n;
+            while ((n = in.read(data, offset, data.length - offset)) >= 0) {
+                offset += n;
+                if (offset == data.length)
+                    data = Arrays.copyOf(data, 2 * data.length);
+            }
+            return data;
+        } finally {
+            in.close();
+        }
+    }
+
+    File createJar(String name, Map<String, byte[]> entries) throws IOException {
+        File jar = new File(name);
+        OutputStream out = new FileOutputStream(jar);
+        try {
+            JarOutputStream jos = new JarOutputStream(out);
+            for (Map.Entry<String,byte[]> e: entries.entrySet()) {
+                jos.putNextEntry(new ZipEntry(e.getKey()));
+                jos.write(e.getValue());
+            }
+            jos.close();
+        } finally {
+            out.close();
+        }
+        return jar;
+    }
+
+    void skip(String testName, String reason) {
+        System.err.println(testName + " skipped: " + reason);
+    }
+
     private int errors;
+
+    File javaHome;
+    boolean modularJDK;
+
+    static File file(File dir, String... path) {
+        File f = dir;
+        for (String p: path)
+            f = new File(f, p);
+        return f;
+    }
 }
 
 class A { }
--- a/test/tools/javac/6508981/p/A.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javac/6508981/p/A.java	Tue May 07 17:14:17 2013 -0700
@@ -21,4 +21,4 @@
  * questions.
  */
 package p;
-class A { }
+public class A { }
--- a/test/tools/javac/6734819/T6734819a.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javac/6734819/T6734819a.java	Tue May 07 17:14:17 2013 -0700
@@ -27,7 +27,7 @@
  * @summary Javac performs flows analysis on already translated classes
  * @author Maurizio Cimadamore
  *
- * @compile/ref=T6734819a.out -XDrawDiagnostics -Xlint:all -XDverboseCompilePolicy T6734819a.java
+ * @compile/ref=T6734819a.out -XDrawDiagnostics -Xlint:all,-path -XDverboseCompilePolicy T6734819a.java
  */
 class Y extends W {}
 class W extends Z {}
--- a/test/tools/javac/6734819/T6734819b.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javac/6734819/T6734819b.java	Tue May 07 17:14:17 2013 -0700
@@ -27,7 +27,7 @@
  * @summary Javac performs flows analysis on already translated classes
  * @author Maurizio Cimadamore
  *
- * @compile/ref=T6734819b.out -XDrawDiagnostics -Xlint:all -XDverboseCompilePolicy T6734819b.java
+ * @compile/ref=T6734819b.out -XDrawDiagnostics -Xlint:all,-path -XDverboseCompilePolicy T6734819b.java
  */
 class A extends B {}
 class B {
--- a/test/tools/javac/6734819/T6734819c.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javac/6734819/T6734819c.java	Tue May 07 17:14:17 2013 -0700
@@ -4,7 +4,7 @@
  * @summary Javac performs flows analysis on already translated classes
  * @author Maurizio Cimadamore
  *
- * @compile/fail/ref=T6734819c.out -XDrawDiagnostics -Xlint:all -XDverboseCompilePolicy T6734819c.java
+ * @compile/fail/ref=T6734819c.out -XDrawDiagnostics -Xlint:all,-path -XDverboseCompilePolicy T6734819c.java
  */
 class Y extends W {}
 class W extends Z {}
--- a/test/tools/javac/OverrideChecks/6199153/T6199153.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javac/OverrideChecks/6199153/T6199153.java	Tue May 07 17:14:17 2013 -0700
@@ -3,7 +3,7 @@
  * @bug 6199153
  * @summary Generic throws and overriding
  * @author  mcimadamore
- * @compile/fail/ref=T6199153.out -Xlint -Werror -XDrawDiagnostics T6199153.java
+ * @compile/fail/ref=T6199153.out -Xlint:all,-path -Werror -XDrawDiagnostics T6199153.java
  */
 
 import java.io.IOException;
--- a/test/tools/javac/Paths/MineField.sh	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javac/Paths/MineField.sh	Tue May 07 17:14:17 2013 -0700
@@ -51,6 +51,18 @@
 #   previous -Xbootclasspath/p: or -Xbootclasspath/a: command line flags.
 #----------------------------------------------------------------
 
+#----------------------------------------------------------------
+#
+# JDK 7: Modules: java.endorsed.dirs java.ext.dirs -endorseddirs -extdirs
+#
+# Endorsed directories and extension directories are currently not supported
+# by javac or by java.
+# Bootclasspath options are supported by javac, and by java in legacy mode.
+# Endorsed and extension directories are internally similar to -Xbootclasspath/p:
+# and -Xbootclasspath/a: and could be treated the same way if necessary.
+#
+#----------------------------------------------------------------
+
 . ${TESTSRC-.}/Util.sh
 
 set -u
--- a/test/tools/javac/T6232928.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javac/T6232928.java	Tue May 07 17:14:17 2013 -0700
@@ -27,7 +27,7 @@
  * @summary Interface package-info should be marked abstract and synthetic
  * @author Wei Tao
  * @compile T6232928.java
- * @compile T6232928/package-info.java
+ * @compile -doe T6232928/package-info.java
  * @run main T6232928
  */
 
--- a/test/tools/javac/T6558476.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javac/T6558476.java	Tue May 07 17:14:17 2013 -0700
@@ -37,6 +37,19 @@
 import com.sun.tools.javac.Main;
 
 public class T6558476 {
+    public static void main(String[] args) throws IOException {
+        File javaHome = new File(System.getProperty("java.home"));
+        if (javaHome.getName().equals("jre"))
+            javaHome = javaHome.getParentFile();
+        if (file(javaHome, "lib", "modules", "%jigsaw-library").exists()
+                && !file(javaHome, "lib", "ext", "dnsns.jar").exists()) {
+            System.err.println("PASS BY DEFAULT: modular JDK found with no dnsns.jar");
+            return;
+        }
+
+        main2(args);
+    }
+
     private static File copyFileTo(File file, File directory) throws IOException {
         File newFile = new File(directory, file.getName());
         FileInputStream fis = null;
@@ -70,7 +83,7 @@
         return sb.toString();
     }
 
-    public static void main(String[] args) throws IOException {
+    public static void main2(String[] args) throws IOException {
         File javaHomeDir = new File(System.getProperty("java.home"));
         File outputDir = new File("outputDir" + new Random().nextInt(65536));
         outputDir.mkdir();
@@ -99,4 +112,11 @@
             throw new Error("Error deleting file \"" + tmpJar.getPath() + "\"");
         }
     }
+
+    static File file(File dir, String... path) {
+        File f = dir;
+        for (String p: path)
+            f = new File(f, p);
+        return f;
+    }
 }
--- a/test/tools/javac/T6654037.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javac/T6654037.java	Tue May 07 17:14:17 2013 -0700
@@ -52,7 +52,7 @@
 
         JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, Arrays.asList("-bootclasspath", bootPath, "-Xjcov"), null, Arrays.asList(new MyFileObject(code)));
         CompilationUnitTree cut = ct.parse().iterator().next();
-        ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0);
+        ClassTree clazz = (ClassTree) cut.getTypeDecls().get(1);
         MethodTree method = (MethodTree) clazz.getMembers().get(0);
         VariableTree condSt = (VariableTree) method.getBody().getStatements().get(1);
         BinaryTree cond = (BinaryTree) condSt.getInitializer();
--- a/test/tools/javac/T6725036.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javac/T6725036.java	Tue May 07 17:14:17 2013 -0700
@@ -43,6 +43,15 @@
 
 public class T6725036 {
     public static void main(String... args) throws Exception {
+        File javaHome = new File(System.getProperty("java.home"));
+        if (javaHome.getName().equals("jre"))
+            javaHome = javaHome.getParentFile();
+        if (file(javaHome, "lib", "modules", "%jigsaw-library").exists()
+                && !file(javaHome, "jre", "lib", "rt.jar").exists()) {
+            System.err.println("PASS BY DEFAULT: modular JDK found with no rt.jar");
+            return;
+        }
+
         new T6725036().run();
     }
 
@@ -92,4 +101,11 @@
     }
 
     int errors;
+
+    static File file(File dir, String... path) {
+        File f = dir;
+        for (String p: path)
+            f = new File(f, p);
+        return f;
+    }
 }
--- a/test/tools/javac/T6873845.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javac/T6873845.java	Tue May 07 17:14:17 2013 -0700
@@ -11,6 +11,15 @@
 
 public class T6873845 {
     public static void main(String... args) throws Exception {
+        File javaHome = new File(System.getProperty("java.home"));
+        if (javaHome.getName().equals("jre"))
+            javaHome = javaHome.getParentFile();
+        if (file(javaHome, "lib", "modules", "%jigsaw-library").exists()
+                && !file(javaHome, "lib", "ct.sym").exists()) {
+            System.err.println("PASS BY DEFAULT: modular JDK found with no ct.sym");
+            return;
+        }
+
         new T6873845().run();
     }
 
@@ -19,8 +28,8 @@
         if (out.contains("sunapi"))
             throw new Exception("unexpected output for -X");
 
-        String warn1 = "T6873845.java:73:9: compiler.warn.sun.proprietary: sun.misc.Unsafe" + newline;
-        String warn2 = "T6873845.java:78:9: compiler.warn.sun.proprietary: sun.misc.Unsafe" + newline;
+        String warn1 = "T6873845.java:81:9: compiler.warn.sun.proprietary: sun.misc.Unsafe" + newline;
+        String warn2 = "T6873845.java:86:9: compiler.warn.sun.proprietary: sun.misc.Unsafe" + newline;
         String note1 = "- compiler.note.sunapi.filename: T6873845.java" + newline;
         String note2 = "- compiler.note.sunapi.recompile" + newline;
 
@@ -81,5 +90,13 @@
     private File testSrc = new File(System.getProperty("test.src", "."));
     private File testClasses = new File(System.getProperty("test.classes", "."));
     private String newline = System.getProperty("line.separator");
+
+
+    static File file(File dir, String... path) {
+        File f = dir;
+        for (String p: path)
+            f = new File(f, p);
+        return f;
+    }
 }
 
--- a/test/tools/javac/api/6411310/Test.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javac/api/6411310/Test.java	Tue May 07 17:14:17 2013 -0700
@@ -48,7 +48,12 @@
     Set<String> foundJars = new TreeSet<String>();
 
     void run() throws Exception {
-        File rt_jar = findRtJar();
+        File javaHome = new File(System.getProperty("java.home"));
+        if (javaHome.getName().equals("jre"))
+            javaHome = javaHome.getParentFile();
+        boolean modularJDK = file(javaHome, "lib", "modules", "%jigsaw-library").exists();
+
+        File rt_jar = modularJDK ? null : findRtJar();
 
         // names for entries to be created in directories and jar files
         String[] entries = { "p/A.java", "p/A.class", "p/resources/A-1.html" };
@@ -63,8 +68,10 @@
             test(createFileManager(useOptimizedZip), createJar("jar", entries), "p", entries);
             test(createFileManager(useOptimizedZip), createJar("jar jar", entries), "p", entries);
 
-            for (boolean useSymbolFile: new boolean[] { false, true }) {
-                test(createFileManager(useOptimizedZip, useSymbolFile), rt_jar, "java.lang.ref", null);
+            if (!modularJDK) {
+                for (boolean useSymbolFile: new boolean[] { false, true }) {
+                    test(createFileManager(useOptimizedZip, useSymbolFile), rt_jar, "java.lang.ref", null);
+                }
             }
         }
 
@@ -72,12 +79,17 @@
             throw new Exception(errors + " errors found");
 
         // Verify that we hit all the impl classes we intended
-        checkCoverage("classes", foundClasses,
-                "RegularFileObject", "SymbolFileObject", "ZipFileIndexFileObject", "ZipFileObject");
+        Set<String> expectClasses = new HashSet<String>(Arrays.asList(
+                "RegularFileObject", "ZipFileIndexFileObject", "ZipFileObject"));
+        if (!modularJDK)
+            expectClasses.add("SymbolFileObject");
+        checkCoverage("classes", foundClasses, expectClasses);
 
         // Verify that we hit the jar files we intended, specifically ct.sym as well as rt.jar
-        checkCoverage("jar files", foundJars,
-                "ct.sym", "jar", "jar jar", "rt.jar");
+        Set<String> expectJars = new HashSet<String>(Arrays.asList("jar", "jar jar"));
+        if (!modularJDK)
+            expectJars.addAll(Arrays.asList("ct.sym", "rt.jar"));
+        checkCoverage("jar files", foundJars, expectJars);
     }
 
     // use a new file manager for each test
@@ -133,11 +145,10 @@
         }
     }
 
-    void checkCoverage(String label, Set<String> found, String... expect) throws Exception {
-        Set<String> e = new TreeSet<String>(Arrays.asList(expect));
-        if (!found.equals(e)) {
-            e.removeAll(found);
-            throw new Exception("expected " + label + " not used: " + e);
+    void checkCoverage(String label, Set<String> found, Set<String> expect) throws Exception {
+        if (!found.equals(expect)) {
+            expect.removeAll(found);
+            throw new Exception("expected " + label + " not used: " + expect);
         }
     }
 
@@ -229,4 +240,11 @@
     }
 
     int errors;
+
+    static File file(File dir, String... path) {
+        File f = dir;
+        for (String p: path)
+            f = new File(f, p);
+        return f;
+    }
 }
--- a/test/tools/javac/api/T6877206.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javac/api/T6877206.java	Tue May 07 17:14:17 2013 -0700
@@ -52,7 +52,12 @@
     Set<String> foundJars = new TreeSet<String>();
 
     void run() throws Exception {
-        File rt_jar = findRtJar();
+        javaHome = new File(System.getProperty("java.home"));
+        if (javaHome.getName().equals("jre"))
+            javaHome = javaHome.getParentFile();
+        boolean modularJDK = file(javaHome, "lib", "modules", "%jigsaw-library").exists();
+
+        File rt_jar = modularJDK ? null : findRtJar();
 
         // names for entries to be created in directories and jar files
         String[] entries = { "p/A.class", "p/resources/A-1.jpg" };
@@ -67,18 +72,25 @@
             test(createFileManager(useOptimizedZip), createJar("jar", entries), "p", entries.length);
             test(createFileManager(useOptimizedZip), createJar("jar jar", entries), "p", entries.length);
 
-            for (boolean useSymbolFile: new boolean[] { false, true }) {
-                test(createFileManager(useOptimizedZip, useSymbolFile), rt_jar, "java.lang.ref", -1);
+            if (!modularJDK) {
+                for (boolean useSymbolFile: new boolean[] { false, true }) {
+                    test(createFileManager(useOptimizedZip, useSymbolFile), rt_jar, "java.lang.ref", -1);
+                }
             }
         }
 
         // Verify that we hit all the impl classes we intended
-        checkCoverage("classes", foundClasses,
-                "RegularFileObject", "SymbolFileObject", "ZipFileIndexFileObject", "ZipFileObject");
+        Set<String> expectClasses = new HashSet<String>(Arrays.asList(
+                "RegularFileObject", "ZipFileIndexFileObject", "ZipFileObject"));
+        if (!modularJDK)
+            expectClasses.add("SymbolFileObject");
+        checkCoverage("classes", foundClasses, expectClasses);
 
         // Verify that we hit the jar files we intended, specifically ct.sym as well as rt.jar
-        checkCoverage("jar files", foundJars,
-                "ct.sym", "jar", "jar jar", "rt.jar");
+        Set<String> expectJars = new HashSet<String>(Arrays.asList("jar", "jar jar"));
+        if (!modularJDK)
+            expectJars.addAll(Arrays.asList("ct.sym", "rt.jar"));
+        checkCoverage("jar files", foundJars, expectJars);
     }
 
     // use a new file manager for each test
@@ -149,11 +161,10 @@
         }
     }
 
-    void checkCoverage(String label, Set<String> found, String... expect) throws Exception {
-        Set<String> e = new TreeSet<String>(Arrays.asList(expect));
-        if (!found.equals(e)) {
-            e.removeAll(found);
-            throw new Exception("expected " + label + " not used: " + e);
+    void checkCoverage(String label, Set<String> found, Set<String> expect) throws Exception {
+        if (!found.equals(expect)) {
+            expect.removeAll(found);
+            throw new Exception("expected " + label + " not used: " + expect);
         }
     }
 
@@ -202,10 +213,7 @@
     }
 
     File findRtJar() throws Exception {
-        File java_home = new File(System.getProperty("java.home"));
-        if (java_home.getName().equals("jre"))
-            java_home = java_home.getParentFile();
-        File rt_jar = new File(new File(new File(java_home, "jre"), "lib"), "rt.jar");
+        File rt_jar = file(javaHome, "jre", "lib", "rt.jar");
         if (!rt_jar.exists())
             throw new Exception("can't find rt.jar");
         return rt_jar;
@@ -236,4 +244,13 @@
             out.close();
         }
     }
+
+    File javaHome;
+
+    static File file(File dir, String... path) {
+        File f = dir;
+        for (String p: path)
+            f = new File(f, p);
+        return f;
+    }
 }
--- a/test/tools/javac/diags/CheckResourceKeys.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javac/diags/CheckResourceKeys.java	Tue May 07 17:14:17 2013 -0700
@@ -276,7 +276,9 @@
             "compiler.misc.",
             "count.",
             "illegal.",
+            "java.",
             "javac.",
+            "javac.debug.modules",
             "verbose."
     ));
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/modules/ClassReaderTest01.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary Tests for reading module-info.class files
+ * @build DirectiveTest
+ * @run main ClassReaderTest01
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardLocation;
+
+public class ClassReaderTest01 extends DirectiveTest {
+    public static void main(String... args) throws Exception {
+        new ClassReaderTest01().run();
+    }
+
+    @Test
+    void basicTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { exports p; }"));
+        files.add(createFile("M1/p/C1.java",
+                "package p; public class C1 { }"));
+        files.add(createFile("M2/module-info.java",
+                "module M2 { requires public M1; }"));
+        fm.setLocation(StandardLocation.MODULE_PATH, Arrays.asList(classesDir));
+        compile(files);
+
+        srcDir = new File(srcDir.getParentFile(), "src2");
+        srcDir.mkdirs();
+        fm.setLocation(StandardLocation.SOURCE_PATH, Arrays.asList(srcDir));
+
+        List<JavaFileObject> files2 = new ArrayList<JavaFileObject>();
+        files2.add(createFile("M3/module-info.java",
+                "module M3 { requires M2; }"));
+        files2.add(createFile("M3/q/C2.java",
+                "package q; public class C2 { void m() { new p.C1(); } }"));
+        compile(files2);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/modules/DirectiveTest.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticListener;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPool;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.ModuleProvides_attribute;
+import com.sun.tools.classfile.ModuleProvides_attribute.View;
+import com.sun.tools.javac.api.ClientCodeWrapper;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.util.JCDiagnostic;
+import com.sun.tools.javap.JavapTask;
+
+/* Utilities for module directives tests. */
+abstract class DirectiveTest {
+
+    protected DirectiveTest() {
+        javac = JavacTool.create();
+        fm = javac.getStandardFileManager(null, null, null);
+    }
+
+    @Retention(RetentionPolicy.RUNTIME)
+    @interface Test { }
+    
+    void run() throws Exception {
+        for (Method m: getClass().getDeclaredMethods()) {
+            Annotation a = m.getAnnotation(Test.class);
+            if (a != null) {
+                init(m.getName());
+                try {
+                    m.invoke(this, new Object[] { });
+                } catch (InvocationTargetException e) {
+                    Throwable cause = e.getCause();
+                    throw (cause instanceof Exception) ? ((Exception) cause) : e;
+                }
+                System.err.println();
+            }
+        }
+        System.err.println(testCount + " tests" + ((errorCount == 0) ? "" : ", " + errorCount + " errors"));
+        if (errorCount > 0)
+            throw new Exception(errorCount + " errors found");
+    }
+
+    void init(String name) throws IOException {
+        System.err.println("Test " + name);
+        testCount++;
+
+        srcDir = new File(name, "src");
+        srcDir.mkdirs();
+        classesDir = new File(name, "classes");
+        classesDir.mkdirs();
+        
+        fm.setLocation(StandardLocation.SOURCE_PATH, Arrays.asList(srcDir));
+        fm.setLocation(StandardLocation.MODULE_PATH, Collections.<File>emptyList());
+        fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(classesDir));
+    }
+
+    void compile(List<JavaFileObject> files) throws Exception {
+        JavacTask task = javac.getTask(null, fm, null, null, null, files);
+        if (!task.call())
+            throw new Exception("compilation failed");
+    }
+
+    void compile(List<JavaFileObject> files, List<String> expectDiags) throws Exception {
+        class DiagListener implements DiagnosticListener<JavaFileObject> {
+            List<String> diags = new ArrayList<String>();
+            @Override
+            public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+                System.err.println(diagnostic);
+                JCDiagnostic d = ((ClientCodeWrapper.DiagnosticSourceUnwrapper) diagnostic).d;
+                diags.add(d.getKind() + ": " + d.getCode() + " " + Arrays.asList(d.getArgs()));
+            }
+        }
+
+        DiagListener dl = new DiagListener();
+        JavacTask task = javac.getTask(null, fm, dl, null, null, files);
+        boolean ok = task.call();
+        System.err.println(ok ? "Compilation succeeded" : "Compilation failed");
+
+        List<String> foundDiags = dl.diags;
+
+        checkEqual("diags", expectDiags, foundDiags);
+    }
+
+    void javap(String path) {
+        List<String> opts = Arrays.asList("-v");
+        List<String> files = Arrays.asList(new File(classesDir, path).getPath());
+        JavapTask t = new JavapTask(null, fm, null, opts, files);
+        t.call();
+    }
+
+    View getView(ClassFile cf, String name) throws ConstantPoolException {
+        ConstantPool cp = cf.constant_pool;
+        ModuleProvides_attribute attr = (ModuleProvides_attribute) cf.getAttribute(Attribute.ModuleProvides);
+        Set<String> found = new HashSet<String>();
+        for (View v: attr.view_table) {
+            if (v.view_name_index == 0 && name == null
+                    || v.view_name_index != 0 && cp.getUTF8Value(v.view_name_index).equals(name)) {
+                return v;
+            }
+        }
+        return null;
+    }
+
+    JavaFileObject createFile(String path, final String body) throws IOException {
+        File f = new File(srcDir, path);
+        f.getParentFile().mkdirs();
+        try (FileWriter out = new FileWriter(f)) {
+            out.write(body);
+        }
+        return fm.getJavaFileObjects(f).iterator().next();
+    }
+
+    <T> Set<T> createSet(T... items) {
+        return new HashSet<T>(Arrays.asList(items));
+    }
+
+    <T> void checkEqual(String label, T expect, T found) {
+        if ((found == null) ? (expect == null) : found.equals(expect))
+            return;
+        System.err.println("Error: mismatch");
+        System.err.println("  expected: " + expect);
+        System.err.println("     found: " + found);
+        errorCount++;
+    }
+
+    <T> void checkEqual(String label, Collection<T> expect, Collection<T> found) {
+        if ((found == null) ? (expect == null) : found.equals(expect))
+            return;
+        System.err.println("Error: mismatch");
+        System.err.println("  expected: " + expect);
+        System.err.println("     found: " + found);
+        errorCount++;
+    }
+
+    JavacTool javac;
+    StandardJavaFileManager fm;
+    File srcDir;
+    File classesDir;
+    int testCount;
+    int errorCount;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/modules/EntrypointTest01.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary Tests for "class class-name;"
+ * @build DirectiveTest
+ * @run main EntrypointTest01
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPool;
+import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.ModuleProvides_attribute.View;
+
+public class EntrypointTest01 extends DirectiveTest {
+    public static void main(String... args) throws Exception {
+        new EntrypointTest01().run();
+    }
+
+    @Test
+    void basicTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { class p.Main; }"));
+        files.add(createFile("M1/p/Main.java",
+                "package p; public class Main { public static void main(String... args) { } }"));
+        compile(files);
+
+        Set<String> expect = createSet("p/Main");
+        Set<String> found = getEntrypoints("M1/module-info.class", null);
+        checkEqual("entrypoint", expect, found);
+    }
+
+    @Test
+    void duplTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { class p.Main; class p.Main2; }"));
+        files.add(createFile("M1/p/Main.java",
+                "package p; public class Main { public static void main(String... args) { } }"));
+        files.add(createFile("M1/p/Main2.java",
+                "package p; public class Main2 { public static void main(String... args) { } }"));
+
+        List<String> expectDiags = Arrays.asList("ERROR: compiler.err.dupl.entrypoint []");
+        compile(files, expectDiags);
+    }
+
+    @Test
+    void mainNotPublicTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { class p.Main; }"));
+        files.add(createFile("M1/p/Main.java",
+                "package p; public class Main { static void main(String... args) { } }"));
+
+        List<String> expectDiags = Arrays.asList("ERROR: compiler.err.no.psv.main [p.Main]");
+        compile(files, expectDiags);
+    }
+
+    @Test
+    void mainNotStaticTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { class p.Main; }"));
+        files.add(createFile("M1/p/Main.java",
+                "package p; public class Main { public void main(String... args) { } }"));
+
+        List<String> expectDiags = Arrays.asList("ERROR: compiler.err.no.psv.main [p.Main]");
+        compile(files, expectDiags);
+    }
+
+    @Test
+    void mainNotVoidTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { class p.Main; }"));
+        files.add(createFile("M1/p/Main.java",
+                "package p; public class Main { public static int main(String... args) { return 0; } }"));
+
+        List<String> expectDiags = Arrays.asList("ERROR: compiler.err.no.psv.main [p.Main]");
+        compile(files, expectDiags);
+    }
+
+    @Test
+    void mainNoArgsTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { class p.Main; }"));
+        files.add(createFile("M1/p/Main.java",
+                "package p; public class Main { public static void main() { } }"));
+
+        List<String> expectDiags = Arrays.asList("ERROR: compiler.err.no.psv.main [p.Main]");
+        compile(files, expectDiags);
+    }
+
+    @Test
+    void mainArgsNotArray1Test() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { class p.Main; }"));
+        files.add(createFile("M1/p/Main.java",
+                "package p; public class Main { public static void main(String arg) { } }"));
+
+        List<String> expectDiags = Arrays.asList("ERROR: compiler.err.no.psv.main [p.Main]");
+        compile(files, expectDiags);
+    }
+
+    @Test
+    void mainArgsNotArray2Test() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { class p.Main; }"));
+        files.add(createFile("M1/p/Main.java",
+                "package p; public class Main { public static void main(int[] arg) { } }"));
+
+        List<String> expectDiags = Arrays.asList("ERROR: compiler.err.no.psv.main [p.Main]");
+        compile(files, expectDiags);
+    }
+
+    Set<String> getEntrypoints(String path, String viewName) throws IOException, ConstantPoolException {
+        javap(path);
+        Set<String> found = new HashSet<String>();
+        ClassFile cf = ClassFile.read(new File(classesDir, path));
+        ConstantPool cp = cf.constant_pool;
+        View v = getView(cf, viewName);
+        CONSTANT_Class_info info = cp.getClassInfo(v.entrypoint_index);
+        found.add(info.getName());
+        return found;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/modules/ExportsTest01.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary Tests for "exports package-name;"
+ * @build DirectiveTest
+ * @run main ExportsTest01
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPool;
+import com.sun.tools.classfile.ConstantPool.CONSTANT_Utf8_info;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.ModuleProvides_attribute.View;
+
+public class ExportsTest01 extends DirectiveTest {
+    public static void main(String... args) throws Exception {
+        new ExportsTest01().run();
+    }
+
+    @Test
+    void basicTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { exports p; }"));
+        files.add(createFile("M1/p/C.java",
+                "package p; public class C { }"));
+        compile(files);
+
+        Set<String> expect = createSet("p");
+        Set<String> found = getExports("M1/module-info.class", null);
+        checkEqual("exports", expect, found);
+    }
+
+    @Test
+    void viewTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { exports p; view V { exports q; } }"));
+        files.add(createFile("M1/p/C.java",
+                "package p; public class C { }"));
+        files.add(createFile("M1/q/C.java",
+                "package q; public class C { }"));
+        compile(files);
+
+        Set<String> expectDefault = createSet("p");
+        Set<String> foundDefault = getExports("M1/module-info.class", null);
+        checkEqual("exports", expectDefault, foundDefault);
+
+        Set<String> expectV = createSet("p", "q");
+        Set<String> foundV = getExports("M1/module-info.class", "V");
+        checkEqual("exports", expectV, foundV);
+    }
+
+    @Test
+    void duplTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { exports p; exports p; }"));
+        files.add(createFile("M1/p/C.java",
+                "package p; public class C { }"));
+
+        List<String> expectDiags = Arrays.asList("ERROR: compiler.err.dupl.exports [p]");
+        compile(files, expectDiags);
+    }
+
+    Set<String> getExports(String path, String viewName) throws IOException, ConstantPoolException {
+        javap(path);
+        Set<String> found = new HashSet<String>();
+        ClassFile cf = ClassFile.read(new File(classesDir, path));
+        ConstantPool cp = cf.constant_pool;
+        View v = getView(cf, viewName);
+        for (int e: v.export_table) {
+            CONSTANT_Utf8_info info = cp.getUTF8Info(e);
+            found.add(info.value);
+        }
+        return found;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/modules/ModuleDataTest01.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,86 @@
+
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary Tests for module data
+ * @build DirectiveTest
+ * @run main ModuleDataTest01
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPool;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.ModuleData_attribute;
+
+public class ModuleDataTest01 extends DirectiveTest {
+    public static void main(String... args) throws Exception {
+        new ModuleDataTest01().run();
+    }
+
+    @Override
+    void run() throws Exception {
+        String[] tests = { /*"", */"  ", "\n", "\nthis is module data\n" };
+        for (String s: tests) {
+            test(s);
+        }
+
+        if (errorCount > 0)
+            throw new Exception(errorCount + " errors found");
+    }
+
+    void test(String s) throws Exception {
+        String testName = "test_" +
+                s.toLowerCase()
+                .replace("\n", "N")
+                .replace(" ",  "S")
+                .replace("\t", "T");
+        init(testName);
+
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { }" + s));
+        compile(files);
+
+        String expect = s.replaceAll("^[ \n\t]*", "");
+        if (expect.isEmpty()) expect = null;
+        String found = getModuleData("M1/module-info.class");
+        checkEqual("module data", expect, found);
+    }
+
+    String getModuleData(String path) throws IOException, ConstantPoolException {
+        javap(path);
+        ClassFile cf = ClassFile.read(new File(classesDir, path));
+        ConstantPool cp = cf.constant_pool;
+        ModuleData_attribute attr = (ModuleData_attribute) cf.getAttribute(Attribute.ModuleData);
+        return (attr == null) ? null : attr.getData(cp);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/modules/PermitsTest01.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary Tests for "permits module-name;"
+ * @build DirectiveTest
+ * @run main PermitsTest01
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPool;
+import com.sun.tools.classfile.ConstantPool.CONSTANT_ModuleId_info;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.ModuleProvides_attribute.View;
+
+public class PermitsTest01 extends DirectiveTest {
+    public static void main(String... args) throws Exception {
+        new PermitsTest01().run();
+    }
+
+    @Test
+    void basicTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { permits M2; }"));
+        files.add(createFile("M2/module-info.java",
+                "module M2 { }"));
+        compile(files);
+
+        Set<String> expect = createSet("M2");
+        Set<String> found = getPermits("M1/module-info.class", null);
+        checkEqual("permits", expect, found);
+    }
+
+    @Test
+    void duplTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { permits M2; permits M2; }"));
+        files.add(createFile("M2/module-info.java",
+                "module M2 { }"));
+
+        List<String> expectDiags = Arrays.asList("ERROR: compiler.err.dupl.permits [M2]");
+        compile(files, expectDiags);
+    }
+
+    Set<String> getPermits(String path, String viewName) throws IOException, ConstantPoolException {
+        javap(path);
+        Set<String> found = new HashSet<String>();
+        ClassFile cf = ClassFile.read(new File(classesDir, path));
+        ConstantPool cp = cf.constant_pool;
+        View v = getView(cf, viewName);
+        for (int i: v.permit_table) {
+            CONSTANT_ModuleId_info info = cp.getModuleIdInfo(i);
+            String s = info.getName();
+            if (info.version_index != 0)
+                s += "@" + info.getVersion();
+            found.add(s);
+        }
+        return found;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/modules/ProvidesModuleTest01.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary Tests for "provides module-name;"
+ * @build DirectiveTest
+ * @run main ProvidesModuleTest01
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPool;
+import com.sun.tools.classfile.ConstantPool.CONSTANT_ModuleId_info;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.ModuleProvides_attribute.View;
+
+public class ProvidesModuleTest01 extends DirectiveTest {
+    public static void main(String... args) throws Exception {
+        new ProvidesModuleTest01().run();
+    }
+
+    @Test
+    void basicTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { provides M1a; }"));
+        compile(files);
+
+        Set<String> expect = createSet("M1a");
+        Set<String> found = getAliases("M1/module-info.class", null);
+        checkEqual("aliases", expect, found);
+    }
+
+    @Test
+    void duplTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { provides M1a; provides M1a; }"));
+
+        List<String> expectDiags = Arrays.asList("ERROR: compiler.err.dupl.provides [M1a]");
+        compile(files, expectDiags);
+    }
+
+    Set<String> getAliases(String path, String viewName) throws IOException, ConstantPoolException {
+        javap(path);
+        Set<String> found = new HashSet<String>();
+        ClassFile cf = ClassFile.read(new File(classesDir, path));
+        ConstantPool cp = cf.constant_pool;
+        View v = getView(cf, viewName);
+        for (int i: v.alias_table) {
+            CONSTANT_ModuleId_info info = cp.getModuleIdInfo(i);
+            String s = info.getName();
+            if (info.version_index != 0)
+                s += "@" + info.getVersion();
+            found.add(s);
+        }
+        return found;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/modules/ProvidesServiceTest01.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary Tests for "provides service service-name with impl-name;"
+ * @build DirectiveTest
+ * @run main ProvidesServiceTest01
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPool;
+import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.ModuleProvides_attribute;
+import com.sun.tools.classfile.ModuleProvides_attribute.View;
+
+public class ProvidesServiceTest01 extends DirectiveTest {
+    public static void main(String... args) throws Exception {
+        new ProvidesServiceTest01().run();
+    }
+
+    @Test
+    void basicTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { provides service p.S1 with p.S2; }"));
+        files.add(createFile("M1/p/S1.java",
+                "package p; public class S1 { }"));
+        files.add(createFile("M1/p/S2.java",
+                "package p; public class S2 extends S1 { }"));
+        compile(files);
+
+        Set<String> expect = createSet("p/S1 p/S2");
+        Set<String> found = getServices("M1/module-info.class", null);
+        checkEqual("services", expect, found);
+    }
+
+    @Test
+    void duplTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { provides service p.S1 with p.S2; provides service p.S1 with p.S2; }"));
+        files.add(createFile("M1/p/S1.java",
+                "package p; public class S1 { }"));
+        files.add(createFile("M1/p/S2.java",
+                "package p; public class S2 extends S1 { }"));
+
+        List<String> expectDiags = Arrays.asList("ERROR: compiler.err.dupl.provides.service [p.S1, p.S2]");
+        compile(files, expectDiags);
+    }
+
+    @Test
+    void implIsAbstractTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { provides service p.S1 with p.S2; }"));
+        files.add(createFile("M1/p/S1.java",
+                "package p; public class S1 { }"));
+        files.add(createFile("M1/p/S2.java",
+                "package p; public abstract class S2 extends S1 { }"));
+
+        List<String> expectDiags = Arrays.asList("ERROR: compiler.err.service.impl.is.abstract [p.S2]");
+        compile(files, expectDiags);
+    }
+
+    @Test
+    void implNotPublicTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { provides service p.S1 with p.S2; }"));
+        files.add(createFile("M1/p/S1.java",
+                "package p; public class S1 { }"));
+        files.add(createFile("M1/p/S2.java",
+                "package p; class S2 extends S1 { }"));
+
+        List<String> expectDiags = Arrays.asList("ERROR: compiler.err.not.def.public.cant.access [p.S2, p]");
+        compile(files, expectDiags);
+    }
+
+    @Test
+    void implConstrNotPublicTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { provides service p.S1 with p.S2; }"));
+        files.add(createFile("M1/p/S1.java",
+                "package p; public class S1 { }"));
+        files.add(createFile("M1/p/S2.java",
+                "package p; public class S2 extends S1 { private S2() { } }"));
+
+        List<String> expectDiags = Arrays.asList("ERROR: compiler.err.service.impl.no.default.constr [p.S2]");
+        compile(files, expectDiags);
+    }
+
+    @Test
+    void implConstrHasArgsTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { provides service p.S1 with p.S2; }"));
+        files.add(createFile("M1/p/S1.java",
+                "package p; public class S1 { }"));
+        files.add(createFile("M1/p/S2.java",
+                "package p; public class S2 extends S1 { public S2(int i) { } }"));
+
+        List<String> expectDiags = Arrays.asList("ERROR: compiler.err.service.impl.no.default.constr [p.S2]");
+        compile(files, expectDiags);
+    }
+
+    @Test
+    void implIsInnerTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { provides service p.S1 with p.S2.Inner; }"));
+        files.add(createFile("M1/p/S1.java",
+                "package p; public class S1 { }"));
+        files.add(createFile("M1/p/S2.java",
+                "package p; public class S2 extends S1 { public class Inner { } }"));
+
+        List<String> expectDiags = Arrays.asList("ERROR: compiler.err.service.impl.is.inner [p.S2.Inner]");
+        compile(files, expectDiags);
+    }
+
+    Set<String> getServices(String path, String viewName) throws IOException, ConstantPoolException {
+        javap(path);
+        Set<String> found = new HashSet<String>();
+        ClassFile cf = ClassFile.read(new File(classesDir, path));
+        ConstantPool cp = cf.constant_pool;
+        View v = getView(cf, viewName);
+        for (ModuleProvides_attribute.Service e: v.service_table) {
+            CONSTANT_Class_info serviceInfo = cp.getClassInfo(e.service_index);
+            CONSTANT_Class_info implInfo = cp.getClassInfo(e.impl_index);
+            found.add(serviceInfo.getName() + " " + implInfo.getName());
+        }
+        return found;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/modules/RequiresModuleTest01.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary Tests for "requires module-name;"
+ * @build DirectiveTest
+ * @run main ProvidesModuleTest01
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPool;
+import com.sun.tools.classfile.ConstantPool.CONSTANT_ModuleQuery_info;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.ModuleRequires_attribute;
+
+import com.sun.tools.javac.jvm.Target;
+
+public class RequiresModuleTest01 extends DirectiveTest {
+    public static void main(String... args) throws Exception {
+        new RequiresModuleTest01().run();
+    }
+
+    @Test
+    void basicTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { requires M2; }"));
+        files.add(createFile("M2/module-info.java",
+                "module M2 { }"));
+        compile(files);
+
+        Set<String> expect = createSet("M2", "java/base@>=" + version);
+        Set<String> found = getRequires("M1/module-info.class");
+        checkEqual("required modules", expect, found);
+    }
+
+    @Test
+    void duplTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { requires M2; requires M2; }"));
+        files.add(createFile("M2/module-info.java",
+                "module M2 { }"));
+
+        List<String> expectDiags = Arrays.asList("ERROR: compiler.err.dupl.requires [M2]");
+        compile(files, expectDiags);
+    }
+
+    @Test
+    void viewTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { view V { requires M1; } }"));
+
+        List<String> expectDiags = Arrays.asList("ERROR: compiler.err.requires.not.allowed.in.view []");
+        compile(files, expectDiags);
+    }
+
+    Set<String> getRequires(String path) throws IOException, ConstantPoolException {
+        javap(path);
+        ClassFile cf = ClassFile.read(new File(classesDir, path));
+        ConstantPool cp = cf.constant_pool;
+        ModuleRequires_attribute attr = (ModuleRequires_attribute) cf.getAttribute(Attribute.ModuleRequires);
+        Set<String> found = new HashSet<String>();
+        for (ModuleRequires_attribute.Entry e: attr.module_table) {
+            CONSTANT_ModuleQuery_info info = cp.getModuleQueryInfo(e.index);
+            String s = info.getName();
+            if (info.version_index != 0)
+                s += "@" + info.getVersion();
+            found.add(s);
+        }
+        return found;
+    }
+
+    Target target = Target.DEFAULT;
+    String version = target.name.replace("1.", "");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/modules/RequiresModuleTest02.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary Tests for requires finding modules in different locations
+ * @run main RequiresModuleTest02
+ */
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class RequiresModuleTest02 {
+    static PrintStream out = System.out;
+
+    public static void main(String... args) throws Exception {
+        new RequiresModuleTest02().run();
+    }
+
+    enum PathKind {
+        SOURCEPATH,
+        MODULEPATH,
+        MODULELIB
+    }
+
+    enum RequireKind {
+        MODULE,
+        ALIAS,
+        VIEW
+    }
+
+    void run() throws Exception {
+        setup();
+        for (PathKind pk: PathKind.values()) {
+            for (RequireKind rk: RequireKind.values()) {
+                test(pk, rk);
+            }
+        }
+
+        out.println(testCount + " tests" + ((errorCount == 0) ? "" : ", " + errorCount + " errors"));
+        if (errorCount > 0)
+            throw new Exception(errorCount + " errors found");
+    }
+
+    void setup() throws Exception {
+        srcDir = new File("src");
+        classesDir = new File("classes");
+        classesDir.mkdirs();
+        moduleLib = new File("mlib");
+
+        List<File> files = Arrays.asList(
+            // module M1
+            createFile(srcDir, "M1/module-info.java",
+                "module M1@1.0 {\n" +
+                "    provides A1;\n" +
+                "    view V1 { }\n" +
+                "}")
+        );
+
+        List<String> args = new ArrayList<String>();
+        args.add("-d");
+        args.add(classesDir.getPath());
+        args.add("-modulepath");
+        args.add(classesDir.getPath());
+        for (File f: files)
+            args.add(f.getPath());
+        compile(args);
+
+        jmod(Arrays.asList("create", "-L", moduleLib.getPath()));
+        jmod(Arrays.asList("install", "-L", moduleLib.getPath(),
+                classesDir.getPath(), "M1"));
+    }
+
+    void test(PathKind pk, RequireKind rk) throws Exception {
+        out.println("Test pk:" + pk + " rk:" + rk);
+        if (rk == RequireKind.ALIAS) {
+            out.println(".... skipped until Jigsaw supports aliases");
+            return;
+        }
+        testCount++;
+
+        File testDir = new File(pk + "-" + rk );
+        File testSrcDir = new File(testDir, "src");
+        File testClassesDir = new File(testDir, "classes");
+        testClassesDir.mkdirs();
+
+        String requires;
+        switch (rk) {
+            case MODULE:    requires = "M1"; break;
+            case ALIAS:     requires = "A1"; break;
+            case VIEW:      requires = "V1"; break;
+            default: throw new IllegalArgumentException();
+        }
+        List<File> files = Arrays.asList(
+            createFile(testSrcDir, "MT/module-info.java",
+                "module MT@1.0 {\n" +
+                "    requires " + requires + ";\n" +
+                "}")
+        );
+
+        List<String> args = new ArrayList<String>();
+        args.add("-d");
+        args.add(testClassesDir.getPath());
+        switch (pk) {
+            case SOURCEPATH:
+                args.add("-modulepath");
+                args.add(testClassesDir.getPath());
+                args.add("-sourcepath");
+                args.add(srcDir.getPath());
+                break;
+            case MODULEPATH:
+                args.add("-modulepath");
+                args.add(classesDir.getPath()
+                        + File.pathSeparator
+                        + testClassesDir.getPath());
+                break;
+            case MODULELIB:
+                args.add("-modulepath");
+                args.add(testClassesDir.getPath());
+                args.add("-L");
+                args.add(moduleLib.getPath());
+                break;
+            default: throw new IllegalArgumentException();
+        }
+        for (File f: files)
+            args.add(f.getPath());
+
+        compile(args, 0);
+    }
+
+    File createFile(File srcDir, String path, final String body) throws IOException {
+        File f = new File(srcDir, path);
+        f.getParentFile().mkdirs();
+        try (FileWriter out = new FileWriter(f)) {
+            out.write(body);
+        }
+        return f;
+    }
+
+    void compile(List<String> args) throws Exception {
+        int rc = com.sun.tools.javac.Main.compile(args.toArray(new String[args.size()]));
+        if (rc != 0)
+            throw new Exception("compilation failed");
+    }
+
+    void compile(List<String> args, int expect_rc) throws Exception {
+        int rc = com.sun.tools.javac.Main.compile(args.toArray(new String[args.size()]));
+        if (rc == expect_rc) {
+            out.println("compilation " + (rc == 0 ? "succeeded" : "failed") + " as expected");
+        } else {
+            error("compilation " + (rc == 0 ? "succeeded" : "failed") + " unexpectedly");
+        }
+    }
+
+    void jmod(List<String> args) throws Exception {
+	// for now, use jmod via CLI; eventually should use API
+        File javaHome = new File(System.getProperty("java.home"));
+        File jmod = new File(new File(javaHome, "bin"), "jmod");
+        List<String> cmdArgs = new ArrayList<String>();
+        cmdArgs.add(jmod.getPath());
+        cmdArgs.addAll(args);
+        Process p = new ProcessBuilder()
+                .command(cmdArgs)
+                .redirectErrorStream(true)
+                .start();
+        try (BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
+            String line;
+            while ((line = r.readLine()) != null)
+                out.println(line);
+            int rc = p.waitFor();
+            if (rc != 0)
+                throw new Exception("jmod failed: rc=" + rc);
+        }
+    }
+
+    void error(String msg) {
+        out.println("ERROR: " + msg);
+        errorCount++;
+    }
+
+    File srcDir;
+    File classesDir;
+    File moduleLib;
+
+    int testCount;
+    int errorCount;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/modules/RequiresServiceTest01.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary Tests for "requires service service-name;"
+ * @build DirectiveTest
+ * @run main RequiresServiceTest01
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPool;
+import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.ModuleRequires_attribute;
+
+import com.sun.tools.javac.jvm.Target;
+
+public class RequiresServiceTest01 extends DirectiveTest {
+    public static void main(String... args) throws Exception {
+        new RequiresServiceTest01().run();
+    }
+
+    @Test
+    void basicTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { requires service p.S1; }"));
+        provideService(files, "M2", "p.S1", "p.S2");
+        compile(files);
+
+        Set<String> expect = createSet("p/S1");
+        Set<String> found = getRequires("M1/module-info.class");
+        checkEqual("required services", expect, found);
+    }
+
+    @Test
+    void duplTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { requires service p.S1; requires service p.S1; }"));
+        provideService(files, "M2", "p.S1", "p.S2");
+
+        List<String> expectDiags = Arrays.asList("ERROR: compiler.err.dupl.requires.service [p.S1]");
+        compile(files, expectDiags);
+    }
+
+    @Test
+    void viewTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { view V { requires service p.S1; } }"));
+        provideService(files, "M2", "p.S1", "p.S2");
+
+        List<String> expectDiags = Arrays.asList("ERROR: compiler.err.requires.not.allowed.in.view []");
+        compile(files, expectDiags);
+    }
+
+    void provideService(List<JavaFileObject> files, String module, String service, String impl)
+            throws IOException {
+        files.add(createFile(module + "/module-info.java",
+                "module " + module + " { provides service " + service + " with " + impl + "; }"));
+        String servicePkg = service.substring(0, service.lastIndexOf("."));
+        String serviceCls = service.substring(service.lastIndexOf(".") + 1);
+        files.add(createFile(module + "/" + service.replace(".", "/") + ".java",
+                "package " + servicePkg + "; public class " + serviceCls + " { }"));
+        String implPkg = impl.substring(0, impl.lastIndexOf("."));
+        String implCls = impl.substring(impl.lastIndexOf(".") + 1);
+        files.add(createFile(module + "/" + impl.replace(".", "/") + ".java",
+                "package " + implPkg + "; public class " + implCls + " extends " + service + " { }"));
+    }
+
+    Set<String> getRequires(String path) throws IOException, ConstantPoolException {
+        javap(path);
+        Set<String> found = new HashSet<String>();
+        ClassFile cf = ClassFile.read(new File(classesDir, path));
+        ConstantPool cp = cf.constant_pool;
+        ModuleRequires_attribute attr = (ModuleRequires_attribute) cf.getAttribute(Attribute.ModuleRequires);
+        for (ModuleRequires_attribute.Entry e: attr.service_table) {
+            CONSTANT_Class_info info = cp.getClassInfo(e.index);
+            found.add(info.getName());
+        }
+        return found;
+    }
+
+    Target target = Target.DEFAULT;
+    String version = target.name.replace("1.", "");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/modules/ViewTest01.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary Tests for "view { ... };"
+ * @build DirectiveTest
+ * @run main ViewTest01
+ */
+
+import com.sun.tools.classfile.Attribute;
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPool;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.ModuleProvides_attribute;
+import com.sun.tools.classfile.ModuleProvides_attribute.View;
+
+public class ViewTest01 extends DirectiveTest {
+    public static void main(String... args) throws Exception {
+        new ViewTest01().run();
+    }
+
+    @Test
+    void emptyTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { }"));
+        compile(files);
+
+        Set<String> expect = null;
+        Set<String> found = getViews("M1/module-info.class");
+        checkEqual("views", expect, found);
+    }
+
+    @Test
+    void basicTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { view V { } }"));
+        compile(files);
+
+        Set<String> expect = createSet("V");
+        Set<String> found = getViews("M1/module-info.class");
+        checkEqual("views", expect, found);
+    }
+
+    @Test
+    void duplTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { view V { } view V { } }"));
+
+        List<String> expectDiags = Arrays.asList("ERROR: compiler.err.dupl.view [V]");
+        compile(files, expectDiags);
+    }
+
+    @Test
+    void inheritDuplTest() throws Exception {
+        List<JavaFileObject> files = new ArrayList<JavaFileObject>();
+        files.add(createFile("M1/module-info.java",
+                "module M1 { view M1 { } }"));
+
+        List<String> expectDiags = Arrays.asList("ERROR: compiler.err.dupl.view [M1]");
+        compile(files, expectDiags);
+    }
+
+    Set<String> getViews(String path) throws IOException, ConstantPoolException {
+        javap(path);
+        ClassFile cf = ClassFile.read(new File(classesDir, path));
+        ConstantPool cp = cf.constant_pool;
+        ModuleProvides_attribute attr = (ModuleProvides_attribute) cf.getAttribute(Attribute.ModuleProvides);
+        if (attr == null)
+            return null;
+        Set<String> found = new HashSet<String>();
+        for (View v: attr.view_table) {
+            found.add(v.view_name_index == 0 ? null : cp.getUTF8Value(v.view_name_index));
+        }
+        return found;
+    }
+}
--- a/test/tools/javac/nio/compileTest/CompileTest.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javac/nio/compileTest/CompileTest.java	Tue May 07 17:14:17 2013 -0700
@@ -41,16 +41,32 @@
 
 
 public class CompileTest {
+    static File javaHome;
+
+    static File file(File dir, String... path) {
+        File f = dir;
+        for (String p: path)
+            f = new File(f, p);
+        return f;
+    }
+
     public static void main(String[] args) throws Exception {
+        javaHome = new File(System.getProperty("java.home"));
+        if (javaHome.getName().equals("jre"))
+            javaHome = javaHome.getParentFile();
+
+        if (file(javaHome, "lib", "modules", "%jigsaw-library").exists()
+                && !file(javaHome, "jre", "lib", "rt.jar").exists()) {
+            System.err.println("PASS BY DEFAULT: modular JDK found with no rt.jar");
+            return;
+        }
+
         new CompileTest().run();
     }
 
     public void run() throws Exception {
         File rtDir = new File("rt.dir");
-        File javaHome = new File(System.getProperty("java.home"));
-        if (javaHome.getName().equals("jre"))
-            javaHome = javaHome.getParentFile();
-        File rtJar = new File(new File(new File(javaHome, "jre"), "lib"), "rt.jar");
+        File rtJar = file(javaHome, "jre", "lib", "rt.jar");
         expand(rtJar, rtDir);
 
         String[] rtDir_opts = {
--- a/test/tools/javac/processing/6348193/T6348193.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javac/processing/6348193/T6348193.java	Tue May 07 17:14:17 2013 -0700
@@ -80,6 +80,7 @@
         args.add(System.getProperty("java.class.path"));
         args.add("-d");
         args.add(".");
+        args.add("-XDnomodules");
 
         JavacTool t = JavacTool.create(); // avoid using class loader
 
@@ -169,7 +170,7 @@
     static class NoLoaderSecurityManager extends SecurityManager
     {
         public void checkCreateClassLoader() {
-            throw new SecurityException("Not today, thanks you!");
+            throw new SecurityException("Not today, thank you!");
         }
 
         public void checkPropertyAccess(String key) { /*OK*/ }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/proprietary/Test.java	Tue May 07 17:14:17 2013 -0700
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * Test runner to check if ct.sym exists and then to execute a series
+ * of simple jtreg-like compile commands.
+ * If this is a modular JDK image (as determined by the presence of a
+ * jigsaw module library), and if ct.sym does not exist, the test will
+ * pass by default.   If this is not a modular JDK image and ct.sym
+ * does not exist, the test will fail.
+ *
+ * The equivalent of @compile and @compile/fail are supported, with
+ * the leading "@" removed. Filenames are assumed to be in the test.src
+ * directory.
+ */
+
+public class Test {
+    public static void main(String... args) throws Exception {
+
+        File javaHome = new File(System.getProperty("java.home"));
+        if (javaHome.getName().equals("jre"))
+            javaHome = javaHome.getParentFile();
+        if (file(javaHome, "lib", "modules", "%jigsaw-library").exists()
+                && !file(javaHome, "lib", "ct.sym").exists()) {
+            System.err.println("PASS BY DEFAULT: modular JDK found with no ct.sym");
+            return;
+        }
+
+        new Test().run(args);
+    }
+
+    void run(String... args) throws Exception {
+        List<String> compileArgs = new ArrayList<String>();
+        boolean expectFail = false;
+
+        for (String arg: args) {
+            if (arg.equals("compile")) {
+                if (compileArgs.size() > 0)
+                    compile(compileArgs, expectFail);
+                compileArgs.clear();
+                expectFail = false;
+            } else if (arg.equals("compile/fail")) {
+                if (compileArgs.size() > 0)
+                    compile(compileArgs, expectFail);
+                compileArgs.clear();
+                expectFail = true;
+            } else {
+                compileArgs.add(arg);
+            }
+        }
+
+        if (compileArgs.size() > 0)
+            compile(compileArgs, expectFail);
+
+        if (errors > 0)
+            throw new Exception(errors + " errors found");
+    }
+
+    void compile(List<String> args, boolean expectFail) {
+        System.err.println("javac: " + args);
+
+        File testSrc = new File(System.getProperty("test.src"));
+        for (int i = 0; i < args.size(); i++) {
+            String arg = args.get(i);
+            if (arg.endsWith(".java"))
+                args.set(i, new File(testSrc, arg).getPath());
+        }
+
+	args.add("-d");
+	args.add(System.getProperty("test.classes"));
+
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        int rc = com.sun.tools.javac.Main.compile(args.toArray(new String[args.size()]), pw);
+        String out = sw.toString();
+        System.err.println(out);
+        if (expectFail && rc == 0)
+            error("compilation succeeded unexpectedly");
+        else if (!expectFail && rc != 0)
+            error("compilation failed unexpectedly, rc=" + rc);
+    }
+
+    void error(String msg) {
+        System.err.println("Error: " + msg);
+        errors++;
+    }
+
+    int errors;
+
+    static File file(File dir, String... path) {
+        File f = dir;
+        for (String p: path)
+            f = new File(f, p);
+        return f;
+    }
+}
--- a/test/tools/javac/proprietary/WarnClass.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javac/proprietary/WarnClass.java	Tue May 07 17:14:17 2013 -0700
@@ -26,11 +26,12 @@
  * @bug     6380059
  * @summary Emit warnings for proprietary packages in the boot class path
  * @author  Peter von der Ah\u00e9
- * @compile WarnClass.java
- * @compile/fail -Werror WarnClass.java
- * @compile/fail -Werror -source 1.4 -nowarn WarnClass.java
- * @compile/fail -Werror -nowarn WarnClass.java
- * @compile/fail -Werror -Xlint:none WarnClass.java
+ * @run main Test
+ *      compile WarnClass.java
+ *      compile/fail -Werror WarnClass.java
+ *      compile/fail -Werror -source 1.4 -nowarn WarnClass.java
+ *      compile/fail -Werror -nowarn WarnClass.java
+ *      compile/fail -Werror -Xlint:none WarnClass.java
  */
 
 public class WarnClass extends sun.misc.Lock {}
--- a/test/tools/javac/proprietary/WarnImport.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javac/proprietary/WarnImport.java	Tue May 07 17:14:17 2013 -0700
@@ -26,11 +26,12 @@
  * @bug     6380059
  * @summary Emit warnings for proprietary packages in the boot class path
  * @author  Peter von der Ah\u00e9
- * @compile WarnImport.java
- * @compile/fail -Werror WarnImport.java
- * @compile/fail -Werror -source 1.4 -nowarn WarnImport.java
- * @compile/fail -Werror -nowarn WarnImport.java
- * @compile/fail -Werror -Xlint:none WarnImport.java
+ * @run main Test
+ *      compile WarnImport.java
+ *      compile/fail -Werror WarnImport.java
+ *      compile/fail -Werror -source 1.4 -nowarn WarnImport.java
+ *      compile/fail -Werror -nowarn WarnImport.java
+ *      compile/fail -Werror -Xlint:none WarnImport.java
  */
 
 import sun.misc.VM;
--- a/test/tools/javac/proprietary/WarnMethod.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javac/proprietary/WarnMethod.java	Tue May 07 17:14:17 2013 -0700
@@ -26,11 +26,12 @@
  * @bug     6380059
  * @summary Emit warnings for proprietary packages in the boot class path
  * @author  Peter von der Ah\u00e9
- * @compile WarnMethod.java
- * @compile/fail -Werror WarnMethod.java
- * @compile/fail -Werror -source 1.4 -nowarn WarnMethod.java
- * @compile/fail -Werror -nowarn WarnMethod.java
- * @compile/fail -Werror -Xlint:none WarnMethod.java
+ * @run main Test
+ *      compile WarnMethod.java
+ *      compile/fail -Werror WarnMethod.java
+ *      compile/fail -Werror -source 1.4 -nowarn WarnMethod.java
+ *      compile/fail -Werror -nowarn WarnMethod.java
+ *      compile/fail -Werror -Xlint:none WarnMethod.java
  */
 
 public class WarnMethod {
--- a/test/tools/javac/proprietary/WarnStaticImport.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javac/proprietary/WarnStaticImport.java	Tue May 07 17:14:17 2013 -0700
@@ -26,11 +26,12 @@
  * @bug     6380059
  * @summary Emit warnings for proprietary packages in the boot class path
  * @author  Peter von der Ah\u00e9
- * @compile WarnStaticImport.java
- * @compile/fail -Werror WarnStaticImport.java
- * @compile/fail -Werror -source 1.4 -nowarn WarnStaticImport.java
- * @compile/fail -Werror -nowarn WarnStaticImport.java
- * @compile/fail -Werror -Xlint:none WarnStaticImport.java
+ * @run main Test
+ *      compile WarnStaticImport.java
+ *      compile/fail -Werror WarnStaticImport.java
+ *      compile/fail -Werror -source 1.4 -nowarn WarnStaticImport.java
+ *      compile/fail -Werror -nowarn WarnStaticImport.java
+ *      compile/fail -Werror -Xlint:none WarnStaticImport.java
  */
 
 import static sun.misc.VM.getFinalRefCount;
--- a/test/tools/javac/proprietary/WarnVariable.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javac/proprietary/WarnVariable.java	Tue May 07 17:14:17 2013 -0700
@@ -26,11 +26,12 @@
  * @bug     6380059
  * @summary Emit warnings for proprietary packages in the boot class path
  * @author  Peter von der Ah\u00e9
- * @compile WarnVariable.java
- * @compile/fail -Werror WarnVariable.java
- * @compile/fail -Werror -source 1.4 -nowarn WarnVariable.java
- * @compile/fail -Werror -nowarn WarnVariable.java
- * @compile/fail -Werror -Xlint:none WarnVariable.java
+ * @run main Test
+ *      compile WarnVariable.java
+ *      compile/fail -Werror WarnVariable.java
+ *      compile/fail -Werror -source 1.4 -nowarn WarnVariable.java
+ *      compile/fail -Werror -nowarn WarnVariable.java
+ *      compile/fail -Werror -Xlint:none WarnVariable.java
  */
 
 public class WarnVariable {
--- a/test/tools/javac/proprietary/WarnWildcard.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javac/proprietary/WarnWildcard.java	Tue May 07 17:14:17 2013 -0700
@@ -26,11 +26,12 @@
  * @bug     6380059
  * @summary Emit warnings for proprietary packages in the boot class path
  * @author  Peter von der Ah\u00e9
- * @compile WarnWildcard.java
- * @compile/fail -Werror WarnWildcard.java
- * @compile/fail -Werror -source 1.4 -nowarn WarnWildcard.java
- * @compile/fail -Werror -nowarn WarnWildcard.java
- * @compile/fail -Werror -Xlint:none WarnWildcard.java
+ * @run main Test
+ *      compile WarnWildcard.java
+ *      compile/fail -Werror WarnWildcard.java
+ *      compile/fail -Werror -source 1.4 -nowarn WarnWildcard.java
+ *      compile/fail -Werror -nowarn WarnWildcard.java
+ *      compile/fail -Werror -Xlint:none WarnWildcard.java
  */
 
 public class WarnWildcard {
--- a/test/tools/javac/tree/TreeKindTest.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javac/tree/TreeKindTest.java	Tue May 07 17:14:17 2013 -0700
@@ -113,6 +113,26 @@
                 ok = ok & verify(k, i, i == AnnotationTree.class);
                 break;
 
+            case MODULE:
+                ok = ok & verify(k, i, i == ModuleTree.class);
+                break;
+
+            case MODULE_CLASS:
+                ok = ok & verify(k, i, i == ModuleClassTree.class);
+                break;
+
+            case MODULE_PERMITS:
+                ok = ok & verify(k, i, i == ModulePermitsTree.class);
+                break;
+
+            case MODULE_REQUIRES:
+                ok = ok & verify(k, i, i == ModuleRequiresTree.class);
+                break;
+
+            case PACKAGE:
+                ok = ok & verify(k, i, i == PackageTree.class);
+                break;
+
             case OTHER:
                 ok = ok & verify(k, i, i == null);
                 break;
--- a/test/tools/javac/varargs/6730476/T6730476b.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javac/varargs/6730476/T6730476b.java	Tue May 07 17:14:17 2013 -0700
@@ -27,7 +27,7 @@
  *
  * @summary invalid "unchecked generic array" warning
  * @author mcimadamore
- * @compile T6730476b.java -Xlint -Werror
+ * @compile T6730476b.java -Xlint:all,-path -Werror
  *
  */
 
--- a/test/tools/javap/T6729471.java	Thu Apr 25 09:24:40 2013 -0700
+++ b/test/tools/javap/T6729471.java	Tue May 07 17:14:17 2013 -0700
@@ -31,14 +31,16 @@
 import java.io.*;
 import java.net.*;
 import java.util.*;
+import java.util.jar.*;
+import java.util.zip.*;
 
 public class T6729471
 {
-    public static void main(String... args) {
+    public static void main(String... args) throws Exception {
         new T6729471().run();
     }
 
-    void run() {
+    void run() throws Exception {
         File testClasses = new File(System.getProperty("test.classes"));
 
         // simple class
@@ -57,16 +59,29 @@
         verify(new File(testClasses, "T6729471.class").toURI().toString(),
                 "public static void main(java.lang.String...)");
 
+        // jar url: local jar
+        File my_jar = createJar("my.jar", getClasses(Map.class));
+        try {
+            verify("jar:" + my_jar.toURL() + "!/java/util/Map.class",
+                "public abstract boolean containsKey(java.lang.Object)");
+        } catch (MalformedURLException e) {
+            error(e.toString());
+        }
+
         // jar url: rt.jar
         File java_home = new File(System.getProperty("java.home"));
         if (java_home.getName().equals("jre"))
             java_home = java_home.getParentFile();
         File rt_jar = new File(new File(new File(java_home, "jre"), "lib"), "rt.jar");
-        try {
-            verify("jar:" + rt_jar.toURL() + "!/java/util/Map.class",
-                "public abstract boolean containsKey(java.lang.Object)");
-        } catch (MalformedURLException e) {
-            error(e.toString());
+        if (rt_jar.exists()) {
+            try {
+                verify("jar:" + rt_jar.toURL() + "!/java/util/Map.class",
+                    "public abstract boolean containsKey(java.lang.Object)");
+            } catch (MalformedURLException e) {
+                error(e.toString());
+            }
+        } else {
+            System.err.println("warning: rt.jar not found; test skipped");
         }
 
         // jar url: ct.sym, if it exists
@@ -78,8 +93,9 @@
             } catch (MalformedURLException e) {
                 error(e.toString());
             }
-        } else
-            System.err.println("warning: ct.sym not found");
+        } else {
+            System.err.println("warning: ct.sym not found; test skipped");
+        }
 
         if (errors > 0)
             throw new Error(errors + " found.");
@@ -116,5 +132,48 @@
             throw new Error("javap reported error.");
         return output;
     }
+
+    Map<String,byte[]> getClasses(Class... classes) throws IOException {
+        ClassLoader cl = getClass().getClassLoader();
+        Map<String,byte[]> results = new HashMap<String, byte[]>();
+        for (Class c: classes) {
+            String name = c.getName().replace(".", "/") + ".class";
+            byte[] data = read(cl.getResourceAsStream(name));
+            results.put(name, data);
+        }
+        return results;
+    }
+
+    byte[] read(InputStream in) throws IOException {
+        try {
+            byte[] data = new byte[8192];
+            int offset = 0;
+            int n;
+            while ((n = in.read(data, offset, data.length - offset)) >= 0) {
+                offset += n;
+                if (offset == data.length)
+                    data = Arrays.copyOf(data, 2 * data.length);
+            }
+            return data;
+        } finally {
+            in.close();
+        }
+    }
+
+    File createJar(String name, Map<String, byte[]> entries) throws IOException {
+        File jar = new File(name);
+        OutputStream out = new FileOutputStream(jar);
+        try {
+            JarOutputStream jos = new JarOutputStream(out);
+            for (Map.Entry<String,byte[]> e: entries.entrySet()) {
+                jos.putNextEntry(new ZipEntry(e.getKey()));
+                jos.write(e.getValue());
+            }
+            jos.close();
+        } finally {
+            out.close();
+        }
+        return jar;
+    }
 }