Merge
authorlana
Thu, 16 Feb 2017 18:29:03 +0000
changeset 43877 a12e388192c0
parent 43855 f402e32dfbf3 (current diff)
parent 43876 bfb874896f7e (diff)
child 43878 4b0a3bda61d3
Merge
--- a/langtools/src/java.compiler/share/classes/javax/annotation/processing/AbstractProcessor.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/java.compiler/share/classes/javax/annotation/processing/AbstractProcessor.java	Thu Feb 16 18:29:03 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -92,7 +92,7 @@
      * same set of strings as the annotation.  If the class is not so
      * annotated, an empty set is returned.
      *
-     * If the {@link ProcessingEvironment#getSourceVersion source
+     * If the {@link ProcessingEnvironment#getSourceVersion source
      * version} does not support modules, in other words if it is less
      * than or equal to {@link SourceVersion#RELEASE_8 RELEASE_8},
      * then any leading {@link Processor#getSupportedAnnotationTypes
--- a/langtools/src/java.compiler/share/classes/javax/annotation/processing/Processor.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/java.compiler/share/classes/javax/annotation/processing/Processor.java	Thu Feb 16 18:29:03 2017 +0000
@@ -291,7 +291,7 @@
      * @apiNote When running in an environment which supports modules,
      * processors are encouraged to include the module prefix when
      * describing their supported annotation types. The method {@link
-     * AbstractProcessor.getSupportedAnnotationTypes
+     * AbstractProcessor#getSupportedAnnotationTypes
      * AbstractProcessor.getSupportedAnnotationTypes} provides support
      * for stripping off the module prefix when running in an
      * environment without modules.
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/Elements.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/Elements.java	Thu Feb 16 18:29:03 2017 +0000
@@ -25,9 +25,12 @@
 
 package javax.lang.model.util;
 
-
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
+import java.util.LinkedHashSet;
 
 import javax.lang.model.AnnotatedConstruct;
 import javax.lang.model.element.*;
@@ -65,6 +68,7 @@
      * @param name  fully qualified package name, or an empty string for an unnamed package
      * @param module module relative to which the lookup should happen
      * @return the specified package, or {@code null} if it cannot be found
+     * @see #getAllPackageElements
      * @since 9
      */
     default PackageElement getPackageElement(ModuleElement module, CharSequence name) {
@@ -72,6 +76,49 @@
     }
 
     /**
+     * Returns all package elements with the given canonical name.
+     *
+     * There may be more than one package element with the same canonical
+     * name if the package elements are in different modules.
+     *
+     * @implSpec The default implementation of this method calls
+     * {@link #getAllModuleElements() getAllModuleElements} and stores
+     * the result. If the set of modules is empty, {@link
+     * #getPackageElement(CharSequence) getPackageElement(name)} is
+     * called passing through the name argument. If {@code
+     * getPackageElement(name)} is {@code null}, an empty set of
+     * package elements is returned; otherwise, a single-element set
+     * with the found package element is returned. If the set of
+     * modules is nonempty, the modules are iterated over and any
+     * non-{@code null} results of {@link
+     * #getPackageElement(ModuleElement, CharSequence)
+     * getPackageElement(module, name)} are accumulated into a
+     * set. The set is then returned.
+     *
+     * @param name  the canonical name
+     * @return the package elements, or an empty set if no package with the name can be found
+     * @see #getPackageElement(ModuleElement, CharSequence)
+     * @since 9
+     */
+    default Set<? extends PackageElement> getAllPackageElements(CharSequence name) {
+        Set<? extends ModuleElement> modules = getAllModuleElements();
+        if (modules.isEmpty()) {
+            PackageElement packageElt = getPackageElement(name);
+            return (packageElt != null) ?
+                Collections.singleton(packageElt):
+                Collections.emptySet();
+        } else {
+            Set<PackageElement> result = new LinkedHashSet<>(1); // Usually expect at most 1 result
+            for (ModuleElement module: modules) {
+                PackageElement packageElt = getPackageElement(module, name);
+                if (packageElt != null)
+                    result.add(packageElt);
+            }
+            return Collections.unmodifiableSet(result);
+        }
+    }
+
+    /**
      * Returns a type element given its canonical name if the type element is unique in the environment.
      * If running with modules, all modules in the modules graph are searched for matching
      * type elements.
@@ -90,6 +137,7 @@
      * @param name  the canonical name
      * @param module module relative to which the lookup should happen
      * @return the named type element, or {@code null} if it cannot be found
+     * @see #getAllTypeElements
      * @since 9
      */
     default TypeElement getTypeElement(ModuleElement module, CharSequence name) {
@@ -97,11 +145,54 @@
     }
 
     /**
+     * Returns all type elements with the given canonical name.
+     *
+     * There may be more than one type element with the same canonical
+     * name if the type elements are in different modules.
+     *
+     * @implSpec The default implementation of this method calls
+     * {@link #getAllModuleElements() getAllModuleElements} and stores
+     * the result. If the set of modules is empty, {@link
+     * #getTypeElement(CharSequence) getTypeElement(name)} is called
+     * passing through the name argument. If {@code
+     * getTypeElement(name)} is {@code null}, an empty set of type
+     * elements is returned; otherwise, a single-element set with the
+     * found type element is returned. If the set of modules is
+     * nonempty, the modules are iterated over and any non-{@code null}
+     * results of {@link #getTypeElement(ModuleElement,
+     * CharSequence) getTypeElement(module, name)} are accumulated
+     * into a set. The set is then returned.
+     *
+     * @param name  the canonical name
+     * @return the type elements, or an empty set if no type with the name can be found
+     * @see #getTypeElement(ModuleElement, CharSequence)
+     * @since 9
+     */
+    default Set<? extends TypeElement> getAllTypeElements(CharSequence name) {
+        Set<? extends ModuleElement> modules = getAllModuleElements();
+        if (modules.isEmpty()) {
+            TypeElement typeElt = getTypeElement(name);
+            return (typeElt != null) ?
+                Collections.singleton(typeElt):
+                Collections.emptySet();
+        } else {
+            Set<TypeElement> result = new LinkedHashSet<>(1); // Usually expect at most 1 result
+            for (ModuleElement module: modules) {
+                TypeElement typeElt = getTypeElement(module, name);
+                if (typeElt != null)
+                    result.add(typeElt);
+            }
+            return Collections.unmodifiableSet(result);
+        }
+    }
+
+    /**
      * Returns a module element given its fully qualified name.
-     * If the named module cannot be found, null is returned. One situation where a module
-     * cannot be found is if the environment does not include modules, such as
-     * an annotation processing environment configured for
-     * a {@linkplain
+     *
+     * If the named module cannot be found, {@code null} is
+     * returned. One situation where a module cannot be found is if
+     * the environment does not include modules, such as an annotation
+     * processing environment configured for a {@linkplain
      * javax.annotation.processing.ProcessingEnvironment#getSourceVersion
      * source version} without modules.
      *
@@ -110,6 +201,7 @@
      *
      * @param name  the name
      * @return the named module element, or {@code null} if it cannot be found
+     * @see #getAllModuleElements
      * @since 9
      * @spec JPMS
      */
@@ -118,6 +210,27 @@
     }
 
     /**
+     * Returns all module elements in the current environment.
+     *
+     * If no modules are present, an empty set is returned. One
+     * situation where no modules are present occurs when the
+     * environment does not include modules, such as an annotation
+     * processing environment configured for a {@linkplain
+     * javax.annotation.processing.ProcessingEnvironment#getSourceVersion
+     * source version} without modules.
+     *
+     * @implSpec The default implementation of this method returns
+     * an empty set.
+     *
+     * @return the known module elements, or an empty set if there are no modules
+     * @see #getModuleElement(CharSequence)
+     * @since 9
+     */
+    default Set<? extends ModuleElement> getAllModuleElements() {
+        return Collections.emptySet();
+    }
+
+    /**
      * Returns the values of an annotation's elements, including defaults.
      *
      * @see AnnotationMirror#getElementValues()
--- a/langtools/src/java.compiler/share/classes/javax/tools/DocumentationTool.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/java.compiler/share/classes/javax/tools/DocumentationTool.java	Thu Feb 16 18:29:03 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -121,7 +121,20 @@
      */
     interface DocumentationTask extends Callable<Boolean> {
         /**
-         * Set the locale to be applied when formatting diagnostics and
+         * Adds root modules to be taken into account during module
+         * resolution.
+         * Invalid module names may cause either
+         * {@code IllegalArgumentException} to be thrown,
+         * or diagnostics to be reported when the task is started.
+         * @param moduleNames the names of the root modules
+         * @throws IllegalArgumentException may be thrown for some
+         *      invalid module names
+         * @throws IllegalStateException if the task has started
+         */
+        void addModules(Iterable<String> moduleNames);
+
+        /**
+         * Sets the locale to be applied when formatting diagnostics and
          * other localized data.
          *
          * @param locale the locale to apply; {@code null} means apply no
--- a/langtools/src/java.compiler/share/classes/javax/tools/JavaCompiler.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/java.compiler/share/classes/javax/tools/JavaCompiler.java	Thu Feb 16 18:29:03 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -25,7 +25,6 @@
 
 package javax.tools;
 
-import java.io.File;
 import java.io.Writer;
 import java.nio.charset.Charset;
 import java.util.Locale;
@@ -296,6 +295,18 @@
      * {@linkplain #setProcessors setProcessors} method.
      */
     interface CompilationTask extends Callable<Boolean> {
+        /**
+         * Adds root modules to be taken into account during module
+         * resolution.
+         * Invalid module names may cause either
+         * {@code IllegalArgumentException} to be thrown,
+         * or diagnostics to be reported when the task is started.
+         * @param moduleNames the names of the root modules
+         * @throws IllegalArgumentException may be thrown for some
+         *      invalid module names
+         * @throws IllegalStateException if the task has started
+         */
+        void addModules(Iterable<String> moduleNames);
 
         /**
          * Sets processors (for annotation processing).  This will
@@ -307,7 +318,7 @@
         void setProcessors(Iterable<? extends Processor> processors);
 
         /**
-         * Set the locale to be applied when formatting diagnostics and
+         * Sets the locale to be applied when formatting diagnostics and
          * other localized data.
          *
          * @param locale the locale to apply; {@code null} means apply no
@@ -330,6 +341,7 @@
          * in user code.
          * @throws IllegalStateException if called more than once
          */
+        @Override
         Boolean call();
     }
 }
--- a/langtools/src/java.compiler/share/classes/javax/tools/JavaFileManager.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/java.compiler/share/classes/javax/tools/JavaFileManager.java	Thu Feb 16 18:29:03 2017 +0000
@@ -130,7 +130,7 @@
      * It is not possible to directly list the classes in a module-oriented
      * location. Instead, you can get a package-oriented location for any specific module
      * using methods like {@link JavaFileManager#getLocationForModule} or
-     * {@link JavaFileManager#listLocationsForModule}.
+     * {@link JavaFileManager#listLocationsForModules}.
      */
     interface Location {
         /**
--- a/langtools/src/java.compiler/share/classes/module-info.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/java.compiler/share/classes/module-info.java	Thu Feb 16 18:29:03 2017 +0000
@@ -29,6 +29,8 @@
   * These APIs model declarations and types of the Java programming language,
   * and define interfaces for tools such as compilers which can be invoked
   * from a program.
+  *
+  * @since 9
   */
 module java.compiler {
     exports javax.annotation.processing;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/BasicJavacTask.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/BasicJavacTask.java	Thu Feb 16 18:29:03 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -155,6 +155,11 @@
     }
 
     @Override @DefinedBy(Api.COMPILER)
+    public void addModules(Iterable<String> moduleNames) {
+        throw new IllegalStateException();
+    }
+
+    @Override @DefinedBy(Api.COMPILER)
     public void setProcessors(Iterable<? extends Processor> processors) {
         throw new IllegalStateException();
     }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java	Thu Feb 16 18:29:03 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -33,17 +33,12 @@
 
 import javax.annotation.processing.Processor;
 import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
 import javax.lang.model.element.TypeElement;
-import javax.lang.model.util.ElementFilter;
 import javax.tools.*;
-import javax.tools.JavaFileObject.Kind;
 
 import com.sun.source.tree.*;
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
-import com.sun.tools.javac.code.Symbol.ModuleSymbol;
-import com.sun.tools.javac.code.Symbol.PackageSymbol;
 import com.sun.tools.javac.comp.*;
 import com.sun.tools.javac.file.BaseFileManager;
 import com.sun.tools.javac.main.*;
@@ -82,6 +77,7 @@
     private ListBuffer<Env<AttrContext>> genList;
     private final AtomicBoolean used = new AtomicBoolean();
     private Iterable<? extends Processor> processors;
+    private ListBuffer<String> addModules = new ListBuffer<>();
 
     protected JavacTaskImpl(Context context) {
         super(context, true);
@@ -101,7 +97,7 @@
                 prepareCompiler(false);
                 if (compiler.errorCount() > 0)
                     return Main.Result.ERROR;
-                compiler.compile(args.getFileObjects(), args.getClassNames(), processors);
+                compiler.compile(args.getFileObjects(), args.getClassNames(), processors, addModules);
                 return (compiler.errorCount() > 0) ? Main.Result.ERROR : Main.Result.OK; // FIXME?
             }, Main.Result.SYSERR, Main.Result.ABNORMAL);
         } finally {
@@ -114,6 +110,18 @@
     }
 
     @Override @DefinedBy(Api.COMPILER)
+    public void addModules(Iterable<String> moduleNames) {
+        Objects.requireNonNull(moduleNames);
+        // not mt-safe
+        if (used.get())
+            throw new IllegalStateException();
+        for (String m : moduleNames) {
+            Objects.requireNonNull(m);
+            addModules.add(m);
+        }
+    }
+
+    @Override @DefinedBy(Api.COMPILER)
     public void setProcessors(Iterable<? extends Processor> processors) {
         Objects.requireNonNull(processors);
         // not mt-safe
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java	Thu Feb 16 18:29:03 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, 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
@@ -79,6 +79,10 @@
      */
     boolean isNewClass = false;
 
+    /** Indicate if the type being visited is a service implementation
+     */
+    boolean visitingServiceImplementation = false;
+
     /** Are arguments to current function applications boxed into an array for varargs?
      */
     Resolve.MethodResolutionPhase pendingResolutionPhase = null;
@@ -127,6 +131,7 @@
         info.isAnonymousDiamond = isAnonymousDiamond;
         info.isNewClass = isNewClass;
         info.preferredTreeForDiagnostics = preferredTreeForDiagnostics;
+        info.visitingServiceImplementation = visitingServiceImplementation;
         return info;
     }
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Thu Feb 16 18:29:03 2017 +0000
@@ -996,8 +996,18 @@
             }
             ListBuffer<ClassSymbol> impls = new ListBuffer<>();
             for (JCExpression implName : tree.implNames) {
-                Type it = attr.attribType(implName, env, syms.objectType);
+                Type it;
+                boolean prevVisitingServiceImplementation = env.info.visitingServiceImplementation;
+                try {
+                    env.info.visitingServiceImplementation = true;
+                    it = attr.attribType(implName, env, syms.objectType);
+                } finally {
+                    env.info.visitingServiceImplementation = prevVisitingServiceImplementation;
+                }
                 ClassSymbol impl = (ClassSymbol) it.tsym;
+                if ((impl.flags_field & PUBLIC) == 0) {
+                    log.error(implName.pos(), Errors.NotDefPublic(impl, impl.location()));
+                }
                 //find provider factory:
                 MethodSymbol factory = factoryMethod(impl);
                 if (factory != null) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java	Thu Feb 16 18:29:03 2017 +0000
@@ -307,6 +307,11 @@
         if (env.enclMethod != null && (env.enclMethod.mods.flags & ANONCONSTR) != 0)
             return true;
 
+        if (env.info.visitingServiceImplementation &&
+            env.toplevel.modle == c.packge().modle) {
+            return true;
+        }
+
         boolean isAccessible = false;
         switch ((short)(c.flags() & AccessFlags)) {
             case PRIVATE:
@@ -389,6 +394,11 @@
         if (env.enclMethod != null && (env.enclMethod.mods.flags & ANONCONSTR) != 0)
             return true;
 
+        if (env.info.visitingServiceImplementation &&
+            env.toplevel.modle == sym.packge().modle) {
+            return true;
+        }
+
         switch ((short)(sym.flags() & AccessFlags)) {
         case PRIVATE:
             return
@@ -2094,7 +2104,7 @@
 
         for (S sym : candidates) {
             if (validate.test(sym))
-                return new InvisibleSymbolError(env, suppressError, sym);
+                return createInvisibleSymbolError(env, suppressError, sym);
         }
 
         Set<ModuleSymbol> recoverableModules = new HashSet<>(syms.getAllModules());
@@ -2113,7 +2123,7 @@
                     S sym = load.apply(ms, name);
 
                     if (sym != null && validate.test(sym)) {
-                        return new InvisibleSymbolError(env, suppressError, sym);
+                        return createInvisibleSymbolError(env, suppressError, sym);
                     }
                 }
             }
@@ -2122,6 +2132,21 @@
         return defaultResult;
     }
 
+    private Symbol createInvisibleSymbolError(Env<AttrContext> env, boolean suppressError, Symbol sym) {
+        if (symbolPackageVisible(env, sym)) {
+            return new AccessError(env, null, sym);
+        } else {
+            return new InvisibleSymbolError(env, suppressError, sym);
+        }
+    }
+
+    private boolean symbolPackageVisible(Env<AttrContext> env, Symbol sym) {
+        ModuleSymbol envMod = env.toplevel.modle;
+        PackageSymbol symPack = sym.packge();
+        return envMod == symPack.modle ||
+               envMod.visiblePackages.containsKey(symPack.fullname);
+    }
+
     /**
      * Find a type declared in a scope (not inherited).  Return null
      * if none is found.
@@ -4094,8 +4119,7 @@
                             pos, "not.def.access.package.cant.access",
                         sym, sym.location(), inaccessiblePackageReason(env, sym.packge()));
                 } else if (   sym.packge() != syms.rootPackage
-                           && sym.packge().modle != env.toplevel.modle
-                           && !isAccessible(env, sym.outermostClass())) {
+                           && !symbolPackageVisible(env, sym)) {
                     return diags.create(dkind, log.currentSource(),
                             pos, "not.def.access.class.intf.cant.access.reason",
                             sym, sym.location(), sym.location().packge(),
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/CommandLine.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/CommandLine.java	Thu Feb 16 18:29:03 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, 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
@@ -29,8 +29,9 @@
 import java.io.Reader;
 import java.nio.file.Files;
 import java.nio.file.Paths;
-
-import com.sun.tools.javac.util.ListBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 /**
  * Various utility methods for processing Java tool command line arguments.
@@ -55,28 +56,80 @@
      * @throws IOException if there is a problem reading any of the @files
      */
     public static String[] parse(String[] args) throws IOException {
-        ListBuffer<String> newArgs = new ListBuffer<>();
+        List<String> newArgs = new ArrayList<>();
+        appendParsedCommandArgs(newArgs, Arrays.asList(args));
+        return newArgs.toArray(new String[newArgs.size()]);
+    }
+
+    private static void appendParsedCommandArgs(List<String> newArgs, List<String> args) throws IOException {
         for (String arg : args) {
             if (arg.length() > 1 && arg.charAt(0) == '@') {
                 arg = arg.substring(1);
                 if (arg.charAt(0) == '@') {
-                    newArgs.append(arg);
+                    newArgs.add(arg);
                 } else {
                     loadCmdFile(arg, newArgs);
                 }
             } else {
-                newArgs.append(arg);
+                newArgs.add(arg);
             }
         }
-        return newArgs.toList().toArray(new String[newArgs.length()]);
     }
 
-    private static void loadCmdFile(String name, ListBuffer<String> args) throws IOException {
+    /**
+     * Process the given environment variable and appends any Win32-style
+     * command files for the specified command line arguments and return
+     * the resulting arguments. A command file argument
+     * is of the form '@file' where 'file' is the name of the file whose
+     * contents are to be parsed for additional arguments. The contents of
+     * the command file are parsed using StreamTokenizer and the original
+     * '@file' argument replaced with the resulting tokens. Recursive command
+     * files are not supported. The '@' character itself can be quoted with
+     * the sequence '@@'.
+     * @param envVariable the env variable to process
+     * @param args the arguments that may contain @files
+     * @return the arguments, with environment variable's content and expansion of @files
+     * @throws IOException if there is a problem reading any of the @files
+     * @throws com.sun.tools.javac.main.CommandLine.UnmatchedQuote
+     */
+    public static List<String> parse(String envVariable, List<String> args)
+            throws IOException, UnmatchedQuote {
+
+        List<String> inArgs = new ArrayList<>();
+        appendParsedEnvVariables(inArgs, envVariable);
+        inArgs.addAll(args);
+        List<String> newArgs = new ArrayList<>();
+        appendParsedCommandArgs(newArgs, inArgs);
+        return newArgs;
+    }
+
+    /**
+     * Process the given environment variable and appends any Win32-style
+     * command files for the specified command line arguments and return
+     * the resulting arguments. A command file argument
+     * is of the form '@file' where 'file' is the name of the file whose
+     * contents are to be parsed for additional arguments. The contents of
+     * the command file are parsed using StreamTokenizer and the original
+     * '@file' argument replaced with the resulting tokens. Recursive command
+     * files are not supported. The '@' character itself can be quoted with
+     * the sequence '@@'.
+     * @param envVariable the env variable to process
+     * @param args the arguments that may contain @files
+     * @return the arguments, with environment variable's content and expansion of @files
+     * @throws IOException if there is a problem reading any of the @files
+     * @throws com.sun.tools.javac.main.CommandLine.UnmatchedQuote
+     */
+    public static String[] parse(String envVariable, String[] args) throws IOException, UnmatchedQuote {
+        List<String> out = parse(envVariable, Arrays.asList(args));
+        return out.toArray(new String[out.size()]);
+    }
+
+    private static void loadCmdFile(String name, List<String> args) throws IOException {
         try (Reader r = Files.newBufferedReader(Paths.get(name))) {
             Tokenizer t = new Tokenizer(r);
             String s;
             while ((s = t.nextToken()) != null) {
-                args.append(s);
+                args.add(s);
             }
         }
     }
@@ -188,4 +241,75 @@
             }
         }
     }
+
+    @SuppressWarnings("fallthrough")
+    private static void appendParsedEnvVariables(List<String> newArgs, String envVariable)
+            throws UnmatchedQuote {
+
+        if (envVariable == null) {
+            return;
+        }
+        String in = System.getenv(envVariable);
+        if (in == null || in.trim().isEmpty()) {
+            return;
+        }
+
+        final char NUL = (char)0;
+        final int len = in.length();
+
+        int pos = 0;
+        StringBuilder sb = new StringBuilder();
+        char quote = NUL;
+        char ch;
+
+        loop:
+        while (pos < len) {
+            ch = in.charAt(pos);
+            switch (ch) {
+                case '\"': case '\'':
+                    if (quote == NUL) {
+                        quote = ch;
+                    } else if (quote == ch) {
+                        quote = NUL;
+                    } else {
+                        sb.append(ch);
+                    }
+                    pos++;
+                    break;
+                case '\f': case '\n': case '\r': case '\t': case ' ':
+                    if (quote == NUL) {
+                        newArgs.add(sb.toString());
+                        sb.setLength(0);
+                        while (ch == '\f' || ch == '\n' || ch == '\r' || ch == '\t' || ch == ' ') {
+                            pos++;
+                            if (pos >= len) {
+                                break loop;
+                            }
+                            ch = in.charAt(pos);
+                        }
+                        break;
+                    }
+                    // fall through
+                default:
+                    sb.append(ch);
+                    pos++;
+            }
+        }
+        if (sb.length() != 0) {
+            newArgs.add(sb.toString());
+        }
+        if (quote != NUL) {
+            throw new UnmatchedQuote(envVariable);
+        }
+    }
+
+    public static class UnmatchedQuote extends Exception {
+        private static final long serialVersionUID = 0;
+
+        public final String variableName;
+
+        UnmatchedQuote(String variable) {
+            this.variableName = variable;
+        }
+    }
 }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Thu Feb 16 18:29:03 2017 +0000
