8159305: Enhance the javadoc tool to support module related options
authorksrini
Thu, 18 Aug 2016 05:48:35 -0700
changeset 40508 74ef30d16fb9
parent 40507 4413083331c7
child 40509 acceda7a3297
8159305: Enhance the javadoc tool to support module related options Reviewed-by: bpatel, jjg
langtools/src/java.compiler/share/classes/javax/tools/JavaCompiler.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/Doclet.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/DocletEnvironment.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/package-info.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractExecutableMemberWriter.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractModuleIndexWriter.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConfigurationImpl.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleFrameWriter.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageFrameWriter.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/AbstractDoclet.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/OverviewElement.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/PackageSummaryBuilder.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/SerializedFormBuilder.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/ClassTree.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/ClassUseMapper.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DeprecatedAPIListBuilder.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/IndexBuilder.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/PackageListWriter.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/TypeElementCatalog.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/AccessKind.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/DocEnvImpl.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolEnvironment.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOption.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties
langtools/test/jdk/javadoc/doclet/testFramesNoFrames/TestFramesNoFrames.java
langtools/test/jdk/javadoc/doclet/testLinkTaglet/TestLinkTaglet.java
langtools/test/jdk/javadoc/doclet/testModules/TestModules.java
langtools/test/jdk/javadoc/tool/6227454/Test.java
langtools/test/jdk/javadoc/tool/BreakIteratorWarning.java
langtools/test/jdk/javadoc/tool/InlineTagsWithBraces.java
langtools/test/jdk/javadoc/tool/NoStar.java
langtools/test/jdk/javadoc/tool/T4994049/T4994049.java
langtools/test/jdk/javadoc/tool/completionFailure/CompletionFailure.java
langtools/test/jdk/javadoc/tool/dupOk/DupOk.java
langtools/test/jdk/javadoc/tool/modules/FilterOptions.java
langtools/test/jdk/javadoc/tool/modules/ModuleTestBase.java
langtools/test/jdk/javadoc/tool/modules/Modules.java
langtools/test/jdk/javadoc/tool/modules/PackageOptions.java
langtools/test/jdk/javadoc/tool/sourceOnly/Test.java
langtools/test/jdk/javadoc/tool/sourceOnly/p/NonSource.class
langtools/test/jdk/javadoc/tool/sourceOnly/p/SourceOnly.java
langtools/test/jdk/javadoc/tool/sourceOption/SourceOption.java
langtools/test/jdk/javadoc/tool/subpackageIgnore/pkg1/ValidFile.java
--- a/langtools/src/java.compiler/share/classes/javax/tools/JavaCompiler.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/java.compiler/share/classes/javax/tools/JavaCompiler.java	Thu Aug 18 05:48:35 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -160,7 +160,7 @@
  *     log all calls to {@linkplain JavaFileManager#flush}:
  *
  *     <pre>
- *       final {@linkplain java.util.logging.Logger Logger} logger = ...;
+ *       final  Logger logger = ...;
  *       {@code Iterable<? extends JavaFileObject>} compilationUnits = ...;
  *       JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
  *       StandardJavaFileManager stdFileManager = compiler.getStandardFileManager(null, null, null);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/Doclet.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/Doclet.java	Thu Aug 18 05:48:35 2016 -0700
@@ -63,8 +63,7 @@
     /**
      * Initializes this doclet with the given locale and error reporter.
      * This locale will be used by the reporter and the doclet components.
-     * It is recommended to call this as early as possible, for a
-     * uniform localized user experience,
+     *
      * @param locale the locale to be used
      * @param reporter the reporter to be used
      */
@@ -74,6 +73,7 @@
      * Returns a name identifying the doclet. A name is a simple identifier
      * without white spaces, as defined in <cite>The Java&trade; Language Specification</cite>,
      * section 6.2 "Names and Identifiers".
+     *
      * @return name of the Doclet
      */
     public abstract String getName();
@@ -81,7 +81,7 @@
     /**
      * Returns all the supported options.
      *
-     * @return a Set containing all the supported options, an empty set if none.
+     * @return a set containing all the supported options, an empty set if none
      */
     public Set<Option> getSupportedOptions();
 
@@ -90,7 +90,7 @@
      * by this doclet.
      *
      * @return  the language version supported by this doclet, usually
-     * the latest version.
+     * the latest version
      */
     public SourceVersion getSupportedSourceVersion();
 
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/DocletEnvironment.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/DocletEnvironment.java	Thu Aug 18 05:48:35 2016 -0700
@@ -30,6 +30,8 @@
 
 import javax.lang.model.SourceVersion;
 import javax.lang.model.element.Element;
+import javax.lang.model.element.ModuleElement;
+import javax.lang.model.element.PackageElement;
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.util.Elements;
 import javax.lang.model.util.Types;
@@ -48,17 +50,34 @@
 public interface DocletEnvironment {
     /**
      * Returns the <a href="package-summary.html#included">included</a>
-     * classes, interfaces and enums in all packages.
+     * modules.
+     *
+     * @return a set of included module elements
+     */
+    Set<ModuleElement> getIncludedModuleElements();
+
+    /**
+     * Returns the <a href="package-summary.html#included">included</a>
+     * annotation types, classes, interfaces and enums in all packages.
      *
-     * @return a Set containing {@link javax.lang.model.element.TypeElement TypeElements}.
+     * @return a set of included type elements
      */
-    Set<TypeElement> getIncludedClasses();
+    Set<TypeElement> getIncludedTypeElements();
+
+    /**
+     * Returns the <a href="package-summary.html#included">included</a>
+     * packages.
+     *
+     * @return a set of included package elements
+     */
+    Set<PackageElement> getIncludedPackageElements();
 
     /**
      * Returns an instance of the {@code DocTrees} utility class.
      * This class provides methods to access {@code TreePath}s, {@code DocCommentTree}s
      * and so on.
-     * @return a utility class to operate on doc trees.
+     *
+     * @return a utility class to operate on doc trees
      */
     DocTrees getDocTrees();
 
@@ -66,21 +85,23 @@
      * Returns an instance of the {@code Elements} utility class.
      * This class provides methods for operating on
      * {@link javax.lang.model.element.Element elements}.
+     *
      * @return a utility class to operate on elements
      */
     Elements getElementUtils();
 
     /**
-     * Returns the selected elements that can be documented.
+     * Returns the <a href="package-summary.html#included">selected</a>
+     * elements that can be documented.
      *
      * @param elements those that need to be checked
-     * @return elements selected, an empty list if none.
+     * @return elements selected, an empty list if none
      */
     List<Element> getSelectedElements(List<? extends Element> elements);
 
     /**
-     * Returns the elements <a href="package-summary.html#included">specified</a>
-     * on the command line, usually PackageElements and TypeElements.
+     * Returns the elements <a href="package-summary.html#specified">specified</a>
+     * on the command line, usually module elements, package elements and type elements.
      * If {@code -subpackages} and {@code -exclude} options
      * are used, return all the non-excluded packages.
      *
@@ -92,6 +113,7 @@
      * Returns an instance of the {@code Types} utility class.
      * This class provides methods for operating on
      * {@link javax.lang.model.type.TypeMirror type mirrors}.
+     *
      * @return a utility class to operate on type mirrors
      */
     Types getTypeUtils();
@@ -117,4 +139,18 @@
      * @return the source version
      */
     SourceVersion getSourceVersion();
+
+    /**
+     * Returns the required level of module documentation.
+     *
+     * @return the required level of module documentation
+     */
+    public ModuleMode getModuleMode();
+
+    enum ModuleMode {
+        /** Indicate API level documentation is required */
+        API,
+        /** Indicate Detailed documentation is required */
+        ALL
+    }
 }
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/package-info.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/package-info.java	Thu Aug 18 05:48:35 2016 -0700
@@ -27,7 +27,7 @@
  * The Doclet API provides an environment which, in conjunction with
  * the Language Model API and Compiler Tree API, allows clients
  * to inspect the source-level structures of programs and
- * libraries, including javadoc comments embedded in the source.
+ * libraries, including API comments embedded in the source.
  *
  * <p style="font-style: italic">
  * <b>Note:</b> The declarations in this package supersede those
@@ -57,15 +57,58 @@
  * <a name="terminology"></a>
  * <h3>Terminology</h3>
  *
+ * <a name="specified"></a>
+ * Module, package and source file names can be provided as parameters to the
+ * javadoc tool -- these are called the <em>specified</em> set containing
+ * module elements, package elements and type elements.
+ * <p>
+ * Javadoc <em>selection control</em> can be specified with
+ * {@code --show-members:value}, {@code --showtypes:value}, where value can be one of
+ * the following:
+ * <ul>
+ * <li> public    -- considers only public elements
+ * <li> protected -- considers public and protected elements
+ * <li> package   -- considers public, protected and package private elements
+ * <li> private   -- considers all elements
+ * </ul>
+ *
+ * The {@code --show-package:value} where a value of "exported" or "all" can be used to
+ * consider only exported packages or all packages within a module.
+ * <p>
+ * The {@code --expand-requires:value}, expands the "requires" directives of a
+ * module declaration, to create a module set to considered for documentation
+ * as follows:
+ * <ul>
+ * <li> public -- follows and expands  all "requires public" edges in the module graph
+ * <li> all    -- follows and expands  all "requires" edges in the module graph.
+ * By default, only the specified modules will be considered, without expansion
+ * of the module dependencies.
+ * </ul>
  * <a name="included"></a>
- * When calling javadoc, one can pass in package names and source file names --
- * these are called the <em>specified</em> PackageElements and TypeElements.
- * Javadoc options are also passed in; the <em>access control</em> Javadoc options
- * ({@code -public}, {@code -protected}, {@code -package},
- * and {@code -private}) are used to filter program elements, producing a
- * result set, called the <em>included</em> set, or "selected" set.
+ * All of the above are used to select the elements, to produce the
+ * <em>included</em> or the <em>selected</em> set.
+ * <p>
+ * {@code --show-module-contents:value} can be used to specify the level at
+ * module declarations could be documented, a value of "api" indicates API
+ * level documentation, and "all" indicates detailed documentation.
  * <p>
-
+ * <a name="legacy-interactions"></a>
+ * <h4>Interactions with older options.</h4>
+ *
+ * The new --show-* options provide a more detailed replacement for the older
+ * options -public, -protected, -package, -private.  Alternatively, the older
+ * options can continue to be used as shorter forms for combinations of the
+ * new options, as described below:
+ <table style="font-family: monospace" border=1>
+    <caption>Short form options mapping</caption>
+    <tr><th>Older option<th colspan="5">Equivalent to these values with the new option
+    <tr><th><th>--show-members<th>--show-types<th>--show-packages<th>--show-module-contents
+    <tr><td>-public<td>public<td>public<td>exported<td>api
+    <tr><td>-protected<td>protected<td>protected<td>exported<td>api
+    <tr><td>-package<td>package<td>package<td>all<td>all
+    <tr><td>-private<td>private<td>private<td>all<td>all
+  </table>
+ * <p>
  * <a name="qualified"></a>
  * A <em>qualified</em> element name is one that has its package
  * name prepended to it, such as {@code java.lang.String}.  A non-qualified
@@ -96,14 +139,14 @@
  *     }
  *
  *     &#64;Override