@@ -888,7 +888,7 @@
 
     public void compile(List<JavaFileObject> sourceFileObject)
         throws Throwable {
-        compile(sourceFileObject, List.nil(), null);
+        compile(sourceFileObject, List.nil(), null, List.nil());
     }
 
     /**
@@ -898,10 +898,13 @@
      * @param classnames class names to process for annotations
      * @param processors user provided annotation processors to bypass
      * discovery, {@code null} means that no processors were provided
+     * @param addModules additional root modules to be used during
+     * module resolution.
      */
     public void compile(Collection<JavaFileObject> sourceFileObjects,
                         Collection<String> classnames,
-                        Iterable<? extends Processor> processors)
+                        Iterable<? extends Processor> processors,
+                        Collection<String> addModules)
     {
         if (!taskListener.isEmpty()) {
             taskListener.started(new TaskEvent(TaskEvent.Kind.COMPILATION));
@@ -932,6 +935,10 @@
                 }
             }
 
+            for (String moduleName : addModules) {
+                modules.addExtraAddModules(moduleName);
+            }
+
             // These method calls must be chained to avoid memory leaks
             processAnnotations(
                 enterTrees(
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java	Thu Feb 16 18:29:03 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, 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
@@ -43,6 +43,7 @@
 import com.sun.tools.javac.file.BaseFileManager;
 import com.sun.tools.javac.file.JavacFileManager;
 import com.sun.tools.javac.jvm.Target;
+import com.sun.tools.javac.main.CommandLine.UnmatchedQuote;
 import com.sun.tools.javac.platform.PlatformDescription;
 import com.sun.tools.javac.processing.AnnotationProcessingError;
 import com.sun.tools.javac.util.*;
@@ -80,6 +81,7 @@
      */
     boolean apiMode;
 
+    private static final String ENV_OPT_NAME = "JDK_JAVAC_OPTIONS";
 
     /** Result codes.
      */
@@ -201,19 +203,12 @@
             return Result.CMDERR;
         }
 
-        // prefix argv with contents of _JAVAC_OPTIONS if set
-        String envOpt = System.getenv("_JAVAC_OPTIONS");
-        if (envOpt != null && !envOpt.trim().isEmpty()) {
-            String[] envv = envOpt.split("\\s+");
-            String[] result = new String[envv.length + argv.length];
-            System.arraycopy(envv, 0, result, 0, envv.length);
-            System.arraycopy(argv, 0, result, envv.length, argv.length);
-            argv = result;
-        }
-
-        // expand @-files
+        // prefix argv with contents of environment variable and expand @-files
         try {
-            argv = CommandLine.parse(argv);
+            argv = CommandLine.parse(ENV_OPT_NAME, argv);
+        } catch (UnmatchedQuote ex) {
+            error("err.unmatched.quote", ex.variableName);
+            return Result.CMDERR;
         } catch (FileNotFoundException | NoSuchFileException e) {
             warning("err.file.not.found", e.getMessage());
             return Result.SYSERR;
@@ -304,7 +299,7 @@
         }
 
         try {
-            comp.compile(args.getFileObjects(), args.getClassNames(), null);
+            comp.compile(args.getFileObjects(), args.getClassNames(), null, List.nil());
 
             if (log.expectDiagKeys != null) {
                 if (log.expectDiagKeys.isEmpty()) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java	Thu Feb 16 18:29:03 2017 +0000
@@ -25,6 +25,7 @@
 
 package com.sun.tools.javac.model;
 
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.Map;
@@ -117,6 +118,14 @@
     }
 
     @Override @DefinedBy(Api.LANGUAGE_MODEL)
+    public Set<? extends ModuleElement> getAllModuleElements() {
+        if (allowModules)
+            return Collections.unmodifiableSet(modules.allModules());
+        else
+            return Collections.emptySet();
+    }
+
+    @Override @DefinedBy(Api.LANGUAGE_MODEL)
     public ModuleSymbol getModuleElement(CharSequence name) {
         ensureEntered("getModuleElement");
         if (modules.getDefaultModule() == syms.noModule)
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu Feb 16 18:29:03 2017 +0000
@@ -915,6 +915,10 @@
     {0} is not public in {1}; cannot be accessed from outside package
 
 # 0: symbol, 1: symbol
+compiler.err.not.def.public=\
+    {0} is not public in {1}
+
+# 0: symbol, 1: symbol
 compiler.misc.not.def.public.cant.access=\
     {0} is not public in {1}; cannot be accessed from outside package
 
@@ -1438,7 +1442,7 @@
 
 # 0: string, 1: string, 2: string
 compiler.note.multiple.elements=\
-    Multiple elements named '{1}' in modules '{2}' were found by javax.lang.model.util.Elements.{0}.
+    Multiple elements named ''{1}'' in modules ''{2}'' were found by javax.lang.model.util.Elements.{0}.
 
 #####
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties	Thu Feb 16 18:29:03 2017 +0000
@@ -377,6 +377,9 @@
 javac.err.repeated.value.for.patch.module=\
     --patch-module specified more than once for {0}
 
+javac.err.unmatched.quote=\
+    unmatched quote in environment variable %s
+
 ## messages
 
 javac.msg.usage.header=\
--- a/langtools/src/jdk.compiler/share/classes/module-info.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/module-info.java	Thu Feb 16 18:29:03 2017 +0000
@@ -26,6 +26,8 @@
 /** Defines the implementation of the
  *  {@link javax.tools.ToolProvider#getSystemJavaCompiler system Java compiler}
  *  and its command line equivalent, <em>javac</em>, as well as <em>javah</em>.
+ *
+ *  @since 9
  */
 module jdk.compiler {
     requires transitive java.compiler;
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java	Thu Feb 16 18:29:03 2017 +0000
@@ -1705,7 +1705,6 @@
         if (lessThanPos < 0) {
             return text;
         }
-
         StringBuilder result = new StringBuilder();
     main: while (lessThanPos != -1) {
             int currPos = lessThanPos + 1;
@@ -1740,17 +1739,16 @@
                     if (ch == '>' && quoteKind == null) {
                         foundGT = true;
                     }
-                    if (++currPos == len)
+                    if (++currPos == len) {
                         break;
+                    }
                     ch = text.charAt(currPos);
                 }
-                startPos = currPos + 1;
-                currPos = startPos;
+                startPos = currPos;
             }
             lessThanPos = text.indexOf('<', currPos);
         }
         result.append(text.substring(startPos));
-
         return result.toString();
     }
 
@@ -1760,10 +1758,6 @@
                 ('1' <= ch && ch <= '6');
     }
 
-    private static boolean isWhitespace(char ch) {
-        return Character.isWhitespace(ch);
-    }
-
     /**
      * Add a link to the stylesheet file.
      *
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/api/JavadocTaskImpl.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/api/JavadocTaskImpl.java	Thu Feb 16 18:29:03 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -25,15 +25,20 @@
 
 package jdk.javadoc.internal.api;
 
+import java.util.ArrayList;
 import java.util.Collections;
+import java.util.List;
 import java.util.Locale;
+import java.util.Objects;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import javax.tools.DocumentationTool.DocumentationTask;
 import javax.tools.JavaFileObject;
 
+import com.sun.tools.javac.main.Option;
 import com.sun.tools.javac.util.ClientCodeException;
 import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Options;
 import jdk.javadoc.internal.tool.Start;
 
 /**
@@ -53,6 +58,7 @@
     private Iterable<String> options;
     private Iterable<? extends JavaFileObject> fileObjects;
     private Locale locale;
+    private List<String> addModules = new ArrayList<>();
 
     public JavadocTaskImpl(Context context, Class<?> docletClass,
             Iterable<String> options, Iterable<? extends JavaFileObject> fileObjects) {
@@ -72,6 +78,16 @@
         this.locale = locale;
     }
 
+    @Override
+    public void addModules(Iterable<String> moduleNames) {
+        nullCheck(moduleNames);
+        if (used.get())
+            throw new IllegalStateException();
+        for (String name : moduleNames) {
+            addModules.add(name);
+        }
+    }
+
     public Boolean call() {
         if (!used.getAndSet(true)) {
             initContext();
@@ -89,6 +105,12 @@
     private void initContext() {
         //initialize compiler's default locale
         context.put(Locale.class, locale);
+        if (!addModules.isEmpty()) {
+            String names = String.join(",", addModules);
+            Options opts = Options.instance(context);
+            String prev = opts.get(Option.ADD_MODULES);
+            opts.put(Option.ADD_MODULES, (prev == null) ? names : prev + "," + names);
+        }
     }
 
     private static <T> Iterable<T> nullCheck(Iterable<T> items) {
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java	Thu Feb 16 18:29:03 2017 +0000
@@ -647,6 +647,13 @@
                 tree.addContent(fixedNavDiv);
                 HtmlTree paddingDiv = HtmlTree.DIV(HtmlStyle.navPadding, Contents.SPACE);
                 tree.addContent(paddingDiv);
+                HtmlTree scriptTree = HtmlTree.SCRIPT();
+                String scriptCode = "<!--\n"
+                        + "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+                        + "//-->\n";
+                RawHtml scriptContent = new RawHtml(scriptCode.replace("\n", DocletConstants.NL));
+                scriptTree.addContent(scriptContent);
+                tree.addContent(scriptTree);
             } else {
                 subDiv.addContent(getMarkerAnchor(SectionName.SKIP_NAVBAR_BOTTOM));
                 tree.addContent(subDiv);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java	Thu Feb 16 18:29:03 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -32,7 +32,6 @@
 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 javax.tools.JavaFileManager;
 import javax.tools.JavaFileObject;
@@ -1116,7 +1115,7 @@
 
         @Override
         public String toString() {
-            return names.toString();
+            return Arrays.toString(names);
         }
 
         @Override
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java	Thu Feb 16 18:29:03 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -46,7 +46,6 @@
 import javax.lang.model.util.Elements;
 import javax.tools.FileObject;
 import javax.tools.JavaFileManager.Location;
-import javax.tools.JavaFileObject;
 
 import com.sun.source.tree.CompilationUnitTree;
 import com.sun.source.util.JavacTask;
@@ -62,7 +61,6 @@
 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.Env;
 import com.sun.tools.javac.model.JavacElements;
@@ -297,6 +295,33 @@
         return null;
     }
 
+    // TODO: the method jx.l.m.Elements::overrides does not check
+    // the return type, see JDK-8174840 until that is resolved,
+    // use a  copy of the same method, with a return type check.
+
+    // Note: the rider.overrides call in this method *must* be consistent
+    // with the call in overrideType(....), the method above.
+    public boolean overrides(ExecutableElement e1, ExecutableElement e2, TypeElement cls) {
+        MethodSymbol rider = (MethodSymbol)e1;
+        MethodSymbol ridee = (MethodSymbol)e2;
+        ClassSymbol origin = (ClassSymbol)cls;
+
+        return rider.name == ridee.name &&
+
+               // not reflexive as per JLS
+               rider != ridee &&
+
+               // we don't care if ridee is static, though that wouldn't
+               // compile
+               !rider.isStatic() &&
+
+               // Symbol.overrides assumes the following
+               ridee.isMemberOf(origin, toolEnv.getTypes()) &&
+
+               // check access, signatures and check return types
+               rider.overrides(ridee, origin, toolEnv.getTypes(), true);
+    }
+
     // TODO: jx.l.m ?
     public Location getLocationForModule(ModuleElement mdle) {
         ModuleSymbol msym = (ModuleSymbol)mdle;
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/script.js	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/script.js	Thu Feb 16 18:29:03 2017 +0000
@@ -92,6 +92,9 @@
     if (!tagSearchIndex) {
         createElem(doc, tag, 'tag-search-index.js');
     }
+    $(window).resize(function() {
+        $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
+    });
 }
 
 function createElem(doc, tag, path) {
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/stylesheet.css	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/stylesheet.css	Thu Feb 16 18:29:03 2017 +0000
@@ -144,7 +144,7 @@
     margin:0;
 }
 .navPadding {
-    padding-top: 100px;
+    padding-top: 107px;
 }
 .fixedNav {
     position:fixed;
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java	Thu Feb 16 18:29:03 2017 +0000
@@ -893,7 +893,7 @@
             }
             List<? extends Element> methods = te.getEnclosedElements();
             for (ExecutableElement ee : ElementFilter.methodsIn(methods)) {
-                if (elementUtils.overrides(method, ee, origin)) {
+                if (configuration.workArounds.overrides(method, ee, origin)) {
                     return ee;
                 }
             }
@@ -1886,11 +1886,6 @@
             }
 
             @Override
-            public String visitPrimitive(PrimitiveType t, Void p) {
-                return t.toString();
-            }
-
-            @Override
             public String visitTypeVariable(javax.lang.model.type.TypeVariable t, Void p) {
                 // The knee jerk reaction is to do this but don't!, as we would like
                 // it to be compatible with the old world, now if we decide to do so
@@ -1900,9 +1895,10 @@
             }
 
             @Override
-            protected String defaultAction(TypeMirror e, Void p) {
-                throw new UnsupportedOperationException("should not happen");
+            protected String defaultAction(TypeMirror t, Void p) {
+                return t.toString();
             }
+
         }.visit(t);
     }
 
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOption.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOption.java	Thu Feb 16 18:29:03 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -338,7 +338,7 @@
         }
     },
 
-    X("-X", STANDARD) {
+    HELP_EXTRA("--help-extra -X", STANDARD) {
         @Override
         public void process(Helper helper) throws OptionException {
            throw new OptionException(OK, helper::Xusage);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties	Thu Feb 16 18:29:03 2017 +0000
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1997, 2017, 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
@@ -205,7 +205,7 @@
 main.opt.J.desc=\
     Pass <flag> directly to the runtime system
 
-main.opt.X.desc=\
+main.opt.help.extra.desc=\
     Print a synopsis of nonstandard options and exit
 
 main.usage.foot=\n\
--- a/langtools/src/jdk.javadoc/share/classes/module-info.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/module-info.java	Thu Feb 16 18:29:03 2017 +0000
@@ -26,6 +26,8 @@
 /** Defines the implementation of the
  *  {@link javax.tools.ToolProvider#getSystemDocumentationTool system documentation tool}
  *  and its command line equivalent, <em>javadoc</em>.
+ *
+ *  @since 9
  */
 module jdk.javadoc {
     requires transitive java.compiler;
--- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/Graph.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/Graph.java	Thu Feb 16 18:29:03 2017 +0000
@@ -116,7 +116,7 @@
                 .forEach(u -> g.adjacentNodes(u).stream()
                                 .filter(v -> isAdjacent(u, v))
                                 .forEach(v -> builder.addEdge(u, v)));
-        return builder.build();
+        return builder.build().reduce();
     }
 
     /**
@@ -274,7 +274,7 @@
         }
 
         public void addNodes(Set<T> nodes) {
-            nodes.addAll(nodes);
+            this.nodes.addAll(nodes);
         }
 
         public void addEdge(T u, T v) {
@@ -335,67 +335,4 @@
             result.addLast(node);
         }
     }
-
-    public static class DotGraph {
-        static final String ORANGE = "#e76f00";
-        static final String BLUE = "#437291";
-        static final String GRAY = "#dddddd";
-
-        static final String REEXPORTS = "";
-        static final String REQUIRES = "style=\"dashed\"";
-        static final String REQUIRES_BASE = "color=\"" + GRAY + "\"";
-
-        static final Set<String> javaModules = modules(name ->
-            (name.startsWith("java.") && !name.equals("java.smartcardio")));
-        static final Set<String> jdkModules = modules(name ->
-            (name.startsWith("java.") ||
-                name.startsWith("jdk.") ||
-                name.startsWith("javafx.")) && !javaModules.contains(name));
-
-        private static Set<String> modules(Predicate<String> predicate) {
-            return ModuleFinder.ofSystem().findAll()
-                               .stream()
-                               .map(ModuleReference::descriptor)
-                               .map(ModuleDescriptor::name)
-                               .filter(predicate)
-                               .collect(Collectors.toSet());
-        }
-
-        static void printAttributes(PrintWriter out) {
-            out.format("  size=\"25,25\";%n");
-            out.format("  nodesep=.5;%n");
-            out.format("  ranksep=1.5;%n");
-            out.format("  pencolor=transparent;%n");
-            out.format("  node [shape=plaintext, fontname=\"DejaVuSans\", fontsize=36, margin=\".2,.2\"];%n");
-            out.format("  edge [penwidth=4, color=\"#999999\", arrowhead=open, arrowsize=2];%n");
-        }
-
-        static void printNodes(PrintWriter out, Graph<String> graph) {
-            out.format("  subgraph se {%n");
-            graph.nodes().stream()
-                 .filter(javaModules::contains)
-                 .forEach(mn -> out.format("  \"%s\" [fontcolor=\"%s\", group=%s];%n",
-                                           mn, ORANGE, "java"));
-            out.format("  }%n");
-            graph.nodes().stream()
-                 .filter(jdkModules::contains)
-                 .forEach(mn -> out.format("    \"%s\" [fontcolor=\"%s\", group=%s];%n",
-                                           mn, BLUE, "jdk"));
-
-            graph.nodes().stream()
-                 .filter(mn -> !javaModules.contains(mn) && !jdkModules.contains(mn))
-                 .forEach(mn -> out.format("  \"%s\";%n", mn));
-        }
-
-        static void printEdges(PrintWriter out, Graph<String> graph,
-                               String node, Set<String> requiresTransitive) {
-            graph.adjacentNodes(node).forEach(dn -> {
-                String attr = dn.equals("java.base") ? REQUIRES_BASE
-                        : (requiresTransitive.contains(dn) ? REEXPORTS : REQUIRES);
-                out.format("  \"%s\" -> \"%s\" [%s];%n", node, dn, attr);
-            });
-        }
-    }
-
-
 }
--- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsConfiguration.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsConfiguration.java	Thu Feb 16 18:29:03 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -207,16 +207,6 @@
     }
 
     /**
-     * Returns the modules that the given module can read
-     */
-    public Stream<Module> reads(Module module) {
-        return configuration.findModule(module.name()).get()
-            .reads().stream()
-            .map(ResolvedModule::name)
-            .map(nameToModule::get);
-    }
-
-    /**
      * Returns the list of packages that split between resolved module and
      * unnamed module
      */
@@ -267,16 +257,15 @@
         return nameToModule;
     }
 