- *     public boolean run(RootDoc root) {
+ *     public boolean run(DocletEnvironment docEnv) {
  *         // cache the DocTrees utility class to access DocComments
- *         DocTrees docTrees = root.getDocTrees();
+ *         DocTrees docTrees = docEnv.getDocTrees();
  *
  *         // location of an element in the same directory as overview.html
  *         try {
  *             Element barElement = null;
- *             for (Element e : root.getIncludedClasses()) {
+ *             for (Element e : docEnv.getIncludedClasses()) {
  *                 if (e.getSimpleName().toString().equals("FooBar")) {
  *                     barElement = e;
  *                 }
@@ -118,7 +161,7 @@
  *             System.err.println("No overview.html found.");
  *         }
  *
- *         for (TypeElement t : root.getIncludedClasses()) {
+ *         for (TypeElement t : docEnv.getIncludedClasses()) {
  *             System.out.println(t.getKind() + ":" + t);
  *             for (Element e : t.getEnclosedElements()) {
  *                 DocCommentTree docCommentTree = docTrees.getDocCommentTree(e);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractExecutableMemberWriter.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractExecutableMemberWriter.java	Thu Aug 18 05:48:35 2016 -0700
@@ -115,7 +115,7 @@
      * Add the summary link for the member.
      *
      * @param context the id of the context where the link will be printed
-     * @param te the classDoc that we should link to
+     * @param te the type element being linked to
      * @param member the member being linked to
      * @param tdSummary the content tree to which the link will be added
      */
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractModuleIndexWriter.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractModuleIndexWriter.java	Thu Aug 18 05:48:35 2016 -0700
@@ -28,6 +28,7 @@
 import java.io.*;
 import java.util.Map;
 import java.util.Set;
+import java.util.SortedMap;
 
 import javax.lang.model.element.ModuleElement;
 import javax.lang.model.element.PackageElement;
@@ -57,7 +58,7 @@
     /**
      * Modules to be documented.
      */
-    protected Map<ModuleElement, Set<PackageElement>> modules;
+    protected SortedMap<ModuleElement, Set<PackageElement>> modules;
 
     /**
      * Constructor. Also initializes the modules variable.
@@ -142,7 +143,7 @@
      *
      * @param title the title of the window.
      * @param includeScript boolean set true if windowtitle script is to be included
-     * @param moduleName the name of the module being documented
+     * @param mdle the name of the module being documented
      */
     protected void buildModulePackagesIndexFile(String title,
             boolean includeScript, ModuleElement mdle) throws IOException {
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java	Thu Aug 18 05:48:35 2016 -0700
@@ -105,7 +105,7 @@
     /**
      * {@inheritDoc}
      */
-    public void addAnnotationDetailsTreeHeader(TypeElement classDoc,
+    public void addAnnotationDetailsTreeHeader(TypeElement te,
             Content memberDetailsTree) {
         if (!writer.printedAnnotationHeading) {
             memberDetailsTree.addContent(writer.getMarkerAnchor(
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java	Thu Aug 18 05:48:35 2016 -0700
@@ -179,7 +179,7 @@
      */
     public static void generate(ConfigurationImpl configuration, ClassTree classtree)  {
         ClassUseMapper mapper = new ClassUseMapper(configuration, classtree);
-        for (TypeElement aClass : configuration.docEnv.getIncludedClasses()) {
+        for (TypeElement aClass : configuration.docEnv.getIncludedTypeElements()) {
             // If -nodeprecated option is set and the containing package is marked
             // as deprecated, do not generate the class-use page. We will still generate
             // the class-use page if the class is marked as deprecated but the containing
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConfigurationImpl.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConfigurationImpl.java	Thu Aug 18 05:48:35 2016 -0700
@@ -25,7 +25,6 @@
 
 package jdk.javadoc.internal.doclets.formats.html;
 
-import java.io.IOException;
 import java.net.*;
 import java.util.*;
 
@@ -34,14 +33,10 @@
 import javax.lang.model.element.TypeElement;
 import javax.tools.JavaFileManager;
 import javax.tools.JavaFileObject;
-import javax.tools.JavaFileManager.Location;
 import javax.tools.StandardJavaFileManager;
-import javax.tools.StandardLocation;
 
 import com.sun.source.util.DocTreePath;
 import com.sun.tools.doclint.DocLint;
-import com.sun.tools.javac.code.Symbol.ModuleSymbol;
-import com.sun.tools.javac.code.Symbol.PackageSymbol;
 
 import jdk.javadoc.doclet.Doclet;
 import jdk.javadoc.doclet.DocletEnvironment;
@@ -383,7 +378,7 @@
         if (!docEnv.getSpecifiedElements().isEmpty()) {
             Map<String, PackageElement> map = new HashMap<>();
             PackageElement pkg;
-            List<TypeElement> classes = new ArrayList<>(docEnv.getIncludedClasses());
+            List<TypeElement> classes = new ArrayList<>(docEnv.getIncludedTypeElements());
             for (TypeElement aClass : classes) {
                 pkg = utils.containingPackage(aClass);
                 if (!map.containsKey(utils.getPackageName(pkg))) {
@@ -420,7 +415,7 @@
      * package to document. It will be a class page(first in the sorted order),
      * if only classes are provided on the command line.
      *
-     * @param docEnv Root of the program structure.
+     * @param docEnv the doclet environment
      */
     protected void setTopFile(DocletEnvironment docEnv) {
         if (!checkForDeprecation(docEnv)) {
@@ -429,9 +424,11 @@
         if (createoverview) {
             topFile = DocPaths.overviewSummary(frames);
         } else {
-            if (packages.size() == 1 && packages.first().isUnnamed()) {
-                if (!docEnv.getIncludedClasses().isEmpty()) {
-                    List<TypeElement> classes = new ArrayList<>(docEnv.getIncludedClasses());
+            if (showModules) {
+                topFile = DocPath.empty.resolve(DocPaths.moduleSummary(modules.first()));
+            } else if (packages.size() == 1 && packages.first().isUnnamed()) {
+                List<TypeElement> classes = new ArrayList<>(docEnv.getIncludedTypeElements());
+                if (!classes.isEmpty()) {
                     TypeElement te = getValidClass(classes);
                     topFile = DocPath.forClass(utils, te);
                 }
@@ -454,7 +451,7 @@
     }
 
     protected boolean checkForDeprecation(DocletEnvironment docEnv) {
-        for (TypeElement te : docEnv.getIncludedClasses()) {
+        for (TypeElement te : docEnv.getIncludedTypeElements()) {
             if (isGeneratedDoc(te)) {
                 return true;
             }
@@ -579,21 +576,6 @@
         return contents.getContent(key, o0, o1, o2);
     }
 
-
-    @Override
-    public Location getLocationForPackage(PackageElement pd) {
-        JavaFileManager fm = getFileManager();
-        if (fm.hasLocation(StandardLocation.MODULE_SOURCE_PATH) && (pd instanceof PackageSymbol)) {
-            try {
-                ModuleSymbol msym = ((PackageSymbol) pd).modle;
-                return fm.getModuleLocation(StandardLocation.MODULE_SOURCE_PATH, msym.name.toString());
-            } catch (IOException e) {
-                throw new DocletAbortException(e);
-            }
-        }
-        return StandardLocation.SOURCE_PATH;
-    }
-
     protected void buildSearchTagIndex() {
         for (SearchIndexItem sii : tagSearchIndex) {
             String tagLabel = sii.getLabel();
@@ -725,7 +707,7 @@
                     return true;
                 }
             },
-            new Hidden(this, "-overview", 1) {
+            new Option(this, "-overview", 1) {
                 @Override
                 public boolean process(String opt,  ListIterator<String> args) {
                     optionsProcessed.add(this);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java	Thu Aug 18 05:48:35 2016 -0700
@@ -827,8 +827,8 @@
      * @return a content tree for the link
      */
     protected Content getNavLinkTree() {
-        List<PackageElement> packages = new ArrayList<>(utils.getSpecifiedPackages());
-        DocPath docPath = packages.size() == 1 && utils.getSpecifiedClasses().isEmpty()
+        List<PackageElement> packages = new ArrayList<>(configuration.getSpecifiedPackages());
+        DocPath docPath = packages.size() == 1 && configuration.getSpecifiedClasses().isEmpty()
                 ? pathString(packages.get(0), DocPaths.PACKAGE_TREE)
                 : pathToRoot.resolve(DocPaths.OVERVIEW_TREE);
         return HtmlTree.LI(getHyperLink(docPath, contents.treeLabel, "", ""));
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleFrameWriter.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleFrameWriter.java	Thu Aug 18 05:48:35 2016 -0700
@@ -80,9 +80,9 @@
             throws IOException {
         super(configuration, DocPaths.moduleTypeFrame(moduleElement));
         this.mdle = moduleElement;
-        if (utils.getSpecifiedPackages().isEmpty()) {
+        if (configuration.getSpecifiedPackages().isEmpty()) {
             documentedClasses = new TreeSet<>(utils.makeGeneralPurposeComparator());
-            documentedClasses.addAll(configuration.docEnv.getIncludedClasses());
+            documentedClasses.addAll(configuration.docEnv.getIncludedTypeElements());
         }
     }
 
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageFrameWriter.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageFrameWriter.java	Thu Aug 18 05:48:35 2016 -0700
@@ -84,9 +84,9 @@
     public PackageFrameWriter(ConfigurationImpl configuration, PackageElement packageElement) {
         super(configuration, DocPath.forPackage(packageElement).resolve(DocPaths.PACKAGE_FRAME));
         this.packageElement = packageElement;
-        if (utils.getSpecifiedPackages().isEmpty()) {
+        if (configuration.getSpecifiedPackages().isEmpty()) {
             documentedClasses = new TreeSet<>(utils.makeGeneralPurposeComparator());
-            documentedClasses.addAll(configuration.docEnv.getIncludedClasses());
+            documentedClasses.addAll(configuration.docEnv.getIncludedTypeElements());
         }
     }
 
@@ -136,7 +136,7 @@
      */
     protected void addClassListing(HtmlTree contentTree) {
         Configuration config = configuration;
-        if (utils.isIncluded(packageElement)) {
+        if (utils.isSpecified(packageElement)) {
             addClassKindListing(utils.getInterfaces(packageElement),
                 contents.interfaces, contentTree);
             addClassKindListing(utils.getOrdinaryClasses(packageElement),
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java	Thu Aug 18 05:48:35 2016 -0700
@@ -70,7 +70,7 @@
     public SerializedFormWriterImpl(ConfigurationImpl configuration)
             throws IOException {
         super(configuration, DocPaths.SERIALIZED_FORM);
-        visibleClasses = configuration.docEnv.getIncludedClasses();
+        visibleClasses = configuration.docEnv.getIncludedTypeElements();
     }
 
     /**
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java	Thu Aug 18 05:48:35 2016 -0700
@@ -112,13 +112,13 @@
         if (docEnv == null || outputdir == null) {
             return;
         }
-        for (PackageElement pkg : utils.getSpecifiedPackages()) {
+        for (PackageElement pkg : configuration.getSpecifiedPackages()) {
             // If -nodeprecated option is set and the package is marked as deprecated,
             // do not convert the package files to HTML.
             if (!(configuration.nodeprecated && utils.isDeprecated(pkg)))
                 convertPackage(pkg, outputdir);
         }
-        for (TypeElement te : utils.getSpecifiedClasses()) {
+        for (TypeElement te : configuration.getSpecifiedClasses()) {
             // If -nodeprecated option is set and the class is marked as deprecated
             // or the containing package is deprecated, do not convert the
             // package files to HTML.
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties	Thu Aug 18 05:48:35 2016 -0700
@@ -204,6 +204,10 @@
 
 doclet.usage.splitindex.description=Split index into one file per letter
 
+doclet.usage.overview.parameters=<file>
+doclet.usage.overview.description=Read overview documentation from HTML file
+
+
 doclet.usage.windowtitle.parameters=<text>
 doclet.usage.windowtitle.description=Browser window title for the documentation
 
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/AbstractDoclet.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/AbstractDoclet.java	Thu Aug 18 05:48:35 2016 -0700
@@ -90,13 +90,13 @@
     /**
      * The method that starts the execution of the doclet.
      *
-     * @param root   the {@link DocletEnvironment} that points to the source to document.
+     * @param docEnv   the {@link DocletEnvironment}.
      * @return true if the doclet executed without error.  False otherwise.
      */
     @Override
-    public boolean run(DocletEnvironment root) {
+    public boolean run(DocletEnvironment docEnv) {
         configuration = configuration();
-        configuration.docEnv = root;
+        configuration.docEnv = docEnv;
         configuration.cmtUtils = new CommentUtils(configuration);
         configuration.utils = new Utils(configuration);
         utils = configuration.utils;
@@ -108,7 +108,7 @@
         }
 
         try {
-            startGeneration(root);
+            startGeneration(docEnv);
         } catch (Configuration.Fault f) {
             configuration.reporter.print(ERROR, f.getMessage());
             return false;
@@ -153,8 +153,8 @@
      *
      * @see jdk.doclet.DocletEnvironment
      */
-    private void startGeneration(DocletEnvironment root) throws Configuration.Fault, Exception {
-        if (root.getIncludedClasses().isEmpty()) {
+    private void startGeneration(DocletEnvironment docEnv) throws Configuration.Fault, Exception {
+        if (docEnv.getIncludedTypeElements().isEmpty()) {
             messages.error("doclet.No_Public_Classes_To_Document");
             return;
         }
@@ -165,24 +165,24 @@
             configuration.getDocletSpecificBuildDate());
         ClassTree classtree = new ClassTree(configuration, configuration.nodeprecated);
 
-        generateClassFiles(root, classtree);
+        generateClassFiles(docEnv, classtree);
         configuration.utils.copyDocFiles(DocPaths.DOC_FILES);
 
         PackageListWriter.generate(configuration);
         generatePackageFiles(classtree);
         generateModuleFiles();
 
-        generateOtherFiles(root, classtree);
+        generateOtherFiles(docEnv, classtree);
         configuration.tagletManager.printReport();
     }
 
     /**
      * Generate additional documentation that is added to the API documentation.
      *
-     * @param root     the DocletEnvironment of source to document.
+     * @param docEnv     the DocletEnvironment.
      * @param classtree the data structure representing the class tree.
      */
-    protected void generateOtherFiles(DocletEnvironment root, ClassTree classtree) throws Exception {
+    protected void generateOtherFiles(DocletEnvironment docEnv, ClassTree classtree) throws Exception {
         BuilderFactory builderFactory = configuration.getBuilderFactory();
         AbstractBuilder constantsSummaryBuilder = builderFactory.getConstantsSummaryBuilder();
         constantsSummaryBuilder.build();
@@ -213,13 +213,16 @@
     /**
      * Iterate through all classes and construct documentation for them.
      *
-     * @param root      the DocletEnvironment of source to document.
+     * @param docEnv      the DocletEnvironment.
      * @param classtree the data structure representing the class tree.
      */
-    protected void generateClassFiles(DocletEnvironment root, ClassTree classtree) {
+    protected void generateClassFiles(DocletEnvironment docEnv, ClassTree classtree) {
         generateClassFiles(classtree);
         SortedSet<PackageElement> packages = new TreeSet<>(utils.makePackageComparator());
-        packages.addAll(utils.getSpecifiedPackages());
+        packages.addAll(configuration.getSpecifiedPackages());
+        configuration.modulePackages.values().stream().forEach(pset -> {
+            packages.addAll(pset);
+        });
         packages.stream().forEach((pkg) -> {
             generateClassFiles(utils.getAllClasses(pkg), classtree);
         });
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java	Thu Aug 18 05:48:35 2016 -0700
@@ -32,8 +32,8 @@
 import javax.lang.model.element.ModuleElement;
 import javax.lang.model.element.PackageElement;
 import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.ElementFilter;
 import javax.tools.JavaFileManager;
-import javax.tools.JavaFileManager.Location;
 import javax.tools.JavaFileObject;
 
 import com.sun.source.util.DocTreePath;
@@ -164,17 +164,17 @@
     public final MetaKeywords metakeywords;
 
     /**
-     * The list of doc-file subdirectories to exclude
+     * The set of doc-file subdirectories to exclude
      */
     protected Set<String> excludedDocFileDirs;
 
     /**
-     * The list of qualifiers to exclude
+     * The set of qualifiers to exclude
      */
     protected Set<String> excludedQualifiers;
 
     /**
-     * The Root of the generated Program Structure from the Doclet API.
+     * The doclet environment.
      */
     public DocletEnvironment docEnv;
 
@@ -314,14 +314,13 @@
     public abstract boolean finishOptionSettings();
 
     public CommentUtils cmtUtils;
-    public SortedSet<ModuleElement> modules;
 
     /**
      * A sorted set of packages specified on the command-line merged with a
      * collection of packages that contain the classes specified on the
      * command-line.
      */
-    public SortedSet<PackageElement> packages;
+    public SortedSet<PackageElement> packages = null;
 
     protected final List<Doclet.Option> optionsProcessed;
 
@@ -335,9 +334,14 @@
     public DocFileFactory docFileFactory;
 
     /**
-     * A sorted set of modules containing the packages.
+     * A sorted map, giving the (specified|included|other) packages for each module.
      */
-    public Map<ModuleElement, Set<PackageElement>> modulePackages;
+    public SortedMap<ModuleElement, Set<PackageElement>> modulePackages;
+
+   /**
+    * The list of known modules, that should be documented.
+    */
+    public SortedSet<ModuleElement> modules;
 
     protected static final String sharedResourceBundleName =
             "jdk.javadoc.internal.doclets.toolkit.resources.doclets";
@@ -372,25 +376,39 @@
 
     private void initModules() {
         // Build the modules structure used by the doclet
+        modules = new TreeSet<>(utils.makeModuleComparator());
+        modules.addAll(getSpecifiedModules());
+
         modulePackages = new TreeMap<>(utils.makeModuleComparator());
         for (PackageElement p: packages) {
             ModuleElement mdle = docEnv.getElementUtils().getModuleOf(p);
             if (mdle != null && !mdle.isUnnamed()) {
-                Set<PackageElement> s = modulePackages.get(mdle);
-                if (s == null)
-                    modulePackages.put(mdle, s = new TreeSet<>(utils.makePackageComparator()));
+                Set<PackageElement> s = modulePackages
+                        .computeIfAbsent(mdle, m -> new TreeSet<>(utils.makePackageComparator()));
                 s.add(p);
             }
         }
-        modules = new TreeSet<>(utils.makeModuleComparator());
+
+        for (PackageElement p: docEnv.getIncludedPackageElements()) {
+            ModuleElement mdle = docEnv.getElementUtils().getModuleOf(p);
+            if (mdle != null && !mdle.isUnnamed()) {
+                Set<PackageElement> s = modulePackages
+                        .computeIfAbsent(mdle, m -> new TreeSet<>(utils.makePackageComparator()));
+                s.add(p);
+            }
+        }
+
         modules.addAll(modulePackages.keySet());
-        showModules = (modulePackages.size() > 1);
+        showModules = !modules.isEmpty();
+        for (Set<PackageElement> pkgs : modulePackages.values()) {
+            packages.addAll(pkgs);
+        }
     }
 
     private void initPackages() {
         packages = new TreeSet<>(utils.makePackageComparator());
-        packages.addAll(utils.getSpecifiedPackages());
-        for (TypeElement aClass : utils.getSpecifiedClasses()) {
+        packages.addAll(getSpecifiedPackages());
+        for (TypeElement aClass : getSpecifiedClasses()) {
             packages.add(utils.containingPackage(aClass));
         }
     }
@@ -629,7 +647,7 @@
         if (docencoding == null) {
             docencoding = encoding;
         }
-        typeElementCatalog = new TypeElementCatalog(utils.getSpecifiedClasses(), this);
+        typeElementCatalog = new TypeElementCatalog(getSpecifiedClasses(), this);
         initTagletManager(customTagStrs);
         groups.stream().forEach((grp) -> {
             group.checkPackageGroups(grp.value1, grp.value2);
@@ -880,6 +898,35 @@
                 : utils.getFullyQualifiedName(te);
     }
 
+    // cache these, as they are repeatedly called.
+    private Set<TypeElement> specifiedClasses = null;
+    private Set<PackageElement> specifiedPackages = null;
+    private Set<ModuleElement> specifiedModules = null;
+
+    public Set<TypeElement> getSpecifiedClasses() {
+        if (specifiedClasses == null) {
+            specifiedClasses = new LinkedHashSet<>(
+                ElementFilter.typesIn(docEnv.getSpecifiedElements()));
+        }
+        return specifiedClasses;
+    }
+
+    public Set<PackageElement> getSpecifiedPackages() {
+        if (specifiedPackages == null) {
+            specifiedPackages = new LinkedHashSet<>(
+                    ElementFilter.packagesIn(docEnv.getSpecifiedElements()));
+        }
+        return specifiedPackages;
+    }
+
+    public Set<ModuleElement> getSpecifiedModules() {
+        if (specifiedModules == null) {
+            specifiedModules = new LinkedHashSet<>(
+                    ElementFilter.modulesIn(docEnv.getSpecifiedElements()));
+        }
+        return specifiedModules;
+    }
+
     /**
      * Convenience method to obtain a resource from the doclet's
      * {@link Resources resources}.
@@ -1146,6 +1193,4 @@
             this.value2 = value2;
         }
     }
-
-    public abstract Location getLocationForPackage(PackageElement pd);
 }
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/OverviewElement.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/OverviewElement.java	Thu Aug 18 05:48:35 2016 -0700
@@ -40,8 +40,8 @@
 import jdk.javadoc.doclet.DocletEnvironment;
 
 /**
- * This is a pseudo element wrapper for the root element, essentially to
- * associate overview documentation's DocCommentTree to this Element.
+ * This is a pseudo element wrapper for the overview element, essentially to
+ * associate overview documentation's DocCommentTree to this element.
  *
  *  <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.
@@ -50,10 +50,10 @@
  */
 public class OverviewElement implements Element {
 
-    public final DocletEnvironment root;
+    public final DocletEnvironment docEnv;
 
-    OverviewElement(DocletEnvironment root) {
-        this.root = root;
+    OverviewElement(DocletEnvironment docEnv) {
+        this.docEnv = docEnv;
     }
 
     @Override @DefinedBy(Api.LANGUAGE_MODEL)
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java	Thu Aug 18 05:48:35 2016 -0700
@@ -187,7 +187,7 @@
 
     // TODO: implement using jx.l.model
     public boolean isVisible(TypeElement te) {
-        return toolEnv.isVisible((ClassSymbol)te);
+        return ((DocEnvImpl)(configuration.docEnv)).etable.isVisible(te);
     }
 
     // TODO: fix the caller
@@ -286,7 +286,7 @@
 
     // TODO: investigate and reimplement without javac dependencies.
     public boolean shouldDocument(Element e) {
-        return toolEnv.shouldDocument(e);
+        return ((DocEnvImpl)(configuration.docEnv)).etable.shouldDocument(e);
     }
 
     //------------------Start of Serializable Implementation---------------------//
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/PackageSummaryBuilder.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/PackageSummaryBuilder.java	Thu Aug 18 05:48:35 2016 -0700
@@ -175,7 +175,7 @@
         List<String> interfaceTableHeader = Arrays.asList(configuration.getText("doclet.Interface"),
         configuration.getText("doclet.Description"));
 
-        SortedSet<TypeElement> ilist = utils.isIncluded(packageElement)
+        SortedSet<TypeElement> ilist = utils.isSpecified(packageElement)
                         ? utils.getTypeElementsAsSortedSet(utils.getInterfaces(packageElement))
                         : configuration.typeElementCatalog.interfaces(packageElement);
         SortedSet<TypeElement> interfaces = utils.filterOutPrivateClasses(ilist, configuration.javafx);
@@ -200,7 +200,7 @@
                 configuration.getText("doclet.classes"));
         List<String> classTableHeader = Arrays.asList(configuration.getText("doclet.Class"),
                 configuration.getText("doclet.Description"));
-        SortedSet<TypeElement> clist = utils.isIncluded(packageElement)
+        SortedSet<TypeElement> clist = utils.isSpecified(packageElement)
             ? utils.getTypeElementsAsSortedSet(utils.getOrdinaryClasses(packageElement))
             : configuration.typeElementCatalog.ordinaryClasses(packageElement);
         SortedSet<TypeElement> classes = utils.filterOutPrivateClasses(clist, configuration.javafx);
@@ -225,7 +225,7 @@
                 configuration.getText("doclet.enums"));
         List<String> enumTableHeader = Arrays.asList(configuration.getText("doclet.Enum"),
                 configuration.getText("doclet.Description"));
-        SortedSet<TypeElement> elist = utils.isIncluded(packageElement)
+        SortedSet<TypeElement> elist = utils.isSpecified(packageElement)
             ? utils.getTypeElementsAsSortedSet(utils.getEnums(packageElement))
             : configuration.typeElementCatalog.enums(packageElement);
         SortedSet<TypeElement> enums = utils.filterOutPrivateClasses(elist, configuration.javafx);
@@ -251,7 +251,7 @@
         List<String> exceptionTableHeader = Arrays.asList(configuration.getText("doclet.Exception"),
                 configuration.getText("doclet.Description"));
         Set<TypeElement> iexceptions =
-            utils.isIncluded(packageElement)
+            utils.isSpecified(packageElement)
                 ? utils.getTypeElementsAsSortedSet(utils.getExceptions(packageElement))
                 : configuration.typeElementCatalog.exceptions(packageElement);
         SortedSet<TypeElement> exceptions = utils.filterOutPrivateClasses(iexceptions,
@@ -278,7 +278,7 @@
         List<String> errorTableHeader = Arrays.asList(configuration.getText("doclet.Error"),
                 configuration.getText("doclet.Description"));
         Set<TypeElement> ierrors =
-            utils.isIncluded(packageElement)
+            utils.isSpecified(packageElement)
                 ? utils.getTypeElementsAsSortedSet(utils.getErrors(packageElement))
                 : configuration.typeElementCatalog.errors(packageElement);
         SortedSet<TypeElement> errors = utils.filterOutPrivateClasses(ierrors, configuration.javafx);
@@ -305,7 +305,7 @@
                 configuration.getText("doclet.AnnotationType"),
                 configuration.getText("doclet.Description"));
         SortedSet<TypeElement> iannotationTypes =
-            utils.isIncluded(packageElement)
+            utils.isSpecified(packageElement)
                 ? utils.getTypeElementsAsSortedSet(utils.getAnnotationTypes(packageElement))
                 : configuration.typeElementCatalog.annotationTypes(packageElement);
         SortedSet<TypeElement> annotationTypes = utils.filterOutPrivateClasses(iannotationTypes,
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/SerializedFormBuilder.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/SerializedFormBuilder.java	Thu Aug 18 05:48:35 2016 -0700
@@ -125,7 +125,7 @@
      */
     public void build() throws IOException {
         SortedSet<TypeElement> rootclasses = new TreeSet<>(utils.makeGeneralPurposeComparator());
-        rootclasses.addAll(configuration.docEnv.getIncludedClasses());
+        rootclasses.addAll(configuration.docEnv.getIncludedTypeElements());
         if (!serialClassFoundToDocument(rootclasses)) {
             //Nothing to document.
             return;
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/ClassTree.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/ClassTree.java	Thu Aug 18 05:48:35 2016 -0700
@@ -117,16 +117,16 @@
         baseEnums = new TreeSet<>(comparator);
         baseClasses = new TreeSet<>(comparator);
         baseInterfaces = new TreeSet<>(comparator);
-        buildTree(configuration.docEnv.getIncludedClasses());
+        buildTree(configuration.docEnv.getIncludedTypeElements());
     }
 
     /**
      * Constructor. Build the Tree using the Root of this Javadoc run.
      *
-     * @param root Root of the Document.
+     * @param docEnv the DocletEnvironment.
      * @param configuration The current configuration of the doclet.
      */
-    public ClassTree(DocletEnvironment root, Configuration configuration) {
+    public ClassTree(DocletEnvironment docEnv, Configuration configuration) {
         this.configuration = configuration;
         this.utils = configuration.utils;
         comparator = utils.makeClassUseComparator();
@@ -134,7 +134,7 @@
         baseEnums = new TreeSet<>(comparator);
         baseClasses = new TreeSet<>(comparator);
         baseInterfaces = new TreeSet<>(comparator);
-        buildTree(configuration.docEnv.getIncludedClasses());
+        buildTree(configuration.docEnv.getIncludedTypeElements());
     }
 
     /**
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/ClassUseMapper.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/ClassUseMapper.java	Thu Aug 18 05:48:35 2016 -0700
@@ -208,7 +208,7 @@
             implementingClasses(intfc);
         }
         // Map methods, fields, constructors using a class.
-        Set<TypeElement> classes = docEnv.getIncludedClasses();
+        Set<TypeElement> classes = docEnv.getIncludedTypeElements();
         for (TypeElement aClass : classes) {
             PackageElement pkg = elementUtils.getPackageOf(aClass);
             mapAnnotations(classToPackageAnnotations, pkg, pkg);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DeprecatedAPIListBuilder.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DeprecatedAPIListBuilder.java	Thu Aug 18 05:48:35 2016 -0700
@@ -96,7 +96,7 @@
             }
         }
         deprecatedMap.put(DeprElementKind.PACKAGE, pset);
-        for (Element e : configuration.docEnv.getIncludedClasses()) {
+        for (Element e : configuration.docEnv.getIncludedTypeElements()) {
             TypeElement te = (TypeElement)e;
             SortedSet<Element> eset;
             if (utils.isDeprecated(e)) {
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/IndexBuilder.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/IndexBuilder.java	Thu Aug 18 05:48:35 2016 -0700
@@ -122,11 +122,11 @@
      * given on the command line. Form separate list of those members depending
      * upon their names.
      *
-     * @param root Root of the documemt.
+     * @param docEnv the doclet environment
      */
-    protected void buildIndexMap(DocletEnvironment root)  {
-        Set<PackageElement> packages = utils.getSpecifiedPackages();
-        Set<TypeElement> classes = root.getIncludedClasses();
+    protected void buildIndexMap(DocletEnvironment docEnv)  {
+        Set<PackageElement> packages = configuration.getSpecifiedPackages();
+        Set<TypeElement> classes = docEnv.getIncludedTypeElements();
         if (!classesOnly) {
             if (packages.isEmpty()) {
                 Set<PackageElement> set = new HashSet<>();
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/PackageListWriter.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/PackageListWriter.java	Thu Aug 18 05:48:35 2016 -0700
@@ -81,7 +81,7 @@
         }
     }
 
-    protected void generatePackageListFile(DocletEnvironment root) {
+    protected void generatePackageListFile(DocletEnvironment docEnv) {
         ArrayList<PackageElement> names = new ArrayList<>();
         for (PackageElement pkg : configuration.packages) {
             // if the -nodeprecated option is set and the package is marked as
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/TypeElementCatalog.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/TypeElementCatalog.java	Thu Aug 18 05:48:35 2016 -0700
@@ -100,7 +100,7 @@
     public TypeElementCatalog(Iterable<TypeElement> typeElements, Configuration config) {
         this(config);
         for (TypeElement typeElement : typeElements) {
-            addClassDoc(typeElement);
+            addTypeElement(typeElement);
         }
     }
 
@@ -127,39 +127,38 @@
      *
      * @param typeElement the TypeElement to add to the catalog.
      */
-    public final void addClassDoc(TypeElement typeElement) {
+    public final void addTypeElement(TypeElement typeElement) {
         if (typeElement == null) {
             return;
         }
-        addClass(typeElement, allClasses);
+        addTypeElement(typeElement, allClasses);
         if (utils.isOrdinaryClass(typeElement)) {
-            addClass(typeElement, ordinaryClasses);
+            addTypeElement(typeElement, ordinaryClasses);
         } else if (utils.isException(typeElement)) {
-            addClass(typeElement, exceptions);
+            addTypeElement(typeElement, exceptions);
         } else if (utils.isEnum(typeElement)) {
-            addClass(typeElement, enums);
+            addTypeElement(typeElement, enums);
         } else if (utils.isAnnotationType(typeElement)) {
-            addClass(typeElement, annotationTypes);
+            addTypeElement(typeElement, annotationTypes);
         } else if (utils.isError(typeElement)) {
-            addClass(typeElement, errors);
+            addTypeElement(typeElement, errors);
         } else if (utils.isInterface(typeElement)) {
-            addClass(typeElement, interfaces);
+            addTypeElement(typeElement, interfaces);
         }
     }
 
     /**
      * Add the given class to the given map.
      *
-     * @param typeElement the ClassDoc to add to the catalog.
+     * @param typeElement the class to add to the catalog.
      * @param map the Map to add the TypeElement to.
      */
-    private void addClass(TypeElement typeElement, Map<PackageElement, SortedSet<TypeElement>> map) {
+    private void addTypeElement(TypeElement typeElement, Map<PackageElement, SortedSet<TypeElement>> map) {
 
         PackageElement pkg = utils.containingPackage(typeElement);
-        if (utils.isIncluded(pkg) || (configuration.nodeprecated && utils.isDeprecated(pkg))) {
+        if (utils.isSpecified(pkg) || configuration.nodeprecated && utils.isDeprecated(pkg)) {
             // No need to catalog this class if it's package is
-            // included on the command line or if -nodeprecated option is set
-            // and the containing package is marked as deprecated.
+            // specified on the command line or if -nodeprecated option is set
             return;
         }
 
@@ -186,7 +185,7 @@
      * @param packageElement the package to return the classes for.
      */
     public SortedSet<TypeElement> allClasses(PackageElement packageElement) {
-        return utils.isIncluded(packageElement)
+        return utils.isSpecified(packageElement)
                 ? utils.getTypeElementsAsSortedSet(utils.getEnclosedTypeElements(packageElement))
                 : getSet(allClasses, packageElement);
     }
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java	Thu Aug 18 05:48:35 2016 -0700
@@ -86,7 +86,6 @@
 
 import static com.sun.source.doctree.DocTree.Kind.*;
 
-import com.sun.source.util.SimpleDocTreeVisitor;
 import jdk.javadoc.internal.doclets.toolkit.Messages;
 
 import static jdk.javadoc.internal.doclets.toolkit.builders.ConstantsSummaryBuilder.MAX_CONSTANT_VALUE_INDEX_LENGTH;
@@ -2220,31 +2219,6 @@
         return oset;
     }
 
-    // cache these two as they are repeatedly called.
-    private Set<TypeElement> specifiedClasses = null;
-    private Set<PackageElement> specifiedPackages = null;
-
-    private void initSpecifiedElements() {
-        specifiedClasses = new LinkedHashSet<>(
-                ElementFilter.typesIn(configuration.docEnv.getSpecifiedElements()));
-        specifiedPackages = new LinkedHashSet<>(
-                ElementFilter.packagesIn(configuration.docEnv.getSpecifiedElements()));
-    }
-
-    public Set<TypeElement> getSpecifiedClasses() {
-        if (specifiedClasses == null || specifiedPackages == null) {
-            initSpecifiedElements();
-        }
-        return specifiedClasses;
-    }
-
-    public Set<PackageElement> getSpecifiedPackages() {
-        if (specifiedClasses == null || specifiedPackages == null) {
-            initSpecifiedElements();
-        }
-        return specifiedPackages;
-    }
-
     private final HashMap<Element, SortedSet<TypeElement>> cachedClasses = new HashMap<>();
     /**
      * Returns a list containing classes and interfaces,
@@ -2577,6 +2551,34 @@
         return configuration.docEnv.isIncluded(e);
     }
 
+    private SimpleElementVisitor9<Boolean, Void> specifiedVisitor = null;
+    public boolean isSpecified(Element e) {
+        if (specifiedVisitor == null) {
+            specifiedVisitor = new SimpleElementVisitor9<Boolean, Void>() {
+                @Override @DefinedBy(Api.LANGUAGE_MODEL)
+                public Boolean visitModule(ModuleElement e, Void p) {
+                    return configuration.getSpecifiedModules().contains(e);
+                }
+
+                @Override @DefinedBy(Api.LANGUAGE_MODEL)
+                public Boolean visitPackage(PackageElement e, Void p) {
+                    return configuration.getSpecifiedPackages().contains(e);
+                }
+
+                @Override @DefinedBy(Api.LANGUAGE_MODEL)
+                public Boolean visitType(TypeElement e, Void p) {
+                    return configuration.getSpecifiedClasses().contains(e);
+                }
+
+                @Override @DefinedBy(Api.LANGUAGE_MODEL)
+                protected Boolean defaultAction(Element e, Void p) {
+                    return false;
+                }
+            };
+        }
+        return specifiedVisitor.visit(e);
+    }
+
     /**
      * package name, an unnamed package is returned as &lt;Unnamed&gt;
      * @param pkg
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/AccessKind.java	Thu Aug 18 05:48:35 2016 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.javadoc.internal.tool;
+
+/**
+ * The access value kinds.
+ */
+
+public enum AccessKind {
+    /** Limits access to public entities */
+    PUBLIC,
+    /** Limits access to public and protected entities */
+    PROTECTED,
+    /** Limits access to public, protected and package private entities */
+    PACKAGE,
+    /** No limits */
+    PRIVATE;
+}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/DocEnvImpl.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/DocEnvImpl.java	Thu Aug 18 05:48:35 2016 -0700
@@ -25,7 +25,6 @@
 
 package jdk.javadoc.internal.tool;
 
-import java.util.Collections;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
@@ -33,6 +32,7 @@
 
 import javax.lang.model.SourceVersion;
 import javax.lang.model.element.Element;
+import javax.lang.model.element.ModuleElement;
 import javax.lang.model.element.PackageElement;
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.util.Elements;
@@ -41,7 +41,6 @@
 
 import com.sun.source.util.DocTrees;
 import com.sun.tools.javac.code.Source;
-import com.sun.tools.javac.tree.JCTree.JCClassDecl;
 import jdk.javadoc.doclet.DocletEnvironment;
 
 /**
@@ -60,202 +59,44 @@
  */
 public class DocEnvImpl implements DocletEnvironment {
 
-    /**
-     * list of classes specified on the command line.
-     */
-    private Set<TypeElement> cmdLineClasses;
-
-    /**
-     * list of packages specified on the command line.
-     */
-    private  Set<PackageElement> cmdLinePackages;
+    public final ElementsTable etable;
 
     public final ToolEnvironment toolEnv;
 
     /**
-     * Constructor used when reading source files.
-     *
-     * @param toolEnv the documentation environment, state for this javadoc run
-     * @param classes list of classes specified on the commandline
-     * @param packages list of package names specified on the commandline
-     */
-    public DocEnvImpl(ToolEnvironment toolEnv, List<JCClassDecl> classes, List<String> packages) {
-        this.toolEnv = toolEnv;
-        setPackages(toolEnv, packages);
-        setClasses(toolEnv, classes);
-    }
-
-    /**
-     * Constructor used when reading class files.
+     * Construct a doclet environment.
      *
-     * @param toolEnv the documentation environment, state for this javadoc run
-     * @param classes list of class names specified on the commandline
+     * @param toolEnv the tool environment
+     * @param etable the includes table, providing all the information
+     * with respect to specified, included/selected elements.
      */
-    public DocEnvImpl(ToolEnvironment toolEnv, List<String> classes) {
-        //super(env, null);
+    public DocEnvImpl(ToolEnvironment toolEnv, ElementsTable etable) {
         this.toolEnv = toolEnv;
-
-        Set<TypeElement> classList = new LinkedHashSet<>();
-        for (String className : classes) {
-            TypeElement c = toolEnv.loadClass(className);
-            if (c == null)
-                toolEnv.error(null, "javadoc.class_not_found", className);
-            else
-                classList.add(c);
-        }
-        cmdLineClasses = classList;
+        this.etable = etable;
     }
 
-    /**
-     * Initialize classes information. Those classes are input from
-     * command line.
-     *
-     * @param toolEnv the compilation environment
-     * @param classes a list of ClassDeclaration
-     */
-    private void setClasses(ToolEnvironment toolEnv, List<JCClassDecl> classes) {
-        Set<TypeElement> result = new LinkedHashSet<>();
-        classes.stream().filter((def) -> (toolEnv.shouldDocument(def.sym))).forEach((def) -> {
-            TypeElement te = (TypeElement)def.sym;
-            if (te != null) {
-                toolEnv.setIncluded((Element)def.sym);
-                result.add(te);
-            }
-        });
-        cmdLineClasses = Collections.unmodifiableSet(result);
+    @Override
+    public Set<ModuleElement> getIncludedModuleElements() {
+        return etable.getIncludedModuleElements();
     }
 
-    /**
-     * Initialize packages information.
-     *
-     * @param toolEnv the compilation environment
-     * @param packages a list of package names (String)
-     */
-    private void setPackages(ToolEnvironment toolEnv, List<String> packages) {
-        Set<PackageElement> packlist = new LinkedHashSet<>();
-        packages.stream().forEach((name) -> {
-            PackageElement pkg =  getElementUtils().getPackageElement(name);
-            if (pkg != null) {
-                toolEnv.setIncluded(pkg);
-                packlist.add(pkg);
-            } else {
-                toolEnv.warning("main.no_source_files_for_package", name);
-            }
-        });
-        cmdLinePackages = Collections.unmodifiableSet(packlist);
-    }
-
-    /**
-     * Packages specified on the command line.
-     */
-    public Set<PackageElement> specifiedPackages() {
-        return cmdLinePackages;
+    @Override
+    public Set<PackageElement> getIncludedPackageElements() {
+        return etable.getIncludedPackageElements();
     }
 
     /**
-     * Classes and interfaces specified on the command line,
-     * including their inner classes
-     */
-    public Set<TypeElement> specifiedClasses() {
-       Set<TypeElement> out = new LinkedHashSet<>();
-       cmdLineClasses.stream().forEach((te) -> {
-            toolEnv.addAllClasses(out, te, true);
-        });
-       return out;
-    }
-
-    private Set<TypeElement> classesToDocument = null;
-    /**
-     * Return all classes and interfaces (including those inside
+     * Return all TypeElements (including those inside
      * packages) to be documented.
      */
-    public Set<TypeElement> getIncludedClasses() {
-        if (classesToDocument == null) {
-            Set<TypeElement> classes = new LinkedHashSet<>();
-
-            cmdLineClasses.stream().forEach((te) -> {
-                toolEnv.addAllClasses(classes, te, true);
-            });
-            cmdLinePackages.stream().forEach((pkg) -> {
-                toolEnv.addAllClasses(classes, pkg);
-            });
-            classesToDocument = Collections.unmodifiableSet(classes);
-        }
-        return classesToDocument;
-    }
-
-    /**
-     * Return the name of this  item.
-     *
-     * @return the string <code>"*RootDocImpl*"</code>.
-     */
-    public String name() {
-        return "*RootDocImpl*";
-    }
-
-    /**
-     * Return the name of this Doc item.
-     *
-     * @return the string <code>"*RootDocImpl*"</code>.
-     */
-    public String qualifiedName() {
-        return "*RootDocImpl*";
+    @Override
+    public Set<TypeElement> getIncludedTypeElements() {
+        return etable.getIncludedTypeElements();
     }
 
-    /**
-     * Return true if this Element is included in the active set.
-     * RootDocImpl isn't even a program entity so it is always false.
-     */
     @Override
     public boolean isIncluded(Element e) {
-        return toolEnv.isIncluded(e);
-    }
-
-//    Note: these reporting methods are no longer used.
-//    /**
-//     * Print error message, increment error count.
-//     *
-//     * @param msg message to print
-//     */
-//    public void printError(String msg) {
-//        env.printError(msg);
-//    }
-//
-//    /**
-//     * Print error message, increment error count.
-//     *
-//     * @param msg message to print
-//     */
-//    public void printError(DocTreePath path, String msg) {
-//        env.printError(path, msg);
-//    }
-//
-//    public void printError(Element e, String msg) {
-//        env.printError(e, msg);
-//    }
-//
-//    public void printWarning(Element e, String msg) {
-//        env.printWarning(e, msg);
-//    }
-//
-//    public void printNotice(Element e, String msg) {
-//       env.printNotice(e, msg);
-//    }
-//
-//    /**
-//     * Print warning message, increment warning count.
-//     *
-//     * @param msg message to print
-//     */
-//    public void printWarning(String msg) {
-//        env.printWarning(msg);
-//    }
-
-    /**
-     * Return the current file manager.
-     */
-    public JavaFileManager getFileManager() {
-        return toolEnv.fileManager;
+        return etable.isIncluded(e);
     }
 
     @Override
@@ -278,12 +119,9 @@
     @Override
     public Set<Element> getSpecifiedElements() {
         Set<Element> out = new LinkedHashSet<>();
-        specifiedPackages().stream().forEach((pe) -> {
-            out.add(pe);
-        });
-        specifiedClasses().stream().forEach((e) -> {
-            out.add(e);
-        });
+        out.addAll(etable.getSpecifiedModuleElements());
+        out.addAll(etable.getSpecifiedPackageElements());
+        out.addAll(etable.getSpecifiedTypeElements());
         return out;
     }
 
@@ -301,4 +139,9 @@
     public SourceVersion getSourceVersion() {
         return Source.toSourceVersion(toolEnv.source);
     }
+
+    @Override
+    public ModuleMode getModuleMode() {
+        return etable.getModuleMode();
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java	Thu Aug 18 05:48:35 2016 -0700
@@ -0,0 +1,1204 @@
+/*
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.javadoc.internal.tool;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.ModuleElement;
+import javax.lang.model.element.ModuleElement.ExportsDirective;
+import javax.lang.model.element.ModuleElement.RequiresDirective;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.SimpleElementVisitor9;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileManager.Location;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardLocation;
+
+import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.code.Kinds.Kind;
+import com.sun.tools.javac.code.Symbol;
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
+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.VarSymbol;
+import com.sun.tools.javac.code.Symtab;
+import com.sun.tools.javac.comp.Modules;
+import com.sun.tools.javac.tree.JCTree.JCClassDecl;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.DefinedBy;
+import com.sun.tools.javac.util.DefinedBy.Api;
+import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.Name;
+import com.sun.tools.javac.util.Names;
+import jdk.javadoc.doclet.DocletEnvironment;
+import jdk.javadoc.doclet.DocletEnvironment.ModuleMode;
+
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
+import static jdk.javadoc.internal.tool.JavadocTool.isValidClassName;
+
+/**
+ * This class manages elements specified on the command line, and
+ * produces "specified" and "included" data sets, needed by the
+ * doclet environment, as well as querying an elements' visibility
+ * or inclusion.
+ *
+ * A. Initialization phase: the class is initialized with the
+ *    options table by the caller. Some program elements may not
+ *    be specified via specific options, such as packages, classes,
+ *    these are set with the use of setter methods, such setClassArgList
+ *    and setClassDeclList.
+ *
+ * B. Scan and decode phase: this is performed by scanSpecifiedItems,
+ *    to identify the modules specified on the command line, modules
+ *    specified with qualified packages and qualified subpackages, the
+ *    modules so identified are used to initialize the module system.
+ *
+ * C. Intermediate phase: before the final analysis can be done,
+ *    intermediate methods can be used to get specified elements from
+ *    the initialization phase, typically used to parse sources or packages
+ *    specified on the command line.
+ *
+ * D. Analysis phase: the final analysis is performed to determine
+ *    the packages that ought to be included, as follows:
+ *
+ *    1. computes the specified modules, by considering the option
+ *       "expand-requires", this must be done exhaustively, as the package
+ *       computation phase expects a completed module graph, in order to
+ *       check the target of a qualified export is in the included set.
+ *
+ *    2. computes the packages that must be documented, by considering
+ *       the option "show-packages", also if only exported packages are
+ *       to be considered, then also check for qualified packages, and
+ *       include only those packages whose target is in the included set.
+ *
+ *    3. compute the specified packages, as part of this, first compute
+ *       the subpackages and exclude any packages, if required.
+ *
+ *    4. Finally, compute the types found by previous parsing steps,
+ *       noting that, all enclosed types (nested types) must also be
+ *       considered.
+ *
+ * E. Finally, this class provides methods to obtain the specified sets,
+ *    which are frozen and cached in the analysis phase, the included
+ *    sets, are computed lazily and cached for future use. An element
+ *    can be checked if it should be documented, in which case, the
+ *    element is checked against the included set and the result is
+ *    cached, for performance reasons.
+ *
+ * Definitions:
+ *    Fully included: an element is included and some or parts
+ *    of it components are included implicitly, subject to a
+ *    selection criteria of its enclosed children.
+ *
+ *    Included: if the item should be documented.
+ *
+ * Rules for processing:
+ *
+ * 1. A specified element, meaning an element given on the
+ *    command-line, and exposed via getSpecifiedElements()
+ * 2. Expand-contents, an internal pseudo term, meaning
+ *    it is part of the recursive expansion of specified
+ *    elements, meaning, the modules are expanded first, then
+ *    the packages contained in the expanded modules, and then
+ *    the types contained within the packages, to produce the
+ *    collections returned by the methods
+ *    getInclude{Module|Package|Type}Elements(), this is a
+ *    downward expansion.
+ * 3. An included element, meaning it should be documented, and
+ *    exposed via isIncluded, this enclosing element (module, package)
+ *    is recursively included.
+ */
+public class ElementsTable {
+
+    private final ToolEnvironment toolEnv;
+    private final Symtab syms;
+    private final Names names;
+    private final JavaFileManager fm;
+    private final Location location;
+    private final Modules modules;
+    private final Map<ToolOption, Object> opts;
+
+    private final Map<String, Entry> entries = new LinkedHashMap<>();
+
+    // specified elements
+    private Set<ModuleElement> specifiedModuleElements = new LinkedHashSet<>();
+    private Set<PackageElement> specifiedPackageElements = new LinkedHashSet<>();
+    private Set<TypeElement> specifiedTypeElements =new LinkedHashSet<>();
+
+    // included elements
+    private Set<ModuleElement> includedModuleElements = null;
+    private Set<PackageElement> includedPackageElements = null;
+    private Set<TypeElement> includedTypeElements = null;
+
+    // cmdline specifiers
+    private Set<ModulePackage> cmdLinePackages = new LinkedHashSet<>();
+    private Set<ModulePackage> excludePackages = new LinkedHashSet<>();
+    private Set<ModulePackage> subPackages = new LinkedHashSet<>();
+
+    private List<JCClassDecl> classDecList = Collections.emptyList();
+    private List<String> classArgList = Collections.emptyList();
+    private com.sun.tools.javac.util.List<JCCompilationUnit> classTreeList = null;
+
+    private final Set<JavaFileObject.Kind> sourceKinds = EnumSet.of(JavaFileObject.Kind.SOURCE);
+
+    private final ModifierFilter accessFilter;
+
+    private final AccessKind expandRequires;
+
+    final boolean xclasses;
+
+    /**
+     * Creates the table to manage included and excluded elements.
+     *
+     * @param context the context to locate commonly used objects
+     * @param location the location used to locate source files
+     */
+    ElementsTable(Context context, Map<ToolOption, Object> opts) {
+        this.toolEnv = ToolEnvironment.instance(context);
+        this.syms = Symtab.instance(context);
+        this.names = Names.instance(context);
+        this.fm = toolEnv.fileManager;
+        this.modules = Modules.instance(context);
+        this.opts = opts;
+        this.location = modules.multiModuleMode
+                ? StandardLocation.MODULE_SOURCE_PATH
+                : toolEnv.fileManager.hasLocation(StandardLocation.SOURCE_PATH)
+                    ? StandardLocation.SOURCE_PATH
+                    : StandardLocation.CLASS_PATH;
+        getEntry("").excluded = false;
+
+        accessFilter = new ModifierFilter(opts);
+        xclasses = (boolean)opts.getOrDefault(ToolOption.XCLASSES, false);
+        expandRequires = (AccessKind)opts.get(ToolOption.EXPAND_REQUIRES);
+    }
+
+    /**
+     * Returns the module documentation level mode.
+     * @return the module documentation level mode
+     */
+    public ModuleMode getModuleMode() {
+        switch(accessFilter.getAccessValue(ElementKind.MODULE)) {
+            case PACKAGE: case PRIVATE:
+                return DocletEnvironment.ModuleMode.ALL;
+            default:
+                return DocletEnvironment.ModuleMode.API;
+        }
+    }
+
+    /**
+     * Returns the selected/included module elements.
+     * A module is fully included,
+     *   - is specified on the command line --module
+     *   - is derived from the module graph, that is, by expanding the
+     *     requires directive, based on --expand-requires
+     *
+     * A module is included if an enclosed package or type is
+     * specified on the command line.
+     * @return the included module elements
+     */
+    public Set<ModuleElement> getIncludedModuleElements() {
+        return includedModuleElements;
+    }
+
+    /**
+     * Returns the selected/included package elements.
+     * A package is fully included,
+     *  - is specified on the command line
+     *  - is derived from expanding -subpackages
+     *  - can be documented in a fully included module based on --show-packages
+     *
+     * A package is included, if an enclosed package or a type is specified on
+     * the command line.
+     *
+     * @return the included package elements
+     */
+    public Set<PackageElement> getIncludedPackageElements() {
+        return includedPackageElements;
+    }
+
+    /**
+     * Returns the selected/included type elements (including those
+     * within specified or included packages) to be documented.
+     * A type is fully included if
+     *  - is specified on the command line with -sourcepath
+     *  - is visible with --show-types filter
+     * A nested type is fully included if
+     *  - is visible with --show-types filter
+     *  - is enclosed in a fully included type
+     *
+     * @return the included type elements
+     * to be documented
+     */
+    public Set<TypeElement> getIncludedTypeElements() {
+        return includedTypeElements;
+    }
+
+    /**
+     * Returns a set of module elements specified on the
+     * command line.
+     * @return the set of module elements specified on the
+     * command line
+     */
+    public Set<ModuleElement> getSpecifiedModuleElements() {
+        return specifiedModuleElements;
+    }
+
+    /**
+     * Returns a set of package elements specified on the
+     * command line. These may also contain children packages
+     * if specified with -subpackage.
+     *
+     * @return the set of package elements specified on the
+     * command line
+     */
+    public Set<PackageElement> getSpecifiedPackageElements() {
+        return specifiedPackageElements;
+    }
+
+    /**
+     * Returns a set of type elements specified on the
+     * command line, including any inner classes.
+     *
+     * @return the set of type elements specified on the command line
+     */
+    public Set<TypeElement> getSpecifiedTypeElements() {
+        return specifiedTypeElements;
+    }
+
+    private IncludedVisitor includedVisitor = null;
+
+    /**
+     * Returns true if the given element is included or selected for
+     * consideration.
+     * This method accumulates elements in the cache as enclosed elements of
+     * fully included elements are tested.
+     * A member (constructor, method, field) is included if
+     *  - it is visible in a fully included type (--show-members)
+     *
+     * @param e the element in question
+     *
+     * @see getIncludedModuleElements
+     * @see getIncludedPackageElements
+     * @see getIncludedTypeElements
+     *
+     * @return true if included
+     */
+    public boolean isIncluded(Element e) {
+        if (e == null) {
+            return false;
+        }
+        if (includedVisitor == null) {
+            includedVisitor = new IncludedVisitor();
+        }
+        return includedVisitor.visit(e);
+    }
+
+    /**
+     * Performs the final computation and freezes the collections.
+     * This is a terminal operation, thus no further modifications
+     * are allowed to the specified data sets.
+     *
+     * @throws IOException if an error occurs
+     */
+    void analyze() throws IOException {
+        // compute the specified element, by expanding module dependencies
+        computeSpecifiedModules();
+
+        // compute all specified packages and subpackages
+        computeSpecifiedPackages();
+
+        // compute the specified types
+        computeSpecifiedTypes();
+
+        // compute the packages belonging to all the specified modules
+        Set<PackageElement> expandedModulePackages = computeModulePackages();
+        initializeIncludedSets(expandedModulePackages);
+
+    }
+
+    ElementsTable classTrees(com.sun.tools.javac.util.List<JCCompilationUnit> classTrees) {
+        this.classTreeList = classTrees;
+        return this;
+    }
+
+    @SuppressWarnings("unchecked")
+    ElementsTable scanSpecifiedItems() throws IOException {
+
+        // scan modules specified on the command line
+        List<String> moduleNames = (List<String>) opts.computeIfAbsent(ToolOption.MODULE,
+                s -> Collections.EMPTY_LIST);
+        List<String> mlist = new ArrayList<>();
+        for (String m : moduleNames) {
+            Location moduleLoc = fm.getModuleLocation(location, m);
+            if (moduleLoc == null) {
+                toolEnv.error("main.module_not_found", m);
+            } else {
+                mlist.add(m);
+                ModuleSymbol msym = syms.enterModule(names.fromString(m));
+                specifiedModuleElements.add((ModuleElement) msym);
+            }
+        }
+
+        // scan for modules with qualified packages
+        cmdLinePackages.stream()
+                .filter((mpkg) -> (mpkg.hasModule()))
+                .forEachOrdered((mpkg) -> {
+                    mlist.add(mpkg.moduleName);
+        });
+
+        // scan for modules with qualified subpackages
+        ((List<String>)opts.computeIfAbsent(ToolOption.SUBPACKAGES, v -> Collections.EMPTY_LIST))
+            .stream()
+            .map((packageName) -> new ModulePackage(packageName))
+            .forEachOrdered((mpkg) -> {
+                subPackages.add(mpkg);
+                if (mpkg.hasModule()) {
+                    mlist.add(mpkg.moduleName);
+                }
+            });
+
+        // all the modules specified on the command line have been scraped
+        // init the module systems
+        modules.addExtraAddModules(mlist.toArray(new String[mlist.size()]));
+        modules.initModules(this.classTreeList);
+
+        return this;
+    }
+
+    /**
+     * Returns the includes table after setting a class names specified on the command line.
+     *
+     * @param classList
+     * @return the include table
+     */
+    ElementsTable setClassArgList(List<String> classList) {
+        classArgList = classList;
+        return this;
+    }
+
+    /**
+     * Returns the includes table after setting the parsed class names.
+     *
+     * @param classesDecList
+     * @return the include table
+     */
+    ElementsTable setClassDeclList(List<JCClassDecl> classesDecList) {
+        this.classDecList = classesDecList;
+        return this;
+    }
+
+    /**
+     * Returns an includes table after setting the specified package
+     * names.
+     * @param packageNames packages on the command line
+     * @return the includes table after setting the specified package
+     * names
+     */
+    ElementsTable packages(Collection<String> packageNames) {
+        packageNames.stream()
+            .map((packageName) -> new ModulePackage(packageName))
+            .forEachOrdered((mpkg) -> cmdLinePackages.add(mpkg));
+        return this;
+    }
+
+    /**
+     * Returns the aggregate set of included packages and specified
+     * sub packages.
+     *
+     * @return the aggregate set of included packages and specified
+     * sub packages
+     */
+    Iterable<ModulePackage> getPackagesToParse() throws IOException {
+        List<ModulePackage> result = new ArrayList<>();
+        result.addAll(cmdLinePackages);
+        result.addAll(subPackages);
+        return result;
+    }
+
+    @SuppressWarnings("unchecked")
+    private void computeSubpackages() throws IOException {
+        ((List<String>) opts.computeIfAbsent(ToolOption.EXCLUDE, v -> Collections.EMPTY_LIST))
+                .stream()
+                .map((packageName) -> new ModulePackage(packageName))
+                .forEachOrdered((mpkg) -> excludePackages.add(mpkg));
+
+        excludePackages.forEach((p) -> {
+            getEntry(p).excluded = true;
+        });
+
+        for (ModulePackage modpkg : subPackages) {
+            Location packageLocn = getLocation(modpkg);
+            for (JavaFileObject fo : fm.list(packageLocn, modpkg.packageName, sourceKinds, true)) {
+                String binaryName = fm.inferBinaryName(packageLocn, fo);
+                String pn = getPackageName(binaryName);
+                String simpleName = getSimpleName(binaryName);
+                Entry e = getEntry(pn);
+                if (!e.isExcluded() && isValidClassName(simpleName)) {
+                    ModuleSymbol msym = (modpkg.hasModule())
+                            ? syms.getModule(names.fromString(modpkg.moduleName))
+                            : findModuleOfPackageName(modpkg.packageName);
+
+                    if (msym != null && !msym.isUnnamed()) {
+                        syms.enterPackage(msym, names.fromString(pn));
+                        ModulePackage npkg = new ModulePackage(msym.toString(), pn);
+                        cmdLinePackages.add(npkg);
+                    } else {
+                        cmdLinePackages.add(e.modpkg);
+                    }
+                    e.files = (e.files == null
+                            ? com.sun.tools.javac.util.List.of(fo)
+                            : e.files.prepend(fo));
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns the "requires" modules for the target module.
+     * @param mdle the target module element
+     * @param isPublic true gets all the public requires, otherwise
+     *                 gets all the non-public requires
+     *
+     * @return a set of modules
+     */
+    private Set<ModuleElement> getModuleRequires(ModuleElement mdle, boolean isPublic) {
+        Set<ModuleElement> result = new HashSet<>();
+        for (RequiresDirective rd : ElementFilter.requiresIn(mdle.getDirectives())) {
+            if (isPublic && rd.isPublic()) {
+                result.add(rd.getDependency());
+            }
+            if (!isPublic && !rd.isPublic()) {
+                result.add(rd.getDependency());
+            }
+        }
+        return result;
+    }
+
+    private void computeSpecifiedModules() {
+        if (expandRequires == null) { // no expansion requested
+            specifiedModuleElements = Collections.unmodifiableSet(specifiedModuleElements);
+            return;
+        }
+
+        final boolean expandAll = expandRequires.equals(AccessKind.PRIVATE)
+                || expandRequires.equals(AccessKind.PACKAGE);
+
+        Set<ModuleElement> result = new LinkedHashSet<>();
+        ListBuffer<ModuleElement> queue = new ListBuffer<>();
+
+        // expand each specified module
+        for (ModuleElement mdle : getSpecifiedModuleElements()) {
+            result.add(mdle); // a specified module is included
+            queue.append(mdle);
+            Set<ModuleElement> publicRequires = getModuleRequires(mdle, true);
+            result.addAll(publicRequires);
+            // add all requires public
+            queue.addAll(publicRequires);
+
+            if (expandAll) {
+                 // add non-public requires if needed
+                result.addAll(getModuleRequires(mdle, !expandAll));
+            }
+        }
+
+        // compute the transitive closure of all the requires public
+        for (ModuleElement m = queue.poll() ; m != null ; m = queue.poll()) {
+            for (ModuleElement mdle : getModuleRequires(m, true)) {
+                if (!result.contains(mdle)) {
+                    result.add(mdle);
+                    queue.append(mdle);
+                }
+            }
+        }
+        specifiedModuleElements = Collections.unmodifiableSet(result);
+    }
+
+    private Set<PackageElement> getAllModulePackages(ModuleElement mdle) throws IOException {
+        Set<PackageElement> result = new HashSet<>();
+        ModuleSymbol msym = (ModuleSymbol)mdle;
+        Location msymloc = fm.getModuleLocation(location, msym.name.toString());
+        for (JavaFileObject fo : fm.list(msymloc, "", sourceKinds, true)) {
+            if (fo.getName().endsWith("module-info.java"))
+                continue;
+            String binaryName = fm.inferBinaryName(msymloc, fo);
+            String pn = getPackageName(binaryName);
+            PackageSymbol psym = syms.enterPackage(msym, names.fromString(pn));
+            result.add((PackageElement)psym);
+        }
+        return result;
+    }
+
+    private Set<PackageElement> computeModulePackages() throws IOException {
+        final AccessKind accessValue = accessFilter.getAccessValue(ElementKind.PACKAGE);
+        final boolean documentAllModulePackages = (accessValue == AccessKind.PACKAGE ||
+                accessValue == AccessKind.PRIVATE);
+
+        Set<PackageElement> expandedModulePackages = new LinkedHashSet<>();
+
+        for (ModuleElement mdle : specifiedModuleElements) {
+            // add all exported packages belonging to a specified module
+            if (specifiedModuleElements.contains(mdle)) {
+                List<ExportsDirective> exports = ElementFilter.exportsIn(mdle.getDirectives());
+                for (ExportsDirective export : exports) {
+                    expandedModulePackages.add(export.getPackage());
+                }
+            }
+
+            // add all packages specified on the command line
+            // belonging to this module
+            if (!cmdLinePackages.isEmpty()) {
+                for (ModulePackage modpkg : cmdLinePackages) {
+                    PackageElement pkg = toolEnv.elements.getPackageElement(mdle,
+                            modpkg.packageName);
+                    if (pkg != null) {
+                        expandedModulePackages.add(pkg);
+                    }
+                }
+            }
+
+            if (!documentAllModulePackages) {
+                List<ExportsDirective> exports = ElementFilter.exportsIn(mdle.getDirectives());
+                // check exported packages
+                for (ExportsDirective export : exports) {
+                    List<? extends ModuleElement> targetModules = export.getTargetModules();
+                    if (targetModules == null) { // no qualified exports, add 'em all
+                        expandedModulePackages.add(export.getPackage());
+                    } else { // qualified export, add only if target module is being considered
+                        for (ModuleElement target : targetModules) {
+                            if (specifiedModuleElements.contains(target)) {
+                                expandedModulePackages.add(export.getPackage());
+                            }
+                        }
+                    }
+                }
+            } else { // add all exported and module private packages
+                List<PackageElement> packages = ElementFilter.packagesIn(mdle.getEnclosedElements());
+                expandedModulePackages.addAll(packages);
+                expandedModulePackages.addAll(getAllModulePackages(mdle));
+            }
+        }
+        return expandedModulePackages;
+    }
+
+    private void initializeIncludedSets(Set<PackageElement> expandedModulePackages) {
+
+        // process modules
+        Set<ModuleElement> imodules = new LinkedHashSet<>();
+        // add all the expanded modules
+        imodules.addAll(specifiedModuleElements);
+
+        // process packages
+        Set<PackageElement> ipackages = new LinkedHashSet<>();
+        // add all packages belonging to expanded modules
+        ipackages.addAll(expandedModulePackages);
+        // add all specified packages
+        specifiedPackageElements.forEach(pkg -> {
+            ModuleElement mdle = toolEnv.elements.getModuleOf(pkg);
+            imodules.add(mdle);
+            ipackages.add(pkg);
+        });
+
+        // process types
+        Set<TypeElement> iclasses = new LinkedHashSet<>();
+        // add all types enclosed in expanded modules and packages
+        ipackages.forEach((pkg) -> {
+            addAllClasses(iclasses, pkg);
+        });
+        // add all types and its nested types
+        specifiedTypeElements.forEach((klass) -> {
+            ModuleElement mdle = toolEnv.elements.getModuleOf(klass);
+            if (!mdle.isUnnamed())
+                imodules.add(mdle);
+            PackageElement pkg = toolEnv.elements.getPackageOf(klass);
+            if (!pkg.isUnnamed())
+                ipackages.add(pkg);
+            addAllClasses(iclasses, klass, true);
+        });
+
+        // all done, freeze the collections
+        includedModuleElements = Collections.unmodifiableSet(imodules);
+        includedPackageElements = Collections.unmodifiableSet(ipackages);
+        includedTypeElements = Collections.unmodifiableSet(iclasses);
+    }
+
+    /**
+     * Computes the included packages and freezes the specified packages list.
+     */
+    private void computeSpecifiedPackages() throws IOException {
+
+        computeSubpackages();
+
+        Set<PackageElement> packlist = new LinkedHashSet<>();
+        cmdLinePackages.forEach((modpkg) -> {
+            ModuleElement mdle = null;
+            PackageElement pkg;
+            if (modpkg.hasModule()) {
+                mdle = toolEnv.elements.getModuleElement(modpkg.moduleName);
+                pkg = toolEnv.elements.getPackageElement(mdle, modpkg.packageName);
+            } else {
+                pkg = toolEnv.elements.getPackageElement(modpkg.toString());
+            }
+
+            if (pkg != null) {
+                packlist.add(pkg);
+            } else {
+                toolEnv.warning("main.package_not_found", modpkg.toString());
+            }
+        });
+        specifiedPackageElements = Collections.unmodifiableSet(packlist);
+    }
+
+    /**
+     * Adds all classes as well as inner classes, to the specified
+     * list.
+     */
+    private void computeSpecifiedTypes() {
+        Set<TypeElement> classes = new LinkedHashSet<>();
+        classDecList.stream().filter((def) -> (shouldDocument(def.sym))).forEach((def) -> {
+            TypeElement te = (TypeElement) def.sym;
+            if (te != null) {
+                addAllClasses(classes, te, true);
+            }
+        });
+        classArgList.forEach((className) -> {
+            TypeElement te = toolEnv.loadClass(className);
+            if (te == null) {
+                toolEnv.error("javadoc.class_not_found", className);
+            } else {
+                addAllClasses(classes, te, true);
+            }
+        });
+        specifiedTypeElements = Collections.unmodifiableSet(classes);
+    }
+
+    private void addFilesForParser(Collection<JavaFileObject> result,
+            Collection<ModulePackage> collection, boolean recurse) throws IOException {
+        for (ModulePackage modpkg : collection) {
+            toolEnv.notice("main.Loading_source_files_for_package", modpkg.toString());
+            List<JavaFileObject> files = getFiles(modpkg, recurse);
+            if (files.isEmpty()) {
+                    toolEnv.error("main.no_source_files_for_package", modpkg.toString());
+            } else {
+                result.addAll(files);
+            }
+        }
+    }
+
+    /**
+     * Returns an aggregated list of java file objects from the items
+     * specified on the command line. The packages specified should not
+     * recurse, however sub-packages should recurse into the sub directories.
+     * @return a list of java file objects
+     * @throws IOException if an error occurs
+     */
+    List<JavaFileObject> getFilesToParse() throws IOException {
+        List<JavaFileObject> result = new ArrayList<>();
+        addFilesForParser(result, cmdLinePackages, false);
+        addFilesForParser(result, subPackages, true);
+        return result;
+    }
+
+    /**
+     * Returns the set of source files for a package.
+     *
+     * @param packageName the specified package
+     * @return the set of file objects for the specified package
+     * @throws IOException if an error occurs while accessing the files
+     */
+    private List<JavaFileObject> getFiles(ModulePackage modpkg, boolean recurse) throws IOException {
+        Entry e = getEntry(modpkg);
+        // The files may have been found as a side effect of searching for subpackages
+        if (e.files != null) {
+            return e.files;
+        }
+
+        ListBuffer<JavaFileObject> lb = new ListBuffer<>();
+        Location packageLocn = getLocation(modpkg);
+        if (packageLocn == null) {
+            return Collections.emptyList();
+        }
+        String pname = modpkg.packageName;
+        for (JavaFileObject fo : fm.list(packageLocn, pname, sourceKinds, recurse)) {
+            String binaryName = fm.inferBinaryName(packageLocn, fo);
+            String simpleName = getSimpleName(binaryName);
+            if (isValidClassName(simpleName)) {
+                lb.append(fo);
+            }
+        }
+
+        return lb.toList();
+    }
+
+    private ModuleSymbol findModuleOfPackageName(String packageName) {
+            Name pack = names.fromString(packageName);
+            for (ModuleSymbol msym : modules.allModules()) {
+                PackageSymbol p = syms.getPackage(msym, pack);
+                if (p != null && !p.members().isEmpty()) {
+                    return msym;
+                }
+            }
+            return null;
+    }
+
+    private Location getLocation(ModulePackage modpkg) throws IOException {
+        if (location != StandardLocation.MODULE_SOURCE_PATH) {
+            return location;
+        }
+
+        if (modpkg.hasModule()) {
+            return fm.getModuleLocation(location, modpkg.moduleName);
+        }
+        // TODO: handle invalid results better.
+        ModuleSymbol msym = findModuleOfPackageName(modpkg.packageName);
+        if (msym == null) {
+            return null;
+        }
+        return fm.getModuleLocation(location, msym.name.toString());
+    }
+
+    private Entry getEntry(String name) {
+        return getEntry(new ModulePackage(name));
+    }
+
+    private Entry getEntry(ModulePackage modpkg) {
+        Entry e = entries.get(modpkg.packageName);
+        if (e == null) {
+            entries.put(modpkg.packageName, e = new Entry(modpkg));
+        }
+        return e;
+    }
+
+    private String getPackageName(String name) {
+        int lastDot = name.lastIndexOf(".");
+        return (lastDot == -1 ? "" : name.substring(0, lastDot));
+    }
+
+    private String getSimpleName(String name) {
+        int lastDot = name.lastIndexOf(".");
+        return (lastDot == -1 ? name : name.substring(lastDot + 1));
+    }
+
+    /**
+     * Adds all inner classes of this class, and their inner classes recursively, to the list
+     */
+    private void addAllClasses(Collection<TypeElement> list, TypeElement typeElement, boolean filtered) {
+        ClassSymbol klass = (ClassSymbol)typeElement;
+        try {
+            // eliminate needless checking, do this first.
+            if (list.contains(klass)) return;
+            if (toolEnv.isSynthetic(klass)) return;
+            // ignore classes with invalid Java class names
+            if (!JavadocTool.isValidClassName(klass.name.toString())) return;
+            if (filtered && !shouldDocument(klass)) return;
+            list.add(klass);
+            for (Symbol sym : klass.members().getSymbols(NON_RECURSIVE)) {
+                if (sym != null && sym.kind == Kind.TYP) {
+                    ClassSymbol s = (ClassSymbol)sym;
+                    if (!toolEnv.isSynthetic(s)) {
+                        addAllClasses(list, s, filtered);
+                    }
+                }
+            }
+        } catch (CompletionFailure e) {
+            // quietly ignore completion failures
+        }
+    }
+
+    /**
+     * Returns a list of all classes contained in this package, including
+     * member classes of those classes, and their member classes, etc.
+     */
+    private void addAllClasses(Collection<TypeElement> list, PackageElement pkg) {
+        boolean filtered = true;
+        PackageSymbol sym = (PackageSymbol)pkg;
+        for (Symbol isym : sym.members().getSymbols(NON_RECURSIVE)) {
+            if (isym != null) {
+                ClassSymbol s = (ClassSymbol)isym;
+                if (!toolEnv.isSynthetic(sym)) {
+                    addAllClasses(list, s, filtered);
+                }
+            }
+        }
+    }
+
+    SimpleElementVisitor9<Boolean, Void> shouldDocumentVisitor = null;
+    /**
+     * Returns whether an element ought to be documented.
+     * @param e the element in question
+     * @return true if the element should be documented
+     */
+    public boolean shouldDocument(Element e) {
+        if (shouldDocumentVisitor == null) {
+            shouldDocumentVisitor = new SimpleElementVisitor9<Boolean, Void>() {
+
+                @Override @DefinedBy(Api.LANGUAGE_MODEL)
+                public Boolean visitType(TypeElement e, Void p) {
+                    return shouldDocument((ClassSymbol) e);
+                }
+
+                @Override @DefinedBy(Api.LANGUAGE_MODEL)
+                public Boolean visitVariable(VariableElement e, Void p) {
+                    return shouldDocument((VarSymbol) e);
+                }
+
+                @Override @DefinedBy(Api.LANGUAGE_MODEL)
+                public Boolean visitExecutable(ExecutableElement e, Void p) {
+                    return shouldDocument((MethodSymbol) e);
+                }
+
+                @Override @DefinedBy(Api.LANGUAGE_MODEL)
+                public Boolean visitPackage(PackageElement e, Void p) {
+                    return accessFilter.checkModifier(e);
+                }
+            };
+        }
+        return shouldDocumentVisitor.visit(e);
+    }
+
+    /** Check whether this member should be documented. */
+    private boolean shouldDocument(VarSymbol sym) {
+        if (toolEnv.isSynthetic(sym)) {
+            return false;
+        }
+        return accessFilter.checkModifier(sym);
+    }
+
+    /** Check whether this member should be documented. */
+    private boolean shouldDocument(MethodSymbol sym) {
+        if (toolEnv.isSynthetic(sym)) {
+            return false;
+        }
+        return accessFilter.checkModifier(sym);
+    }
+
+    /** Check whether this class should be documented. */
+    private boolean shouldDocument(ClassSymbol sym) {
+        return
+            !toolEnv.isSynthetic(sym) && // no synthetics
+            (xclasses || toolEnv.hasPath(sym)) &&
+            isVisible(sym);
+    }
+
+    /**
+     * Returns the visibility of a type element.
+     * If the type element is a nested type, then check if the
+     * enclosing is static or the enclosed is visible.
+     *
+     * @param te the type element to be checked
+     * @return true if the element is visible
+     */
+    public boolean isVisible(TypeElement te) {
+        ClassSymbol sym = (ClassSymbol)te;
+        if (!accessFilter.checkModifier(sym)) {
+            return false;
+        }
+        ClassSymbol encl = sym.owner.enclClass();
+        return (encl == null || (sym.flags_field & Flags.STATIC) != 0 || isVisible(encl));
+    }
+
+    private class IncludedVisitor extends SimpleElementVisitor9<Boolean, Void> {
+
+        final private Set<Element> includedCache;
+
+        public IncludedVisitor() {
+            includedCache = new LinkedHashSet<>();
+        }
+
+        @Override @DefinedBy(Api.LANGUAGE_MODEL)
+        public Boolean visitModule(ModuleElement e, Void p) {
+            // deduced by specified and/or requires expansion
+            return includedModuleElements.contains(e);
+        }
+
+        @Override @DefinedBy(Api.LANGUAGE_MODEL)
+        public Boolean visitPackage(PackageElement e, Void p) {
+            // deduced by specified or downward expansions
+            return includedPackageElements.contains(e);
+        }
+
+        @Override @DefinedBy(Api.LANGUAGE_MODEL)
+        public Boolean visitType(TypeElement e, Void p) {
+            if (includedTypeElements.contains(e)) {
+                return true;
+            }
+            if (shouldDocument(e)) {
+                // Class is nameable from top-level and
+                // the class and all enclosing classes
+                // pass the modifier filter.
+                PackageElement pkg = toolEnv.elements.getPackageOf(e);
+                if (specifiedPackageElements.contains(pkg)) {
+                    return true;
+                }
+                Element enclosing = e.getEnclosingElement();
+                if (enclosing != null) {
+                    switch(enclosing.getKind()) {
+                        case PACKAGE:
+                            return specifiedPackageElements.contains((PackageElement)enclosing);
+                        case CLASS: case INTERFACE: case ENUM: case ANNOTATION_TYPE:
+                            return visit((TypeElement) enclosing);
+                        default:
+                            throw new AssertionError("unknown element: " + enclosing);
+                    }
+                }
+            }
+            return false;
+        }
+
+        // members
+        @Override @DefinedBy(Api.LANGUAGE_MODEL)
+        public Boolean defaultAction(Element e, Void p) {
+            if (includedCache.contains(e))
+                return true;
+            if (visit(e.getEnclosingElement()) && shouldDocument(e)) {
+                switch(e.getKind()) {
+                    case ANNOTATION_TYPE: case CLASS: case ENUM: case INTERFACE:
+                    case MODULE: case OTHER: case PACKAGE:
+                        throw new AssertionError("invalid element for this operation: " + e);
+                    default:
+                        // the only allowed kinds in the cache are "members"
+                        includedCache.add(e);
+                        return true;
+                }
+            }
+            return false;
+        }
+
+        @Override @DefinedBy(Api.LANGUAGE_MODEL)
+        public Boolean visitUnknown(Element e, Void p) {
+            throw new AssertionError("unknown element: " + e);
+        }
+
+    }
+
+    class Entry {
+        final ModulePackage modpkg;
+        Boolean excluded = false;
+        com.sun.tools.javac.util.List<JavaFileObject> files;
+
+        Entry(ModulePackage modpkg) {
+            this.modpkg = modpkg;
+        }
+
+        Entry(String name) {
+            modpkg = new ModulePackage(name);
+        }
+
+        boolean isExcluded() {
+            return excluded;
+        }
+
+        @Override
+        public String toString() {
+            return "Entry{" + "modpkg=" + modpkg + ", excluded=" + excluded + ", files=" + files + '}';
+        }
+    }
+
+    /**
+     * A container class to retrieve the module and package pair
+     * from a parsed qualified package name.
+     */
+    static class ModulePackage {
+
+        public final String moduleName;
+        public final String packageName;
+
+        ModulePackage(String modulename, String packagename) {
+            this.moduleName = modulename;
+            this.packageName = packagename;
+        }
+
+        ModulePackage(ModuleElement msym, String packagename) {
+            this.moduleName = msym.toString();
+            this.packageName = packagename;
+        }
+
+        ModulePackage(String name) {
+            String a[] = name.split("/");
+            if (a.length == 2) {
+                this.moduleName = a[0];
+                this.packageName = a[1];
+            } else {
+                moduleName = null;
+                packageName = name;
+            }
+        }
+
+        boolean hasModule() {
+            return this.moduleName != null;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof ModulePackage) {
+                ModulePackage that = (ModulePackage)obj;
+                return this.toString().equals(that.toString());
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+             return toString().hashCode();
+        }
+
+        @Override
+        public String toString() {
+            return moduleName == null ? packageName : moduleName + "/" + packageName;
+        }
+    }
+
+    /**
+     * A class which filters the access flags on classes, fields, methods, etc.
+     *
+     * @see javax.lang.model.element.Modifier
+     */
+
+    static class ModifierFilter {
+        /**
+         * The allowed ElementKind that can be stored.
+         */
+        static final EnumSet<ElementKind> ALLOWED_KINDS = EnumSet.of(ElementKind.METHOD,
+                                                    ElementKind.CLASS,
+                                                    ElementKind.PACKAGE,
+                                                    ElementKind.MODULE);
+
+        // all possible accesss levels allowed for each element
+        private final EnumMap<ElementKind, EnumSet<AccessKind>> filterMap =
+                new EnumMap<>(ElementKind.class);
+
+        // the specified access level for each element
+        private final EnumMap<ElementKind, AccessKind> accessMap =
+                new EnumMap<>(ElementKind.class);
+
+        /**
+         * Constructor - Specify a filter.
+         *
+         * @param accessSet an Access filter.
+         */
+        ModifierFilter(Map<ToolOption, Object> opts) {
+
+            AccessKind accessValue = null;
+            for (ElementKind kind : ALLOWED_KINDS) {
+                switch (kind) {
+                    case METHOD:
+                        accessValue  = (AccessKind)opts.get(ToolOption.SHOW_MEMBERS);
+                        break;
+                    case CLASS:
+                        accessValue  = (AccessKind)opts.get(ToolOption.SHOW_TYPES);
+                        break;
+                    case PACKAGE:
+                        accessValue  = (AccessKind)opts.get(ToolOption.SHOW_PACKAGES);
+                        break;
+                    case MODULE:
+                        accessValue  = (AccessKind)opts.get(ToolOption.SHOW_MODULE_CONTENTS);
+                        break;
+                    default:
+                        throw new AssertionError("unknown element: " + kind);
+
+                }
+                accessMap.put(kind, accessValue);
+                filterMap.put(kind, getFilterSet(accessValue));
+            }
+        }
+
+        static EnumSet<AccessKind> getFilterSet(AccessKind acccessValue) {
+            switch (acccessValue) {
+                case PUBLIC:
+                    return EnumSet.of(AccessKind.PUBLIC);
+                case PROTECTED:
+                default:
+                    return EnumSet.of(AccessKind.PUBLIC, AccessKind.PROTECTED);
+                case PACKAGE:
+                    return EnumSet.of(AccessKind.PUBLIC, AccessKind.PROTECTED, AccessKind.PACKAGE);
+                case PRIVATE:
+                    return EnumSet.allOf(AccessKind.class);
+            }
+        }
+
+        public AccessKind getAccessValue(ElementKind kind) {
+            if (!ALLOWED_KINDS.contains(kind)) {
+                throw new IllegalArgumentException("not allowed: " + kind);
+            }
+            return accessMap.getOrDefault(kind, AccessKind.PROTECTED);
+        }
+
+        /**
+         * Returns true if access is allowed.
+         *
+         * @param e the element in question
+         * @return whether the modifiers pass this filter
+         */
+        public boolean checkModifier(Element e) {
+            Set<Modifier> modifiers = e.getModifiers();
+            AccessKind fflag = AccessKind.PACKAGE;
+            if (modifiers.contains(Modifier.PUBLIC)) {
+                fflag = AccessKind.PUBLIC;
+            } else if (modifiers.contains(Modifier.PROTECTED)) {
+                fflag = AccessKind.PROTECTED;
+            } else if (modifiers.contains(Modifier.PRIVATE)) {
+                fflag = AccessKind.PRIVATE;
+            }
+            EnumSet<AccessKind> filterSet = filterMap.get(getAllowedKind(e.getKind()));
+            return filterSet.contains(fflag);
+        }
+
+        // convert a requested element kind to an allowed access kind
+        private ElementKind getAllowedKind(ElementKind kind) {
+            switch (kind) {
+                case CLASS: case METHOD: case MODULE: case PACKAGE:
+                    return kind;
+                case ANNOTATION_TYPE: case ENUM: case INTERFACE:
+                    return ElementKind.CLASS;
+                case CONSTRUCTOR: case ENUM_CONSTANT: case EXCEPTION_PARAMETER:
+                case FIELD: case INSTANCE_INIT: case LOCAL_VARIABLE: case PARAMETER:
+                case RESOURCE_VARIABLE: case STATIC_INIT: case TYPE_PARAMETER:
+                    return ElementKind.METHOD;
+                default:
+                    throw new AssertionError("unsupported kind: " + kind);
+            }
+        }
+    } // end ModifierFilter
+}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java	Thu Aug 18 05:48:35 2016 -0700
@@ -29,27 +29,18 @@
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
 import java.util.HashSet;
-import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import javax.tools.JavaFileManager;
-import javax.tools.JavaFileManager.Location;
 import javax.tools.JavaFileObject;
 import javax.tools.StandardJavaFileManager;
-import javax.tools.StandardLocation;
 
 import com.sun.tools.javac.code.ClassFinder;
 import com.sun.tools.javac.code.Symbol.Completer;
 import com.sun.tools.javac.code.Symbol.CompletionFailure;
-import com.sun.tools.javac.code.Symbol.ModuleSymbol;
-import com.sun.tools.javac.code.Symbol.PackageSymbol;
 import com.sun.tools.javac.comp.Enter;
 import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
@@ -57,11 +48,9 @@
 import com.sun.tools.javac.util.Abort;
 import com.sun.tools.javac.util.Context;
 import com.sun.tools.javac.util.ListBuffer;
-import com.sun.tools.javac.util.Name;
 import com.sun.tools.javac.util.Position;
 import jdk.javadoc.doclet.DocletEnvironment;
 
-
 /**
  *  This class could be the main entry point for Javadoc when Javadoc is used as a
  *  component in a larger software system. It provides operations to
@@ -131,44 +120,41 @@
         }
     }
 
-    public DocletEnvironment getEnvironment(String encoding,
-                                      String showAccess,
-                                      String overviewpath,
-                                      List<String> args,
-                                      Iterable<? extends JavaFileObject> fileObjects,
-                                      List<String> subPackages,
-                                      List<String> excludedPackages,
-                                      boolean docClasses,
-                                      boolean quiet) throws IOException {
+    public DocletEnvironment getEnvironment(Map<ToolOption, Object> jdtoolOpts,
+                                      List<String> javaNames,
+                                      Iterable<? extends JavaFileObject> fileObjects) throws IOException {
         toolEnv = ToolEnvironment.instance(context);
-        toolEnv.intialize(encoding, showAccess, overviewpath, args, fileObjects,
-                         subPackages, excludedPackages, docClasses, quiet);
-
-        javadocFinder.sourceCompleter = docClasses ? Completer.NULL_COMPLETER : sourceCompleter;
+        toolEnv.initialize(jdtoolOpts);
+        ElementsTable etable = new ElementsTable(context, jdtoolOpts);
+        javadocFinder.sourceCompleter = etable.xclasses
+                ? Completer.NULL_COMPLETER
+                : sourceCompleter;
 
-        if (docClasses) {
-            // If -Xclasses is set, the args should be a series of class names
-            for (String arg: args) {
+        if (etable.xclasses) {
+            // If -Xclasses is set, the args should be a list of class names
+            for (String arg: javaNames) {
                 if (!isValidPackageName(arg)) // checks
-                    toolEnv.error(null, "main.illegal_class_name", arg);
+                    toolEnv.error("main.illegal_class_name", arg);
             }
             if (messager.nerrors() != 0) {
                 return null;
             }
-            return new DocEnvImpl(toolEnv, args);
+            etable.setClassArgList(javaNames);
+            // prepare, force the data structures to be analyzed
+            etable.analyze();
+            return new DocEnvImpl(toolEnv, etable);
         }
 
         ListBuffer<JCCompilationUnit> classTrees = new ListBuffer<>();
-        Set<String> includedPackages = new LinkedHashSet<>();
 
         try {
-
             StandardJavaFileManager fm = toolEnv.fileManager instanceof StandardJavaFileManager
-                    ? (StandardJavaFileManager) toolEnv.fileManager : null;
+                    ? (StandardJavaFileManager) toolEnv.fileManager
+                    : null;
             Set<String> packageNames = new LinkedHashSet<>();
             // Normally, the args should be a series of package names or file names.
             // Parse the files and collect the package names.
-            for (String arg: args) {
+            for (String arg: javaNames) {
                 if (fm != null && arg.endsWith(".java") && new File(arg).exists()) {
                     if (new File(arg).getName().equals("module-info.java")) {
                         toolEnv.warning("main.file_ignored", arg);
@@ -181,37 +167,22 @@
                     if (fm == null)
                         throw new IllegalArgumentException();
                     else
-                        toolEnv.error(null, "main.file_not_found", arg);
+                        toolEnv.error("main.file_not_found", arg);
                 } else {
-                    toolEnv.error(null, "main.illegal_package_name", arg);
+                    toolEnv.error("main.illegal_package_name", arg);
                 }
             }
 
             // Parse file objects provide via the DocumentationTool API
             parse(fileObjects, classTrees, true);
 
-            modules.initModules(classTrees.toList());
-
-            // Build up the complete list of any packages to be documented
-            Location location = modules.multiModuleMode ? StandardLocation.MODULE_SOURCE_PATH
-                    : toolEnv.fileManager.hasLocation(StandardLocation.SOURCE_PATH) ? StandardLocation.SOURCE_PATH
-                    : StandardLocation.CLASS_PATH;
-
-            PackageTable t = new PackageTable(toolEnv.fileManager, location)
-                    .packages(packageNames)
-                    .subpackages(subPackages, excludedPackages);
+            etable.packages(packageNames)
+                    .classTrees(classTrees.toList())
+                    .scanSpecifiedItems();
 
-            includedPackages = t.getIncludedPackages();
-
-            // Parse the files in the packages to be documented
+            // Parse the files in the packages and subpackages to be documented
             ListBuffer<JCCompilationUnit> packageTrees = new ListBuffer<>();
-            for (String packageName: includedPackages) {
-                List<JavaFileObject> files = t.getFiles(packageName);
-                toolEnv.notice("main.Loading_source_files_for_package", packageName);
-                if (files.isEmpty())
-                    toolEnv.warning("main.no_source_files_for_package", packageName);
-                parse(files, packageTrees, false);
-            }
+            parse(etable.getFilesToParse(), packageTrees, false);
             modules.enter(packageTrees.toList(), null);
 
             if (messager.nerrors() != 0) {
@@ -220,24 +191,40 @@
 
             // Enter symbols for all files
             toolEnv.notice("main.Building_tree");
-            javadocEnter.main(classTrees.toList().appendList(packageTrees.toList()));
+            javadocEnter.main(classTrees.toList().appendList(packageTrees));
+            etable.setClassDeclList(listClasses(classTrees.toList()));
 
             enterDone = true;
+            etable.analyze();
+        } catch (CompletionFailure cf) {
+            toolEnv.printError(cf.getMessage());
         } catch (Abort ex) {}
 
         if (messager.nerrors() != 0)
             return null;
-        toolEnv.docEnv = new DocEnvImpl(toolEnv, listClasses(classTrees.toList()),
-                                      new ArrayList<>(includedPackages));
+
+        toolEnv.docEnv = new DocEnvImpl(toolEnv, etable);
         return toolEnv.docEnv;
     }
 
     /** Is the given string a valid package name? */
     boolean isValidPackageName(String s) {
-        int index;
-        while ((index = s.indexOf('.')) != -1) {
-            if (!isValidClassName(s.substring(0, index))) return false;
-            s = s.substring(index+1);
+        if (s.contains("/")) {
+            String[] a = s.split("/");
+            if (a.length == 2) {
+                 return isValidPackageName0(a[0]) && isValidPackageName0(a[1]);
+            }
+            return false;
+        }
+        return isValidPackageName0(s);
+    }
+
+    private boolean isValidPackageName0(String s) {
+        for (int index = s.indexOf('.') ; index != -1; index = s.indexOf('.')) {
+            if (!isValidClassName(s.substring(0, index))) {
+                return false;
+            }
+            s = s.substring(index + 1);
         }
         return isValidClassName(s);
     }
@@ -253,8 +240,7 @@
         }
     }
 
-    /** Are surrogates supported?
-     */
+    /** Are surrogates supported? */
     final static boolean surrogatesSupported = surrogatesSupported();
     private static boolean surrogatesSupported() {
         try {
@@ -279,7 +265,7 @@
             int cp = s.codePointAt(0);
             if (!Character.isJavaIdentifierStart(cp))
                 return false;
-            for (int j=Character.charCount(cp); j<s.length(); j+=Character.charCount(cp)) {
+            for (int j = Character.charCount(cp); j < s.length(); j += Character.charCount(cp)) {
                 cp = s.codePointAt(j);
                 if (!Character.isJavaIdentifierPart(cp))
                     return false;
@@ -287,7 +273,7 @@
         } else {
             if (!Character.isJavaIdentifierStart(s.charAt(0)))
                 return false;
-            for (int j=1; j<s.length(); j++)
+            for (int j = 1; j < s.length(); j++)
                 if (!Character.isJavaIdentifierPart(s.charAt(j)))
                     return false;
         }
@@ -307,141 +293,4 @@
         }
         return result;
     }
-
-    /**
-     * A table to manage included and excluded packages.
-     */
-    class PackageTable {
-        private final Map<String, Entry> entries = new LinkedHashMap<>();
-        private final Set<String> includedPackages = new LinkedHashSet<>();
-        private final JavaFileManager fm;
-        private final Location location;
-        private final Set<JavaFileObject.Kind> sourceKinds = EnumSet.of(JavaFileObject.Kind.SOURCE);
-
-        /**
-         * Creates a table to manage included and excluded packages.
-         * @param fm The file manager used to locate source files
-         * @param locn the location used to locate source files
-         */
-        PackageTable(JavaFileManager fm, Location locn) {
-            this.fm = fm;
-            this.location = locn;
-            getEntry("").excluded = false;
-        }
-
-        PackageTable packages(Collection<String> packageNames) {
-            includedPackages.addAll(packageNames);
-            return this;
-        }
-
-        PackageTable subpackages(Collection<String> packageNames, Collection<String> excludePackageNames)
-                throws IOException {
-            for (String p: excludePackageNames) {
-                getEntry(p).excluded = true;
-            }
-
-            for (String packageName: packageNames) {
-                for (JavaFileObject fo: fm.list(location, packageName, sourceKinds, true)) {
-                    String binaryName = fm.inferBinaryName(location, fo);
-                    String pn = getPackageName(binaryName);
-                    String simpleName = getSimpleName(binaryName);
-                    Entry e = getEntry(pn);
-                    if (!e.isExcluded() && isValidClassName(simpleName)) {
-                        includedPackages.add(pn);
-                        e.files = (e.files == null
-                                ? com.sun.tools.javac.util.List.of(fo)
-                                : e.files.prepend(fo));
-                    }
-                }
-            }
-            return this;
-        }
-
-        /**
-         * Returns the aggregate set of included packages.
-         * @return the aggregate set of included packages
-         */
-        Set<String> getIncludedPackages() {
-            return includedPackages;
-        }
-
-        /**
-         * Returns the set of source files for a package.
-         * @param packageName the specified package
-         * @return the set of file objects for the specified package
-         * @throws IOException if an error occurs while accessing the files
-         */
-        List<JavaFileObject> getFiles(String packageName) throws IOException {
-            Entry e = getEntry(packageName);
-            // The files may have been found as a side effect of searching for subpackages
-            if (e.files != null)
-                return e.files;
-
-            ListBuffer<JavaFileObject> lb = new ListBuffer<>();
-            Location packageLocn = getLocation(packageName);
-            if (packageLocn == null)
-                return Collections.emptyList();
-            for (JavaFileObject fo: fm.list(packageLocn, packageName, sourceKinds, false)) {
-                String binaryName = fm.inferBinaryName(packageLocn, fo);
-                String simpleName = getSimpleName(binaryName);
-                if (isValidClassName(simpleName)) {
-                    lb.append(fo);
-                }
-            }
-
-            return lb.toList();
-        }
-
-        private Location getLocation(String packageName) throws IOException {
-            if (location == StandardLocation.MODULE_SOURCE_PATH) {
-                // TODO: handle invalid results better.
-                Name pack = names.fromString(packageName);
-
-                for (ModuleSymbol msym : modules.allModules()) {
-                    PackageSymbol p = syms.getPackage(msym, pack);
-                    if (p != null && !p.members().isEmpty()) {
-                        return fm.getModuleLocation(location, msym.name.toString());
-                    }
-                }
-
-                return null;
-            } else {
-                return location;
-            }
-        }
-
-        private Entry getEntry(String name) {
-            Entry e = entries.get(name);
-            if (e == null)
-                entries.put(name, e = new Entry(name));
-            return e;
-        }
-
-        private String getPackageName(String name) {
-            int lastDot = name.lastIndexOf(".");
-            return (lastDot == -1 ? "" : name.substring(0, lastDot));
-        }
-
-        private String getSimpleName(String name) {
-            int lastDot = name.lastIndexOf(".");
-            return (lastDot == -1 ? name : name.substring(lastDot + 1));
-        }
-
-        class Entry {
-            final String name;
-            Boolean excluded;
-            com.sun.tools.javac.util.List<JavaFileObject> files;
-
-            Entry(String name) {
-                this.name = name;
-            }
-
-            boolean isExcluded() {
-                if (excluded == null)
-                    excluded = getEntry(getPackageName(name)).isExcluded();
-                return excluded;
-            }
-        }
-    }
-
 }
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java	Thu Aug 18 05:48:35 2016 -0700
@@ -29,7 +29,6 @@
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.PrintWriter;
-import java.lang.reflect.Method;
 import java.nio.file.Path;
 import java.text.BreakIterator;
 import java.util.ArrayList;
@@ -41,8 +40,6 @@
 import java.util.Objects;
 import java.util.Set;
 
-import static javax.tools.DocumentationTool.Location.*;
-
 import javax.tools.JavaFileManager;
 import javax.tools.JavaFileObject;
 import javax.tools.StandardJavaFileManager;
@@ -65,6 +62,8 @@
 import jdk.javadoc.doclet.Doclet.Option;
 import jdk.javadoc.doclet.DocletEnvironment;
 
+import static javax.tools.DocumentationTool.Location.*;
+
 import static com.sun.tools.javac.main.Option.*;
 
 /**
@@ -92,9 +91,6 @@
 
     private static final String ProgramName = "javadoc";
 
-    // meaning we allow all visibility of PROTECTED and PUBLIC
-    private static final String defaultModifier = "protected";
-
     private Messager messager;
 
     private final String docletName;
@@ -337,6 +333,7 @@
     /**
      * Main program - internal
      */
+    @SuppressWarnings("unchecked")
     private boolean parseAndExecute(List<String> argList,
             Iterable<? extends JavaFileObject> fileObjects) throws IOException {
         long tm = System.currentTimeMillis();
@@ -390,28 +387,25 @@
         }
 
         compOpts.notifyListeners();
+        List<String> modules = (List<String>) jdtoolOpts.computeIfAbsent(ToolOption.MODULE,
+                s -> Collections.EMPTY_LIST);
 
-        if (javaNames.isEmpty() && subPackages.isEmpty() && isEmpty(fileObjects)) {
-            usageError("main.No_packages_or_classes_specified");
+        if (modules.isEmpty()) {
+            List<String> subpkgs = (List<String>) jdtoolOpts.computeIfAbsent(ToolOption.SUBPACKAGES,
+                    s -> Collections.EMPTY_LIST);
+            if (subpkgs.isEmpty()) {
+                if (javaNames.isEmpty() && isEmpty(fileObjects)) {
+                    usageError("main.No_modules_packages_or_classes_specified");
+                }
+            }
         }
 
         JavadocTool comp = JavadocTool.make0(context);
         if (comp == null) return false;
 
-        if (showAccess == null) {
-            setFilter(defaultModifier);
-        }
-
-        DocletEnvironment root = comp.getEnvironment(
-                encoding,
-                showAccess,
-                overviewpath,
+        DocletEnvironment docEnv = comp.getEnvironment(jdtoolOpts,
                 javaNames,
-                fileObjects,
-                subPackages,
-                excludedPackages,
-                docClasses,
-                quiet);
+                fileObjects);
 
         // release resources
         comp = null;
@@ -421,8 +415,8 @@
             trees.setBreakIterator(BreakIterator.getSentenceInstance(locale));
         }
         // pass off control to the doclet
-        boolean ok = root != null;
-        if (ok) ok = doclet.run(root);
+        boolean ok = docEnv != null;
+        if (ok) ok = doclet.run(docEnv);
 
         // We're done.
         if (compOpts.get("-verbose") != null) {
@@ -470,11 +464,11 @@
         for (int i = 0 ; i < argv.size() ; i++) {
             String arg = argv.get(i);
             if (arg.equals(ToolOption.LOCALE.opt)) {
-                oneArg(argv, i++);
+                checkOneArg(argv, i++);
                 String lname = argv.get(i);
                 locale = getLocale(lname);
             } else if (arg.equals(ToolOption.DOCLET.opt)) {
-                oneArg(argv, i++);
+                checkOneArg(argv, i++);
                 if (userDocletName != null) {
                     usageError("main.more_than_one_doclet_specified_0_and_1",
                             userDocletName, argv.get(i));
@@ -485,7 +479,7 @@
                 }
                 userDocletName = argv.get(i);
             } else if (arg.equals(ToolOption.DOCLETPATH.opt)) {
-                oneArg(argv, i++);
+                checkOneArg(argv, i++);
                 if (userDocletPath == null) {
                     userDocletPath = argv.get(i);
                 } else {
@@ -605,12 +599,11 @@
                 handleDocletOptions(i, args, true);
 
                 if (o.hasArg) {
-                    oneArg(args, i++);
+                    checkOneArg(args, i++);
                     o.process(this, args.get(i));
                 } else if (o.hasSuffix) {
                     o.process(this, arg);
                 } else {
-                    setOption(arg);
                     o.process(this);
                 }
             } else if (arg.startsWith("-XD")) {
@@ -633,13 +626,11 @@
     }
 
     /**
-     * Set one arg option.
+     * Check the one arg option.
      * Error and exit if one argument is not provided.
      */
-    private void oneArg(List<String> args, int index) {
-        if ((index + 1) < args.size()) {
-            setOption(args.get(index), args.get(index+1));
-        } else {
+    private void checkOneArg(List<String> args, int index) {
+        if ((index + 1) >= args.size() || args.get(index + 1).startsWith("-d")) {
             usageError("main.requires_argument", args.get(index));
         }
     }
@@ -659,32 +650,6 @@
     }
 
     /**
-     * indicate an option with no arguments was given.
-     */
-    private void setOption(String opt) {
-        String[] option = { opt };
-        options.add(Arrays.asList(option));
-    }
-
-    /**
-     * indicate an option with one argument was given.
-     */
-    private void setOption(String opt, String argument) {
-        String[] option = { opt, argument };
-        options.add(Arrays.asList(option));
-    }
-
-    /**
-     * indicate an option with the specified list of arguments was given.
-     */
-    private void setOption(String opt, List<String> arguments) {
-        List<String> args = new ArrayList<>(arguments.size() + 1);
-        args.add(opt);
-        args.addAll(arguments);
-        options.add(args);
-    }
-
-    /**
      * Get the locale if specified on the command line
      * else return null and if locale option is not used
      * then return default locale.
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolEnvironment.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolEnvironment.java	Thu Aug 18 05:48:35 2016 -0700
@@ -26,16 +26,12 @@
 package jdk.javadoc.internal.tool;
 
 
-import java.lang.reflect.Modifier;
 import java.util.*;
 
 import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
 import javax.lang.model.element.PackageElement;
 import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
 import javax.lang.model.util.Elements;
-import javax.lang.model.util.SimpleElementVisitor9;
 import javax.tools.JavaFileManager;
 import javax.tools.JavaFileObject;
 
@@ -44,15 +40,11 @@
 import com.sun.tools.javac.api.JavacTrees;
 import com.sun.tools.javac.code.ClassFinder;
 import com.sun.tools.javac.code.Flags;
-import com.sun.tools.javac.code.Kinds.Kind;
 import com.sun.tools.javac.code.Source;
 import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
 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.VarSymbol;
 import com.sun.tools.javac.code.Symtab;
 import com.sun.tools.javac.comp.AttrContext;
 import com.sun.tools.javac.comp.Check;
@@ -67,13 +59,9 @@
 import com.sun.tools.javac.tree.JCTree.JCPackageDecl;
 import com.sun.tools.javac.util.Context;
 import com.sun.tools.javac.util.Convert;
-import com.sun.tools.javac.util.DefinedBy;
-import com.sun.tools.javac.util.DefinedBy.Api;
 import com.sun.tools.javac.util.Name;
 import com.sun.tools.javac.util.Names;
 
-import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
-
 /**
  * Holds the environment for a run of javadoc.
  * Holds only the information needed throughout the
@@ -113,14 +101,8 @@
     /** The name table. */
     private Names names;
 
-    /** The encoding name. */
-    private String encoding;
-
     final Symbol externalizableSym;
 
-    /** Access filter (public, protected, ...).  */
-    protected ModifierFilter filter;
-
     /**
      * True if we do not want to print any notifications at all.
      */
@@ -181,20 +163,8 @@
         elementToTreePath = new HashMap<>();
     }
 
-    public void intialize(String encoding,
-            String showAccess,
-            String overviewpath,
-            List<String> javaNames,
-            Iterable<? extends JavaFileObject> fileObjects,
-            List<String> subPackages,
-            List<String> excludedPackages,
-            boolean docClasses,
-            boolean quiet) {
-        this.filter = ModifierFilter.getModifierFilter(showAccess);
-        this.quiet = quiet;
-
-        this.setEncoding(encoding);
-        this.docClasses = docClasses;
+    public void initialize(Map<ToolOption, Object> toolOpts) {
+        this.quiet = (boolean)toolOpts.getOrDefault(ToolOption.QUIET, false);
     }
 
     /**
@@ -212,54 +182,8 @@
         }
     }
 
-    private boolean isSynthetic(long flags) {
-        return (flags & Flags.SYNTHETIC) != 0;
-    }
-
-    private boolean isSynthetic(Symbol sym) {
-        return isSynthetic(sym.flags_field);
-    }
-
-    SimpleElementVisitor9<Boolean, Void> shouldDocumentVisitor = null;
-    public boolean shouldDocument(Element e) {
-        if (shouldDocumentVisitor == null) {
-            shouldDocumentVisitor = new SimpleElementVisitor9<Boolean, Void>() {
-
-            @Override @DefinedBy(Api.LANGUAGE_MODEL)
-            public Boolean visitType(TypeElement e, Void p) {
-                return shouldDocument((ClassSymbol)e);
-            }
-
-            @Override @DefinedBy(Api.LANGUAGE_MODEL)
-            public Boolean visitVariable(VariableElement e, Void p) {
-                return shouldDocument((VarSymbol)e);
-            }
-
-            @Override @DefinedBy(Api.LANGUAGE_MODEL)
-            public Boolean visitExecutable(ExecutableElement e, Void p) {
-                return shouldDocument((MethodSymbol)e);
-            }
-        };
-        }
-        return shouldDocumentVisitor.visit(e);
-    }
-
-    /** Check whether this member should be documented. */
-    public boolean shouldDocument(VarSymbol sym) {
-        long mod = sym.flags();
-        if (isSynthetic(mod)) {
-            return false;
-        }
-        return filter.checkModifier(translateModifiers(mod));
-    }
-
-    /** Check whether this member should be documented. */
-    public boolean shouldDocument(MethodSymbol sym) {
-        long mod = sym.flags();
-        if (isSynthetic(mod)) {
-            return false;
-        }
-        return filter.checkModifier(translateModifiers(mod));
+    boolean isSynthetic(Symbol sym) {
+        return (sym.flags() & Flags.SYNTHETIC) != 0;
     }
 
     void setElementToTreePath(Element e, TreePath tree) {
@@ -268,43 +192,16 @@
         elementToTreePath.put(e, tree);
     }
 
-    private boolean hasLeaf(ClassSymbol sym) {
+    /**
+     * Returns true if the symbol has a tree path associated with it.
+     * Primarily used to disambiguate a symbol associated with a source
+     * file versus a class file.
+     * @param sym the symbol to be checked
+     * @return true if the symbol has a tree path
+     */
+    boolean hasPath(ClassSymbol sym) {
         TreePath path = elementToTreePath.get(sym);
-        if (path == null)
-            return false;
-        return path.getLeaf() != null;
-    }
-
-    /** check whether this class should be documented. */
-    public boolean shouldDocument(ClassSymbol sym) {
-        return
-            !isSynthetic(sym.flags_field) && // no synthetics
-            (docClasses || hasLeaf(sym)) &&
-            isVisible(sym);
-    }
-
-    //### Comment below is inaccurate wrt modifier filter testing
-    /**
-     * Check the visibility if this is an nested class.
-     * if this is not a nested class, return true.
-     * if this is an static visible nested class,
-     *    return true.
-     * if this is an visible nested class
-     *    if the outer class is visible return true.
-     *    else return false.
-     * IMPORTANT: This also allows, static nested classes
-     * to be defined inside an nested class, which is not
-     * allowed by the compiler. So such an test case will
-     * not reach upto this method itself, but if compiler
-     * allows it, then that will go through.
-     */
-    public boolean isVisible(ClassSymbol sym) {
-        long mod = sym.flags_field;
-        if (!filter.checkModifier(translateModifiers(mod))) {
-            return false;
-        }
-        ClassSymbol encl = sym.owner.enclClass();
-        return (encl == null || (mod & Flags.STATIC) != 0 || isVisible(encl));
+        return path != null;
     }
 
     //---------------- print forwarders ----------------//
@@ -366,6 +263,15 @@
 
     /**
      * Print error message, increment error count.
+     * @param key selects message from resource
+     * @param args replacement arguments
+     */
+    public void error(String key, String... args) {
+        error(null, key, args);
+    }
+
+    /**
+     * Print error message, increment error count.
      *
      * @param element the source element
      * @param key selects message from resource
@@ -553,48 +459,6 @@
         throw new Messager.ExitJavadoc();
     }
 
-    /**
-     * Adds all inner classes of this class, and their inner classes recursively, to the list
-     */
-    void addAllClasses(Collection<TypeElement> list, TypeElement typeElement, boolean filtered) {
-        ClassSymbol klass = (ClassSymbol)typeElement;
-        try {
-            if (isSynthetic(klass.flags())) return;
-            // sometimes synthetic classes are not marked synthetic
-            if (!JavadocTool.isValidClassName(klass.name.toString())) return;
-            if (filtered && !shouldDocument(klass)) return;
-            if (list.contains(klass)) return;
-            list.add(klass);
-            for (Symbol sym : klass.members().getSymbols(NON_RECURSIVE)) {
-                if (sym != null && sym.kind == Kind.TYP) {
-                    ClassSymbol s = (ClassSymbol)sym;
-                    if (!isSynthetic(s.flags())) {
-                        addAllClasses(list, s, filtered);
-                    }
-                }
-            }
-        } catch (CompletionFailure e) {
-            // quietly ignore completion failures
-        }
-    }
-
-    /**
-     * Return a list of all classes contained in this package, including
-     * member classes of those classes, and their member classes, etc.
-     */
-    void addAllClasses(Collection<TypeElement> list, PackageElement pkg) {
-        boolean filtered = true;
-        PackageSymbol sym = (PackageSymbol)pkg;
-        for (Symbol isym : sym.members().getSymbols(NON_RECURSIVE)) {
-            if (isym != null) {
-                ClassSymbol s = (ClassSymbol)isym;
-                if (!isSynthetic(s)) {
-                    addAllClasses(list, s, filtered);
-                }
-            }
-        }
-    }
-
     TreePath getTreePath(JCCompilationUnit tree) {
         TreePath p = treePaths.get(tree);
         if (p == null)
@@ -624,225 +488,11 @@
         return types;
     }
 
-    /**
-     * Set the encoding.
-     */
-    public void setEncoding(String encoding) {
-        this.encoding = encoding;
-    }
-
     public Env<AttrContext> getEnv(ClassSymbol tsym) {
         return enter.getEnv(tsym);
     }
 
-    /**
-     * Get the encoding.
-     */
-    public String getEncoding() {
-        return encoding;
-    }
-
-    /**
-     * Convert modifier bits from private coding used by
-     * the compiler to that of java.lang.reflect.Modifier.
-     */
-    static int translateModifiers(long flags) {
-        int result = 0;
-        if ((flags & Flags.ABSTRACT) != 0)
-            result |= Modifier.ABSTRACT;
-        if ((flags & Flags.FINAL) != 0)
-            result |= Modifier.FINAL;
-        if ((flags & Flags.INTERFACE) != 0)
-            result |= Modifier.INTERFACE;
-        if ((flags & Flags.NATIVE) != 0)
-            result |= Modifier.NATIVE;
-        if ((flags & Flags.PRIVATE) != 0)
-            result |= Modifier.PRIVATE;
-        if ((flags & Flags.PROTECTED) != 0)
-            result |= Modifier.PROTECTED;
-        if ((flags & Flags.PUBLIC) != 0)
-            result |= Modifier.PUBLIC;
-        if ((flags & Flags.STATIC) != 0)
-            result |= Modifier.STATIC;
-        if ((flags & Flags.SYNCHRONIZED) != 0)
-            result |= Modifier.SYNCHRONIZED;
-        if ((flags & Flags.TRANSIENT) != 0)
-            result |= Modifier.TRANSIENT;
-        if ((flags & Flags.VOLATILE) != 0)
-            result |= Modifier.VOLATILE;
-        return result;
-    }
-
-    private final Set<Element> includedSet = new HashSet<>();
-
-    public void setIncluded(Element element) {
-        includedSet.add(element);
-    }
-
-    private SimpleElementVisitor9<Boolean, Void> includedVisitor = null;
-
-    public boolean isIncluded(Element e) {
-        if (e == null) {
-            return false;
-        }
-        if (includedVisitor == null) {
-            includedVisitor = new SimpleElementVisitor9<Boolean, Void>() {
-                @Override @DefinedBy(Api.LANGUAGE_MODEL)
-                public Boolean visitType(TypeElement e, Void p) {
-                    if (includedSet.contains(e)) {
-                        return true;
-                    }
-                    if (shouldDocument(e)) {
-                        // Class is nameable from top-level and
-                        // the class and all enclosing classes
-                        // pass the modifier filter.
-                        PackageElement pkg = elements.getPackageOf(e);
-                        if (includedSet.contains(pkg)) {
-                            setIncluded(e);
-                            return true;
-                        }
-                        Element enclosing = e.getEnclosingElement();
-                        if (enclosing != null && includedSet.contains(enclosing)) {
-                            setIncluded(e);
-                            return true;
-                        }
-                    }
-                    return false;
-                }
-
-                @Override @DefinedBy(Api.LANGUAGE_MODEL)
-                public Boolean visitPackage(PackageElement e, Void p) {
-                    return includedSet.contains(e);
-                }
-
-                @Override @DefinedBy(Api.LANGUAGE_MODEL)
-                public Boolean visitUnknown(Element e, Void p) {
-                    throw new AssertionError("unknown element: " + e);
-                }
-
-                @Override @DefinedBy(Api.LANGUAGE_MODEL)
-                public Boolean defaultAction(Element e, Void p) {
-                    return visit(e.getEnclosingElement()) && shouldDocument(e);
-                }
-            };
-        }
-        return includedVisitor.visit(e);
-    }
-
     public boolean isQuiet() {
         return quiet;
     }
-
-    /**
-     * A class which filters the access flags on classes, fields, methods, etc.
-     *
-     * <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>
-     *
-     * @see javax.lang.model.element.Modifier
-     * @author Robert Field
-     */
-
-    private static class ModifierFilter {
-
-        static enum FilterFlag {
-            PACKAGE,
-            PRIVATE,
-            PROTECTED,
-            PUBLIC
-        }
-
-        private Set<FilterFlag> oneOf;
-
-        /**
-         * Constructor - Specify a filter.
-         *
-         * @param oneOf a set containing desired flags to be matched.
-         */
-        ModifierFilter(Set<FilterFlag> oneOf) {
-            this.oneOf = oneOf;
-        }
-
-        /**
-         * Constructor - Specify a filter.
-         *
-         * @param oneOf an array containing desired flags to be matched.
-         */
-        ModifierFilter(FilterFlag... oneOf) {
-            this.oneOf = new HashSet<>();
-            this.oneOf.addAll(Arrays.asList(oneOf));
-        }
-
-        static ModifierFilter getModifierFilter(String showAccess) {
-            switch (showAccess) {
-                case "public":
-                    return new ModifierFilter(FilterFlag.PUBLIC);
-                case "package":
-                    return new ModifierFilter(FilterFlag.PUBLIC, FilterFlag.PROTECTED,
-                                              FilterFlag.PACKAGE);
-                case "private":
-                    return new ModifierFilter(FilterFlag.PRIVATE);
-                default:
-                    return new ModifierFilter(FilterFlag.PUBLIC, FilterFlag.PROTECTED);
-            }
-        }
-
-        private boolean hasFlag(long flag, long modifierBits) {
-            return (flag & modifierBits) != 0;
-        }
-
-        private List<FilterFlag> flagsToModifiers(long modifierBits) {
-            List<FilterFlag> list = new ArrayList<>();
-            boolean isPackage = true;
-            if (hasFlag(com.sun.tools.javac.code.Flags.PRIVATE, modifierBits)) {
-                list.add(FilterFlag.PRIVATE);
-                isPackage = false;
-            }
-            if (hasFlag(com.sun.tools.javac.code.Flags.PROTECTED, modifierBits)) {
-                list.add(FilterFlag.PROTECTED);
-                isPackage = false;
-            }
-            if (hasFlag(com.sun.tools.javac.code.Flags.PUBLIC, modifierBits)) {
-                list.add(FilterFlag.PUBLIC);
-                isPackage = false;
-            }
-            if (isPackage) {
-                list.add(FilterFlag.PACKAGE);
-            }
-            return list;
-        }
-
-        /**
-         * Filter on modifier bits.
-         *
-         * @param modifierBits Bits as specified in the Modifier class
-         *
-         * @return Whether the modifierBits pass this filter.
-         */
-        public boolean checkModifier(int modifierBits) {
-            return checkModifier(flagsToModifiers(modifierBits));
-        }
-
-        /**
-         * Filter on Filter flags
-         *
-         * @param modifiers Flags as specified in the FilterFlags enumeration.
-         *
-         * @return if the modifier is contained.
-         */
-        public boolean checkModifier(List<FilterFlag> modifiers) {
-            if (oneOf.contains(FilterFlag.PRIVATE)) {
-                return true;
-            }
-            for (FilterFlag mod : modifiers) {
-                if (oneOf.contains(mod)) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-    } // end ModifierFilter
 }
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOption.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOption.java	Thu Aug 18 05:48:35 2016 -0700
@@ -26,10 +26,13 @@
 package jdk.javadoc.internal.tool;
 
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.StringTokenizer;
+
+import javax.lang.model.element.ElementKind;
 
 import com.sun.tools.javac.main.Option;
 import com.sun.tools.javac.main.OptionHelper;
@@ -44,6 +47,7 @@
  *  deletion without notice.</b>
  */
 public enum ToolOption {
+
     // ----- options for underlying compiler -----
 
     BOOTCLASSPATH("-bootclasspath", true) {
@@ -193,10 +197,16 @@
         }
     },
 
+    MODULE("--module", true) {
+        @Override
+        public void process(Helper helper, String arg) {
+            helper.addToList(this, ",", arg);
+        }
+    },
+
     ENCODING("-encoding", true) {
         @Override
         public void process(Helper helper, String arg) {
-            helper.encoding = arg;
             helper.setFileManagerOpt(Option.ENCODING, arg);
         }
     },
@@ -296,14 +306,14 @@
     SUBPACKAGES("-subpackages", true) {
         @Override
         public void process(Helper helper, String arg) {
-            helper.addToList(helper.subPackages, arg);
+            helper.addToList(this, ":", arg);
         }
     },
 
     EXCLUDE("-exclude", true) {
         @Override
         public void process(Helper helper, String arg) {
-            helper.addToList(helper.excludedPackages, arg);
+            helper.addToList(this, ":", arg);
         }
     },
 
@@ -312,28 +322,63 @@
     PACKAGE("-package") {
         @Override
         public void process(Helper helper) {
-            helper.setFilter("package");
+            helper.setSimpleFilter("package");
         }
     },
 
     PRIVATE("-private") {
         @Override
         public void process(Helper helper) {
-            helper.setFilter("private");
+            helper.setSimpleFilter("private");
         }
     },
 
     PROTECTED("-protected") {
         @Override
         public void process(Helper helper) {
-            helper.setFilter("protected");
+            helper.setSimpleFilter("protected");
         }
     },
 
     PUBLIC("-public") {
         @Override
         public void process(Helper helper) {
-            helper.setFilter("public");
+            helper.setSimpleFilter("public");
+        }
+    },
+
+    SHOW_MEMBERS("--show-members:") {
+        @Override
+        public void process(Helper helper, String arg) {
+            helper.setFilter(this, arg);
+        }
+    },
+
+    SHOW_TYPES("--show-types:") {
+        @Override
+        public void process(Helper helper, String arg) {
+            helper.setFilter(this, arg);
+        }
+    },
+
+    SHOW_PACKAGES("--show-packages:") {
+        @Override
+        public void process(Helper helper, String arg) {
+            helper.setShowPackageAccess(SHOW_PACKAGES, helper.getOptionArgumentValue(arg));
+        }
+    },
+
+    SHOW_MODULE_CONTENTS("--show-module-contents:") {
+        @Override
+        public void process(Helper helper, String arg) {
+            helper.setShowModuleContents(SHOW_MODULE_CONTENTS, helper.getOptionArgumentValue(arg));
+        }
+    },
+
+    EXPAND_REQUIRES("--expand-requires:") {
+        @Override
+        public void process(Helper helper, String arg) {
+            helper.setExpandRequires(EXPAND_REQUIRES, helper.getOptionArgumentValue(arg));
         }
     },
 
@@ -350,7 +395,7 @@
     QUIET("-quiet") {
         @Override
         public void process(Helper helper) {
-            helper.quiet = true;
+            helper.jdtoolOpts.put(QUIET, true);
         }
     },
 
@@ -385,19 +430,10 @@
         }
     },
 
-    // the doclet consumes this
-    OVERVIEW("-overview", true) {
-        @Override
-        public void process(Helper helper, String arg) {
-            helper.setOverviewpath(arg);
-        }
-    },
-
     XCLASSES("-Xclasses") {
         @Override
         public void process(Helper helper) {
-            helper.docClasses = true;
-
+            helper.jdtoolOpts.put(XCLASSES, true);
         }
     },
 
@@ -452,14 +488,6 @@
     }
 
     static abstract class Helper {
-        /** List of decoded options. */
-        final List<List<String>> options = new ArrayList<>();
-
-        /** Selected packages, from -subpackages. */
-        final List<String> subPackages = new ArrayList<>();
-
-        /** Excluded packages, from -exclude. */
-        final List<String> excludedPackages = new ArrayList<>();
 
         // File manager options
         final Map<Option, String> fileManagerOpts = new LinkedHashMap<>();
@@ -467,18 +495,12 @@
         /** javac options, set by various options. */
         Options compOpts; // = Options.instance(context)
 
-        /* Encoding for javac, and files written? set by -encoding. */
-        String encoding = null;
+        /** Javadoc tool options */
+        final Map<ToolOption, Object> jdtoolOpts = new EnumMap<>(ToolOption.class);
 
         /** Set by -breakiterator. */
         boolean breakiterator = false;
 
-        /** Set by -quiet. */
-        boolean quiet = false;
-
-        /** Set by -Xclasses. */
-        boolean docClasses = false;
-
         /** Set by -Xwerror. */
         boolean rejectWarnings = false;
 
@@ -488,9 +510,9 @@
         /** Set by -locale. */
         String docLocale = "";
 
-        /** Set by -public, private, -protected, -package. */
-        String showAccess = null;
-        String overviewpath;
+        Helper() {
+            populateDefaultAccessMap();
+        }
 
         abstract void usage();
         abstract void Xusage();
@@ -498,33 +520,129 @@
         abstract void usageError(String msg, Object... args);
         abstract OptionHelper getOptionHelper();
 
-        void addToList(List<String> list, String str){
-            StringTokenizer st = new StringTokenizer(str, ":");
-            String current;
-            while(st.hasMoreTokens()){
-                current = st.nextToken();
-                list.add(current);
+        @SuppressWarnings("unchecked")
+        void addToList(ToolOption opt, String delimiter, String str) {
+            List<String> list = (List<String>) jdtoolOpts.computeIfAbsent(opt, v -> new ArrayList<>());
+            list.addAll(Arrays.asList(str.split(delimiter)));
+            jdtoolOpts.put(opt, list);
+        }
+
+        String getOptionArgumentValue(String in) {
+            String[] values = in.trim().split(":");
+            return values[1];
+        }
+
+        void setExpandRequires(ToolOption opt, String arg) {
+            switch (arg) {
+                case "public":
+                    jdtoolOpts.put(opt, AccessKind.PUBLIC);
+                    break;
+                case "all":
+                    jdtoolOpts.put(opt, AccessKind.PRIVATE);
+                    break;
+                default:
+                    usageError("main.illegal_option_value", arg);
             }
         }
 
-        void setFilter(String showAccess) {
-            if (showAccess != null) {
-                if (!"public".equals(showAccess)
-                        && !"protected".equals(showAccess)
-                        && !"private".equals(showAccess)
-                        && !"package".equals(showAccess)) {
-                    usageError("main.incompatible.access.flags");
-                }
-                this.showAccess = showAccess;
+        void setShowModuleContents(ToolOption opt, String arg) {
+            switch (arg) {
+                case "api":
+                    jdtoolOpts.put(opt, AccessKind.PUBLIC);
+                    break;
+                case "all":
+                    jdtoolOpts.put(opt, AccessKind.PRIVATE);
+                    break;
+                default:
+                    usageError("main.illegal_option_value", arg);
             }
         }
 
+        void setShowPackageAccess(ToolOption opt, String arg) {
+            switch (arg) {
+                case "exported":
+                    jdtoolOpts.put(opt, AccessKind.PUBLIC);
+                    break;
+                case "all":
+                    jdtoolOpts.put(opt, AccessKind.PRIVATE);
+                    break;
+                default:
+                    usageError("main.illegal_option_value", arg);
+            }
+        }
+
+
+        void setFilter(ToolOption opt, String arg) {
+            jdtoolOpts.put(opt, getAccessValue(arg));
+        }
+
+        void setSimpleFilter(String arg) {
+            handleSimpleOption(arg);
+        }
+
         void setFileManagerOpt(Option opt, String arg) {
             fileManagerOpts.put(opt, arg);
         }
 
-        private void setOverviewpath(String arg) {
-            this.overviewpath = arg;
+        void handleSimpleOption(String arg) {
+            populateSimpleAccessMap(getAccessValue(arg));
+        }
+
+        /*
+         * This method handles both the simple options -package,
+         * -private, so on, in addition to the new ones such as
+         * --show-types:public and so on.
+         */
+        private AccessKind getAccessValue(String arg) {
+            int colon = arg.indexOf(':');
+            String value = (colon > 0)
+                    ? arg.substring(colon + 1)
+                    : arg;
+            switch (value) {
+                case "public":
+                    return AccessKind.PUBLIC;
+                case "protected":
+                    return AccessKind.PROTECTED;
+                case "package":
+                    return AccessKind.PACKAGE;
+                case "private":
+                    return AccessKind.PRIVATE;
+                default:
+                    usageError("main.illegal_option_value", value);
+                    return null;
+            }
+        }
+
+        /*
+         * Sets the entire kind map to PROTECTED this is the default.
+         */
+        private void populateDefaultAccessMap() {
+            populateSimpleAccessMap(AccessKind.PROTECTED);
+        }
+
+        /*
+         * This sets access to all the allowed kinds in the
+         * access map.
+         */
+        void populateSimpleAccessMap(AccessKind accessValue) {
+            for (ElementKind kind : ElementsTable.ModifierFilter.ALLOWED_KINDS) {
+                switch (kind) {
+                    case METHOD:
+                        jdtoolOpts.put(SHOW_MEMBERS, accessValue);
+                        break;
+                    case CLASS:
+                        jdtoolOpts.put(SHOW_TYPES, accessValue);
+                        break;
+                    case PACKAGE:
+                        jdtoolOpts.put(SHOW_PACKAGES, accessValue);
+                        break;
+                    case MODULE:
+                        jdtoolOpts.put(SHOW_MODULE_CONTENTS, accessValue);
+                        break;
+                    default:
+                        throw new AssertionError("unknown element kind:" + kind);
+                }
+            }
         }
     }
 }
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties	Thu Aug 18 05:48:35 2016 -0700
@@ -31,18 +31,53 @@
 main.usage=Usage: javadoc [options] [packagenames] [sourcefiles] [@files]\n\
 \  -overview <file>                 Read overview documentation from HTML file\n\
 \  -public                          Show only public classes and members\n\
-\  -protected                       Show protected/public classes and members (default)\n\
-\  -package                         Show package/protected/public classes and members\n\
+\  -protected                       Show protected/public classes and \n\
+\                                   members (default)\n\
+\  -package                         Show package/protected/public classes\n\
+\                                   and members\n\
 \  -private                         Show all classes and members\n\
+\  --show-members:value             Specifies which members (fields, methods\n\
+\                                   etc.) will be documented, where value can\n\
+\                                   be one of "public", "protected", "package"\n\
+\                                   or "private".\n\
+\                                   Default is protected, will show public and\n\
+\                                   protected members, "public" will show only\n\
+\                                   public members, "package" will show public,\n\
+\                                   protected and package members and \n\
+\                                   "private" will show all  members\n\
+\  --show-types:value               Specifies which types (classes, interfaces\n\
+\                                   etc.) will be documented, where value can be\n\
+\                                   one of "public", "protected", "package" or\n\
+\                                   "private".\n\
+\                                   Default is "protected", show public and\n\
+\                                   protected types, "package" will show public,\n\
+\                                   protected and package types and "private"\n\
+\                                   will show all types\n\
+\  --show-packages:value            Specifies which module's packages will be\n\
+\                                   documented. Possible values are "exported"\n\
+\                                   or "all" packages\n\
+\  --show-module-contents:value     Specifies the documentation granularity of\n\
+\                                   module declarations.\n\
+\                                   Possible values are "api" or "all".\n\
+\  --expand-requires:value          Instructs the tool to expand the "requires"\n\
+\                                   module dependencies "public" expands all the\n\
+\                                   "requires public" edges of the module graph.\n\
+\                                   "all" expands all the "requires" edges of\n\
+\                                   the module graph by default only the\n\
+\                                   specified modules will be considered.\n\
 \  -help                            Display command line options and exit\n\
+\  --module m1, m2..                Document the specified module(s)\n\
 \  -doclet <class>                  Generate output via alternate doclet\n\
 \  -docletpath <path>               Specify where to find doclet class files\n\
-\  --module-source-path <path>      Specify where to find input source files for multiple modules\n\
+\  --module-source-path <path>      Specify where to find input source files\n\
+\                                   for multiple modules\n\
 \  --upgrade-module-path <path>     Override location of upgradeable modules\n\
 \  --module-path <path>, -p <path>  Specify where to find application modules\n\
 \  --add-modules <module>(,<module>)*\n\
-\                                   Root modules to resolve in addition to the initial modules,\n\
-\                                   or all modules on the module path if <module> is ALL-MODULE-PATH.\n\
+\                                   Root modules to resolve in addition to the\n\
+\                                   initial modules,\n\
+\                                   or all modules on the module path if\n\
+\                                   <module> is ALL-MODULE-PATH.\n\
 \  --limit-modules <module>(,<module>)*\n\
 \                                   Limit the universe of observable modules\n\
 \  --source-path <path>             Specify where to find source files\n\
@@ -57,35 +92,40 @@
 \                                   used for non-modular releases\n\
 \  --system <jdk>                   Override location of system modules used\n\
 \                                   for modular releases.\n\
-\  --release <release>              Provide source compatibility with specified release\n\
-\  -source <release>                Provide source compatibility with specified release\n\
+\  --release <release>              Provide source compatibility with\n\
+\                                   specified release\n\
+\  -source <release>                Provide source compatibility with\n\
+\                                   specified release\n\
 \  -extdirs <dirlist>               Override location of installed extensions\n\
 \  -verbose                         Output messages about what Javadoc is doing\n\
 \  -locale <name>                   Locale to be used, e.g. en_US or en_US_WIN\n\
 \  -encoding <name>                 Source file encoding name\n\
 \  -quiet                           Do not display status messages\n\
 \  -J<flag>                         Pass <flag> directly to the runtime system\n\
-\  -X                               Print a synopsis of nonstandard options and exit\n
+\  -X                               Print a synopsis of nonstandard\n\
+\                                   options and exit\n
 
 main.usage.foot=\n\
-GNU-style options may use '=' instead whitespace to separate the name of an option\n\
-from its value.\n
+GNU-style options may use '=' instead of whitespace to separate the name of an\n\
+option from its value.\n
 
 main.Xusage=\
 \  -Xmaxerrs <number>               Set the maximum number of errors to print\n\
 \  -Xmaxwarns <number>              Set the maximum number of warnings to print\n\
 \  --add-exports <module>/<package>=<other-module>(,<other-module>)*\n\
-\                                   Specify a package to be considered as exported from its \n\
-\                                   defining module to additional modules, or to all unnamed \n\
-\                                   modules if <other-module> is ALL-UNNAMED.\n\
+\                                   Specify a package to be considered as exported\n\
+\                                   from its defining module to additional modules,\n\
+\                                   or to all unnamed modules if <other-module> is\n\
+\                                   ALL-UNNAMED.\n\
 \  --add-reads <module>=<other-module>(,<other-module>)*\n\
-\                                   Specify additional modules to be considered as required by a\n\
-\                                   given module. <other-module> may be ALL-UNNAMED to require\n\
-\                                   the unnamed module.\n\
-\  -Xmodule:<module-name>           Specify a module to which the classes being compiled belong.\n\
+\                                   Specify additional modules to be considered as\n\
+\                                   required by a given module. <other-module> may be\n\
+\                                   ALL-UNNAMED to require the unnamed module.\n\
+\  -Xmodule:<module-name>           Specify a module to which the classes being\n\
+\                                   compiled belong.\n\
 \  --patch-module <module>=<file>(:<file>)*\n\
-\                                   Override or augment a module with classes and resources\n\
-\                                   in JAR files or directories\n\
+\                                   Override or augment a module with classes\n\
+\                                   and resources in JAR files or directories\n\
 \  -Xold                            Invoke the legacy javadoc tool\n
 
 main.Xusage.foot=\
@@ -95,13 +135,14 @@
 
 main.requires_argument=option {0} requires an argument.
 main.invalid_flag=invalid flag: {0}
-main.No_packages_or_classes_specified=No packages or classes specified.
-main.incompatible.access.flags=More than one of -public, -private, -package, or -protected specified.
+main.No_modules_packages_or_classes_specified=No modules, packages or classes specified.
+main.module_not_found=module {0} not found.\n
 main.cant.read=cannot read {0}
 main.Loading_source_files_for_package=Loading source files for package {0}...
 main.Loading_source_file=Loading source file {0}...
 main.Building_tree=Constructing Javadoc information...
 main.no_source_files_for_package=No source files for package {0}
+main.package_not_found=Package {0} not found
 main.fatal.error=fatal error
 main.fatal.exception=fatal exception
 main.out.of.memory=java.lang.OutOfMemoryError: Please increase memory.\n\
@@ -119,6 +160,7 @@
 main.file_ignored=File ignored: "{0}" (not yet supported)
 main.illegal_class_name=Illegal class name: "{0}"
 main.illegal_package_name=Illegal package name: "{0}"
+main.illegal_option_value=Illegal option value: "{0}"
 main.release.bootclasspath.conflict=option {0} cannot be used together with -release
 main.unsupported.release.version=release version {0} not supported
 main.release.not.standard.file.manager=-release option specified, but the provided JavaFileManager is not a StandardJavaFileManager.
--- a/langtools/test/jdk/javadoc/doclet/testFramesNoFrames/TestFramesNoFrames.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/test/jdk/javadoc/doclet/testFramesNoFrames/TestFramesNoFrames.java	Thu Aug 18 05:48:35 2016 -0700
@@ -205,10 +205,7 @@
     void testModules(Path base, FrameKind fKind, OverviewKind oKind, HtmlKind hKind) throws IOException {
         javadoc(base, fKind, oKind, hKind,
             "-modulesourcepath", gensrcModules.toString(),
-            "-addmods", "m1,m2,m3", // TEMPORARY, SHOULD NOT BE NECESSARY
-            "m1p1", "m1p2", "m1p3",
-            "m2p1", "m2p2", "m2p3",
-            "m3p1", "m3p2", "m3p3");
+            "--module", "m1,m2,m3");
 
         new Checker(fKind, oKind, hKind)
             .classes("m1/m1p1.M1P1C1", "m1/m1p1.M1P1C2", "m1/m1p1.M1P1C3",
--- a/langtools/test/jdk/javadoc/doclet/testLinkTaglet/TestLinkTaglet.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/test/jdk/javadoc/doclet/testLinkTaglet/TestLinkTaglet.java	Thu Aug 18 05:48:35 2016 -0700
@@ -70,5 +70,7 @@
 
         checkOutput(Output.OUT, false,
                 "Tag @see: reference not found: A");
+
+        checkFiles(false, "checkPkg/A.html");
     }
 }
--- a/langtools/test/jdk/javadoc/doclet/testModules/TestModules.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/test/jdk/javadoc/doclet/testModules/TestModules.java	Thu Aug 18 05:48:35 2016 -0700
@@ -158,7 +158,7 @@
         javadoc("-d", "out-moduleSummary", "-use",
                 "-modulesourcepath", testSrc,
                 "-addmods", "module1,module2",
-                "testpkgmdl1", "testpkgmdl2", "testpkg2mdl2");
+                "testpkgmdl1", "testpkgmdl2", "module2/testpkg2mdl2");
         checkExit(Exit.OK);
         checkModuleSummary();
         checkNegatedModuleSummary();
@@ -174,7 +174,7 @@
                 "-addmods", "module1",
                 "testpkgmdl1");
         checkExit(Exit.OK);
-        checkModuleFilesAndLinks(false);
+        checkModuleFilesAndLinks(true);
     }
 
     void checkDescription(boolean found) {
@@ -418,7 +418,8 @@
                 + "</a>");
         checkOutput("module2-summary.html", true,
                 "<tr class=\"rowColor\">\n"
-                + "<td class=\"colFirst\">testpkg2mdl2</td>\n"
+                + "<td class=\"colFirst\"><a href=\"testpkg2mdl2/package-summary.html\">"
+                + "testpkg2mdl2</a></td>\n"
                 + "<td class=\"colSecond\">module1</td>\n"
                 + "<td class=\"colLast\">&nbsp;</td>\n"
                 + "</tr>");
@@ -445,9 +446,10 @@
                 + "</tr>");
         checkOutput("module2-summary.html", true,
                 "<tr class=\"altColor\">\n"
-                + "<td class=\"colFirst\">testpkg2mdl2.TestInterfaceInModule2<br>(<span "
-                + "class=\"implementationLabel\">Implementation:</span>&nbsp;<a "
-                + "href=\"testpkgmdl2/TestClassInModule2.html\" title=\"class in testpkgmdl2\">"
+                + "<td class=\"colFirst\"><a href=\"testpkg2mdl2/TestInterfaceInModule2.html\" "
+                + "title=\"interface in testpkg2mdl2\">TestInterfaceInModule2</a><br>"
+                + "(<span class=\"implementationLabel\">Implementation:</span>&nbsp;"
+                + "<a href=\"testpkgmdl2/TestClassInModule2.html\" title=\"class in testpkgmdl2\">"
                 + "TestClassInModule2</a>)</td>\n"
                 + "<td class=\"colLast\">&nbsp;</td>\n"
                 + "</tr");
--- a/langtools/test/jdk/javadoc/tool/6227454/Test.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/test/jdk/javadoc/tool/6227454/Test.java	Thu Aug 18 05:48:35 2016 -0700
@@ -140,9 +140,9 @@
 
     public boolean run(DocletEnvironment root) {
         DocTrees docTrees = root.getDocTrees();
-        System.out.println("classes:" + root.getIncludedClasses());
+        System.out.println("classes:" + root.getIncludedTypeElements());
 
-        Element klass = root.getIncludedClasses().iterator().next();
+        Element klass = root.getIncludedTypeElements().iterator().next();
         String text = "";
         try {
             DocCommentTree dcTree = docTrees.getDocCommentTree(klass, overviewpath);
--- a/langtools/test/jdk/javadoc/tool/BreakIteratorWarning.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/test/jdk/javadoc/tool/BreakIteratorWarning.java	Thu Aug 18 05:48:35 2016 -0700
@@ -75,7 +75,7 @@
     }
 
     public boolean run(DocletEnvironment root) {
-        TypeElement cd = root.getIncludedClasses().iterator().next();
+        TypeElement cd = root.getIncludedTypeElements().iterator().next();
         VariableElement fd = getFields(cd).get(0);
         DocTrees docTrees = root.getDocTrees();
         DocCommentTree docCommentTree = docTrees.getDocCommentTree(fd);
--- a/langtools/test/jdk/javadoc/tool/InlineTagsWithBraces.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/test/jdk/javadoc/tool/InlineTagsWithBraces.java	Thu Aug 18 05:48:35 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -80,7 +80,7 @@
 
     public boolean run(DocletEnvironment root) {
         DocTrees trees = root.getDocTrees();
-        TypeElement cd = root.getIncludedClasses().iterator().next();
+        TypeElement cd = root.getIncludedTypeElements().iterator().next();
         DocCommentTree docCommentTree = trees.getDocCommentTree(cd);
         List<? extends DocTree> tags = docCommentTree.getBody();
 
--- a/langtools/test/jdk/javadoc/tool/NoStar.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/test/jdk/javadoc/tool/NoStar.java	Thu Aug 18 05:48:35 2016 -0700
@@ -62,7 +62,7 @@
     }
 
     public boolean run(DocletEnvironment root) {
-        Set<TypeElement> classes = root.getIncludedClasses();
+        Set<TypeElement> classes = root.getIncludedTypeElements();
         if (classes.size() != 1)
             throw new Error("1 " + Arrays.asList(classes));
         TypeElement self = classes.iterator().next();
--- a/langtools/test/jdk/javadoc/tool/T4994049/T4994049.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/test/jdk/javadoc/tool/T4994049/T4994049.java	Thu Aug 18 05:48:35 2016 -0700
@@ -59,7 +59,7 @@
         DocTrees trees = root.getDocTrees();
 
         SourcePositions sourcePositions = trees.getSourcePositions();
-        for (TypeElement klass : root.getIncludedClasses()) {
+        for (TypeElement klass : root.getIncludedTypeElements()) {
             for (ExecutableElement method : getMethods(klass)) {
                 if (method.getSimpleName().toString().equals("tabbedMethod")) {
                     TreePath path = trees.getPath(method);
--- a/langtools/test/jdk/javadoc/tool/completionFailure/CompletionFailure.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/test/jdk/javadoc/tool/completionFailure/CompletionFailure.java	Thu Aug 18 05:48:35 2016 -0700
@@ -54,7 +54,7 @@
     }
 
     public boolean run(DocletEnvironment root) {
-        Set<TypeElement> classes = root.getIncludedClasses();
+        Set<TypeElement> classes = root.getIncludedTypeElements();
         if (classes.size() != 1)
             throw new Error("1 " + Arrays.asList(classes));
         return true;
--- a/langtools/test/jdk/javadoc/tool/dupOk/DupOk.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/test/jdk/javadoc/tool/dupOk/DupOk.java	Thu Aug 18 05:48:35 2016 -0700
@@ -48,7 +48,6 @@
         String path1 = new File(srcFile, "sp1").getPath();
         String path2 = new File(srcFile, "sp2").getPath();
         String[] aargs = {
-            "javadoc",
             "-docletpath",
             new File(System.getProperty("test.classes", ".")).getPath(),
             "-doclet",
@@ -63,7 +62,7 @@
     }
 
     public boolean run(DocletEnvironment root) {
-        Set<TypeElement> classes = root.getIncludedClasses();
+        Set<TypeElement> classes = root.getIncludedTypeElements();
         if (classes.size() != 2)
             throw new Error("1 " + Arrays.asList(classes));
         for (TypeElement clazz : classes) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/modules/FilterOptions.java	Thu Aug 18 05:48:35 2016 -0700
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8159305
+ * @summary Tests elements filtering options
+ * @modules
+ *      jdk.javadoc/jdk.javadoc.internal.api
+ *      jdk.javadoc/jdk.javadoc.internal.doclets.standard
+ *      jdk.javadoc/jdk.javadoc.internal.tool
+ *      jdk.compiler/com.sun.tools.javac.api
+ *      jdk.compiler/com.sun.tools.javac.main
+ * @library /tools/lib
+ * @build toolbox.ToolBox toolbox.TestRunner
+ * @run main FilterOptions
+ */
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import toolbox.*;
+
+public class FilterOptions extends ModuleTestBase {
+
+    private static final String NL = System.getProperty("line.separator");
+    private static final String INDENT = "    ";
+
+    // the sources are shared, so create it once
+    private final String src;
+
+    public static void main(String... args) throws Exception {
+        new FilterOptions().runTests();
+    }
+
+    FilterOptions() throws IOException {
+        this.src = createSources(Paths.get(".").resolve("src"));
+    }
+
+    @Test
+    public void testDefault(Path base) throws Exception {
+        execTask("-modulesourcepath", src, "--module", "m1");
+
+        checkModulesSpecified("m1");
+        checkModulesIncluded("m1");
+        checkPackagesIncluded("pub");
+        checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
+    }
+
+    @Test
+    public void testModuleModeApi(Path base) throws Exception {
+        execTask("-modulesourcepath", src,
+                "--module", "m1", "--show-module-contents:api");
+
+        checkModuleMode("API");
+    }
+
+    @Test
+    public void testModuleModeAll(Path base) throws Exception {
+        execTask("-modulesourcepath", src,
+                "--module", "m1", "--show-module-contents:all");
+
+        checkModuleMode("ALL");
+    }
+
+    @Test
+    public void testShowPackagesExported(Path base)  throws Exception {
+        execTask("-modulesourcepath", src,
+                "--module", "m1",
+                "--show-packages:exported"); // default
+
+        checkModulesSpecified("m1");
+        checkModulesIncluded("m1");
+        checkPackagesIncluded("pub");
+        checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
+    }
+
+    @Test
+    public void testShowPackagesAll(Path base) throws Exception {
+        execTask("-modulesourcepath", src,
+                "--module", "m1",
+                "--show-packages:all");
+        checkModulesSpecified("m1");
+        checkModulesIncluded("m1");
+        checkPackagesIncluded("pub", "pro");
+
+        checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested",
+                           "pro.A", "pro.A.ProtectedNested", "pro.A.PublicNested");
+    }
+
+    @Test
+    public void testShowTypesPrivate(Path base) throws Exception {
+        execTask("-modulesourcepath", src,
+                "--module", "m1",
+                "--show-types:private");
+
+        checkModulesSpecified("m1");
+        checkModulesIncluded("m1");
+        checkPackagesIncluded("pub");
+
+        checkTypesIncluded("pub.A", "pub.A.PrivateNested", "pub.A.Nested", "pub.A.ProtectedNested",
+                           "pub.A.PublicNested",
+                           "pub.B", "pub.B.PrivateNested", "pub.B.Nested", "pub.B.ProtectedNested",
+                           "pub.B.PublicNested");
+
+    }
+
+    @Test
+    public void testShowTypesPackage(Path base) throws Exception {
+        execTask("-modulesourcepath", src,
+                "--module", "m1",
+                "--show-types:package");
+
+        checkModulesSpecified("m1");
+        checkModulesIncluded("m1");
+        checkPackagesIncluded("pub");
+
+        checkTypesIncluded("pub.A", "pub.A.Nested", "pub.A.ProtectedNested", "pub.A.PublicNested",
+                           "pub.B", "pub.B.Nested", "pub.B.ProtectedNested", "pub.B.PublicNested");
+
+        checkTypesNotIncluded(".*private.*");
+    }
+
+    @Test
+    public void testShowTypesProtected(Path base) throws Exception {
+        execTask("-modulesourcepath", src,
+                "--module", "m1",
+                "--show-types:protected");
+
+        checkModulesSpecified("m1");
+        checkModulesIncluded("m1");
+        checkPackagesIncluded("pub");
+
+        checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
+
+        checkTypesNotIncluded("pub.A.Nested", "pub.A.PrivateNested", "pub.B.Nested",
+                              "pub.B.PrivateNested", "pub.B.ProtectedNested",
+                              "pub.B.PublicNested");
+    }
+
+    @Test
+    public void testShowTypesPublic(Path base) throws Exception {
+        execTask("-modulesourcepath", src,
+                "--module", "m1",
+                "--show-types:public");
+
+        checkModulesSpecified("m1");
+        checkModulesIncluded("m1");
+        checkPackagesIncluded("pub");
+
+        checkTypesIncluded("pub.A", "pub.A.PublicNested");
+        checkTypesNotIncluded("pub.A.Nested",
+                              "pub.A.ProtectedNested", "pub.A.PrivateNested",
+                              "pub.B.Nested", "pub.B.ProtectedNested", "pub.B.PrivateNested",
+                              "pub.B.PublicNested");
+    }
+
+    @Test
+    public void testShowMembersPrivate(Path base) throws Exception {
+        execTask("-modulesourcepath", src,
+                "--module", "m1",
+                "--show-members:private");
+
+        checkMembers(Visibility.PRIVATE);
+    }
+
+    @Test
+    public void testShowMembersPackage(Path base) throws Exception {
+        execTask("-modulesourcepath", src,
+                "--module", "m1",
+                "--show-members:package");
+
+        checkMembers(Visibility.PACKAGE);
+    }
+
+    @Test
+    public void testShowMembersProtected(Path base) throws Exception {
+        execTask("-modulesourcepath", src,
+                "--module", "m1",
+                "--show-members:protected");
+
+        checkMembers(Visibility.PROTECTED);
+    }
+
+    @Test
+    public void testShowMembersPublic(Path base) throws Exception {
+        execTask("-modulesourcepath", src,
+                "--module", "m1",
+                "--show-members:public");
+
+        checkMembers(Visibility.PUBLIC);
+    }
+
+    @Test
+    public void testLegacyPublic(Path base) throws Exception {
+        execTask("-modulesourcepath", src,
+                "--module", "m1",
+                "-public");
+
+        checkModuleMode("API");
+        checkModulesSpecified("m1");
+        checkModulesIncluded("m1");
+        checkPackagesIncluded("pub");
+        checkTypesIncluded("pub.A", "pub.A.PublicNested");
+
+        checkMembers(Visibility.PUBLIC);
+    }
+
+    @Test
+    public void testLegacyDefault(Path base) throws Exception {
+        execTask("-modulesourcepath", src,
+                "--module", "m1");
+
+        checkModuleMode("API");
+        checkModulesSpecified("m1");
+        checkModulesIncluded("m1");
+        checkPackagesIncluded("pub");
+        checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
+
+        checkMembers(Visibility.PROTECTED);
+    }
+
+    @Test
+    public void testLegacyProtected(Path base) throws Exception {
+        execTask("-modulesourcepath", src,
+                "--module", "m1",
+                "-protected");
+
+        checkModuleMode("API");
+        checkModulesSpecified("m1");
+        checkModulesIncluded("m1");
+        checkPackagesIncluded("pub");
+        checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
+
+        checkMembers(Visibility.PROTECTED);
+    }
+
+    @Test
+    public void testLegacyPackage(Path base) throws Exception {
+        execTask("-modulesourcepath", src,
+                "--module", "m1",
+                "-package");
+
+        checkModuleMode("ALL");
+        checkModulesSpecified("m1");
+        checkModulesIncluded("m1");
+        checkPackagesIncluded("pub");
+        checkPackagesIncluded("pro");
+        checkTypesIncluded("pub.B", "pub.B.Nested", "pub.B.ProtectedNested", "pub.B.PublicNested",
+                           "pub.A", "pub.A.Nested", "pub.A.ProtectedNested", "pub.A.PublicNested",
+                           "pro.B", "pro.B.Nested", "pro.B.ProtectedNested", "pro.B.PublicNested",
+                           "pro.A", "pro.A.Nested", "pro.A.ProtectedNested", "pro.A.PublicNested");
+
+        checkMembers(Visibility.PACKAGE);
+    }
+
+    @Test
+    public void testLegacyPrivate(Path base) throws Exception {
+        execTask("-modulesourcepath", src,
+                "--module", "m1",
+                "-private");
+
+        checkModuleMode("ALL");
+        checkModulesSpecified("m1");
+        checkModulesIncluded("m1");
+        checkPackagesIncluded("pub");
+        checkPackagesIncluded("pro");
+        checkTypesIncluded("pub.B", "pub.B.PrivateNested", "pub.B.Nested", "pub.B.ProtectedNested",
+                           "pub.B.PublicNested",
+                           "pub.A", "pub.A.PrivateNested", "pub.A.Nested", "pub.A.ProtectedNested",
+                           "pub.A.PublicNested",
+                           "pro.B", "pro.B.PrivateNested", "pro.B.Nested", "pro.B.ProtectedNested",
+                           "pro.B.PublicNested",
+                           "pro.A", "pro.A.PrivateNested", "pro.A.Nested", "pro.A.ProtectedNested",
+                           "pro.A.PublicNested");
+
+        checkMembers(Visibility.PRIVATE);
+    }
+
+    private static enum Visibility {
+        PRIVATE, PACKAGE, PROTECTED, PUBLIC;
+    }
+
+    void checkMembers(Visibility v) throws Exception {
+        checkMembersPresence(v);
+        checkMembersAbsence(v);
+    }
+
+    void checkMembersPresence(Visibility v) throws Exception {
+        switch (v) {
+            case PRIVATE:
+                checkMembersSelected("pub.A.privateFieldA",
+                                     "pub.A.PublicNested.privateFieldPublicNested",
+                                     "pub.A.ProtectedNested.privateFieldProtectedNested");
+
+            case PACKAGE:
+                checkMembersSelected("pub.A.FieldA",
+                                     "pub.A.PublicNested.FieldPublicNested",
+                                     "pub.A.ProtectedNested.FieldProtectedNested");
+
+            case PROTECTED:
+                checkMembersSelected("pub.A.<init>",
+                                     "pub.A.protectedFieldA",
+                                     "pub.A.PublicNested.protectedFieldPublicNested",
+                                     "pub.A.ProtectedNested.<init>",
+                                     "pub.A.ProtectedNested.protectedFieldProtectedNested",
+                                     "pub.A.ProtectedNested.publicFieldProtectedNested");
+
+            case PUBLIC:
+                checkMembersSelected("pub.A.publicFieldA",
+                                     "pub.A.PublicNested.<init>",
+                                     "pub.A.PublicNested.publicFieldPublicNested");
+
+                break;
+        }
+    }
+
+    void checkMembersAbsence(Visibility v) throws Exception {
+        switch (v) {
+            case PUBLIC:
+                checkMembersNotSelected("pub.A.protectedFieldA",
+                                        "pub.A.PublicNested.protectedFieldPublicNested",
+                                        "pub.A.ProtectedNested.<init>",
+                                        "pub.A.ProtectedNested.protectedFieldProtectedNested");
+
+            case PROTECTED:
+                checkMembersNotSelected("pub.A.FieldA",
+                                        "pub.A.PublicNested.FieldPublicNested",
+                                        "pub.A.ProtectedNested.FieldProtectedNested");
+
+            case PACKAGE:
+                checkMembersNotSelected("pub.A.privateFieldA",
+                                        "pub.A.PublicNested.privateFieldPublicNested",
+                                        "pub.A.ProtectedNested.privateFieldProtectedNested");
+
+            case PRIVATE:
+                break;
+        }
+    }
+
+    String createSources(Path src) throws IOException {
+        ModuleBuilder mb1 = new ModuleBuilder(tb, "m1");
+        mb1.comment("The first module.")
+                .classes(createClass("pub", "A", true))
+                .classes(createClass("pub", "B", false))
+                .classes(createClass("pro", "A", true))
+                .classes(createClass("pro", "B", false))
+                .exports("pub")
+                .write(src);
+        return src.toString();
+    }
+
+    String createClass(String pkg, String name, boolean isPublic) {
+        StringBuilder sb = new StringBuilder("package ")
+                .append(pkg)
+                .append("; ")
+                .append(NL);
+        sb.append(" /** Klass ")
+                .append(name)
+                .append(" */")
+                .append(NL);
+        sb.append(isPublic ? "public " : " ")
+                .append("class ")
+                .append(name)
+                .append(" {")
+                .append(NL);
+
+        sb.append(createMembers(INDENT, name));
+        sb.append(createNestedClass(INDENT, "PublicNested", name, "public"));
+        sb.append(createNestedClass(INDENT, "ProtectedNested", name, "protected"));
+        sb.append(createNestedClass(INDENT, "Nested", name, ""));
+        sb.append(createNestedClass(INDENT, "PrivateNested", name, "private"));
+
+        return sb.append("}").toString();
+    }
+
+    StringBuilder createNestedClass(String indent, String name, String enclosing, String visibility) {
+        return new StringBuilder()
+                .append(indent).append(" /** Klass ").append(name).append(" */").append(NL)
+                .append(indent).append(visibility).append(" class ").append(name).append(" {").append(NL)
+                .append(createMembers(indent + INDENT, name)).append(indent).append("}").append(NL);
+    }
+
+    StringBuilder createMembers(String indent, String enclosing) {
+        return new StringBuilder()
+                .append(indent).append(createMember(enclosing, "public"))
+                .append(indent).append(createMember(enclosing, "protected"))
+                .append(indent).append(createMember(enclosing, ""))
+                .append(indent).append(createMember(enclosing, "private"))
+                .append(NL);
+    }
+
+    StringBuilder createMember(String enclosingClass, String visibility) {
+        return new StringBuilder()
+                .append("/** a ")
+                .append(visibility)
+                .append("Field in ")
+                .append(enclosingClass)
+                .append(" */ ")
+                .append(visibility)
+                .append(" String ")
+                .append(visibility)
+                .append("Field")
+                .append(enclosingClass)
+                .append(";")
+                .append(NL);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/modules/ModuleTestBase.java	Thu Aug 18 05:48:35 2016 -0700
@@ -0,0 +1,391 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ModuleElement;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.SimpleElementVisitor9;
+
+import jdk.javadoc.doclet.Doclet;
+import jdk.javadoc.doclet.DocletEnvironment;
+import jdk.javadoc.doclet.Reporter;
+
+import toolbox.JavadocTask;
+import toolbox.Task;
+import toolbox.Task.Expect;
+import toolbox.TestRunner;
+import toolbox.ToolBox;
+
+import static toolbox.Task.OutputKind.*;
+
+/**
+ * Base class for module tests.
+ */
+public class ModuleTestBase extends TestRunner {
+
+    // Field Separator
+    private static final String FS = " ";
+
+    protected ToolBox tb;
+    private final Class<?> docletClass;
+
+    private Task.Result currentTask = null;
+
+    ModuleTestBase() {
+        super(System.err);
+        tb = new ToolBox();
+        ClassLoader cl = ModuleTestBase.class.getClassLoader();
+        try {
+            docletClass = cl.loadClass("ModuleTestBase$ModulesTesterDoclet");
+        } catch (ClassNotFoundException cfe) {
+            throw new Error(cfe);
+        }
+    }
+
+    /**
+     * Execute methods annotated with @Test, and throw an exception if any
+     * errors are reported..
+     *
+     * @throws Exception if any errors occurred
+     */
+    protected void runTests() throws Exception {
+        runTests(m -> new Object[] { Paths.get(m.getName()) });
+    }
+
+    Task.Result execTask(String... args) {
+        return execTask0(false, args);
+    }
+
+    Task.Result execNegativeTask(String... args) {
+        return execTask0(true, args);
+    }
+
+    private Task.Result execTask0(boolean isNegative, String... args) {
+        JavadocTask et = new JavadocTask(tb, Task.Mode.API);
+        et.docletClass(docletClass);
+        //Arrays.asList(args).forEach((a -> System.err.println("arg: " + a)));
+        System.err.println(Arrays.asList(args));
+        currentTask = isNegative
+                ? et.options(args).run(Expect.FAIL)
+                : et.options(args).run();
+        return currentTask;
+    }
+
+    Path[] findHtmlFiles(Path... paths) throws IOException {
+        return tb.findFiles(".html", paths);
+    }
+
+    boolean grep(String regex, Path file) throws Exception {
+        List<String> lines = tb.readAllLines(file);
+        List<String> foundList = tb.grep(regex, lines);
+        return !foundList.isEmpty();
+    }
+
+    String normalize(String in) {
+        return in.replace('\\', '/');
+    }
+
+    void checkModulesSpecified(String... args) throws Exception {
+        for (String arg : args) {
+            checkDocletOutputPresent("Specified", ElementKind.MODULE, arg);
+        }
+    }
+
+    void checkPackagesSpecified(String... args) throws Exception {
+        for (String arg : args) {
+            checkDocletOutputPresent("Specified", ElementKind.PACKAGE, arg);
+        }
+    }
+
+    void checkTypesSpecified(String... args) throws Exception {
+        for (String arg : args) {
+            checkDocletOutputPresent("Specified", ElementKind.CLASS, arg);
+        }
+    }
+
+    void checkModulesIncluded(String... args) throws Exception {
+        for (String arg : args) {
+            checkDocletOutputPresent("Included", ElementKind.MODULE, arg);
+        }
+    }
+
+    void checkPackagesIncluded(String... args) throws Exception {
+        for (String arg : args) {
+            checkDocletOutputPresent("Included", ElementKind.PACKAGE, arg);
+        }
+    }
+
+    void checkTypesIncluded(String... args) throws Exception {
+        for (String arg : args) {
+            checkDocletOutputPresent("Included", ElementKind.CLASS, arg);
+        }
+    }
+
+    void checkMembersSelected(String... args) throws Exception {
+        for (String arg : args) {
+            checkDocletOutputPresent("Selected", ElementKind.METHOD, arg);
+        }
+    }
+
+    void checkModuleMode(String mode) throws Exception {
+        assertPresent("^ModuleMode" + FS + mode);
+    }
+
+    void checkStringPresent(String regex) throws Exception {
+        assertPresent(regex);
+    }
+
+    void checkDocletOutputPresent(String category, ElementKind kind, String regex) throws Exception {
+        assertPresent("^" + category + " " + kind.toString() + " " + regex);
+    }
+
+    void assertPresent(String regex) throws Exception {
+        assertPresent(regex, STDOUT);
+    }
+
+    void assertErrorPresent(String regex) throws Exception {
+        assertPresent(regex, Task.OutputKind.DIRECT);
+    }
+
+    void assertPresent(String regex, Task.OutputKind kind) throws Exception {
+        List<String> foundList = tb.grep(regex, currentTask.getOutputLines(kind));
+        if (foundList.isEmpty()) {
+            dumpDocletDiagnostics();
+            throw new Exception(regex + " not found in: " + kind);
+        }
+    }
+
+    void dumpDocletDiagnostics() {
+        for (Task.OutputKind kind : Task.OutputKind.values()) {
+            String output = currentTask.getOutput(kind);
+            if (output != null && !output.isEmpty()) {
+                System.err.println("<" + kind + ">");
+                System.err.println(output);
+            }
+        }
+    }
+
+    void checkModulesNotSpecified(String... args) throws Exception {
+        for (String arg : args) {
+            checkDocletOutputAbsent("Specified", ElementKind.MODULE, arg);
+        }
+    }
+
+    void checkPackagesNotSpecified(String... args) throws Exception {
+        for (String arg : args) {
+            checkDocletOutputAbsent("Specified", ElementKind.PACKAGE, arg);
+        }
+    }
+
+    void checkTypesNotSpecified(String... args) throws Exception {
+        for (String arg : args) {
+            checkDocletOutputAbsent("Specified", ElementKind.CLASS, arg);
+        }
+    }
+
+    void checkModulesNotIncluded(String... args) throws Exception {
+        for (String arg : args) {
+            checkDocletOutputAbsent("Included", ElementKind.MODULE, arg);
+        }
+    }
+
+    void checkPackagesNotIncluded(String... args) throws Exception {
+        for (String arg : args) {
+            checkDocletOutputAbsent("Included", ElementKind.PACKAGE, arg);
+        }
+    }
+
+    void checkTypesNotIncluded(String... args) throws Exception {
+        for (String arg : args) {
+            checkDocletOutputAbsent("Included", ElementKind.CLASS, arg);
+        }
+    }
+
+    void checkMembersNotSelected(String... args) throws Exception {
+        for (String arg : args) {
+            checkDocletOutputAbsent("Selected", ElementKind.METHOD, arg);
+        }
+    }
+
+    void checkStringAbsent(String regex) throws Exception {
+        assertAbsent(regex);
+    }
+
+    void checkDocletOutputAbsent(String category, ElementKind kind, String regex) throws Exception {
+        assertAbsent("^" + category + FS + kind.toString() + FS + regex);
+    }
+
+    void assertAbsent(String regex) throws Exception {
+        List<String> foundList = tb.grep(regex, currentTask.getOutputLines(STDOUT));
+        if (!foundList.isEmpty()) {
+            dumpDocletDiagnostics();
+            throw new Exception(regex + " found in: " + STDOUT);
+        }
+    }
+
+    public static class ModulesTesterDoclet implements Doclet {
+        StringWriter sw = new StringWriter();
+        PrintWriter ps = new PrintWriter(sw);
+
+        // csv style output, for simple regex verification
+        void printDataSet(String header, Set<? extends Element> set) {
+            for (Element e : set) {
+                ps.print(header);
+                new SimpleElementVisitor9<Void, Void>() {
+                    @Override
+                    public Void visitModule(ModuleElement e, Void p) {
+                        ps.print(FS);
+                        ps.print(e.getKind());
+                        ps.print(FS);
+                        ps.println(e.getQualifiedName());
+                        return null;
+                    }
+
+                    @Override
+                    public Void visitPackage(PackageElement e, Void p) {
+                        ps.print(FS);
+                        ps.print(e.getKind());
+                        ps.print(FS);
+                        ps.println(e.getQualifiedName());
+                        return null;
+                    }
+
+                    @Override
+                    public Void visitType(TypeElement e, Void p) {
+                        ps.print(FS);
+                        ps.print(ElementKind.CLASS);
+                        ps.print(FS);
+                        ps.println(e.getQualifiedName());
+                        return null;
+                    }
+
+                    @Override
+                    protected Void defaultAction(Element e, Void p) {
+                        Element encl = e.getEnclosingElement();
+                        CharSequence fqn = new SimpleElementVisitor9<CharSequence, Void>() {
+                            @Override
+                            public CharSequence visitModule(ModuleElement e, Void p) {
+                                return e.getQualifiedName();
+                            }
+
+                            @Override
+                            public CharSequence visitType(TypeElement e, Void p) {
+                                return e.getQualifiedName();
+                            }
+
+                            @Override
+                            public CharSequence visitPackage(PackageElement e, Void p) {
+                                return e.getQualifiedName();
+                            }
+
+                        }.visit(encl);
+
+                        ps.print(FS);
+                        ps.print(ElementKind.METHOD); // always METHOD
+                        ps.print(FS);
+                        ps.print(fqn);
+                        ps.print(".");
+                        ps.println(e.getSimpleName());
+                        return null;
+                    }
+                }.visit(e);
+            }
+        }
+
+        @Override
+        public boolean run(DocletEnvironment docenv) {
+            ps.println("ModuleMode" + FS + docenv.getModuleMode());
+            printDataSet("Specified", docenv.getSpecifiedElements());
+            printDataSet("Included", docenv.getIncludedModuleElements());
+            printDataSet("Included", docenv.getIncludedPackageElements());
+            printDataSet("Included", docenv.getIncludedTypeElements());
+            printDataSet("Selected", getAllSelectedElements(docenv));
+            System.out.println(sw);
+            return true;
+        }
+
+        Set<Element> getAllSelectedElements(DocletEnvironment docenv) {
+            Set<Element> result = new TreeSet<Element>((Element e1, Element e2) -> {
+                // some grouping by kind preferred
+                int rc = e1.getKind().compareTo(e2.getKind());
+                if (rc != 0) return rc;
+                rc = e1.toString().compareTo(e2.toString());
+                if (rc != 0) return rc;
+                return Integer.compare(e1.hashCode(), e2.hashCode());
+            });
+            for (ModuleElement me : docenv.getIncludedModuleElements()) {
+                addEnclosedElements(docenv, result, me);
+            }
+            for (PackageElement pe : docenv.getIncludedPackageElements()) {
+                addEnclosedElements(docenv, result, docenv.getElementUtils().getModuleOf(pe));
+                addEnclosedElements(docenv, result, pe);
+            }
+            for (TypeElement te : docenv.getIncludedTypeElements()) {
+                addEnclosedElements(docenv, result, te);
+            }
+            return result;
+        }
+
+        void addEnclosedElements(DocletEnvironment docenv, Set<Element> result, Element e) {
+            List<? extends Element> elems = docenv.getSelectedElements(e.getEnclosedElements());
+            result.addAll(elems);
+            for (TypeElement t : ElementFilter.typesIn(elems)) {
+                addEnclosedElements(docenv, result, t);
+            }
+        }
+
+        @Override
+        public Set<Doclet.Option> getSupportedOptions() {
+            return Collections.emptySet();
+        }
+
+        @Override
+        public void init(Locale locale, Reporter reporter) {}
+
+        @Override
+        public String getName() {
+            return "ModulesTesterDoclet";
+        }
+
+        @Override
+        public SourceVersion getSupportedSourceVersion() {
+            return SourceVersion.latest();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/modules/Modules.java	Thu Aug 18 05:48:35 2016 -0700
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8159305
+ * @summary Tests primarily the module graph computations.
+ * @modules
+ *      jdk.javadoc/jdk.javadoc.internal.api
+ *      jdk.javadoc/jdk.javadoc.internal.doclets.standard
+ *      jdk.javadoc/jdk.javadoc.internal.tool
+ *      jdk.compiler/com.sun.tools.javac.api
+ *      jdk.compiler/com.sun.tools.javac.main
+ * @library /tools/lib
+ * @build toolbox.ToolBox toolbox.TestRunner
+ * @run main Modules
+ */
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import toolbox.*;
+
+public class Modules extends ModuleTestBase {
+
+    public static void main(String... args) throws Exception {
+        new Modules().runTests();
+    }
+
+    @Test
+    public void testBasicMoption(Path base) throws Exception {
+        Files.createDirectory(base);
+        Path src = base.resolve("src");
+        ModuleBuilder mb = new ModuleBuilder(tb, "m1");
+        mb.comment("The first module.")
+                .exports("pub")
+                .classes("package pub; /** Klass A */ public class A {}")
+                .classes("package pro; /** Klass B */ public class B {}")
+                .write(src);
+        execTask("-modulesourcepath", src.toString(),
+                 "--module", "m1");
+        checkModulesSpecified("m1");
+        checkPackagesIncluded("pub");
+        checkTypesIncluded("pub.A");
+    }
+
+    @Test
+    public void testMultipleModulesOption1(Path base) throws Exception {
+        Path src = base.resolve("src");
+
+        ModuleBuilder mb1 = new ModuleBuilder(tb, "m1");
+        mb1.comment("The first module.")
+                .exports("m1pub")
+                .requires("m2")
+                .classes("package m1pub; /** Klass A */ public class A {}")
+                .classes("package m1pro; /** Klass B */ public class B {}")
+                .write(src);
+
+        ModuleBuilder mb2 = new ModuleBuilder(tb, "m2");
+        mb2.comment("The second module.")
+                .exports("m2pub")
+                .classes("package m2pub; /** Klass A */ public class A {}")
+                .classes("package m2pro; /** Klass B */ public class B {}")
+                .write(src);
+        execTask("-modulesourcepath", src.toString(),
+            "--module", "m1,m2");
+        checkModulesSpecified("m1", "m2");
+        checkPackagesIncluded("m1pub", "m2pub");
+        checkTypesIncluded("m1pub.A", "m2pub.A");
+
+    }
+
+    @Test
+    public void testMultipleModulesAggregatedModuleOption(Path base) throws Exception {
+        Path src = base.resolve("src");
+
+        ModuleBuilder mb1 = new ModuleBuilder(tb, "m1");
+        mb1.comment("The first module.")
+                .exports("m1pub")
+                .requires("m2")
+                .classes("package m1pub; /** Klass A */ public class A {}")
+                .classes("package m1pro; /** Klass B */ public class B {}")
+                .write(src);
+
+        ModuleBuilder mb2 = new ModuleBuilder(tb, "m2");
+        mb2.comment("The second module.")
+                .exports("m2pub")
+                .classes("package m2pub; /** Klass A */ public class A {}")
+                .classes("package m2pro; /** Klass B */ public class B {}")
+                .write(src);
+        execTask("-modulesourcepath", src.toString(),
+            "--module", "m1",
+            "--module", "m2");
+        checkModulesSpecified("m1", "m2");
+        checkPackagesIncluded("m1pub", "m2pub");
+        checkTypesIncluded("m1pub.A", "m2pub.A");
+
+    }
+
+   /**
+     * Tests diamond graph, inspired by javac diamond tests.
+     *
+     *
+     * Module M : test module, with variable requires
+     *
+     * Module N :
+     *     requires public O  --->   Module O:
+     *                                 requires J   ---->   Module J:
+     *                                 exports openO          exports openJ
+     *
+     *
+     * Module L :
+     *     requires public P  --->   Module P:
+     *                                 exports openP
+     *
+     *
+     */
+
+    @Test
+    public void testExpandRequiresNone(Path base) throws Exception {
+        Path src = base.resolve("src");
+
+        createAuxiliaryModules(src);
+
+        new ModuleBuilder(tb, "M")
+                .comment("The M module.")
+                .requires("N", src)
+                .requires("L", src)
+                .requires("O", src)
+                .exports("p")
+                .classes("package p; public class Main { openO.O o; openN.N n; openL.L l; }")
+                .write(src);
+
+        execTask("-modulesourcepath", src.toString(),
+                "--module", "M");
+
+        checkModulesSpecified("M");
+        checkModulesIncluded("M");
+        checkPackagesIncluded("p");
+        checkTypesIncluded("p.Main");
+        checkPackagesNotIncluded(".*open.*");
+    }
+
+    @Test
+    public void testExpandRequiresPublic(Path base) throws Exception {
+        Path src = base.resolve("src");
+
+        createAuxiliaryModules(src);
+
+        new ModuleBuilder(tb, "M")
+                .comment("The M module.")
+                .requiresPublic("N", src)
+                .requires("L", src)
+                .exports("p")
+                .classes("package p; public class Main { openO.O o; openN.N n; openL.L l; }")
+                .write(src);
+
+        execTask("-modulesourcepath", src.toString(),
+                "--module", "M",
+                "--expand-requires:public");
+
+        checkModulesSpecified("M", "N", "O");
+        checkModulesIncluded("M", "N", "O");
+        checkPackagesIncluded("p", "openN", "openO");
+        checkTypesIncluded("p.Main", "openN.N", "openO.O");
+    }
+
+    @Test
+    public void testExpandRequiresAll(Path base) throws Exception {
+        Path src = base.resolve("src");
+
+        createAuxiliaryModules(src);
+
+        new ModuleBuilder(tb, "M")
+                .comment("The M module.")
+                .requiresPublic("N", src)
+                .requires("L", src)
+                .requires("O", src)
+                .exports("p")
+                .classes("package p; public class Main { openO.O o; openN.N n; openL.L l; }")
+                .write(src);
+
+        execTask("-modulesourcepath", src.toString(),
+                "--module", "M",
+                "--expand-requires:all");
+
+        checkModulesSpecified("M", "java.base", "N", "L", "O");
+        checkModulesIncluded("M", "java.base", "N", "L", "O");
+        checkModulesNotIncluded("P", "J", "Q");
+        checkPackagesIncluded("p", "openN", "openL", "openO");
+        checkPackagesNotIncluded(".*openP.*", ".*openJ.*");
+        checkTypesIncluded("p.Main", "openN.N", "openL.L", "openO.O");
+        checkTypesNotIncluded(".*openP.*", ".*openJ.*");
+    }
+
+    @Test
+    public void testMissingModule(Path base) throws Exception {
+        Path src = base.resolve("src");
+
+        createAuxiliaryModules(src);
+
+        new ModuleBuilder(tb, "M")
+                .comment("The M module.")
+                .requiresPublic("N", src)
+                .requires("L", src)
+                .requires("O", src)
+                .exports("p")
+                .classes("package p; public class Main { openO.O o; openN.N n; openL.L l; }")
+                .write(src);
+
+        execNegativeTask("-modulesourcepath", src.toString(),
+                "--module", "MIA",
+                "--expand-requires:all");
+
+        assertErrorPresent("javadoc: error - module MIA not found.");
+    }
+
+    @Test
+    public void testMissingModuleMultiModuleCmdline(Path base) throws Exception {
+        Path src = base.resolve("src");
+
+        createAuxiliaryModules(src);
+
+        new ModuleBuilder(tb, "M")
+                .comment("The M module.")
+                .requiresPublic("N", src)
+                .requires("L", src)
+                .requires("O", src)
+                .exports("p")
+                .classes("package p; public class Main { openO.O o; openN.N n; openL.L l; }")
+                .write(src);
+
+        execNegativeTask("-modulesourcepath", src.toString(),
+                "--module", "M,N,L,MIA,O,P",
+                "--expand-requires:all");
+
+        assertErrorPresent("javadoc: error - module MIA not found");
+    }
+
+    void createAuxiliaryModules(Path src) throws IOException {
+
+        new ModuleBuilder(tb, "J")
+                .comment("The J module.")
+                .exports("openJ")
+                .classes("package openJ;  /** Klass J open. */ public class J { }")
+                .classes("package closedJ; /** Klass J closed. */ public class J  { }")
+                .write(src);
+
+        new ModuleBuilder(tb, "L")
+                .comment("The L module.")
+                .exports("openL")
+                .requiresPublic("P")
+                .classes("package openL; /** Klass L open */ public class L { }")
+                .classes("package closedL;  /** Klass L closed */ public class L { }")
+                .write(src);
+
+        new ModuleBuilder(tb, "N")
+                .comment("The N module.")
+                .exports("openN")
+                .requiresPublic("O")
+                .classes("package openN; /** Klass N open */ public class N  { }")
+                .classes("package closedN; /** Klass N closed */ public class N { }")
+                .write(src);
+
+        new ModuleBuilder(tb, "O")
+                .comment("The O module.")
+                .exports("openO")
+                .requires("J")
+                .classes("package openO; /** Klass O open. */ public class O { openJ.J j; }")
+                .classes("package closedO;  /** Klass O closed. */ public class O { }")
+                .write(src);
+
+        new ModuleBuilder(tb, "P")
+                .comment("The O module.")
+                .exports("openP")
+                .requires("J")
+                .classes("package openP; /** Klass O open. */ public class O { openJ.J j; }")
+                .classes("package closedP;  /** Klass O closed. */ public class O { }")
+                .write(src);
+
+        new ModuleBuilder(tb, "Q")
+                .comment("The Q module.")
+                .exports("openQ")
+                .requires("J")
+                .classes("package openQ; /** Klass Q open. */ public class Q { openJ.J j; }")
+                .classes("package closedQ;  /** Klass Q closed. */ public class Q { }")
+                .write(src);
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/modules/PackageOptions.java	Thu Aug 18 05:48:35 2016 -0700
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8159305
+ * @summary Test modules with packages and subpackages filtering
+ * @modules
+ *      jdk.javadoc/jdk.javadoc.internal.api
+ *      jdk.javadoc/jdk.javadoc.internal.doclets.standard
+ *      jdk.javadoc/jdk.javadoc.internal.tool
+ *      jdk.compiler/com.sun.tools.javac.api
+ *      jdk.compiler/com.sun.tools.javac.main
+ * @library /tools/lib
+ * @build toolbox.ToolBox toolbox.TestRunner
+ * @run main PackageOptions
+ */
+
+import java.io.IOException;
+import java.nio.file.DirectoryIteratorException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import toolbox.*;
+
+public class PackageOptions extends ModuleTestBase {
+
+    public static void main(String... args) throws Exception {
+        new PackageOptions().runTests();
+    }
+
+    @Test
+    public void testExportedNonQualifiedPackagesLegacyMode(Path base)  throws Exception {
+        execTask("-modulesourcepath", createSources(base.resolve("src")),
+                "-addmods", "m1",
+                "m1pub");
+
+        checkModulesNotSpecified("m1");
+        checkModulesIncluded("m1");
+        checkPackagesSpecified("m1pub");
+        checkPackagesIncluded("m1pub");
+    }
+
+    @Test
+    public void testExportedQualifiedPackagesLegacyMode(Path base)  throws Exception {
+        execTask("-modulesourcepath", createSources(base.resolve("src")),
+                "-addmods", "m1",
+                "m1/m1pub");
+
+        checkModulesNotSpecified("m1");
+        checkModulesIncluded("m1");
+        checkPackagesSpecified("m1pub");
+        checkPackagesIncluded("m1pub");
+    }
+
+    @Test
+    public void testNonExportedQualifedPackagesLegacyMode(Path base)  throws Exception {
+        execTask("-modulesourcepath", createSources(base.resolve("src")),
+                "-addmods", "m1",
+                "m1/m1pro.pro1" /* not exported, therefore qualify with module */);
+
+        checkModulesNotSpecified("m1");
+        checkModulesIncluded("m1");
+        checkPackagesSpecified("m1pro.pro1");
+        checkPackagesIncluded("m1pro.pro1");
+        checkPackagesNotIncluded("m1pro.pro2");
+        checkPackagesNotIncluded("m1pub");
+    }
+
+    @Test
+    public void testTypesLegacyMode(Path base) throws Exception {
+        Path srcPath = base.resolve("src");
+        Path typPath = srcPath.resolve("m1/m1pub/A.java");
+        execTask("-modulesourcepath", createSources(srcPath),
+                "-addmods", "m1",
+                typPath.toString());
+        checkModulesNotSpecified("m1");
+        checkModulesIncluded("m1");
+        checkPackagesIncluded("m1pub");
+        checkPackagesNotIncluded("m1pro");
+        checkTypesSpecified("m1pub.A");
+        checkTypesIncluded("m1pub.A");
+        checkTypesNotIncluded("m1pub.B");
+        checkTypesNotIncluded("m1pub.C");
+    }
+
+    @Test
+    public void testSubclassedTypesLegacyMode(Path base) throws Exception {
+        Path srcPath = base.resolve("src");
+        Path typPath = srcPath.resolve("m1/m1pub/B.java");
+        execTask("-modulesourcepath", createSources(srcPath),
+                "-addmods", "m1",
+                typPath.toString());
+        checkModulesNotSpecified("m1");
+        checkModulesIncluded("m1");
+        checkPackagesIncluded("m1pub");
+        checkPackagesNotIncluded("m1pro");
+        checkTypesSpecified("m1pub.B");
+        checkTypesIncluded("m1pub.B");
+        checkTypesNotIncluded("m1pub.A");
+        checkTypesNotIncluded("m1pub.C");
+    }
+
+    @Test
+    public void testDefaultPackages(Path base) throws Exception {
+        execTask("-modulesourcepath", createSources(base.resolve("src")),
+                "--module", "m1");
+
+        checkModulesSpecified("m1");
+
+        checkPackagesIncluded("m1pub", "m1pub.pub1", "m1pub.pub1.pub11",
+                              "m1pub.pub1.pub12", "m1pub.pub2.pub21");
+    }
+
+    @Test
+    public void testEmptyPackageDirectory(Path base) throws Exception {
+        Path src = base.resolve("src");
+        createSources(src);
+
+        // need an empty package directory, to check whether
+        // the behavior of subpackage and package
+        Path pkgdir = src.resolve("m1/m1pro/");
+        try (DirectoryStream<Path> stream = Files.newDirectoryStream(pkgdir, "*.java")) {
+            for (Path entry : stream) {
+                Files.deleteIfExists(entry);
+            }
+        } catch (DirectoryIteratorException ex) {
+            // I/O error encounted during the iteration
+            throw ex.getCause();
+        }
+        execTask("-modulesourcepath", src.toString(),
+                "-subpackages", "m1/m1pro");
+
+        checkPackagesSpecified("m1pro", "m1pro.pro1", "m1pro.pro2");
+
+        // empty package directory should cause an error
+        execNegativeTask("-modulesourcepath", src.toString(),
+                         "m1/m1pro");
+
+    }
+
+    @Test
+    public void testExportedQualifiedSubpackageWithMultipleModules(Path base) throws Exception {
+        execTask("-modulesourcepath", createSources(base.resolve("src"), 2),
+                "--module", "m1",
+                "-subpackages", "m1/m1pro.pro1:m1/m1pro.pro2:m2/m2pub.pub1");
+
+        checkModulesSpecified("m1");
+        checkPackagesSpecified("m1pro", "m1pro.pro2");
+        checkPackagesSpecified("m2pub.pub1");
+
+        checkPackagesIncluded("m1pub", "m1pub.pub1", "m1pub.pub1.pub11",
+                              "m1pub.pub1.pub12", "m1pub.pub2.pub21");
+        checkPackagesIncluded("m2pub.pub1");
+    }
+
+    @Test
+    public void testUnexportedUnqualifiedSubpackages(Path base) throws Exception {
+        execNegativeTask("-modulesourcepath", createSources(base.resolve("src")),
+                         "--module", "m1",
+                         "-subpackages", "m1pub.pub1:pro");
+
+        assertErrorPresent("javadoc: error - No source files for package pro");
+    }
+
+    @Test
+    public void testUnexportedQualifiedPackage(Path base) throws Exception {
+        execTask("-modulesourcepath", createSources(base.resolve("src")),
+                "--module", "m1",
+                "m1/m1pro");
+
+        checkModulesSpecified("m1");
+        checkPackagesSpecified("m1pro");
+
+        checkPackagesIncluded("m1pub", "m1pub.pub1", "m1pub.pub1.pub11",
+                              "m1pub.pub1.pub12", "m1pub.pub2.pub21");
+
+        checkTypesIncluded("m1pro.L");
+    }
+
+    @Test
+    public void testUnexportedQualifiedSubpackage(Path base) throws Exception {
+        execTask("-modulesourcepath", createSources(base.resolve("src")),
+                "--module", "m1",
+                "-subpackages", "m1/m1pro");
+
+        checkModulesSpecified("m1");
+        checkPackagesSpecified("m1pro", "m1pro.pro1", "m1pro.pro2");
+
+        checkPackagesIncluded("m1pub", "m1pub.pub1", "m1pub.pub1.pub11",
+                              "m1pub.pub1.pub12", "m1pub.pub2.pub21");
+
+        checkTypesIncluded("m1pro.L", "m1pro.pro1.M", "m1pro.pro2.O");
+    }
+
+    @Test
+    public void testUnexportedQualifiedSubpackageExcludeQualified(Path base) throws Exception {
+        execTask("-modulesourcepath", createSources(base.resolve("src")),
+                "--module", "m1",
+                "-subpackages", "m1/m1pro",
+                "-exclude", "m1/m1pro.pro1.pro11:m1/m1pro.pro2.pro21");
+
+        checkModulesSpecified("m1");
+        checkPackagesSpecified("m1pro", "m1pro.pro1", "m1pro.pro2");
+
+        checkPackagesIncluded("m1pub", "m1pub.pub1", "m1pub.pub1.pub11",
+                              "m1pub.pub1.pub12", "m1pub.pub2.pub21");
+
+        checkTypesIncluded("m1pro.L", "m1pro.pro1.M", "m1pro.pro2.O");
+        checkPackagesNotSpecified(".*pro11.*", ".*pro21.*");
+    }
+
+    @Test
+    public void testUnexportedQualifiedSubpackageExcludeUnqualified(Path base) throws Exception {
+        execTask("-modulesourcepath", createSources(base.resolve("src")),
+                "--module", "m1",
+                "-subpackages", "m1/m1pro",
+                "-exclude", "m1pro.pro1.pro11:m1pro.pro2.pro21");
+
+        checkModulesSpecified("m1");
+        checkPackagesSpecified("m1pro", "m1pro.pro1", "m1pro.pro2");
+
+        checkPackagesIncluded("m1pub", "m1pub.pub1", "m1pub.pub1.pub11",
+                              "m1pub.pub1.pub12", "m1pub.pub2.pub21");
+
+        checkTypesIncluded("m1pro.L", "m1pro.pro1.M", "m1pro.pro2.O");
+        checkPackagesNotSpecified(".*pro11.*", ".*pro21.*");
+    }
+
+    @Test
+    public void testUnexportedQualifiedSubpackages(Path base) throws Exception {
+        execTask("-modulesourcepath", createSources(base.resolve("src")),
+                "--module", "m1",
+                "-subpackages", "m1/m1pro.pro1:m1/m1pro.pro2");
+
+        checkModulesSpecified("m1");
+        checkPackagesSpecified("m1pro.pro1.pro11");
+
+        checkPackagesIncluded("m1pub", "m1pub.pub1", "m1pub.pub1.pub11",
+                               "m1pub.pub1.pub12", "m1pub.pub2.pub21");
+        checkTypesIncluded("m1pro.pro1.pro11.N", "m1pro.pro2.pro21.P");
+        checkTypesNotIncluded("m1pro.L");
+    }
+
+    String createSources(Path src) throws IOException {
+        return createSources0(src, 1);
+    }
+
+    String createSources(Path src, int n) throws IOException {
+        for (int i = 1 ; i <= n ; i++) {
+            createSources0(src, i);
+        }
+        return src.toString();
+    }
+
+    String createSources0(Path src, int n) throws IOException {
+        String mn = "m" + n;
+        String pn = "package " + mn;
+
+        ModuleBuilder mb1 = new ModuleBuilder(tb, mn);
+        mb1.comment("The module #" + n)
+                .classes(pn + "pub; /** Klass A */ public class A {}")
+                .classes(pn + "pub; /** Klass B */ public class B extends A{}")
+                .classes(pn + "pub; /** Klass C */ public class C {}")
+                .classes(pn + "pub;")
+                .classes(pn + "pub.pub1; /** Klass B */ public class B {}")
+                .classes(pn + "pub.pub1.pub11; /** Klass C */ public class C {}")
+                .classes(pn + "pub.pub1.pub12; /** Klass C */ public class C {}")
+                .classes(pn + "pub.pub2.pub21; /** Klass C */ public class C {}")
+                .classes(pn + "pro; /** Klass L */ public class L {}")
+                .classes(pn + "pro.pro1; /** Klass M */ public class M {}")
+                .classes(pn + "pro.pro1.pro11; /** Klass N */ public class N {}")
+                .classes(pn + "pro.pro2; /** Klass O */ public class O {}")
+                .classes(pn + "pro.pro2.pro21; /** Klass P */ public class P {}")
+                .exports(mn + "pub")
+                .exports(mn + "pub.pub1")
+                .exports(mn + "pub.pub1.pub11")
+                .exports(mn + "pub.pub1.pub12")
+                .exports(mn + "pub.pub2.pub21")
+                .write(src);
+        return src.toString();
+    }
+}
--- a/langtools/test/jdk/javadoc/tool/sourceOnly/Test.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/test/jdk/javadoc/tool/sourceOnly/Test.java	Thu Aug 18 05:48:35 2016 -0700
@@ -34,7 +34,12 @@
 public class Test {
     public static void main(String[] args) {
         // run javadoc on package p
-        if (jdk.javadoc.internal.tool.Main.execute("javadoc", "p.SourceOnly", "p") != 0)
+        String[] jdargs = {
+            "-doclet", "p.SourceOnly",
+            "-docletpath", System.getProperty("test.classes", "."),
+            "p"
+        };
+        if (jdk.javadoc.internal.tool.Main.execute(jdargs) != 0)
             throw new Error();
     }
 }
Binary file langtools/test/jdk/javadoc/tool/sourceOnly/p/NonSource.class has changed
--- a/langtools/test/jdk/javadoc/tool/sourceOnly/p/SourceOnly.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/test/jdk/javadoc/tool/sourceOnly/p/SourceOnly.java	Thu Aug 18 05:48:35 2016 -0700
@@ -39,11 +39,12 @@
  */
 public class SourceOnly implements Doclet {
     NonSource dependency; // force a compilation error if not on classpath.
+
     @Override
     public boolean run(DocletEnvironment root) {
-        if (root.getIncludedClasses().size() != 1)
+        if (root.getIncludedTypeElements().size() != 1)
             throw new Error("wrong set of classes documented: " +
-                    Arrays.asList(root.getIncludedClasses()));
+                    Arrays.asList(root.getIncludedTypeElements()));
         return true;
     }
 
--- a/langtools/test/jdk/javadoc/tool/sourceOption/SourceOption.java	Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/test/jdk/javadoc/tool/sourceOption/SourceOption.java	Thu Aug 18 05:48:35 2016 -0700
@@ -92,7 +92,7 @@
     }
 
     public boolean run(DocletEnvironment root) {
-        root.getIncludedClasses();         // force parser into action
+        root.getIncludedTypeElements();
         return true;
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/subpackageIgnore/pkg1/ValidFile.java	Thu Aug 18 05:48:35 2016 -0700
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 pkg1;
+
+/**
+ * This file exists simply to ensure that javadoc passes
+ * without complaining about empty directory.
+ */
+public class ValidFile {}