-    public Stream<Module> resolve(Set<String> roots) {
-        if (roots.isEmpty()) {
-            return nameToModule.values().stream();
-        } else {
-            return Configuration.empty()
-                    .resolve(finder, ModuleFinder.of(), roots)
-                    .modules().stream()
-                    .map(ResolvedModule::name)
-                    .map(nameToModule::get);
-        }
+    /**
+     * Returns Configuration with the given roots
+     */
+    public Configuration resolve(Set<String> roots) {
+        if (roots.isEmpty())
+            throw new IllegalArgumentException("empty roots");
+
+        return Configuration.empty()
+                    .resolve(finder, ModuleFinder.of(), roots);
     }
 
     public List<Archive> classPathArchives() {
--- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java	Thu Feb 16 18:29:03 2017 +0000
@@ -721,9 +721,9 @@
             return run(config, writer, type);
         }
 
-        boolean run(JdepsConfiguration config, JdepsWriter writer, Type type) throws IOException {
-
-
+        boolean run(JdepsConfiguration config, JdepsWriter writer, Type type)
+            throws IOException
+        {
             // analyze the dependencies
             DepsAnalyzer analyzer = new DepsAnalyzer(config,
                                                      dependencyFilter(config),
@@ -1024,8 +1024,10 @@
         boolean run(JdepsConfiguration config) throws IOException {
             if ((options.showSummary || options.verbose == MODULE) &&
                 !options.addmods.isEmpty() && inputArgs.isEmpty()) {
-                // print module descriptor
-                return new ModuleAnalyzer(config, log).genDotFiles(dotOutputDir);
+                // generate dot graph from the resolved graph from module
+                // resolution.  No class dependency analysis is performed.
+                return new ModuleDotGraph(config, options.apiOnly)
+                        .genDotFiles(dotOutputDir);
             }
 
             Type type = getAnalyzerType();
--- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleAnalyzer.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleAnalyzer.java	Thu Feb 16 18:29:03 2017 +0000
@@ -59,15 +59,10 @@
 
     private final JdepsConfiguration configuration;
     private final PrintWriter log;
-
     private final DependencyFinder dependencyFinder;
     private final Map<Module, ModuleDeps> modules;
 
     public ModuleAnalyzer(JdepsConfiguration config,
-                          PrintWriter log) {
-        this(config, log, Collections.emptySet());
-    }
-    public ModuleAnalyzer(JdepsConfiguration config,
                           PrintWriter log,
                           Set<String> names) {
         this.configuration = config;
@@ -333,88 +328,6 @@
         return true;
     }
 
-    /**
-     * Generate dotfile from module descriptor
-     *
-     * @param dir output directory
-     */
-    public boolean genDotFiles(Path dir) throws IOException {
-        Files.createDirectories(dir);
-        for (Module m : modules.keySet()) {
-            genDotFile(dir, m.name());
-        }
-        return true;
-    }
-
-
-    private void genDotFile(Path dir, String name) throws IOException {
-        try (OutputStream os = Files.newOutputStream(dir.resolve(name + ".dot"));
-             PrintWriter out = new PrintWriter(os)) {
-            Set<Module> modules = configuration.resolve(Set.of(name))
-                .collect(Collectors.toSet());
-
-            // transitive reduction
-            Graph<String> graph = gengraph(modules);
-
-            out.format("digraph \"%s\" {%n", name);
-            DotGraph.printAttributes(out);
-            DotGraph.printNodes(out, graph);
-
-            modules.stream()
-                .map(Module::descriptor)
-                .sorted(Comparator.comparing(ModuleDescriptor::name))
-                .forEach(md -> {
-                    String mn = md.name();
-                    Set<String> requiresTransitive = md.requires().stream()
-                        .filter(d -> d.modifiers().contains(TRANSITIVE))
-                        .map(d -> d.name())
-                        .collect(toSet());
-
-                    DotGraph.printEdges(out, graph, mn, requiresTransitive);
-                });
-
-            out.println("}");
-        }
-    }
-
-    /**
-     * Returns a Graph of the given Configuration after transitive reduction.
-     *
-     * Transitive reduction of requires transitive edge and requires edge have
-     * to be applied separately to prevent the requires transitive edges
-     * (e.g. U -> V) from being reduced by a path (U -> X -> Y -> V)
-     * in which  V would not be re-exported from U.
-     */
-    private Graph<String> gengraph(Set<Module> modules) {
-        // build a Graph containing only requires transitive edges
-        // with transitive reduction.
-        Graph.Builder<String> rpgbuilder = new Graph.Builder<>();
-        for (Module module : modules) {
-            ModuleDescriptor md = module.descriptor();
-            String mn = md.name();
-            md.requires().stream()
-                    .filter(d -> d.modifiers().contains(TRANSITIVE))
-                    .map(d -> d.name())
-                    .forEach(d -> rpgbuilder.addEdge(mn, d));
-        }
-
-        Graph<String> rpg = rpgbuilder.build().reduce();
-
-        // build the readability graph
-        Graph.Builder<String> builder = new Graph.Builder<>();
-        for (Module module : modules) {
-            ModuleDescriptor md = module.descriptor();
-            String mn = md.name();
-            builder.addNode(mn);
-            configuration.reads(module)
-                    .map(Module::name)
-                    .forEach(d -> builder.addEdge(mn, d));
-        }
-
-        // transitive reduction of requires edges
-        return builder.build().reduce(rpg);
-    }
-
     // ---- for testing purpose
     public ModuleDescriptor[] descriptors(String name) {
         ModuleDeps moduleDeps = modules.keySet().stream()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleDotGraph.java	Thu Feb 16 18:29:03 2017 +0000
@@ -0,0 +1,368 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.jdeps;
+
+import static java.lang.module.ModuleDescriptor.Requires.Modifier.*;
+import static java.util.stream.Collectors.*;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.lang.module.Configuration;
+import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleFinder;
+import java.lang.module.ModuleReference;
+import java.lang.module.ResolvedModule;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * Generate dot graph for modules
+ */
+public class ModuleDotGraph {
+    private final Map<String, Configuration> configurations;
+    private final boolean apiOnly;
+    public ModuleDotGraph(JdepsConfiguration config, boolean apiOnly) {
+        this(config.rootModules().stream()
+                   .map(Module::name)
+                   .sorted()
+                   .collect(toMap(Function.identity(), mn -> config.resolve(Set.of(mn)))),
+             apiOnly);
+    }
+
+    public ModuleDotGraph(Map<String, Configuration> configurations, boolean apiOnly) {
+        this.configurations = configurations;
+        this.apiOnly = apiOnly;
+    }
+
+    /**
+     * Generate dotfile for all modules
+     *
+     * @param dir output directory
+     */
+    public boolean genDotFiles(Path dir) throws IOException {
+        Files.createDirectories(dir);
+        for (String mn : configurations.keySet()) {
+            Path path = dir.resolve(mn + ".dot");
+            genDotFile(path, mn, configurations.get(mn));
+        }
+        return true;
+    }
+
+    /**
+     * Generate dotfile of the given path
+     */
+    public void genDotFile(Path path, String name, Configuration configuration)
+        throws IOException
+    {
+        // transitive reduction
+        Graph<String> graph = apiOnly
+                ? requiresTransitiveGraph(configuration, Set.of(name))
+                : gengraph(configuration);
+
+        DotGraphBuilder builder = new DotGraphBuilder(name, graph);
+        builder.subgraph("se", "java", DotGraphBuilder.ORANGE,
+                         DotGraphBuilder.JAVA_SE_SUBGRAPH)
+               .subgraph("jdk", "jdk", DotGraphBuilder.BLUE,
+                         DotGraphBuilder.JDK_SUBGRAPH)
+               .descriptors(graph.nodes().stream()
+                                 .map(mn -> configuration.findModule(mn).get()
+                                                .reference().descriptor()));
+        // build dot file
+        builder.build(path);
+    }
+
+    /**
+     * Returns a Graph of the given Configuration after transitive reduction.
+     *
+     * Transitive reduction of requires transitive edge and requires edge have
+     * to be applied separately to prevent the requires transitive edges
+     * (e.g. U -> V) from being reduced by a path (U -> X -> Y -> V)
+     * in which  V would not be re-exported from U.
+     */
+    private Graph<String> gengraph(Configuration cf) {
+        Graph.Builder<String> builder = new Graph.Builder<>();
+        cf.modules().stream()
+            .forEach(resolvedModule -> {
+                String mn = resolvedModule.reference().descriptor().name();
+                builder.addNode(mn);
+                resolvedModule.reads().stream()
+                    .map(ResolvedModule::name)
+                    .forEach(target -> builder.addEdge(mn, target));
+            });
+
+        Graph<String> rpg = requiresTransitiveGraph(cf, builder.nodes);
+        return builder.build().reduce(rpg);
+    }
+
+
+    /**
+     * Returns a Graph containing only requires transitive edges
+     * with transitive reduction.
+     */
+    public Graph<String> requiresTransitiveGraph(Configuration cf,
+                                                 Set<String> roots)
+    {
+        Deque<String> deque = new ArrayDeque<>(roots);
+        Set<String> visited = new HashSet<>();
+        Graph.Builder<String> builder = new Graph.Builder<>();
+
+        while (deque.peek() != null) {
+            String mn = deque.pop();
+            if (visited.contains(mn))
+                continue;
+
+            visited.add(mn);
+            builder.addNode(mn);
+            ModuleDescriptor descriptor = cf.findModule(mn).get()
+                .reference().descriptor();
+            descriptor.requires().stream()
+                .filter(d -> d.modifiers().contains(TRANSITIVE)
+                                || d.name().equals("java.base"))
+                .map(d -> d.name())
+                .forEach(d -> {
+                    deque.add(d);
+                    builder.addEdge(mn, d);
+                });
+        }
+
+        return builder.build().reduce();
+    }
+
+    public static class DotGraphBuilder {
+        static final Set<String> JAVA_SE_SUBGRAPH = javaSE();
+        static final Set<String> JDK_SUBGRAPH = jdk();
+
+        private static Set<String> javaSE() {
+            String root = "java.se.ee";
+            ModuleFinder system = ModuleFinder.ofSystem();
+            if (system.find(root).isPresent()) {
+                return Stream.concat(Stream.of(root),
+                                     Configuration.empty().resolve(system,
+                                                                   ModuleFinder.of(),
+                                                                   Set.of(root))
+                                                  .findModule(root).get()
+                                                  .reads().stream()
+                                                  .map(ResolvedModule::name))
+                             .collect(toSet());
+            } else {
+                // approximation
+                return system.findAll().stream()
+                    .map(ModuleReference::descriptor)
+                    .map(ModuleDescriptor::name)
+                    .filter(name -> name.startsWith("java.") &&
+                                        !name.equals("java.smartcardio"))
+                    .collect(Collectors.toSet());
+            }
+        }
+
+        private static Set<String> jdk() {
+            return ModuleFinder.ofSystem().findAll().stream()
+                    .map(ModuleReference::descriptor)
+                    .map(ModuleDescriptor::name)
+                    .filter(name -> !JAVA_SE_SUBGRAPH.contains(name) &&
+                                        (name.startsWith("java.") ||
+                                            name.startsWith("jdk.") ||
+                                            name.startsWith("javafx.")))
+                    .collect(Collectors.toSet());
+        }
+
+        static class SubGraph {
+            final String name;
+            final String group;
+            final String color;
+            final Set<String> nodes;
+            SubGraph(String name, String group, String color, Set<String> nodes) {
+                this.name = Objects.requireNonNull(name);
+                this.group = Objects.requireNonNull(group);
+                this.color = Objects.requireNonNull(color);
+                this.nodes = Objects.requireNonNull(nodes);
+            }
+        }
+
+        static final String ORANGE = "#e76f00";
+        static final String BLUE = "#437291";
+        static final String GRAY = "#dddddd";
+        static final String BLACK = "#000000";
+
+        static final String FONT_NAME = "DejaVuSans";
+        static final int FONT_SIZE = 12;
+        static final int ARROW_SIZE = 1;
+        static final int ARROW_WIDTH = 2;
+        static final int RANK_SEP = 1;
+
+        static final String REEXPORTS = "";
+        static final String REQUIRES = "style=\"dashed\"";
+        static final String REQUIRES_BASE = "color=\"" + GRAY + "\"";
+
+        // can be configured
+        static double rankSep   = RANK_SEP;
+        static String fontColor = BLACK;
+        static String fontName  = FONT_NAME;
+        static int fontsize     = FONT_SIZE;
+        static int arrowWidth   = ARROW_WIDTH;
+        static int arrowSize    = ARROW_SIZE;
+        static final Map<String, Integer> weights = new HashMap<>();
+        static final List<Set<String>> ranks = new ArrayList<>();
+
+        private final String name;
+        private final Graph<String> graph;
+        private final Set<ModuleDescriptor> descriptors = new TreeSet<>();
+        private final List<SubGraph> subgraphs = new ArrayList<>();
+        public DotGraphBuilder(String name, Graph<String> graph) {
+            this.name = name;
+            this.graph = graph;
+        }
+
+        public DotGraphBuilder descriptors(Stream<ModuleDescriptor> descriptors) {
+            descriptors.forEach(this.descriptors::add);
+            return this;
+        }
+
+        public void build(Path filename) throws IOException {
+            try (BufferedWriter writer = Files.newBufferedWriter(filename);
+                 PrintWriter out = new PrintWriter(writer)) {
+
+                out.format("digraph \"%s\" {%n", name);
+                out.format("  nodesep=.5;%n");
+                out.format("  ranksep=%f;%n", rankSep);
+                out.format("  pencolor=transparent;%n");
+                out.format("  node [shape=plaintext, fontname=\"%s\", fontsize=%d, margin=\".2,.2\"];%n",
+                           fontName, fontsize);
+                out.format("  edge [penwidth=%d, color=\"#999999\", arrowhead=open, arrowsize=%d];%n",
+                           arrowWidth, arrowSize);
+
+                // same RANKS
+                ranks.stream()
+                     .map(nodes -> descriptors.stream()
+                                        .map(ModuleDescriptor::name)
+                                        .filter(nodes::contains)
+                                        .map(mn -> "\"" + mn + "\"")
+                                        .collect(joining(",")))
+                     .filter(group -> group.length() > 0)
+                     .forEach(group -> out.format("  {rank=same %s}%n", group));
+
+                subgraphs.forEach(subgraph -> {
+                    out.format("  subgraph %s {%n", subgraph.name);
+                    descriptors.stream()
+                        .map(ModuleDescriptor::name)
+                        .filter(subgraph.nodes::contains)
+                        .forEach(mn -> printNode(out, mn, subgraph.color, subgraph.group));
+                    out.format("  }%n");
+                });
+
+                descriptors.stream()
+                    .filter(md -> graph.contains(md.name()) &&
+                                    !graph.adjacentNodes(md.name()).isEmpty())
+                    .forEach(md -> printNode(out, md, graph.adjacentNodes(md.name())));
+
+                out.println("}");
+            }
+        }
+
+        public DotGraphBuilder subgraph(String name, String group, String color,
+                                 Set<String> nodes) {
+            subgraphs.add(new SubGraph(name, group, color, nodes));
+            return this;
+        }
+
+        public void printNode(PrintWriter out, String node, String color, String group) {
+            out.format("  \"%s\" [fontcolor=\"%s\", group=%s];%n",
+                       node, color, group);
+        }
+
+        public void printNode(PrintWriter out, ModuleDescriptor md, Set<String> edges) {
+            Set<String> requiresTransitive = md.requires().stream()
+                .filter(d -> d.modifiers().contains(TRANSITIVE))
+                .map(d -> d.name())
+                .collect(toSet());
+
+            String mn = md.name();
+            edges.stream().forEach(dn -> {
+                String attr = dn.equals("java.base") ? REQUIRES_BASE
+                    : (requiresTransitive.contains(dn) ? REEXPORTS : REQUIRES);
+
+                int w = weightOf(mn, dn);
+                if (w > 1) {
+                    if (!attr.isEmpty())
+                        attr += ", ";
+
+                    attr += "weight=" + w;
+                }
+                out.format("  \"%s\" -> \"%s\" [%s];%n", mn, dn, attr);
+            });
+        }
+
+        public int weightOf(String s, String t) {
+            int w = weights.getOrDefault(s + ":" + t, 1);
+            if (w != 1)
+                return w;
+            if (s.startsWith("java.") && t.startsWith("java."))
+                return 10;
+            return 1;
+        }
+
+        public static void sameRankNodes(Set<String> nodes) {
+            ranks.add(nodes);
+        }
+
+        public static void weight(String s, String t, int w) {
+            weights.put(s + ":" + t, w);
+        }
+
+        public static void setRankSep(double value) {
+            rankSep = value;
+        }
+
+        public static void setFontSize(int size) {
+            fontsize = size;
+        }
+
+        public static void setFontColor(String color) {
+            fontColor = color;
+        }
+
+        public static void setArrowSize(int size) {
+            arrowSize = size;
+        }
+
+        public static void setArrowWidth(int width) {
+            arrowWidth = width;
+        }
+    }
+}
--- a/langtools/src/jdk.jdeps/share/classes/module-info.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.jdeps/share/classes/module-info.java	Thu Feb 16 18:29:03 2017 +0000
@@ -25,6 +25,8 @@
 
 /** Defines tools for analysing dependencies in Java libraries and programs, including
  *  the <em>jdeps</em> and <em>javap</em> tools.
+ *
+ *  @since 9
  */
 module jdk.jdeps {
     requires java.base;
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Thu Feb 16 18:29:03 2017 +0000
@@ -349,9 +349,56 @@
             }
         }
 
+        // check that the supplied string represent valid class/module paths
+        // converting any ~/ to user home
+        private Collection<String> validPaths(Collection<String> vals, String context, boolean isModulePath) {
+            Stream<String> result = vals.stream()
+                    .map(s -> Arrays.stream(s.split(File.pathSeparator))
+                        .map(sp -> toPathResolvingUserHome(sp))
+                        .filter(p -> checkValidPathEntry(p, context, isModulePath))
+                        .map(p -> p.toString())
+                        .collect(Collectors.joining(File.pathSeparator)));
+            if (failed) {
+                return Collections.emptyList();
+            } else {
+                return result.collect(toList());
+            }
+        }
+
+        // Adapted from compiler method Locations.checkValidModulePathEntry
+        private boolean checkValidPathEntry(Path p, String context, boolean isModulePath) {
+            if (!Files.exists(p)) {
+                msg("jshell.err.file.not.found", context, p);
+                failed = true;
+                return false;
+            }
+            if (Files.isDirectory(p)) {
+                // if module-path, either an exploded module or a directory of modules
+                return true;
+            }
+
+            String name = p.getFileName().toString();
+            int lastDot = name.lastIndexOf(".");
+            if (lastDot > 0) {
+                switch (name.substring(lastDot)) {
+                    case ".jar":
+                        return true;
+                    case ".jmod":
+                        if (isModulePath) {
+                            return true;
+                        }
+                }
+            }
+            msg("jshell.err.arg", context, p);
+            failed = true;
+            return false;
+        }
+
         Options parse(OptionSet options) {
-            addOptions(OptionKind.CLASS_PATH, options.valuesOf(argClassPath));
-            addOptions(OptionKind.MODULE_PATH, options.valuesOf(argModulePath));
+            addOptions(OptionKind.CLASS_PATH,
+                    validPaths(options.valuesOf(argClassPath), "--class-path", false));
+            addOptions(OptionKind.MODULE_PATH,
+                    validPaths(options.valuesOf(argModulePath), "--module-path", true));
             addOptions(OptionKind.ADD_MODULES, options.valuesOf(argAddModules));
             addOptions(OptionKind.ADD_EXPORTS, options.valuesOf(argAddExports).stream()
                     .map(mp -> mp.contains("=") ? mp : mp + "=ALL-UNNAMED")
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties	Thu Feb 16 18:29:03 2017 +0000
@@ -650,7 +650,7 @@
    varinit    -- variable declaration with init\n\t\
    expression -- expression -- note: {name}==scratch-variable-name\n\t\
    varvalue   -- variable value expression\n\t\
-   assignment -- assign variable\n\t\
+   assignment -- assign variable\n\
 The action selector kind describes what happened to the snippet.  The values are:\n\t\
    added     -- snippet has been added\n\t\
    modified  -- an existing snippet has been modified\n\t\
--- a/langtools/test/com/sun/javadoc/testNonInlineHtmlTagRemoval/C.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/test/com/sun/javadoc/testNonInlineHtmlTagRemoval/C.java	Thu Feb 16 18:29:03 2017 +0000
@@ -71,4 +71,9 @@
      * caseA <ul type='"a">b'> <li> end of sentence. <li> more </ul>
      */
     public void caseA() {}
+
+    /**
+     * caseB <blockquote>A block quote example:</blockquote>
+     */
+    public void caseB() {}
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testNonInlineHtmlTagRemoval/Negative.java	Thu Feb 16 18:29:03 2017 +0000
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+public class Negative {
+    /**
+     * case1: A hanging &lt;  : <blockquote>xx</blockquote><
+     */
+    public void case1() {}
+}
--- a/langtools/test/com/sun/javadoc/testNonInlineHtmlTagRemoval/TestNonInlineHtmlTagRemoval.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/test/com/sun/javadoc/testNonInlineHtmlTagRemoval/TestNonInlineHtmlTagRemoval.java	Thu Feb 16 18:29:03 2017 +0000
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug      8048628
+ * @bug      8048628 8174715
  * @summary  Verify html inline tags are removed correctly in the first sentence.
  * @library  ../lib
  * @modules jdk.javadoc
@@ -39,22 +39,34 @@
     }
 
     @Test
-    void test() {
-        javadoc("-d", "out",
+    void testPositive() {
+        javadoc("-d", "out1",
                 "-sourcepath", testSrc,
                 testSrc("C.java"));
         checkExit(Exit.OK);
 
         checkOutput("C.html", true,
-                "<div class=\"block\">case1 end of sentence.</div>",
-                "<div class=\"block\">case2 end of sentence.</div>",
-                "<div class=\"block\">case3 end of sentence.</div>",
-                "<div class=\"block\">case4 end of sentence.</div>",
-                "<div class=\"block\">case5 end of sentence.</div>",
-                "<div class=\"block\">case6 end of sentence.</div>",
-                "<div class=\"block\">case7 end of sentence.</div>",
-                "<div class=\"block\">case8 end of sentence.</div>",
-                "<div class=\"block\">case9 end of sentence.</div>",
-                "<div class=\"block\">caseA end of sentence.</div>");
+                "<div class=\"block\">case1   end of sentence.</div>",
+                "<div class=\"block\">case2   end of sentence.</div>",
+                "<div class=\"block\">case3   end of sentence.</div>",
+                "<div class=\"block\">case4   end of sentence.</div>",
+                "<div class=\"block\">case5   end of sentence.</div>",
+                "<div class=\"block\">case6   end of sentence.</div>",
+                "<div class=\"block\">case7   end of sentence.</div>",
+                "<div class=\"block\">case8   end of sentence.</div>",
+                "<div class=\"block\">case9   end of sentence.</div>",
+                "<div class=\"block\">caseA   end of sentence.</div>",
+                "<div class=\"block\">caseB A block quote example:</div>");
+    }
+
+    @Test
+    void testNegative() {
+        javadoc("-d", "out2",
+                "-sourcepath", testSrc,
+                testSrc("Negative.java"));
+        checkExit(Exit.FAILED);
+
+        checkOutput("Negative.html", true,
+                "<div class=\"block\">case1: A hanging &lt;  : xx<</div>");
     }
 }
--- a/langtools/test/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java	Thu Feb 16 18:29:03 2017 +0000
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8072945 8081854 8141492 8148985 8150188 4649116 8173707
+ * @bug 8072945 8081854 8141492 8148985 8150188 4649116 8173707 8151743
  * @summary Test the version of HTML generated by the javadoc tool.
  * @author bpatel
  * @library ../lib
@@ -710,6 +710,10 @@
                 "<!-- ========= END OF TOP NAVBAR ========= -->\n"
                 + "</div>\n"
                 + "<div class=\"navPadding\">&nbsp;</div>\n"
+                + "<script type=\"text/javascript\"><!--\n"
+                + "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+                + "//-->\n"
+                + "</script>\n"
                 + "<div class=\"header\">",
                 "<table class=\"constantsSummary\" summary=\"Constant Field Values table, listing constant fields, and values\">");
 
@@ -723,6 +727,10 @@
                 "<!-- ========= END OF TOP NAVBAR ========= -->\n"
                 + "</div>\n"
                 + "<div class=\"navPadding\">&nbsp;</div>\n"
+                + "<script type=\"text/javascript\"><!--\n"
+                + "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+                + "//-->\n"
+                + "</script>\n"
                 + "<div class=\"header\">\n"
                 + "<h1 title=\"Deprecated API\" class=\"title\">Deprecated API</h1>\n"
                 + "<h2 title=\"Contents\">Contents</h2>",
@@ -747,6 +755,10 @@
                 "<!-- ========= END OF TOP NAVBAR ========= -->\n"
                 + "</div>\n"
                 + "<div class=\"navPadding\">&nbsp;</div>\n"
+                + "<script type=\"text/javascript\"><!--\n"
+                + "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+                + "//-->\n"
+                + "</script>\n"
                 + "<div class=\"header\">",
                 "<li class=\"blockList\">\n"
                 + "<h2 title=\"Package\">Package&nbsp;pkg</h2>");
@@ -761,6 +773,10 @@
                 "<!-- ========= END OF TOP NAVBAR ========= -->\n"
                 + "</div>\n"
                 + "<div class=\"navPadding\">&nbsp;</div>\n"
+                + "<script type=\"text/javascript\"><!--\n"
+                + "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+                + "//-->\n"
+                + "</script>\n"
                 + "<div class=\"header\">",
                 "<div class=\"contentContainer\">\n"
                 + "<h2 title=\"Class Hierarchy\">Class Hierarchy</h2>",
@@ -779,6 +795,10 @@
                 "<!-- ========= END OF TOP NAVBAR ========= -->\n"
                 + "</div>\n"
                 + "<div class=\"navPadding\">&nbsp;</div>\n"
+                + "<script type=\"text/javascript\"><!--\n"
+                + "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+                + "//-->\n"
+                + "</script>\n"
                 + "<div class=\"contentContainer\">");
 
         // Negated test for src-html page
@@ -797,6 +817,10 @@
                 "<!-- ========= END OF TOP NAVBAR ========= -->\n"
                 + "</div>\n"
                 + "<div class=\"navPadding\">&nbsp;</div>\n"
+                + "<script type=\"text/javascript\"><!--\n"
+                + "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+                + "//-->\n"
+                + "</script>\n"
                 + "<div class=\"header\">",
                 "<ul class=\"blockList\">\n"
                 + "<li class=\"blockList\">\n"
@@ -1005,6 +1029,10 @@
                 "<!-- ========= END OF TOP NAVBAR ========= -->\n"
                 + "</div>\n"
                 + "<div class=\"navPadding\">&nbsp;</div>\n"
+                + "<script type=\"text/javascript\"><!--\n"
+                + "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+                + "//-->\n"
+                + "</script>\n"
                 + "<div class=\"header\">",
                 "<table class=\"useSummary\" summary=\"Use table, listing packages, and an explanation\">",
                 "<li class=\"blockList\"><a name=\"pkg\">\n"
@@ -1123,6 +1151,10 @@
                 "<!-- ========= END OF TOP NAVBAR ========= -->\n"
                 + "</div>\n"
                 + "<div class=\"navPadding\">&nbsp;</div>\n"
+                + "<script type=\"text/javascript\"><!--\n"
+                + "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+                + "//-->\n"
+                + "</script>\n"
                 + "<div class=\"header\">",
                 "<table class=\"constantsSummary\" summary=\"Constant Field Values table, listing constant fields, and values\">");
 
@@ -1136,6 +1168,10 @@
                 "<!-- ========= END OF TOP NAVBAR ========= -->\n"
                 + "</div>\n"
                 + "<div class=\"navPadding\">&nbsp;</div>\n"
+                + "<script type=\"text/javascript\"><!--\n"
+                + "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+                + "//-->\n"
+                + "</script>\n"
                 + "<div class=\"header\">\n"
                 + "<h1 title=\"Deprecated API\" class=\"title\">Deprecated API</h1>\n"
                 + "<h2 title=\"Contents\">Contents</h2>",
@@ -1160,6 +1196,10 @@
                 "<!-- ========= END OF TOP NAVBAR ========= -->\n"
                 + "</div>\n"
                 + "<div class=\"navPadding\">&nbsp;</div>\n"
+                + "<script type=\"text/javascript\"><!--\n"
+                + "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+                + "//-->\n"
+                + "</script>\n"
                 + "<div class=\"header\">",
                 "<li class=\"blockList\">\n"
                 + "<h2 title=\"Package\">Package&nbsp;pkg</h2>");
@@ -1175,6 +1215,10 @@
                 "<!-- ========= END OF TOP NAVBAR ========= -->\n"
                 + "</div>\n"
                 + "<div class=\"navPadding\">&nbsp;</div>\n"
+                + "<script type=\"text/javascript\"><!--\n"
+                + "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+                + "//-->\n"
+                + "</script>\n"
                 + "<div class=\"header\">",
                 "<h1 class=\"title\">Hierarchy For All Packages</h1>\n"
                 + "<span class=\"packageHierarchyLabel\">Package Hierarchies:</span>",
@@ -1195,6 +1239,10 @@
                 "<!-- ========= END OF TOP NAVBAR ========= -->\n"
                 + "</div>\n"
                 + "<div class=\"navPadding\">&nbsp;</div>\n"
+                + "<script type=\"text/javascript\"><!--\n"
+                + "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+                + "//-->\n"
+                + "</script>\n"
                 + "<div class=\"contentContainer\">");
 
         // Test for src-html page
@@ -1213,6 +1261,10 @@
                 "<!-- ========= END OF TOP NAVBAR ========= -->\n"
                 + "</div>\n"
                 + "<div class=\"navPadding\">&nbsp;</div>\n"
+                + "<script type=\"text/javascript\"><!--\n"
+                + "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+                + "//-->\n"
+                + "</script>\n"
                 + "<div class=\"header\">",
                 "<ul class=\"blockList\">\n"
                 + "<li class=\"blockList\">\n"
@@ -1421,6 +1473,10 @@
                 "<!-- ========= END OF TOP NAVBAR ========= -->\n"
                 + "</div>\n"
                 + "<div class=\"navPadding\">&nbsp;</div>\n"
+                + "<script type=\"text/javascript\"><!--\n"
+                + "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+                + "//-->\n"
+                + "</script>\n"
                 + "<div class=\"header\">",
                 "<table class=\"useSummary\" summary=\"Use table, listing packages, and an explanation\">",
                 "<li class=\"blockList\"><a name=\"pkg\">\n"
--- a/langtools/test/jdk/javadoc/doclet/testJavascript/TestJavascript.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testJavascript/TestJavascript.java	Thu Feb 16 18:29:03 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2017, 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
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug      4665566 4855876 7025314 8012375 8015997 8016328 8024756 8148985 8151921
+ * @bug      4665566 4855876 7025314 8012375 8015997 8016328 8024756 8148985 8151921 8151743
  * @summary  Verify that the output has the right javascript.
  * @author   jamieh
  * @library  ../lib
@@ -47,7 +47,11 @@
         checkExit(Exit.OK);
 
         checkOutput("pkg/C.html", true,
-                "<a href=\"../index.html?pkg/C.html\" target=\"_top\">Frames</a>");
+                "<a href=\"../index.html?pkg/C.html\" target=\"_top\">Frames</a>",
+                "<script type=\"text/javascript\"><!--\n"
+                + "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+                + "//-->\n"
+                + "</script>");
 
         checkOutput("TestJavascript.html", true,
                 "<a href=\"index.html?TestJavascript.html\" target=\"_top\">Frames</a>");
@@ -119,5 +123,10 @@
                 + "    }\n"
                 + "    catch(err) {\n"
                 + "    }");
+
+        checkOutput("script.js", true,
+                "$(window).resize(function() {\n"
+                + "        $('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+                + "    });");
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testMissingType/TestMissingType.java	Thu Feb 16 18:29:03 2017 +0000
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2017, 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      8173804
+ * @summary  make sure doclet can handle missing types
+ * @library  ../lib
+ * @modules jdk.javadoc/jdk.javadoc.internal.tool
+ * @build    JavadocTester
+ * @run main TestMissingType
+ */
+
+public class TestMissingType extends JavadocTester {
+
+    public static void main(String... args) throws Exception {
+        TestMissingType tester = new TestMissingType();
+        tester.runTests();
+    }
+
+    @Test
+    void test() {
+        javadoc("-d", "out",
+                "-use",
+                "-sourcepath", testSrc,
+                "p");
+        checkExit(Exit.OK);
+        checkFiles(true, "p/class-use/MissingType.html");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testMissingType/p/MissingType.java	Thu Feb 16 18:29:03 2017 +0000
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2017, 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 p;
+
+public final class MissingType  {
+    /**
+     * Do something with a missing type.
+     *
+     * @param out use the missing type
+     */
+    public void encode(MissingMe out) {}
+}
--- a/langtools/test/jdk/javadoc/doclet/testNavigation/TestNavigation.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testNavigation/TestNavigation.java	Thu Feb 16 18:29:03 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug      4131628 4664607 7025314 8023700 7198273 8025633 8026567 8081854 8150188
+ * @bug      4131628 4664607 7025314 8023700 7198273 8025633 8026567 8081854 8150188 8151743
  * @summary  Make sure the Next/Prev Class links iterate through all types.
  *           Make sure the navagation is 2 columns, not 3.
  * @author   jamieh
@@ -77,12 +77,20 @@
                 "<!-- ========= END OF TOP NAVBAR ========= -->\n"
                 + "</div>\n"
                 + "<div class=\"navPadding\">&nbsp;</div>\n"
+                + "<script type=\"text/javascript\"><!--\n"
+                + "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+                + "//-->\n"
+                + "</script>\n"
                 + "<!-- ======== START OF CLASS DATA ======== -->");
 
         checkOutput("pkg/package-summary.html", true,
                 "<!-- ========= END OF TOP NAVBAR ========= -->\n"
                 + "</div>\n"
                 + "<div class=\"navPadding\">&nbsp;</div>\n"
+                + "<script type=\"text/javascript\"><!--\n"
+                + "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+                + "//-->\n"
+                + "</script>\n"
                 + "<div class=\"header\">");
     }
 
@@ -98,6 +106,10 @@
                 "<!-- ========= END OF TOP NAVBAR ========= -->\n"
                 + "</div>\n"
                 + "<div class=\"navPadding\">&nbsp;</div>\n"
+                + "<script type=\"text/javascript\"><!--\n"
+                + "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+                + "//-->\n"
+                + "</script>\n"
                 + "</nav>\n"
                 + "</header>\n"
                 + "<!-- ======== START OF CLASS DATA ======== -->");
@@ -106,6 +118,10 @@
                 "<!-- ========= END OF TOP NAVBAR ========= -->\n"
                 + "</div>\n"
                 + "<div class=\"navPadding\">&nbsp;</div>\n"
+                + "<script type=\"text/javascript\"><!--\n"
+                + "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+                + "//-->\n"
+                + "</script>\n"
                 + "</nav>");
     }
 
@@ -121,12 +137,20 @@
                 "<!-- ========= END OF TOP NAVBAR ========= -->\n"
                 + "</div>\n"
                 + "<div class=\"navPadding\">&nbsp;</div>\n"
+                + "<script type=\"text/javascript\"><!--\n"
+                + "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+                + "//-->\n"
+                + "</script>\n"
                 + "<!-- ======== START OF CLASS DATA ======== -->");
 
         checkOutput("pkg/package-summary.html", false,
                 "<!-- ========= END OF TOP NAVBAR ========= -->\n"
                 + "</div>\n"
                 + "<div class=\"navPadding\">&nbsp;</div>\n"
+                + "<script type=\"text/javascript\"><!--\n"
+                + "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+                + "//-->\n"
+                + "</script>\n"
                 + "<div class=\"header\">");
     }
 
@@ -142,6 +166,10 @@
                 "<!-- ========= END OF TOP NAVBAR ========= -->\n"
                 + "</div>\n"
                 + "<div class=\"navPadding\">&nbsp;</div>\n"
+                + "<script type=\"text/javascript\"><!--\n"
+                + "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+                + "//-->\n"
+                + "</script>\n"
                 + "</nav>\n"
                 + "</header>\n"
                 + "<!-- ======== START OF CLASS DATA ======== -->");
@@ -150,6 +178,10 @@
                 "<!-- ========= END OF TOP NAVBAR ========= -->\n"
                 + "</div>\n"
                 + "<div class=\"navPadding\">&nbsp;</div>\n"
+                + "<script type=\"text/javascript\"><!--\n"
+                + "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+                + "//-->\n"
+                + "</script>\n"
                 + "</nav>");
     }
 }
--- a/langtools/test/jdk/javadoc/doclet/testNonInlineHtmlTagRemoval/C.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testNonInlineHtmlTagRemoval/C.java	Thu Feb 16 18:29:03 2017 +0000
@@ -71,4 +71,9 @@
      * caseA <ul type='"a">b'> <li> end of sentence. <li> more </ul>
      */
     public void caseA() {}
+
+    /**
+     * caseB <blockquote>A block quote example:</blockquote>
+     */
+    public void caseB() {}
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testNonInlineHtmlTagRemoval/Negative.java	Thu Feb 16 18:29:03 2017 +0000
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+public class Negative {
+    /**
+     * case1: A hanging &lt;  : <blockquote>xx</blockquote><
+     */
+    public void case1() {}
+}
--- a/langtools/test/jdk/javadoc/doclet/testNonInlineHtmlTagRemoval/TestNonInlineHtmlTagRemoval.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testNonInlineHtmlTagRemoval/TestNonInlineHtmlTagRemoval.java	Thu Feb 16 18:29:03 2017 +0000
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug      8048628
+ * @bug      8048628 8174715
  * @summary  Verify html inline tags are removed correctly in the first sentence.
  * @library  ../lib
  * @modules jdk.javadoc/jdk.javadoc.internal.tool
@@ -39,8 +39,8 @@
     }
 
     @Test
-    void test() {
-        javadoc("-d", "out",
+    void testPositive() {
+        javadoc("-d", "out1",
                 "-sourcepath", testSrc,
                 testSrc("C.java"));
         checkExit(Exit.OK);
@@ -55,6 +55,18 @@
                 "<div class=\"block\">case7   end of sentence.</div>",
                 "<div class=\"block\">case8   end of sentence.</div>",
                 "<div class=\"block\">case9   end of sentence.</div>",
-                "<div class=\"block\">caseA   end of sentence.</div>");
+                "<div class=\"block\">caseA   end of sentence.</div>",
+                "<div class=\"block\">caseB A block quote example:</div>");
+    }
+
+    @Test
+    void testNegative() {
+        javadoc("-d", "out2",
+                "-sourcepath", testSrc,
+                testSrc("Negative.java"));
+        checkExit(Exit.ERROR);
+
+        checkOutput("Negative.html", true,
+                "<div class=\"block\">case1: A hanging &lt;  : xx<</div>");
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testOverridenMethods/TestBadOverride.java	Thu Feb 16 18:29:03 2017 +0000
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2017, 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      8174839
+ * @summary  Bad overriding method should not crash
+ * @library  ../lib
+ * @modules jdk.javadoc/jdk.javadoc.internal.tool
+ * @build    JavadocTester
+ * @run main TestBadOverride
+ */
+
+public class TestBadOverride extends JavadocTester {
+
+    /**
+     * The entry point of the test.
+     * @param args the array of command line arguments.
+     */
+    public static void main(String... args) throws Exception {
+        TestBadOverride tester = new TestBadOverride();
+        tester.runTests();
+    }
+
+    @Test
+    void test() {
+        javadoc("-d", "out",
+                "-sourcepath", testSrc,
+                "pkg4");
+        checkExit(Exit.OK);
+
+        checkOutput("pkg4/Foo.html", true,
+                "<li class=\"blockList\">\n"
+                + "<h4>toString</h4>\n"
+                + "<pre>public&nbsp;void&nbsp;toString()</pre>\n"
+                + "<div class=\"block\">Why can't I do this ?</div>\n"
+                + "</li>");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testOverridenMethods/pkg4/Foo.java	Thu Feb 16 18:29:03 2017 +0000
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2017, 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 pkg4;
+
+public class Foo {
+    /**
+     * Why can't I do this ?
+     */
+    public void toString() {}
+}
--- a/langtools/test/jdk/javadoc/doclet/testStylesheet/TestStylesheet.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testStylesheet/TestStylesheet.java	Thu Feb 16 18:29:03 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug      4494033 7028815 7052425 8007338 8023608 8008164 8016549 8072461 8154261 8162363 8160196
+ * @bug      4494033 7028815 7052425 8007338 8023608 8008164 8016549 8072461 8154261 8162363 8160196 8151743
  * @summary  Run tests on doclet stylesheet.
  * @author   jamieh
  * @library  ../lib
@@ -159,7 +159,10 @@
                 + "    float:none;\n"
                 + "    display:inline;\n"
                 + "}",
-                "@import url('resources/fonts/dejavu.css');");
+                "@import url('resources/fonts/dejavu.css');",
+                ".navPadding {\n"
+                + "    padding-top: 107px;\n"
+                + "}");
 
         // Test whether a link to the stylesheet file is inserted properly
         // in the class documentation.
--- a/langtools/test/jdk/javadoc/doclet/testXOption/TestXOption.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testXOption/TestXOption.java	Thu Feb 16 18:29:03 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -62,6 +62,16 @@
     }
 
     @Test
+    void testWithHelpExtraOption() {
+        javadoc("-d", "out1",
+                "-sourcepath", testSrc,
+                "--help-extra",
+                testSrc("TestXOption.java"));
+        checkExit(Exit.OK);
+        checkOutput(true);
+    }
+
+    @Test
     void testWithOption() {
         javadoc("-d", "out1",
                 "-sourcepath", testSrc,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/api/basic/AddModulesTest.java	Thu Feb 16 18:29:03 2017 +0000
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2012, 2017, 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 8173596
+ * @summary DocumentationTool.DocumentationTask should support addModules
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ *          jdk.compiler/com.sun.tools.javac.main
+ * @library /tools/lib
+ * @build APITest toolbox.JavacTask toolbox.ToolBox
+ * @run main AddModulesTest
+ */
+
+import java.io.StringWriter;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+
+import javax.tools.DocumentationTool;
+import javax.tools.DocumentationTool.DocumentationTask;
+import javax.tools.DocumentationTool.Location;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+
+import toolbox.Assert;
+import toolbox.JavacTask;
+import toolbox.ToolBox;
+
+/**
+ * Tests for DocumentationTask.addModules method.
+ */
+public class AddModulesTest extends APITest {
+    public static void main(String... args) throws Exception {
+        new AddModulesTest().run();
+    }
+
+    private final ToolBox tb = new ToolBox();
+
+    /**
+     * Verify that addModules works as expected.
+     */
+    @Test
+    public void testAddModules() throws Exception {
+        Path base = Paths.get("testAddModules");
+        Path src = base.resolve("src");
+
+        // setup some utility modules
+        Path src_m1 = src.resolve("m1x");
+        tb.writeJavaFiles(src_m1,
+                          "module m1x { exports p1; }",
+                          "package p1; public class C1 { }");
+        Path src_m2 = src.resolve("m2x");
+        tb.writeJavaFiles(src_m2,
+                          "module m2x { exports p2; }",
+                          "package p2; public class C2 { }");
+        Path modules = base.resolve("modules");
+        tb.createDirectories(modules);
+
+        new JavacTask(tb)
+                .options("--module-source-path", src.toString())
+                .outdir(modules)
+                .files(tb.findJavaFiles(src))
+                .run()
+                .writeAll();
+
+        // now test access to the modules
+        Path src2 = base.resolve("src2");
+        tb.writeJavaFiles(src2,
+                          "public class Dummy { p1.C1 c1; p2.C2 c2; }");
+        Path api = base.resolve("api");
+        tb.createDirectories(api);
+
+        DocumentationTool tool = ToolProvider.getSystemDocumentationTool();
+        try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) {
+            fm.setLocationFromPaths(StandardLocation.MODULE_PATH, Arrays.asList(modules));
+            fm.setLocationFromPaths(Location.DOCUMENTATION_OUTPUT, Arrays.asList(api));
+            Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(tb.findJavaFiles(src2));
+
+            for (boolean useOption : new boolean[] { false, true }) {
+                System.err.println("Use --add-modules option: " + useOption);
+                StringWriter sw = new StringWriter();
+                DocumentationTask t = tool.getTask(sw, fm, null, null, null, files);
+                if (useOption) {
+                    t.addModules(Arrays.asList("m1x", "m2x"));
+                }
+                String out;
+                boolean ok;
+                try {
+                    ok = t.call();
+                } finally {
+                    out = sw.toString();
+                    System.err.println(out);
+                }
+                System.err.println("ok: " + ok);
+                boolean expectErrors = !useOption;
+                check(out, "package p1 is not visible", expectErrors);
+                check(out, "package p2 is not visible", expectErrors);
+                System.err.println();
+            }
+        }
+    }
+
+    void check(String out, String text, boolean expected) {
+        System.err.println("Checking for "
+            + (expected ? "expected" : "unexpected")
+            + " text: " + text);
+
+        if (expected) {
+            if (!out.contains(text)) {
+                error("expected text not found: " + text);
+            }
+        } else {
+            if (out.contains(text)) {
+                error("unexpected text found: " + text);
+            }
+        }
+    }
+}
+
--- a/langtools/test/jdk/jshell/ToolBasicTest.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/test/jdk/jshell/ToolBasicTest.java	Thu Feb 16 18:29:03 2017 +0000
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8143037 8142447 8144095 8140265 8144906 8146138 8147887 8147886 8148316 8148317 8143955 8157953 8080347 8154714 8166649 8167643 8170162 8172102 8165405
+ * @bug 8143037 8142447 8144095 8140265 8144906 8146138 8147887 8147886 8148316 8148317 8143955 8157953 8080347 8154714 8166649 8167643 8170162 8172102 8165405 8174796 8174797
  * @summary Tests for Basic tests for REPL tool
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.main
@@ -35,6 +35,7 @@
  * @run testng/timeout=600 ToolBasicTest
  */
 
+import java.io.File;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.io.StringWriter;
@@ -272,23 +273,58 @@
         );
     }
 
-    public void testClasspathJar() {
+    private String makeSimpleJar() {
         Compiler compiler = new Compiler();
         Path outDir = Paths.get("testClasspathJar");
         compiler.compile(outDir, "package pkg; public class A { public String toString() { return \"A\"; } }");
         String jarName = "test.jar";
         compiler.jar(outDir, jarName, "pkg/A.class");
-        Path jarPath = compiler.getPath(outDir).resolve(jarName);
+        return compiler.getPath(outDir).resolve(jarName).toString();
+    }
+
+    public void testClasspathJar() {
+        String jarPath = makeSimpleJar();
         test(
                 (a) -> assertCommand(a, "/env --class-path " + jarPath,
                         "|  Setting new options and restoring state."),
                 (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "A")
         );
-        test(new String[] { "--class-path", jarPath.toString() },
+        test(new String[] { "--class-path", jarPath },
                 (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "A")
         );
     }
 
+    public void testClasspathUserHomeExpansion() {
+        String jarPath = makeSimpleJar();
+        String tilde = "~" + File.separator;
+        test(
+                (a) -> assertCommand(a, "/env --class-path " + tilde + "forblato",
+                        "|  File '" + System.getProperty("user.home") + File.separator
+                                + "forblato' for '--class-path' is not found."),
+                (a) -> assertCommand(a, "/env --class-path " + jarPath + File.pathSeparator
+                                                            + tilde + "forblato",
+                        "|  File '" + System.getProperty("user.home") + File.separator
+                                + "forblato' for '--class-path' is not found.")
+        );
+    }
+
+    public void testBadClasspath() {
+        String jarPath = makeSimpleJar();
+        Compiler compiler = new Compiler();
+        Path t1 = compiler.getPath("whatever/thing.zip");
+        compiler.writeToFile(t1, "");
+        Path t2 = compiler.getPath("whatever/thing.jmod");
+        compiler.writeToFile(t2, "");
+        test(
+                (a) -> assertCommand(a, "/env --class-path " + t1.toString(),
+                        "|  Invalid '--class-path' argument: " + t1.toString()),
+                (a) -> assertCommand(a, "/env --class-path " + jarPath + File.pathSeparator + t1.toString(),
+                        "|  Invalid '--class-path' argument: " + t1.toString()),
+                (a) -> assertCommand(a, "/env --class-path " + t2.toString(),
+                        "|  Invalid '--class-path' argument: " + t2.toString())
+        );
+    }
+
     public void testModulePath() {
         Compiler compiler = new Compiler();
         Path modsDir = Paths.get("mods");
@@ -304,6 +340,25 @@
         );
     }
 
+    public void testModulePathUserHomeExpansion() {
+        String tilde = "~" + File.separatorChar;
+        test(
+                (a) -> assertCommand(a, "/env --module-path " + tilde + "snardugol",
+                        "|  File '" + System.getProperty("user.home")
+                                + File.separatorChar + "snardugol' for '--module-path' is not found.")
+        );
+    }
+
+    public void testBadModulePath() {
+        Compiler compiler = new Compiler();
+        Path t1 = compiler.getPath("whatever/thing.zip");
+        compiler.writeToFile(t1, "");
+        test(
+                (a) -> assertCommand(a, "/env --module-path " + t1.toString(),
+                        "|  Invalid '--module-path' argument: " + t1.toString())
+        );
+    }
+
     public void testStartupFileOption() {
         Compiler compiler = new Compiler();
         Path startup = compiler.getPath("StartupFileOption/startup.txt");
--- a/langtools/test/jdk/jshell/ToolSimpleTest.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/test/jdk/jshell/ToolSimpleTest.java	Thu Feb 16 18:29:03 2017 +0000
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024 8160089 8153897 8167128 8154513 8170015 8170368 8172102 8172103  8165405 8173073 8173848 8174041 8173916 8174028 8174262
+ * @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024 8160089 8153897 8167128 8154513 8170015 8170368 8172102 8172103  8165405 8173073 8173848 8174041 8173916 8174028 8174262 8174797
  * @summary Simple jshell tool tests
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.main
@@ -212,6 +212,14 @@
     }
 
     @Test
+    public void testInvalidClassPath() {
+        test(
+                a -> assertCommand(a, "/env --class-path snurgefusal",
+                        "|  File 'snurgefusal' for '--class-path' is not found.")
+        );
+    }
+
+    @Test
     public void testNoArgument() {
         test(
                 (a) -> assertCommand(a, "/save",
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ServiceImplNotPublic/ServiceImplNotPublic.java	Thu Feb 16 18:29:03 2017 +0000
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+// key: compiler.err.not.def.public
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ServiceImplNotPublic/example/ServiceImpl.java	Thu Feb 16 18:29:03 2017 +0000
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2017, 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 example;
+class ServiceImpl implements example.SomeService {
+    public ServiceImpl() {}
+    public void foo() {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ServiceImplNotPublic/example/SomeService.java	Thu Feb 16 18:29:03 2017 +0000
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2017, 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 example;
+public interface SomeService {
+    public void foo();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ServiceImplNotPublic/module-info.java	Thu Feb 16 18:29:03 2017 +0000
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+module m {
+    exports example;
+    provides example.SomeService with example.ServiceImpl;
+}
--- a/langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java	Thu Feb 16 18:29:03 2017 +0000
@@ -26,6 +26,7 @@
  * @bug 8002099 8010822
  * @summary Add support for intersection types in cast expression
  * @modules jdk.compiler/com.sun.tools.javac.util
+ * @run main/othervm IntersectionTargetTypeTest
  */
 
 import com.sun.source.util.JavacTask;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/main/EnvVariableTest.java	Thu Feb 16 18:29:03 2017 +0000
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2017, 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 8173308
+ * @summary Check JDK_JAVA_OPTIONS parsing behavior
+ * @library /tools/lib
+ * @modules jdk.compiler/com.sun.tools.javac.main
+ * @build toolbox.ToolBox toolbox.TestRunner
+ * @run main EnvVariableTest
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.nio.file.Path;
+
+import toolbox.*;
+
+import com.sun.tools.javac.main.CommandLine;
+
+public class EnvVariableTest extends TestRunner {
+    final String testClasses;
+    final ToolBox tb;
+    final Path javaExePath;
+    final ExecTask task;
+    final PrintStream ostream;
+    final ByteArrayOutputStream baos;
+
+    public EnvVariableTest() {
+        super(System.err);
+        ostream = System.err;
+        baos = new ByteArrayOutputStream();
+        testClasses = System.getProperty("test.classes");
+        tb = new ToolBox();
+        javaExePath = tb.getJDKTool("java");
+        task = new ExecTask(tb, javaExePath);
+    }
+
+    public static void main(String... args) throws Exception {
+        EnvVariableTest t = new EnvVariableTest();
+        t.runTests();
+    }
+
+    @Test
+    public void testDoubleQuote() throws Exception {
+        // white space quoted with double quotes
+        test("-version -cp \"c:\\\\java libs\\\\one.jar\" \n",
+                "-version", "-cp", "c:\\\\java libs\\\\one.jar");
+    }
+
+    @Test
+    public void testSingleQuote() throws Exception {
+        // white space quoted with single quotes
+        test("-version -cp \'c:\\\\java libs\\\\one.jar\' \n",
+                "-version", "-cp", "c:\\\\java libs\\\\one.jar");
+    }
+
+    @Test
+    public void testEscapeCharacters() throws Exception {
+        // escaped characters
+        test("escaped chars testing \"\\a\\b\\c\\f\\n\\r\\t\\v\\9\\6\\23\\82\\28\\377\\477\\278\\287\"",
+                "escaped", "chars", "testing", "\\a\\b\\c\\f\\n\\r\\t\\v\\9\\6\\23\\82\\28\\377\\477\\278\\287");
+    }
+
+    @Test
+    public void testMixedQuotes() throws Exception {
+        // more mixing of quote types
+        test("\"mix 'single quote' in double\" 'mix \"double quote\" in single' partial\"quote me\"this",
+                "mix 'single quote' in double", "mix \"double quote\" in single", "partialquote methis");
+    }
+
+    @Test
+    public void testWhiteSpaces() throws Exception {
+        // whitespace tests
+        test("line one #comment\n'line #2' #rest are comment\r\n#comment on line 3\fline 4 #comment to eof",
+                "line", "one", "#comment", "line #2", "#rest", "are", "comment", "#comment", "on", "line",
+                "3", "line", "4", "#comment", "to", "eof");
+    }
+
+    @Test
+    public void testMismatchedDoubleQuote() throws Exception {
+        // mismatched quote
+        test("This is an \"open quote \n    across line\n\t, note for WS.",
+                "Exception: JDK_JAVAC_OPTIONS");
+    }
+
+    @Test
+    public void testMismatchedSingleQuote() throws Exception {
+        // mismatched quote
+        test("This is an \'open quote \n    across line\n\t, note for WS.",
+                "Exception: JDK_JAVAC_OPTIONS");
+    }
+
+    void test(String full, String... expectedArgs) throws Exception {
+        task.envVar("JDK_JAVAC_OPTIONS", full);
+        task.args("--add-exports", "jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED",
+                "-cp", testClasses, "EnvVariableTest$Tester");
+        Task.Result tr = task.run(Task.Expect.SUCCESS);
+        String expected = Tester.arrayToString(expectedArgs);
+        String in = tr.getOutput(Task.OutputKind.STDOUT);
+        System.err.println("Matching...");
+        System.err.println("Obtained: " + in);
+        System.err.println("Expected: " + expected);
+        if (in.contains(expected)) {
+            System.err.println("....OK");
+            return;
+        }
+        throw new Exception("Expected strings not found");
+    }
+
+    /**
+     * A tester class that is invoked to invoke the CommandLine class, and
+     * print the result.
+     */
+    public static class Tester {
+        private static final String[] EMPTY_ARRAY = new String[0];
+        static String arrayToString(String... args) {
+            return String.join(", ", args);
+        }
+        public static void main(String... args) throws IOException {
+            try {
+                String[] argv = CommandLine.parse("JDK_JAVAC_OPTIONS", EMPTY_ARRAY);
+                System.out.print(arrayToString(argv));
+            } catch (CommandLine.UnmatchedQuote ex) {
+                System.out.print("Exception: " + ex.variableName);
+            }
+        }
+    }
+}
--- a/langtools/test/tools/javac/modules/AddModulesTest.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/test/tools/javac/modules/AddModulesTest.java	Thu Feb 16 18:29:03 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -23,17 +23,27 @@
 
 /*
  * @test
+ * @bug 8167975 8173596
  * @summary Test the --add-modules option
  * @library /tools/lib
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.main
- * @build toolbox.ToolBox toolbox.JavacTask ModuleTestBase
+ * @build toolbox.Assert toolbox.ToolBox toolbox.JavacTask ModuleTestBase
  * @run main AddModulesTest
  */
 
 
 import java.nio.file.Path;
+import java.util.Arrays;
 
+import javax.tools.JavaCompiler;
+import javax.tools.JavaCompiler.CompilationTask;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+
+import toolbox.Assert;
 import toolbox.JavacTask;
 import toolbox.Task;
 
@@ -227,5 +237,46 @@
                 .run()
                 .writeAll();
     }
+
+    @Test
+    public void testAddModulesAPI(Path base) throws Exception {
+        Path src = base.resolve("src");
+
+        // setup some utility modules
+        Path src_m1 = src.resolve("m1x");
+        tb.writeJavaFiles(src_m1,
+                          "module m1x { exports p1; }",
+                          "package p1; public class C1 { }");
+        Path src_m2 = src.resolve("m2x");
+        tb.writeJavaFiles(src_m2,
+                          "module m2x { exports p2; }",
+                          "package p2; public class C2 { }");
+        Path modules = base.resolve("modules");
+        tb.createDirectories(modules);
+
+        new JavacTask(tb)
+                .options("--module-source-path", src.toString())
+                .outdir(modules)
+                .files(findJavaFiles(src))
+                .run()
+                .writeAll();
+
+        // now test access to the modules
+        Path src2 = base.resolve("src2");
+        tb.writeJavaFiles(src2,
+                          "class Dummy { p1.C1 c1; p2.C2 c2; }");
+        Path classes = base.resolve("classes");
+        tb.createDirectories(classes);
+
+        JavaCompiler c = ToolProvider.getSystemJavaCompiler();
+        try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) {
+            fm.setLocationFromPaths(StandardLocation.MODULE_PATH, Arrays.asList(modules));
+            fm.setLocationFromPaths(StandardLocation.CLASS_OUTPUT, Arrays.asList(classes));
+            Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(findJavaFiles(src2));
+            CompilationTask t = c.getTask(null, fm, null, null, null, files);
+            t.addModules(Arrays.asList("m1x", "m2x"));
+            Assert.check(t.call());
+        }
+    }
 }
 
--- a/langtools/test/tools/javac/modules/AllDefaultTest.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/test/tools/javac/modules/AllDefaultTest.java	Thu Feb 16 18:29:03 2017 +0000
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 0000000
+ * @bug 8164590 8170691
  * @summary Test use of ALL-DEFAULT token
  * @library /tools/lib
  * @modules
--- a/langtools/test/tools/javac/modules/ConvenientAccessErrorsTest.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/test/tools/javac/modules/ConvenientAccessErrorsTest.java	Thu Feb 16 18:29:03 2017 +0000
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8169197 8172668 8173117
+ * @bug 8169197 8172668 8173117 8175007
  * @summary Check convenient errors are produced for inaccessible classes.
  * @library /tools/lib
  * @modules jdk.compiler/com.sun.tools.javac.api
@@ -704,4 +704,44 @@
             throw new Exception("Expected names not generated: " + actual);
         }
     }
+
+    @Test
+    public void testInaccessibleInVisible(Path base) throws Exception {
+        Path src = base.resolve("src");
+        Path src_ma = src.resolve("ma");
+        tb.writeJavaFiles(src_ma,
+                          "module ma { exports ma; }",
+                          "package ma; class NotApi { public static class Inner { } }");
+        Path classes = base.resolve("classes");
+        tb.createDirectories(classes);
+
+        new JavacTask(tb)
+            .outdir(classes)
+            .files(findJavaFiles(src_ma))
+            .run()
+            .writeAll();
+
+        Path src_mb = src.resolve("mb");
+        tb.writeJavaFiles(src_mb,
+                          "module mb { requires ma; }",
+                          "package mb.a; public class Test { ma.NotApi.Inner i1; mb.b.NotApi.Inner i2; }",
+                          "package mb.b; class NotApi { public static class Inner { } }");
+
+        List<String> log = new JavacTask(tb)
+                .options("-XDrawDiagnostics",
+                         "--module-path", classes.toString())
+                .outdir(classes)
+                .files(findJavaFiles(src_mb))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+
+        List<String> expected = Arrays.asList(
+                "Test.java:1:44: compiler.err.not.def.access.class.intf.cant.access: ma.NotApi.Inner, ma.NotApi",
+                "Test.java:1:66: compiler.err.not.def.access.class.intf.cant.access: mb.b.NotApi.Inner, mb.b.NotApi",
+                "2 errors");
+
+        if (!expected.equals(log))
+            throw new Exception("expected output not found; actual: " + log);
+    }
 }
--- a/langtools/test/tools/javac/modules/EnvVarTest.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/test/tools/javac/modules/EnvVarTest.java	Thu Feb 16 18:29:03 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8156962
- * @summary Tests use of _JAVAC_OPTIONS env variable
+ * @summary Tests use of JDK_JAVAC_OPTIONS env variable
  * @library /tools/lib
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.main
@@ -71,7 +71,7 @@
 
         tb.out.println("test that addExports can be provided with env variable");
         new JavacTask(tb, Mode.EXEC)
-                .envVar("_JAVAC_OPTIONS", "--add-exports jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED")
+                .envVar("JDK_JAVAC_OPTIONS", "--add-exports jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED")
                 .outdir(classes)
                 .files(findJavaFiles(src))
                 .run(Expect.SUCCESS)
@@ -83,7 +83,7 @@
                 "--add-exports jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED");
 
         new JavacTask(tb, Mode.EXEC)
-                .envVar("_JAVAC_OPTIONS", "@" + atFile)
+                .envVar("JDK_JAVAC_OPTIONS", "@" + atFile)
                 .outdir(classes)
                 .files(findJavaFiles(src))
                 .run(Expect.SUCCESS)
--- a/langtools/test/tools/javac/modules/InheritRuntimeEnvironmentTest.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/test/tools/javac/modules/InheritRuntimeEnvironmentTest.java	Thu Feb 16 18:29:03 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -238,7 +238,7 @@
                 Arrays.asList("--add-exports", "jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED");
         List<Path> files = Arrays.asList(findJavaFiles(src));
 
-        String envName = "_JAVAC_OPTIONS";
+        String envName = "JDK_JAVAC_OPTIONS";
         String envValue = String.join(" ", testOpts);
 
         out.println("  javac:");
--- a/langtools/test/tools/javac/modules/ModuleInfoTest.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/test/tools/javac/modules/ModuleInfoTest.java	Thu Feb 16 18:29:03 2017 +0000
@@ -557,4 +557,187 @@
                 throw new Exception("expected output not found for: " + moduleInfo + "; actual: " + log);
         }
     }
-}
+
+    @Test
+    public void testMalformedModuleNames(Path base) throws Exception {
+        testMalformedName(base, "m1.package", "module-info.java:1:11: compiler.err.expected: token.identifier");
+        testMalformedName(base, "m1/package", "module-info.java:1:10: compiler.err.expected: '{'");
+        testMalformedName(base, "m1->long", "module-info.java:1:10: compiler.err.expected: '{'");
+        testMalformedName(base, "m1::long", "module-info.java:1:10: compiler.err.expected: '{'");
+        testMalformedName(base, "m1&long", "module-info.java:1:10: compiler.err.expected: '{'");
+        testMalformedName(base, "m1%long", "module-info.java:1:10: compiler.err.expected: '{'");
+        testMalformedName(base, "m1@long", "module-info.java:1:10: compiler.err.expected: '{'");
+        testMalformedName(base, "@m1", "module-info.java:1:7: compiler.err.expected: token.identifier");
+        testMalformedName(base, "!", "module-info.java:1:7: compiler.err.expected: token.identifier");
+        testMalformedName(base, "m1#long", "module-info.java:1:10: compiler.err.illegal.char: #");
+        testMalformedName(base, "m1\\long", "module-info.java:1:10: compiler.err.illegal.char: \\");
+        testMalformedName(base, "module.", "module-info.java:1:15: compiler.err.expected: token.identifier");
+        testMalformedName(base, ".module", "module-info.java:1:7: compiler.err.expected: token.identifier");
+        testMalformedName(base, "1module", "module-info.java:1:7: compiler.err.expected: token.identifier");
+        testMalformedName(base, "module module", "module-info.java:1:14: compiler.err.expected: '{'");
+    }
+
+    private void testMalformedName(Path base, String name, String expected) throws Exception {
+        Path src = base.resolve("src");
+        Path src_m1 = src.resolve("m1");
+        tb.writeJavaFiles(src_m1, "module " + name + " { }");
+
+        Path classes = base.resolve("classes");
+        Files.createDirectories(classes);
+
+        String log = new JavacTask(tb)
+                .options("-XDrawDiagnostics", "--module-source-path", src.toString())
+                .outdir(classes)
+                .files(findJavaFiles(src))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+
+        if (!log.contains(expected))
+            throw new Exception("expected output not found. Name: " + name + " Expected: " + expected);
+    }
+
+    @Test
+    public void testWrongOpensTransitiveFlag(Path base) throws Exception {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src, "module M { opens transitive p1; }",
+                "package p1; public class A { }");
+        String log = new JavacTask(tb)
+                .options("-XDrawDiagnostics")
+                .files(findJavaFiles(src))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+
+        if (!log.contains("module-info.java:1:28: compiler.err.expected: ';'"))
+            throw new Exception("expected output not found");
+    }
+
+    @Test
+    public void testWrongOpensStaticFlag(Path base) throws Exception {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src, "module M { opens static p1; }",
+                "package p1; public class A { }");
+        String log = new JavacTask(tb)
+                .options("-XDrawDiagnostics")
+                .files(findJavaFiles(src))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+
+        if (!log.contains("module-info.java:1:17: compiler.err.expected: token.identifier"))
+            throw new Exception("expected output not found");
+    }
+
+    @Test
+    public void testSeveralOpensDirectives(Path base) throws Exception {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src, "module M { opens opens p1; }",
+                "package p1; public class A { }");
+        String log = new JavacTask(tb)
+                .options("-XDrawDiagnostics")
+                .files(findJavaFiles(src))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+
+        if (!log.contains("module-info.java:1:23: compiler.err.expected: ';'"))
+            throw new Exception("expected output not found");
+    }
+
+    @Test
+    public void testUnknownDirective(Path base) throws Exception {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src, "module M { boolean p1; }",
+                "package p1; public class A { }");
+        String log = new JavacTask(tb)
+                .options("-XDrawDiagnostics")
+                .files(findJavaFiles(src))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+
+        if (!log.contains("module-info.java:1:11: compiler.err.expected: '}'"))
+            throw new Exception("expected output not found");
+    }
+
+    @Test
+    public void testUnknownModuleFlag(Path base) throws Exception {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src, "private module M { }",
+                "package p1; public class A { }");
+        String log = new JavacTask(tb)
+                .options("-XDrawDiagnostics")
+                .files(findJavaFiles(src))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+
+        if (!log.contains("module-info.java:1:9: compiler.err.mod.not.allowed.here: private"))
+            throw new Exception("expected output not found");
+    }
+
+    @Test
+    public void testDirectiveOnModuleDeclaration(Path base) throws Exception {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src, "opens module M { }",
+                "package p1; public class A { }");
+        String log = new JavacTask(tb)
+                .options("-XDrawDiagnostics")
+                .files(findJavaFiles(src))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+
+        if (!log.contains("module-info.java:1:1: compiler.err.expected.module.or.open"))
+            throw new Exception("expected output not found");
+    }
+
+    @Test
+    public void testTooOpenModule(Path base) throws Exception {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src, "open open module M { }",
+                "package p1; public class A { }");
+        String log = new JavacTask(tb)
+                .options("-XDrawDiagnostics")
+                .files(findJavaFiles(src))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+
+        if (!log.contains("module-info.java:1:6: compiler.err.expected.module"))
+            throw new Exception("expected output not found");
+    }
+
+    @Test
+    public void testEnumAsModuleFlag(Path base) throws Exception {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src, "enum module M { }",
+                "package p1; public class A { }");
+        String log = new JavacTask(tb)
+                .options("-XDrawDiagnostics")
+                .files(findJavaFiles(src))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+
+        if (!log.contains("module-info.java:1:12: compiler.err.expected: '{'"))
+            throw new Exception("expected output not found");
+    }
+
+    @Test
+    public void testClassInModule(Path base) throws Exception {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src, "module M { class B { } }",
+                "package p1; public class A { }");
+        String log = new JavacTask(tb)
+                .options("-XDrawDiagnostics")
+                .files(findJavaFiles(src))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+
+        if (!log.contains("module-info.java:1:11: compiler.err.expected: '}'"))
+            throw new Exception("expected output not found");
+    }
+}
\ No newline at end of file
--- a/langtools/test/tools/javac/modules/ProvidesTest.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/test/tools/javac/modules/ProvidesTest.java	Thu Feb 16 18:29:03 2017 +0000
@@ -377,7 +377,7 @@
                 .writeAll()
                 .getOutputLines(Task.OutputKind.DIRECT);
 
-        List<String> expected = Arrays.asList("module-info.java:1:34: compiler.err.not.def.public.cant.access: p2.C2, p2",
+        List<String> expected = Arrays.asList("module-info.java:1:34: compiler.err.not.def.public: p2.C2, p2",
                 "1 error");
         if (!output.containsAll(expected)) {
             throw new Exception("Expected output not found");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/modules/WrongErrorMessageForNestedServiceProviderTest.java	Thu Feb 16 18:29:03 2017 +0000
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2017, 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 8174243
+ * @summary incorrect error message for nested service provider
+ * @library /tools/lib
+ * @modules
+ *      jdk.compiler/com.sun.tools.javac.api
+ *      jdk.compiler/com.sun.tools.javac.main
+ * @build toolbox.ToolBox toolbox.JavacTask ModuleTestBase
+ * @run main WrongErrorMessageForNestedServiceProviderTest
+ */
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
+
+import toolbox.JavacTask;
+import toolbox.Task;
+import toolbox.ToolBox;
+
+public class WrongErrorMessageForNestedServiceProviderTest extends ModuleTestBase {
+    public static void main(String... args) throws Exception {
+        WrongErrorMessageForNestedServiceProviderTest t = new WrongErrorMessageForNestedServiceProviderTest();
+        t.runTests();
+    }
+
+    private static final String twoServicesModuleDef =
+            "module m {\n" +
+            "    exports example;\n" +
+            "    provides example.SomeService with example.ServiceImpl;\n" +
+            "    provides example.SomeServiceOuter with example.Outer.ServiceImplOuter;\n" +
+            "}";
+
+    private static final String someServiceInt =
+            "package example;\n" +
+            "public interface SomeService {\n" +
+            "    public void foo();\n" +
+            "}";
+
+    private static final String someServiceIntOuter =
+            "package example;\n" +
+            "public interface SomeServiceOuter {\n" +
+            "    public void foo();\n" +
+            "}";
+
+    @Test
+    public void testPositive(Path base) throws Exception {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src,
+                twoServicesModuleDef,
+                someServiceInt,
+                someServiceIntOuter,
+                "package example;\n" +
+                "public class ServiceImpl implements example.SomeService {\n" +
+                "    public ServiceImpl() {}\n" +
+                "    public void foo() {}\n" +
+                "}",
+
+                "package example;\n" +
+                "class Outer {\n" +
+                "    public static class ServiceImplOuter implements example.SomeServiceOuter {\n" +
+                "        public ServiceImplOuter() {}\n" +
+                "        public void foo() {}\n" +
+                "    }\n" +
+                "}");
+        Path classes = base.resolve("classes");
+        Files.createDirectories(classes);
+
+        List<String> output = new JavacTask(tb)
+                .outdir(classes)
+                .options("-Werror", "-XDrawDiagnostics")
+                .files(findJavaFiles(src))
+                .run(Task.Expect.SUCCESS)
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+        List<String> expected = Arrays.asList("");
+        if (!output.containsAll(expected)) {
+            throw new Exception("Expected output not found");
+        }
+    }
+
+    @Test
+    public void testNegative(Path base) throws Exception {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src,
+                twoServicesModuleDef,
+                someServiceInt,
+                someServiceIntOuter,
+
+                "package example;\n" +
+                "class ServiceImpl implements example.SomeService {\n" +
+                "    public ServiceImpl() {}\n" +
+                "    public void foo() {}\n" +
+                "}",
+
+                "package example;\n" +
+                "class Outer {\n" +
+                "    static class ServiceImplOuter implements example.SomeServiceOuter {\n" +
+                "        public ServiceImplOuter() {}\n" +
+                "        public void foo() {}\n" +
+                "    }\n" +
+                "}");
+        Path classes = base.resolve("classes");
+        Files.createDirectories(classes);
+
+        List<String> output = new JavacTask(tb)
+                .outdir(classes)
+                .options("-Werror", "-XDrawDiagnostics")
+                .files(findJavaFiles(src))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+        List<String> expected = Arrays.asList(
+                "module-info.java:3:46: compiler.err.not.def.public: example.ServiceImpl, example",
+                "module-info.java:4:57: compiler.err.not.def.public: example.Outer.ServiceImplOuter, example.Outer",
+                "2 errors");
+        if (!output.containsAll(expected)) {
+            throw new Exception("Expected output not found");
+        }
+    }
+
+    @Test
+    public void testClassWrappedByPrivateClass(Path base) throws Exception {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src,
+                "module m {\n" +
+                "    exports example;\n" +
+                "    provides example.SomeServiceOuter with example.Outer1.Outer2.ServiceImplOuter;\n" +
+                "}",
+
+                someServiceIntOuter,
+
+                "package example;\n" +
+                "class Outer1 {\n" +
+                "    static private class Outer2 {\n" +
+                "        public static class ServiceImplOuter implements example.SomeServiceOuter {\n" +
+                "            public ServiceImplOuter() {}\n" +
+                "            public void foo() {}\n" +
+                "        }\n" +
+                "    }\n" +
+                "}");
+        Path classes = base.resolve("classes");
+        Files.createDirectories(classes);
+
+        List<String> output = new JavacTask(tb)
+                .outdir(classes)
+                .options("-Werror", "-XDrawDiagnostics")
+                .files(findJavaFiles(src))
+                .run(Task.Expect.SUCCESS)
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+        List<String> expected = Arrays.asList("");
+        if (!output.containsAll(expected)) {
+            throw new Exception("Expected output not found");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/util/elements/TestAllFoos.java	Thu Feb 16 18:29:03 2017 +0000
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2017, 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 8173945
+ * @summary Test Elements.getAll{Type, Package, Module}Elements
+ * @library /tools/javac/lib
+ * @modules java.compiler
+ *          jdk.compiler
+ * @build   JavacTestingAbstractProcessor TestAllFoos
+ * @compile -processor TestAllFoos -proc:only --release 8 --source-path modules/m1/pkg  modules/m1/pkg/C.java
+ * @compile -processor TestAllFoos -proc:only --release 8 --source-path modules/m2/pkg  modules/m2/pkg/C.java
+ */
+// @compile -processor TestAllFoos -proc:only             --module-source-path  modules -m m1,m2
+
+import java.util.Set;
+import static java.util.Objects.*;
+import javax.annotation.processing.*;
+import static javax.lang.model.SourceVersion.*;
+import javax.lang.model.element.*;
+import javax.lang.model.util.*;
+
+/**
+ * Test basic workings of Elements.getAll{Type, Package, Module}Elements under
+ * pre- and post-modules.
+ */
+public class TestAllFoos extends JavacTestingAbstractProcessor {
+    public boolean process(Set<? extends TypeElement> annotations,
+                           RoundEnvironment roundEnv) {
+        if (!roundEnv.processingOver()) {
+            boolean expectModules =
+                (processingEnv.getSourceVersion().compareTo(RELEASE_9) >= 0);
+
+            testSetSize(eltUtils.getAllTypeElements("java.lang.String"), 1);
+            testSetSize(eltUtils.getAllTypeElements("example.com"), 0);
+
+            if (!expectModules) {
+                // Expect empty modules set, single package named "pkg" with one type "pkg.C".
+                testSetSize(eltUtils.getAllModuleElements(), 0);
+                testSetSize(eltUtils.getAllPackageElements("pkg"), 1);
+                testSetSize(eltUtils.getAllTypeElements("pkg.C"),  1);
+            } else {
+                Set<? extends ModuleElement> modules =
+                    requireNonNull(eltUtils.getAllModuleElements());
+
+                ModuleElement m1 = requireNonNull(eltUtils.getModuleElement("m1"));
+                ModuleElement m2 = requireNonNull(eltUtils.getModuleElement("m2"));
+
+                if (!modules.contains(m1) ||
+                    !modules.contains(m2) ||
+                    !modules.contains(requireNonNull(eltUtils.getModuleElement("java.base"))))
+                    throw new RuntimeException("Missing modules " + modules);
+
+                // Expect two packages named "pkg" and two types named "pkg.C".
+                testSetSize(eltUtils.getAllPackageElements("pkg"), 2);
+                testSetSize(eltUtils.getAllTypeElements("pkg.C"),  2);
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Check the set argument against null and throw an exception if
+     * the set is not of the expected size.
+     */
+    private static <E> Set<E> testSetSize(Set<E> set, int expectedSize) {
+        requireNonNull(set);
+        if (set.size() != expectedSize)
+            throw new RuntimeException("Unexpected size of set " + set);
+        return set;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/util/elements/modules/m1/module-info.java	Thu Feb 16 18:29:03 2017 +0000
@@ -0,0 +1,4 @@
+/* /nodynamiccopyright/ */
+
+module m1 {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/util/elements/modules/m1/pkg/C.java	Thu Feb 16 18:29:03 2017 +0000
@@ -0,0 +1,11 @@
+/* /nodynamiccopyright/ */
+
+package pkg;
+
+/**
+ * A lovely description of class C of package pkg in module m1.
+ */
+public class C {
+    public C() {}
+    public static String foo() {return "foo";}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/util/elements/modules/m1/pkg/package-info.java	Thu Feb 16 18:29:03 2017 +0000
@@ -0,0 +1,6 @@
+/* /nodynamiccopyright/ */
+
+/**
+ * A lovely description of package pkg in module m1.
+ */
+package pkg;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/util/elements/modules/m2/module-info.java	Thu Feb 16 18:29:03 2017 +0000
@@ -0,0 +1,4 @@
+/* /nodynamiccopyright/ */
+
+module m2 {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/util/elements/modules/m2/pkg/C.java	Thu Feb 16 18:29:03 2017 +0000
@@ -0,0 +1,11 @@
+/* /nodynamiccopyright/ */
+
+package pkg;
+
+/**
+ * A lovely description of class C of package pkg in module m2.
+ */
+public class C {
+    public C() {}
+    public static String bar() {return "bar";}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/util/elements/modules/m2/pkg/package-info.java	Thu Feb 16 18:29:03 2017 +0000
@@ -0,0 +1,6 @@
+/* /nodynamiccopyright/ */
+
+/**
+ * A lovely description of package pkg in module m2.
+ */
+package pkg;
--- a/langtools/test/tools/javac/tree/JavacTreeScannerTest.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/test/tools/javac/tree/JavacTreeScannerTest.java	Thu Feb 16 18:29:03 2017 +0000
@@ -41,7 +41,7 @@
  *          jdk.compiler/com.sun.tools.javac.tree
  *          jdk.compiler/com.sun.tools.javac.util
  * @build AbstractTreeScannerTest JavacTreeScannerTest
- * @run main JavacTreeScannerTest -q -r .
+ * @run main/othervm JavacTreeScannerTest -q -r .
  */
 
 import java.io.*;
--- a/langtools/test/tools/javac/tree/SourceTreeScannerTest.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/test/tools/javac/tree/SourceTreeScannerTest.java	Thu Feb 16 18:29:03 2017 +0000
@@ -41,7 +41,7 @@
  *          jdk.compiler/com.sun.tools.javac.tree
  *          jdk.compiler/com.sun.tools.javac.util
  * @build AbstractTreeScannerTest SourceTreeScannerTest
- * @run main SourceTreeScannerTest -q -r .
+ * @run main/othervm SourceTreeScannerTest -q -r .
  */
 
 import java.io.*;
--- a/langtools/test/tools/javac/tree/TreePosTest.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/test/tools/javac/tree/TreePosTest.java	Thu Feb 16 18:29:03 2017 +0000
@@ -108,7 +108,7 @@
  *          jdk.compiler/com.sun.tools.javac.file
  *          jdk.compiler/com.sun.tools.javac.tree
  *          jdk.compiler/com.sun.tools.javac.util
- * @run main TreePosTest -q -r .
+ * @run main/othervm TreePosTest -q -r .
  */
 public class TreePosTest {
     /**
--- a/langtools/test/tools/javac/varargs/7043922/T7043922.java	Thu Feb 16 17:13:01 2017 +0000
+++ b/langtools/test/tools/javac/varargs/7043922/T7043922.java	Thu Feb 16 18:29:03 2017 +0000
@@ -28,6 +28,7 @@
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.file
  *          jdk.compiler/com.sun.tools.javac.util
+ * @run main/othervm T7043922
  */
 
 import com.sun.source.util.JavacTask;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/jdeps/modules/DotFileTest.java	Thu Feb 16 18:29:03 2017 +0000
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2017, 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 8173374
+ * @summary Tests module dot graph
+ * @modules java.desktop
+ *          java.sql
+ *          jdk.jdeps/com.sun.tools.jdeps
+ * @run testng DotFileTest
+ */
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Set;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.spi.ToolProvider;
+import java.util.stream.Collectors;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertEquals;
+
+public class DotFileTest {
+    private static final ToolProvider JDEPS = ToolProvider.findFirst("jdeps")
+        .orElseThrow(() -> new RuntimeException("jdeps not found"));
+
+    private static final Path DOTS_DIR = Paths.get("dots");
+    private static final Path SPEC_DIR = Paths.get("spec");
+
+    @DataProvider(name = "modules")
+    public Object[][] modules() {
+        return new Object[][]{
+            {"java.desktop", Set.of("java.datatransfer -> java.base",
+                                    "java.desktop -> java.datatransfer",
+                                    "java.desktop -> java.prefs",
+                                    "java.prefs -> java.xml",
+                                    "java.xml -> java.base" )
+            },
+            { "java.sql",    Set.of("java.logging -> java.base",
+                                    "java.sql -> java.logging",
+                                    "java.sql -> java.xml",
+                                    "java.xml -> java.base" )
+            }
+        };
+    }
+    @DataProvider(name = "specVersion")
+    public Object[][] specVersion() {
+        return new Object[][]{
+            {"java.desktop", Set.of("java.datatransfer -> java.base",
+                                    "java.desktop -> java.datatransfer",
+                                    "java.desktop -> java.xml",
+                                    "java.xml -> java.base")
+            },
+            { "java.sql",    Set.of("java.logging -> java.base",
+                                    "java.sql -> java.logging",
+                                    "java.sql -> java.xml",
+                                    "java.xml -> java.base" )
+            }
+        };
+    }
+
+    @Test(dataProvider = "modules")
+    public void test(String name, Set<String> edges) throws Exception {
+        String[] options = new String[] {
+            "-dotoutput", DOTS_DIR.toString(),
+            "-s", "-m", name
+        };
+        assertTrue(JDEPS.run(System.out, System.out, options) == 0);
+
+        Path path = DOTS_DIR.resolve(name + ".dot");
+        assertTrue(Files.exists(path));
+        Set<String> lines = Files.readAllLines(path).stream()
+                                 .filter(l -> l.contains(" -> "))
+                                 .map(this::split)
+                                 .collect(Collectors.toSet());
+        assertEquals(lines, edges);
+    }
+
+    @Test(dataProvider = "specVersion")
+    public void testAPIOnly(String name, Set<String> edges) throws Exception {
+        String[] options = new String[]{
+            "-dotoutput", SPEC_DIR.toString(),
+            "-s", "-apionly",
+            "-m", name
+        };
+        assertTrue(JDEPS.run(System.out, System.out, options) == 0);
+
+        Path path = SPEC_DIR.resolve(name + ".dot");
+        assertTrue(Files.exists(path));
+        Set<String> lines = Files.readAllLines(path).stream()
+                                 .filter(l -> l.contains(" -> "))
+                                 .map(this::split)
+                                 .collect(Collectors.toSet());
+        assertEquals(lines, edges);
+    }
+
+    static Pattern PATTERN = Pattern.compile(" *\"(\\S+)\" -> \"(\\S+)\" .*");
+    String split(String line) {
+        Matcher pm = PATTERN.matcher(line);
+        assertTrue(pm.find());
+        return String.format("%s -> %s", pm.group(1), pm.group(2));
+    }
+}