Merge
authorlana
Wed, 23 Nov 2016 19:15:26 +0000
changeset 42274 0399970337fa
parent 42257 43104fb390fd (current diff)
parent 42273 ee07db0e65a3 (diff)
child 42275 f013dc075d67
Merge
langtools/test/tools/javac/diags/examples/BadNameForOption.java
--- a/langtools/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileManager.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileManager.java	Wed Nov 23 19:15:26 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -165,12 +165,12 @@
         fileManager.close();
     }
 
-    public Location getModuleLocation(Location location, String moduleName) throws IOException {
-        return fileManager.getModuleLocation(location, moduleName);
+    public Location getLocationForModule(Location location, String moduleName) throws IOException {
+        return fileManager.getLocationForModule(location, moduleName);
     }
 
-    public Location getModuleLocation(Location location, JavaFileObject fo, String pkgName) throws IOException {
-        return fileManager.getModuleLocation(location, fo, pkgName);
+    public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
+        return fileManager.getLocationForModule(location, fo, pkgName);
     }
 
     public <S> ServiceLoader<S> getServiceLoader(Location location, Class<S> service) throws  IOException {
@@ -181,7 +181,7 @@
         return fileManager.inferModuleName(location);
     }
 
-    public Iterable<Set<Location>> listModuleLocations(Location location) throws IOException {
-        return fileManager.listModuleLocations(location);
+    public Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
+        return fileManager.listLocationsForModules(location);
     }
 }
--- a/langtools/src/java.compiler/share/classes/javax/tools/JavaFileManager.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/java.compiler/share/classes/javax/tools/JavaFileManager.java	Wed Nov 23 19:15:26 2016 +0000
@@ -109,6 +109,28 @@
     /**
      * Interface for locations of file objects.  Used by file managers
      * to determine where to place or search for file objects.
+     *
+     * <p>Informally, a {@code Location} corresponds to a "search path", such as a class
+     * path or module path, as used by command-line tools that use the default file system.
+     *
+     * <p>Some locations are typically used to identify a place in which
+     * a tool can find files to be read; others are typically used to identify
+     * a place where a tool can write files. If a location is used to identify
+     * a place for reading files, those files may be organized in a simple
+     * <em>package/class</em> hierarchy: such locations are described as
+     * <strong>package-oriented</strong>.
+     * Alternatively, the files may be organized in a <em>module/package/class</em>
+     * hierarchy: such locations are described as <strong>module-oriented</strong>.
+     * If a location is typically used to identify a place where a tool can write files,
+     * it is up to the tool that writes the files to specify how those files will be
+     * organized.
+     *
+     * <p>You can access the classes in a package-oriented location using methods like
+     * {@link JavaFileManager#getJavaFileForInput} or {@link JavaFileManager#list}.
+     * 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}.
      */
     interface Location {
         /**
@@ -119,30 +141,41 @@
         String getName();
 
         /**
-         * Determines if this is an output location.  An output
-         * location is a location that is conventionally used for
+         * Determines if this is an output location.
+         * An output location is a location that is conventionally used for
          * output.
          *
+         * @apiNote An output location may be used to write files in either
+         * a package-oriented organization or in a module-oriented organization.
+         *
          * @return true if this is an output location, false otherwise
          */
         boolean isOutputLocation();
 
         /**
-         * Indicates if this location is expected to contain modules,
-         * as compared to a location which contains packages and classes.
+         * Indicates if this location is module-oriented location, and therefore
+         * expected to contain classes in a <em>module/package/class</em>
+         * hierarchy, as compared to a package-oriented location, which
+         * is expected to contain classes in a <em>package/class</em> hierarchy.
+         * The result of this method is undefined if this is an output
+         * location.
+         *
+         * @implNote This implementation returns true if the name includes
+         * the word "MODULE".
          *
          * @return true if this location is expected to contain modules
          * @since 9
          */
-        default boolean isModuleLocation() {
-            return false;
+        default boolean isModuleOrientedLocation() {
+            return getName().matches("\\bMODULE\\b");
         }
     }
 
     /**
      * Returns a class loader for loading plug-ins from the given
-     * location.  For example, to load annotation processors, a
-     * compiler will request a class loader for the {@link
+     * package-oriented location.
+     * For example, to load annotation processors,
+     * a compiler will request a class loader for the {@link
      * StandardLocation#ANNOTATION_PROCESSOR_PATH
      * ANNOTATION_PROCESSOR_PATH} location.
      *
@@ -154,13 +187,14 @@
      * in the current security context
      * @throws IllegalStateException if {@link #close} has been called
      * and this file manager cannot be reopened
+     * @throws IllegalArgumentException if the location is a module-oriented location
      */
     ClassLoader getClassLoader(Location location);
 
     /**
      * Lists all file objects matching the given criteria in the given
-     * location.  List file objects in "subpackages" if recurse is
-     * true.
+     * package-oriented location.
+     * List file objects in "subpackages" if recurse is true.
      *
      * <p>Note: even if the given location is unknown to this file
      * manager, it may not return {@code null}.  Also, an unknown
@@ -174,6 +208,7 @@
      * @throws IOException if an I/O error occurred, or if {@link
      * #close} has been called and this file manager cannot be
      * reopened
+     * @throws IllegalArgumentException if the location is a module-oriented location
      * @throws IllegalStateException if {@link #close} has been called
      * and this file manager cannot be reopened
      */
@@ -184,14 +219,15 @@
         throws IOException;
 
     /**
-     * Infers a binary name of a file object based on a location.  The
-     * binary name returned might not be a valid binary name according to
+     * Infers a binary name of a file object based on a package-oriented location.
+     * The binary name returned might not be a valid binary name according to
      * <cite>The Java&trade; Language Specification</cite>.
      *
      * @param location a location
      * @param file a file object
      * @return a binary name or {@code null} the file object is not
      * found in the given location
+     * @throws IllegalArgumentException if the location is a module-oriented location
      * @throws IllegalStateException if {@link #close} has been called
      * and this file manager cannot be reopened
      */
@@ -239,7 +275,7 @@
     /**
      * Returns a {@linkplain JavaFileObject file object} for input
      * representing the specified class of the specified kind in the
-     * given location.
+     * given package-oriented location.
      *
      * @param location a location
      * @param className the name of a class
@@ -250,7 +286,8 @@
      * file does not exist
      * @throws IllegalArgumentException if the location is not known
      * to this file manager and the file manager does not support
-     * unknown locations, or if the kind is not valid
+     * unknown locations, or if the kind is not valid, or if the
+     * location is a module-oriented location
      * @throws IOException if an I/O error occurred, or if {@link
      * #close} has been called and this file manager cannot be
      * reopened
@@ -265,7 +302,7 @@
     /**
      * Returns a {@linkplain JavaFileObject file object} for output
      * representing the specified class of the specified kind in the
-     * given location.
+     * given package-oriented location.
      *
      * <p>Optionally, this file manager might consider the sibling as
      * a hint for where to place the output.  The exact semantics of
@@ -276,7 +313,7 @@
      * the originating source file as sibling when calling this
      * method.
      *
-     * @param location a location
+     * @param location a package-oriented location
      * @param className the name of a class
      * @param kind the kind of file, must be one of {@link
      * JavaFileObject.Kind#SOURCE SOURCE} or {@link
@@ -287,7 +324,8 @@
      * @throws IllegalArgumentException if sibling is not known to
      * this file manager, or if the location is not known to this file
      * manager and the file manager does not support unknown
-     * locations, or if the kind is not valid
+     * locations, or if the kind is not valid, or if the location is
+     * not an output location
      * @throws IOException if an I/O error occurred, or if {@link
      * #close} has been called and this file manager cannot be
      * reopened
@@ -303,7 +341,7 @@
     /**
      * Returns a {@linkplain FileObject file object} for input
      * representing the specified <a href="JavaFileManager.html#relative_name">relative
-     * name</a> in the specified package in the given location.
+     * name</a> in the specified package in the given package-oriented location.
      *
      * <p>If the returned object represents a {@linkplain
      * JavaFileObject.Kind#SOURCE source} or {@linkplain
@@ -325,14 +363,15 @@
      * a valid result would be a file object representing the file
      * <code>"C:\Documents&nbsp;and&nbsp;Settings\UncleBob\src\share\classes\com\sun\tools\javac\resources\compiler.properties"</code>.
      *
-     * @param location a location
+     * @param location a package-oriented location
      * @param packageName a package name
      * @param relativeName a relative name
      * @return a file object, might return {@code null} if the file
      * does not exist
      * @throws IllegalArgumentException if the location is not known
      * to this file manager and the file manager does not support
-     * unknown locations, or if {@code relativeName} is not valid
+     * unknown locations, or if {@code relativeName} is not valid,
+     * or if the location is a module-oriented location
      * @throws IOException if an I/O error occurred, or if {@link
      * #close} has been called and this file manager cannot be
      * reopened
@@ -368,7 +407,7 @@
      * relative name or next to the sibling argument.  See {@link
      * #getFileForInput getFileForInput} for an example.
      *
-     * @param location a location
+     * @param location an output location
      * @param packageName a package name
      * @param relativeName a relative name
      * @param sibling a file object to be used as hint for placement;
@@ -377,7 +416,8 @@
      * @throws IllegalArgumentException if sibling is not known to
      * this file manager, or if the location is not known to this file
      * manager and the file manager does not support unknown
-     * locations, or if {@code relativeName} is not valid
+     * locations, or if {@code relativeName} is not valid,
+     * or if the location is not an output location
      * @throws IOException if an I/O error occurred, or if {@link
      * #close} has been called and this file manager cannot be
      * reopened
@@ -416,7 +456,12 @@
     void close() throws IOException;
 
     /**
-     * Gets a location for a named module within a module-oriented location.
+     * Gets a location for a named module within a location, which may be either
+     * a module-oriented location or an output location.
+     * The result will be an output location if the given location is
+     * an output location, or it will be a package-oriented location.
+     *
+     * @implSpec This implementation throws {@code UnsupportedOperationException}.
      *
      * @param location the module-oriented location
      * @param moduleName the name of the module to be found
@@ -424,33 +469,49 @@
      *
      * @throws IOException if an I/O error occurred
      * @throws UnsupportedOperationException if this operation if not supported by this file manager
+     * @throws IllegalArgumentException if the location is neither an output location nor a
+     * module-oriented location
      * @since 9
      */ // TODO: describe failure modes
-    default Location getModuleLocation(Location location, String moduleName) throws IOException {
+    default Location getLocationForModule(Location location, String moduleName) throws IOException {
         throw new UnsupportedOperationException();
     }
 
     /**
      * Gets a location for the module containing a specific file representing a Java
-     * source or class.
+     * source or class, to be found in a module-oriented location.
+     * The result will be a package-oriented location.
      *
-     * @param location a module-oriented location
+     * @apiNote the package name is used to identify the position of the file object
+     * within the <em>module/package/class</em> hierarchy identified by by the location.
+     *
+     * @implSpec This implementation throws {@code UnsupportedOperationException}.
+     *
+     * @param location the module-oriented location
      * @param fo the file
      * @param pkgName the package name for the class(es) defined in this file
      * @return the module containing the file
      *
      * @throws IOException if an I/O error occurred
      * @throws UnsupportedOperationException if this operation if not supported by this file manager
+     * @throws IllegalArgumentException if the location is not a module-oriented location
      * @since 9
-     */ // TODO: describe failure modes
-    default Location getModuleLocation(Location location, JavaFileObject fo, String pkgName) throws IOException {
+     */
+    default Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
         throw new UnsupportedOperationException();
     }
 
     /**
      * Get a service loader for a specific service class from a given location.
      *
-     * @param location the location
+     * If the location is a module-oriented location, the service loader will use the
+     * service declarations in the modules found in that location. Otherwise, a service loader
+     * is created using the package-oriented location, in which case, the services are
+     * determined using the provider-configuration files in {@code META-INF/services}.
+     *
+     * @implSpec This implementation throws {@code UnsupportedOperationException}.
+     *
+     * @param location the module-oriented location
      * @param service  the {@code Class} object of the service class
      * @param <S> the service class
      * @return a service loader for the given service class
@@ -465,13 +526,16 @@
 
     /**
      * Infer the name of the module from its location, as returned by
-     * getModuleLocation or listModuleLocations.
+     * {@code getLocationForModule} or {@code listModuleLocations}.
      *
-     * @param location a location representing a module
+     * @implSpec This implementation throws {@code UnsupportedOperationException}.
+     *
+     * @param location a package-oriented location representing a module
      * @return the name of the module
      *
      * @throws IOException if an I/O error occurred
      * @throws UnsupportedOperationException if this operation if not supported by this file manager
+     * @throws IllegalArgumentException if the location is not one known to this file manager
      * @since 9
      */ // TODO: describe failure modes
     default String inferModuleName(Location location) throws IOException {
@@ -479,16 +543,20 @@
     }
 
     /**
-     * Lists the modules in a module-oriented location.
+     * Lists the locations for all the modules in a module-oriented location.
+     * The locations that are returned will be package-oriented locations.
      *
-     * @param location  the location for which to list the modules
+     * @implSpec This implementation throws {@code UnsupportedOperationException}.
+     *
+     * @param location  the module-oriented location for which to list the modules
      * @return  a series of sets of locations containing modules
      *
      * @throws IOException if an I/O error occurred
      * @throws UnsupportedOperationException if this operation if not supported by this file manager
+     * @throws IllegalArgumentException if the location is not a module-oriented location
      * @since 9
      */ // TODO: describe failure modes
-    default Iterable<Set<Location>> listModuleLocations(Location location) throws IOException {
+    default Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
         throw new UnsupportedOperationException();
     }
 
--- a/langtools/src/java.compiler/share/classes/javax/tools/StandardLocation.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/java.compiler/share/classes/javax/tools/StandardLocation.java	Wed Nov 23 19:15:26 2016 +0000
@@ -109,7 +109,9 @@
      * property must hold: {@code locationFor(x) ==
      * locationFor(y)} if and only if {@code x.equals(y)}.
      * The returned location will be an output location if and only if
-     * name ends with {@code "_OUTPUT"}.
+     * name ends with {@code "_OUTPUT"}. It will be considered to
+     * be a module-oriented location if the name contains the word
+     * {@code "MODULE"}.
      *
      * @param name a name
      * @return a location
@@ -149,7 +151,7 @@
     }
 
     @Override
-    public boolean isModuleLocation() {
+    public boolean isModuleOrientedLocation() {
         switch (this) {
             case MODULE_SOURCE_PATH:
             case ANNOTATION_PROCESSOR_MODULE_PATH:
--- a/langtools/src/java.compiler/share/classes/javax/tools/ToolProvider.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/java.compiler/share/classes/javax/tools/ToolProvider.java	Wed Nov 23 19:15:26 2016 +0000
@@ -57,7 +57,7 @@
      * {@code null} if no compiler is provided
      * @implNote This implementation returns the compiler provided
      * by the {@code jdk.compiler} module if that module is available,
-     * and null otherwise.
+     * and {@code null} otherwise.
      */
     public static JavaCompiler getSystemJavaCompiler() {
         return getSystemTool(JavaCompiler.class,
@@ -78,7 +78,7 @@
      * {@code null} if no documentation tool is provided
      * @implNote This implementation returns the tool provided
      * by the {@code jdk.javadoc} module if that module is available,
-     * and null otherwise.
+     * and {@code null} otherwise.
      */
     public static DocumentationTool getSystemDocumentationTool() {
         return getSystemTool(DocumentationTool.class,
@@ -86,16 +86,19 @@
     }
 
     /**
-     * Returns the class loader for tools provided with this platform.
-     * This does not include user-installed tools.  Use the
-     * {@linkplain java.util.ServiceLoader service provider mechanism}
-     * for locating user installed tools.
-     *
-     * @return the class loader for tools provided with this platform
-     * or {@code null} if no tools are provided
+     * Returns a class loader that may be used to load system tools,
+     * or {@code null} if no such special loader is provided.
+     * @implSpec This implementation always returns {@code null}.
+     * @deprecated This method is subject to removal in a future version of
+     * Java SE.
+     * Use the {@link java.util.spi.ToolProvider system tool provider} or
+     * {@link java.util.ServiceLoader service loader} mechanisms to
+     * locate system tools as well as user-installed tools.
+     * @return a class loader, or {@code null}
      */
+    @Deprecated
     public static ClassLoader getSystemToolClassLoader() {
-        return ClassLoader.getSystemClassLoader();
+        return null;
     }
 
     private static final boolean useLegacy;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java	Wed Nov 23 19:15:26 2016 +0000
@@ -348,9 +348,9 @@
         }
 
         @Override @DefinedBy(Api.COMPILER)
-        public Location getModuleLocation(Location location, String moduleName) throws IOException {
+        public Location getLocationForModule(Location location, String moduleName) throws IOException {
             try {
-                return clientJavaFileManager.getModuleLocation(location, moduleName);
+                return clientJavaFileManager.getLocationForModule(location, moduleName);
             } catch (ClientCodeException e) {
                 throw e;
             } catch (RuntimeException | Error e) {
@@ -359,9 +359,9 @@
         }
 
         @Override @DefinedBy(Api.COMPILER)
-        public Location getModuleLocation(Location location, JavaFileObject fo, String pkgName) throws IOException {
+        public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
             try {
-                return clientJavaFileManager.getModuleLocation(location, fo, pkgName);
+                return clientJavaFileManager.getLocationForModule(location, fo, pkgName);
             } catch (ClientCodeException e) {
                 throw e;
             } catch (RuntimeException | Error e) {
@@ -381,9 +381,9 @@
         }
 
         @Override @DefinedBy(Api.COMPILER)
-        public Iterable<Set<Location>> listModuleLocations(Location location) throws IOException {
+        public Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
             try {
-                return clientJavaFileManager.listModuleLocations(location);
+                return clientJavaFileManager.listLocationsForModules(location);
             } catch (ClientCodeException e) {
                 throw e;
             } catch (RuntimeException | Error e) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ModuleFinder.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ModuleFinder.java	Wed Nov 23 19:15:26 2016 +0000
@@ -131,7 +131,7 @@
                     if (outerIter.hasNext()) {
                         outer = outerIter.next();
                         try {
-                            innerIter = fileManager.listModuleLocations(outer).iterator();
+                            innerIter = fileManager.listLocationsForModules(outer).iterator();
                         } catch (IOException e) {
                             System.err.println("error listing module locations for " + outer + ": " + e);  // FIXME
                         }
@@ -282,7 +282,7 @@
                         if (moduleLocationIterator.outer == StandardLocation.MODULE_SOURCE_PATH) {
                             msym.sourceLocation = l;
                             if (fileManager.hasLocation(StandardLocation.CLASS_OUTPUT)) {
-                                msym.classLocation = fileManager.getModuleLocation(StandardLocation.CLASS_OUTPUT, msym.name.toString());
+                                msym.classLocation = fileManager.getLocationForModule(StandardLocation.CLASS_OUTPUT, msym.name.toString());
                             }
                         } else {
                             msym.classLocation = l;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Wed Nov 23 19:15:26 2016 +0000
@@ -364,7 +364,7 @@
                         if (msym.sourceLocation == null) {
                             msym.sourceLocation = locn;
                             if (fileManager.hasLocation(StandardLocation.CLASS_OUTPUT)) {
-                                msym.classLocation = fileManager.getModuleLocation(
+                                msym.classLocation = fileManager.getLocationForModule(
                                         StandardLocation.CLASS_OUTPUT, msym.name.toString());
                             }
                         }
@@ -466,7 +466,7 @@
     private Location getModuleLocation(JavaFileObject fo, Name pkgName) throws IOException {
         // For now, just check module source path.
         // We may want to check source path as well.
-        return fileManager.getModuleLocation(StandardLocation.MODULE_SOURCE_PATH,
+        return fileManager.getLocationForModule(StandardLocation.MODULE_SOURCE_PATH,
                 fo, (pkgName == null) ? null : pkgName.toString());
     }
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileManager.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileManager.java	Wed Nov 23 19:15:26 2016 +0000
@@ -249,8 +249,11 @@
             return false;
         }
 
-        if (!o.handleOption(helper, current, remaining))
-            throw new IllegalArgumentException(current);
+        try {
+            o.handleOption(helper, current, remaining);
+        } catch (Option.InvalidValueException e) {
+            throw new IllegalArgumentException(e.getMessage(), e);
+        }
 
         return true;
     }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Wed Nov 23 19:15:26 2016 +0000
@@ -671,7 +671,7 @@
 
     @Override @DefinedBy(Api.COMPILER)
     public ClassLoader getClassLoader(Location location) {
-        nullCheck(location);
+        checkNotModuleOrientedLocation(location);
         Iterable<? extends File> path = getLocation(location);
         if (path == null)
             return null;
@@ -694,6 +694,7 @@
                                          boolean recurse)
         throws IOException
     {
+        checkNotModuleOrientedLocation(location);
         // validatePackageName(packageName);
         nullCheck(packageName);
         nullCheck(kinds);
@@ -715,8 +716,8 @@
 
     @Override @DefinedBy(Api.COMPILER)
     public String inferBinaryName(Location location, JavaFileObject file) {
+        checkNotModuleOrientedLocation(location);
         Objects.requireNonNull(file);
-        Objects.requireNonNull(location);
         // Need to match the path semantics of list(location, ...)
         Iterable<? extends Path> path = getLocationAsPaths(location);
         if (path == null) {
@@ -750,7 +751,7 @@
                                               JavaFileObject.Kind kind)
         throws IOException
     {
-        nullCheck(location);
+        checkNotModuleOrientedLocation(location);
         // validateClassName(className);
         nullCheck(className);
         nullCheck(kind);
@@ -765,7 +766,7 @@
                                       String relativeName)
         throws IOException
     {
-        nullCheck(location);
+        checkNotModuleOrientedLocation(location);
         // validatePackageName(packageName);
         nullCheck(packageName);
         if (!isRelativeUri(relativeName))
@@ -798,7 +799,7 @@
                                                FileObject sibling)
         throws IOException
     {
-        nullCheck(location);
+        checkOutputLocation(location);
         // validateClassName(className);
         nullCheck(className);
         nullCheck(kind);
@@ -814,7 +815,7 @@
                                        FileObject sibling)
         throws IOException
     {
-        nullCheck(location);
+        checkOutputLocation(location);
         // validatePackageName(packageName);
         nullCheck(packageName);
         if (!isRelativeUri(relativeName))
@@ -948,10 +949,14 @@
     }
 
     @Override @DefinedBy(Api.COMPILER)
-    public Location getModuleLocation(Location location, String moduleName) throws IOException {
-        nullCheck(location);
+    public Location getLocationForModule(Location location, String moduleName) throws IOException {
+        Objects.requireNonNull(location);
+        if (!location.isOutputLocation() && !location.isModuleOrientedLocation())
+            throw new IllegalArgumentException(
+                    "location is not an output location or a module-oriented location: "
+                            + location.getName());
         nullCheck(moduleName);
-        return locations.getModuleLocation(location, moduleName);
+        return locations.getLocationForModule(location, moduleName);
     }
 
     @Override @DefinedBy(Api.COMPILER)
@@ -959,7 +964,7 @@
         nullCheck(location);
         nullCheck(service);
         Module.getModule(getClass()).addUses(service);
-        if (location.isModuleLocation()) {
+        if (location.isModuleOrientedLocation()) {
             Collection<Path> paths = locations.getLocation(location);
             ModuleFinder finder = ModuleFinder.of(paths.toArray(new Path[paths.size()]));
             Layer bootLayer = Layer.boot();
@@ -972,8 +977,8 @@
     }
 
     @Override @DefinedBy(Api.COMPILER)
-    public Location getModuleLocation(Location location, JavaFileObject fo, String pkgName) throws IOException {
-        nullCheck(location);
+    public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
+        checkModuleOrientedLocation(location);
         if (!(fo instanceof PathFileObject))
             throw new IllegalArgumentException(fo.getName());
         int depth = 1; // allow 1 for filename
@@ -993,7 +998,7 @@
             Path subpath = p.subpath(0, fc - depth);
             Path dir = (root == null) ? subpath : root.resolve(subpath);
             // need to find dir in location
-            return locations.getModuleLocation(location, dir);
+            return locations.getLocationForModule(location, dir);
         } else {
             return null;
         }
@@ -1001,14 +1006,14 @@
 
     @Override @DefinedBy(Api.COMPILER)
     public String inferModuleName(Location location) {
-        nullCheck(location);
+        checkNotModuleOrientedLocation(location);
         return locations.inferModuleName(location);
     }
 
     @Override @DefinedBy(Api.COMPILER)
-    public Iterable<Set<Location>> listModuleLocations(Location location) throws IOException {
-        nullCheck(location);
-        return locations.listModuleLocations(location);
+    public Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
+        checkModuleOrientedLocation(location);
+        return locations.listLocationsForModules(location);
     }
 
     @Override @DefinedBy(Api.COMPILER)
@@ -1087,6 +1092,24 @@
         return e.toString();
     }
 
+    private void checkOutputLocation(Location location) {
+        Objects.requireNonNull(location);
+        if (!location.isOutputLocation())
+            throw new IllegalArgumentException("location is not an output location: " + location.getName());
+    }
+
+    private void checkModuleOrientedLocation(Location location) {
+        Objects.requireNonNull(location);
+        if (!location.isModuleOrientedLocation())
+            throw new IllegalArgumentException("location is not module-oriented: " + location.getName());
+    }
+
+    private void checkNotModuleOrientedLocation(Location location) {
+        Objects.requireNonNull(location);
+        if (location.isModuleOrientedLocation())
+            throw new IllegalArgumentException("location is module-oriented: " + location.getName());
+    }
+
     /* Converters between files and paths.
      * These are temporary until we can update the StandardJavaFileManager API.
      */
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java	Wed Nov 23 19:15:26 2016 +0000
@@ -415,16 +415,16 @@
         abstract void setPaths(Iterable<? extends Path> files) throws IOException;
 
         /**
-         * @see JavaFileManager#getModuleLocation(Location, String)
+         * @see JavaFileManager#getLocationForModule(Location, String)
          */
-        Location getModuleLocation(String moduleName) throws IOException {
+        Location getLocationForModule(String moduleName) throws IOException {
             return null;
         }
 
         /**
-         * @see JavaFileManager#getModuleLocation(Location, JavaFileObject, String)
+         * @see JavaFileManager#getLocationForModule(Location, JavaFileObject, String)
          */
-        Location getModuleLocation(Path dir) {
+        Location getLocationForModule(Path dir) {
             return null;
         }
 
@@ -436,9 +436,9 @@
         }
 
         /**
-         * @see JavaFileManager#listModuleLocations
+         * @see JavaFileManager#listLocationsForModules
          */
-        Iterable<Set<Location>> listModuleLocations() throws IOException {
+        Iterable<Set<Location>> listLocationsForModules() throws IOException {
             return null;
         }
     }
@@ -524,7 +524,7 @@
         }
 
         @Override
-        Location getModuleLocation(String name) {
+        Location getLocationForModule(String name) {
             if (moduleLocations == null)
                 moduleLocations = new HashMap<>();
             Location l = moduleLocations.get(name);
@@ -904,7 +904,7 @@
         }
 
         @Override
-        Iterable<Set<Location>> listModuleLocations() {
+        Iterable<Set<Location>> listLocationsForModules() {
             if (searchPath == null)
                 return Collections.emptyList();
 
@@ -1320,17 +1320,17 @@
         }
 
         @Override
-        Location getModuleLocation(String name) {
+        Location getLocationForModule(String name) {
             return (moduleLocations == null) ? null : moduleLocations.get(name);
         }
 
         @Override
-        Location getModuleLocation(Path dir) {
+        Location getLocationForModule(Path dir) {
             return (pathLocations == null) ? null : pathLocations.get(dir);
         }
 
         @Override
-        Iterable<Set<Location>> listModuleLocations() {
+        Iterable<Set<Location>> listLocationsForModules() {
             if (moduleLocations == null)
                 return Collections.emptySet();
             Set<Location> locns = new LinkedHashSet<>();
@@ -1411,13 +1411,13 @@
         }
 
         @Override
-        Location getModuleLocation(String name) throws IOException {
+        Location getLocationForModule(String name) throws IOException {
             initSystemModules();
             return systemModules.get(name);
         }
 
         @Override
-        Iterable<Set<Location>> listModuleLocations() throws IOException {
+        Iterable<Set<Location>> listLocationsForModules() throws IOException {
             initSystemModules();
             Set<Location> locns = new LinkedHashSet<>();
             for (Location l: systemModules.values())
@@ -1591,14 +1591,14 @@
         h.setPaths(files);
     }
 
-    Location getModuleLocation(Location location, String name) throws IOException {
+    Location getLocationForModule(Location location, String name) throws IOException {
         LocationHandler h = getHandler(location);
-        return (h == null ? null : h.getModuleLocation(name));
+        return (h == null ? null : h.getLocationForModule(name));
     }
 
-    Location getModuleLocation(Location location, Path dir) {
+    Location getLocationForModule(Location location, Path dir) {
         LocationHandler h = getHandler(location);
-        return (h == null ? null : h.getModuleLocation(dir));
+        return (h == null ? null : h.getLocationForModule(dir));
     }
 
     String inferModuleName(Location location) {
@@ -1606,9 +1606,9 @@
         return (h == null ? null : h.inferModuleName());
     }
 
-    Iterable<Set<Location>> listModuleLocations(Location location) throws IOException {
+    Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
         LocationHandler h = getHandler(location);
-        return (h == null ? null : h.listModuleLocations());
+        return (h == null ? null : h.listLocationsForModules());
     }
 
     protected LocationHandler getHandler(Location location) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Wed Nov 23 19:15:26 2016 +0000
@@ -1626,7 +1626,7 @@
         Location outLocn;
         if (multiModuleMode) {
             ModuleSymbol msym = c.owner.kind == MDL ? (ModuleSymbol) c.owner : c.packge().modle;
-            outLocn = fileManager.getModuleLocation(CLASS_OUTPUT, msym.name.toString());
+            outLocn = fileManager.getLocationForModule(CLASS_OUTPUT, msym.name.toString());
         } else {
             outLocn = CLASS_OUTPUT;
         }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/JNIWriter.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/JNIWriter.java	Wed Nov 23 19:15:26 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -179,7 +179,7 @@
         Location outLocn;
         if (multiModuleMode) {
             ModuleSymbol msym = c.owner.kind == MDL ? (ModuleSymbol) c.owner : c.packge().modle;
-            outLocn = fileManager.getModuleLocation(StandardLocation.NATIVE_HEADER_OUTPUT, msym.name.toString());
+            outLocn = fileManager.getLocationForModule(StandardLocation.NATIVE_HEADER_OUTPUT, msym.name.toString());
         } else {
             outLocn = StandardLocation.NATIVE_HEADER_OUTPUT;
         }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java	Wed Nov 23 19:15:26 2016 +0000
@@ -161,16 +161,6 @@
         }
 
         @Override
-        public void error(String key, Object... args) {
-            Arguments.this.error(key, args);
-        }
-
-        @Override
-        public void error(JCDiagnostic.Error error) {
-            Arguments.this.error(error);
-        }
-
-        @Override
         public void addFile(Path p) {
             files.add(p);
         }
@@ -222,11 +212,6 @@
         }
 
         @Override
-        public void error(String key, Object... args) {
-            Arguments.this.error(key, args);
-        }
-
-        @Override
         public Log getLog() {
             return Arguments.this.log;
         }
@@ -263,6 +248,17 @@
     }
 
     /**
+     * Minimal initialization for tools, like javadoc,
+     * to be able to process javac options for themselves,
+     * and then call validate.
+     * @param ownName  the name of this tool; used to prefix messages
+     */
+    public void init(String ownName) {
+        this.ownName = ownName;
+        errorMode = ErrorMode.LOG;
+    }
+
+    /**
      * Gets the files to be compiled.
      * @return the files to be compiled
      */
@@ -379,7 +375,10 @@
             }
 
             if (option != null) {
-                if (!option.handleOption(helper, arg, argIter)) {
+                try {
+                    option.handleOption(helper, arg, argIter);
+                } catch (Option.InvalidValueException e) {
+                    error(e);
                     return false;
                 }
                 continue;
@@ -416,11 +415,11 @@
                 java.util.List<String> modules = Arrays.asList(options.get(Option.MODULE).split(","));
                 try {
                     for (String module : modules) {
-                        Location sourceLoc = fm.getModuleLocation(StandardLocation.MODULE_SOURCE_PATH, module);
+                        Location sourceLoc = fm.getLocationForModule(StandardLocation.MODULE_SOURCE_PATH, module);
                         if (sourceLoc == null) {
                             log.error(Errors.ModuleNotFoundInModuleSourcePath(module));
                         } else {
-                            Location classLoc = fm.getModuleLocation(StandardLocation.CLASS_OUTPUT, module);
+                            Location classLoc = fm.getLocationForModule(StandardLocation.CLASS_OUTPUT, module);
 
                             for (JavaFileObject file : fm.list(sourceLoc, "", EnumSet.of(JavaFileObject.Kind.SOURCE), true)) {
                                 String className = fm.inferBinaryName(sourceLoc, file);
@@ -446,24 +445,23 @@
             // It is allowed to compile nothing if just asking for help or version info.
             // But also note that none of these options are supported in API mode.
             if (options.isSet(Option.HELP)
-                || options.isSet(Option.X)
-                || options.isSet(Option.VERSION)
-                || options.isSet(Option.FULLVERSION)
-                || options.isSet(Option.MODULE))
-                return true;
-
-            if (emptyAllowed)
+                    || options.isSet(Option.X)
+                    || options.isSet(Option.VERSION)
+                    || options.isSet(Option.FULLVERSION)
+                    || options.isSet(Option.MODULE)) {
                 return true;
-
-            if (!errors) {
-                if (JavaCompiler.explicitAnnotationProcessingRequested(options)) {
-                    error("err.no.source.files.classes");
-                } else {
-                    error("err.no.source.files");
-                }
             }
 
-            return false;
+            if (!emptyAllowed) {
+                if (!errors) {
+                    if (JavaCompiler.explicitAnnotationProcessingRequested(options)) {
+                        error("err.no.source.files.classes");
+                    } else {
+                        error("err.no.source.files");
+                    }
+                }
+                return false;
+            }
         }
 
         if (!checkDirectory(Option.D)) {
@@ -555,7 +553,6 @@
         }
 
         boolean lintOptions = options.isUnset(Option.XLINT_CUSTOM, "-" + LintCategory.OPTIONS.option);
-
         if (lintOptions && source.compareTo(Source.DEFAULT) < 0 && !options.isSet(Option.RELEASE)) {
             if (fm instanceof BaseFileManager) {
                 if (((BaseFileManager) fm).isDefaultBootClassPath())
@@ -710,7 +707,6 @@
             for (String moduleName : addModules.split(",")) {
                 switch (moduleName) {
                     case "":
-                    case "ALL-DEFAULT":
                     case "ALL-SYSTEM":
                     case "ALL-MODULE-PATH":
                         break;
@@ -718,7 +714,7 @@
                     default:
                         if (!SourceVersion.isName(moduleName, sv)) {
                             // syntactically invalid module name:  e.g. --add-modules m1,m!
-                            log.warning(Warnings.BadNameForOption(Option.ADD_MODULES, moduleName));
+                            log.error(Errors.BadNameForOption(Option.ADD_MODULES, moduleName));
                         }
                         break;
                 }
@@ -742,7 +738,7 @@
                     default:
                         if (!SourceVersion.isName(moduleName, sv)) {
                             // syntactically invalid module name:  e.g. --limit-modules m1,m!
-                            log.warning(Warnings.BadNameForOption(Option.LIMIT_MODULES, moduleName));
+                            log.error(Errors.BadNameForOption(Option.LIMIT_MODULES, moduleName));
                         }
                         break;
                 }
@@ -757,7 +753,7 @@
     public boolean isEmpty() {
         return ((files == null) || files.isEmpty())
                 && ((fileObjects == null) || fileObjects.isEmpty())
-                && classNames.isEmpty();
+                && (classNames == null || classNames.isEmpty());
     }
 
     public void allowEmpty() {
@@ -886,6 +882,21 @@
         }
     }
 
+    void error(Option.InvalidValueException f) {
+        String msg = f.getMessage();
+        errors = true;
+        switch (errorMode) {
+            case ILLEGAL_ARGUMENT: {
+                throw new PropagatedException(new IllegalArgumentException(msg, f.getCause()));
+            }
+            case ILLEGAL_STATE: {
+                throw new PropagatedException(new IllegalStateException(msg, f.getCause()));
+            }
+            case LOG:
+                log.printRawLines(ownName + ": " + msg);
+        }
+    }
+
     void warning(String key, Object... args) {
         report(key, args);
     }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java	Wed Nov 23 19:15:26 2016 +0000
@@ -194,7 +194,10 @@
                 @Override
                 public void put(String name, String value) { }
             };
-            Option.HELP.process(h, "-help");
+            try {
+                Option.HELP.process(h, "-help");
+            } catch (Option.InvalidValueException ignore) {
+            }
             return Result.CMDERR;
         }
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java	Wed Nov 23 19:15:26 2016 +0000
@@ -93,9 +93,8 @@
 
     G_NONE("-g:none", "opt.g.none", STANDARD, BASIC) {
         @Override
-        public boolean process(OptionHelper helper, String option) {
+        public void process(OptionHelper helper, String option) {
             helper.put("-g:", "none");
-            return false;
         }
     },
 
@@ -138,11 +137,10 @@
         }
 
         @Override
-        public boolean process(OptionHelper helper, String option) {
+        public void process(OptionHelper helper, String option) {
             String prev = helper.get(XDOCLINT_CUSTOM);
             String next = (prev == null) ? option : (prev + " " + option);
             helper.put(XDOCLINT_CUSTOM.primaryName, next);
-            return false;
         }
     },
 
@@ -154,20 +152,18 @@
         }
 
         @Override
-        public boolean process(OptionHelper helper, String option) {
+        public void process(OptionHelper helper, String option) {
             String prev = helper.get(XDOCLINT_PACKAGE);
             String next = (prev == null) ? option : (prev + " " + option);
             helper.put(XDOCLINT_PACKAGE.primaryName, next);
-            return false;
         }
     },
 
     // -nowarn is retained for command-line backward compatibility
     NOWARN("-nowarn", "opt.nowarn", STANDARD, BASIC) {
         @Override
-        public boolean process(OptionHelper helper, String option) {
+        public void process(OptionHelper helper, String option) {
             helper.put("-Xlint:none", option);
-            return false;
         }
     },
 
@@ -176,9 +172,8 @@
     // -deprecation is retained for command-line backward compatibility
     DEPRECATION("-deprecation", "opt.deprecation", STANDARD, BASIC) {
         @Override
-        public boolean process(OptionHelper helper, String option) {
+        public void process(OptionHelper helper, String option) {
             helper.put("-Xlint:deprecation", option);
-            return false;
         }
     },
 
@@ -201,15 +196,13 @@
         // the the module=path pairs by an invalid path character, NULL.
         // The standard file manager code knows to split apart the NULL-separated components.
         @Override
-        public boolean process(OptionHelper helper, String option, String arg) {
+        public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
             if (arg.isEmpty()) {
-                helper.error("err.no.value.for.option", option);
-                return true;
+                throw helper.newInvalidValueException("err.no.value.for.option", option);
             } else if (getPattern().matcher(arg).matches()) {
                 String prev = helper.get(PATCH_MODULE);
                 if (prev == null) {
                     super.process(helper, option, arg);
-                    return false;
                 } else {
                     String argModulePackage = arg.substring(0, arg.indexOf('='));
                     boolean isRepeated = Arrays.stream(prev.split("\0"))
@@ -217,16 +210,13 @@
                             .collect(Collectors.toSet())
                             .contains(argModulePackage);
                     if (isRepeated) {
-                        helper.error("err.repeated.value.for.patch.module", argModulePackage);
-                        return true;
+                        throw helper.newInvalidValueException("err.repeated.value.for.patch.module", argModulePackage);
                     } else {
                         super.process(helper, option, prev + '\0' + arg);
-                        return false;
                     }
                 }
             } else {
-                helper.error("err.bad.value.for.option", option, arg);
-                return true;
+                throw helper.newInvalidValueException("err.bad.value.for.option", option, arg);
             }
         }
 
@@ -238,10 +228,10 @@
 
     BOOT_CLASS_PATH("--boot-class-path -bootclasspath", "opt.arg.path", "opt.bootclasspath", STANDARD, FILEMANAGER) {
         @Override
-        public boolean process(OptionHelper helper, String option, String arg) {
+        public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
             helper.remove("-Xbootclasspath/p:");
             helper.remove("-Xbootclasspath/a:");
-            return super.process(helper, option, arg);
+            super.process(helper, option, arg);
         }
     },
 
@@ -251,10 +241,10 @@
 
     XBOOTCLASSPATH("-Xbootclasspath:", "opt.arg.path", "opt.bootclasspath", EXTENDED, FILEMANAGER) {
         @Override
-        public boolean process(OptionHelper helper, String option, String arg) {
+        public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
             helper.remove("-Xbootclasspath/p:");
             helper.remove("-Xbootclasspath/a:");
-            return super.process(helper, "-bootclasspath", arg);
+            super.process(helper, "-bootclasspath", arg);
         }
     },
 
@@ -262,8 +252,8 @@
 
     DJAVA_EXT_DIRS("-Djava.ext.dirs=", "opt.arg.dirs", "opt.extdirs", EXTENDED, FILEMANAGER) {
         @Override
-        public boolean process(OptionHelper helper, String option, String arg) {
-            return EXTDIRS.process(helper, "-extdirs", arg);
+        public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
+            EXTDIRS.process(helper, "-extdirs", arg);
         }
     },
 
@@ -271,8 +261,8 @@
 
     DJAVA_ENDORSED_DIRS("-Djava.endorsed.dirs=", "opt.arg.dirs", "opt.endorseddirs", EXTENDED, FILEMANAGER) {
         @Override
-        public boolean process(OptionHelper helper, String option, String arg) {
-            return ENDORSEDDIRS.process(helper, "-endorseddirs", arg);
+        public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
+            ENDORSEDDIRS.process(helper, "-endorseddirs", arg);
         }
     },
 
@@ -298,25 +288,23 @@
 
     SOURCE("-source", "opt.arg.release", "opt.source", STANDARD, BASIC) {
         @Override
-        public boolean process(OptionHelper helper, String option, String operand) {
+        public void process(OptionHelper helper, String option, String operand) throws InvalidValueException {
             Source source = Source.lookup(operand);
             if (source == null) {
-                helper.error("err.invalid.source", operand);
-                return true;
+                throw helper.newInvalidValueException("err.invalid.source", operand);
             }
-            return super.process(helper, option, operand);
+            super.process(helper, option, operand);
         }
     },
 
     TARGET("-target", "opt.arg.release", "opt.target", STANDARD, BASIC) {
         @Override
-        public boolean process(OptionHelper helper, String option, String operand) {
+        public void process(OptionHelper helper, String option, String operand) throws InvalidValueException {
             Target target = Target.lookup(operand);
             if (target == null) {
-                helper.error("err.invalid.target", operand);
-                return true;
+                throw helper.newInvalidValueException("err.invalid.target", operand);
             }
-            return super.process(helper, option, operand);
+            super.process(helper, option, operand);
         }
     },
 
@@ -345,46 +333,45 @@
 
     PROFILE("-profile", "opt.arg.profile", "opt.profile", STANDARD, BASIC) {
         @Override
-        public boolean process(OptionHelper helper, String option, String operand) {
+        public void process(OptionHelper helper, String option, String operand) throws InvalidValueException {
             Profile profile = Profile.lookup(operand);
             if (profile == null) {
-                helper.error("err.invalid.profile", operand);
-                return true;
+                throw helper.newInvalidValueException("err.invalid.profile", operand);
             }
-            return super.process(helper, option, operand);
+            super.process(helper, option, operand);
         }
     },
 
     VERSION("-version", "opt.version", STANDARD, INFO) {
         @Override
-        public boolean process(OptionHelper helper, String option) {
+        public void process(OptionHelper helper, String option) throws InvalidValueException {
             Log log = helper.getLog();
             String ownName = helper.getOwnName();
             log.printLines(WriterKind.STDOUT, PrefixKind.JAVAC, "version", ownName,  JavaCompiler.version());
-            return super.process(helper, option);
+            super.process(helper, option);
         }
     },
 
     FULLVERSION("-fullversion", null, HIDDEN, INFO) {
         @Override
-        public boolean process(OptionHelper helper, String option) {
+        public void process(OptionHelper helper, String option) throws InvalidValueException {
             Log log = helper.getLog();
             String ownName = helper.getOwnName();
             log.printLines(WriterKind.STDOUT, PrefixKind.JAVAC, "fullVersion", ownName,  JavaCompiler.fullVersion());
-            return super.process(helper, option);
+            super.process(helper, option);
         }
     },
 
     // Note: -h is already taken for "native header output directory".
     HELP("--help -help", "opt.help", STANDARD, INFO) {
         @Override
-        public boolean process(OptionHelper helper, String option) {
+        public void process(OptionHelper helper, String option) throws InvalidValueException {
             Log log = helper.getLog();
             String ownName = helper.getOwnName();
             log.printLines(WriterKind.STDOUT, PrefixKind.JAVAC, "msg.usage.header", ownName);
             showHelp(log, OptionKind.STANDARD);
             log.printNewline(WriterKind.STDOUT);
-            return super.process(helper, option);
+            super.process(helper, option);
         }
     },
 
@@ -401,31 +388,28 @@
         // Mapping for processor options created in
         // JavacProcessingEnvironment
         @Override
-        public boolean process(OptionHelper helper, String option) {
+        public void process(OptionHelper helper, String option) throws InvalidValueException {
             int argLength = option.length();
             if (argLength == 2) {
-                helper.error("err.empty.A.argument");
-                return true;
+                throw helper.newInvalidValueException("err.empty.A.argument");
             }
             int sepIndex = option.indexOf('=');
             String key = option.substring(2, (sepIndex != -1 ? sepIndex : argLength) );
             if (!JavacProcessingEnvironment.isValidOptionName(key)) {
-                helper.error("err.invalid.A.key", option);
-                return true;
+                throw helper.newInvalidValueException("err.invalid.A.key", option);
             }
             helper.put(option, option);
-            return false;
         }
     },
 
     X("-X", "opt.X", STANDARD, INFO) {
         @Override
-        public boolean process(OptionHelper helper, String option) {
+        public void process(OptionHelper helper, String option) throws InvalidValueException {
             Log log = helper.getLog();
             showHelp(log, OptionKind.EXTENDED);
             log.printNewline(WriterKind.STDOUT);
             log.printLines(WriterKind.STDOUT, PrefixKind.JAVAC, "msg.usage.nonstandard.footer");
-            return super.process(helper, option);
+            super.process(helper, option);
         }
     },
 
@@ -433,16 +417,16 @@
     // It's actually implemented by the launcher.
     J("-J", "opt.arg.flag", "opt.J", STANDARD, INFO, ArgKind.ADJACENT) {
         @Override
-        public boolean process(OptionHelper helper, String option) {
+        public void process(OptionHelper helper, String option) {
             throw new AssertionError("the -J flag should be caught by the launcher.");
         }
     },
 
     MOREINFO("-moreinfo", null, HIDDEN, BASIC) {
         @Override
-        public boolean process(OptionHelper helper, String option) {
+        public void process(OptionHelper helper, String option) throws InvalidValueException {
             Type.moreInfo = true;
-            return super.process(helper, option);
+            super.process(helper, option);
         }
     },
 
@@ -462,9 +446,8 @@
     // display warnings for generic unchecked operations
     WARNUNCHECKED("-warnunchecked", null, HIDDEN, BASIC) {
         @Override
-        public boolean process(OptionHelper helper, String option) {
+        public void process(OptionHelper helper, String option) {
             helper.put("-Xlint:unchecked", option);
-            return false;
         }
     },
 
@@ -474,15 +457,14 @@
 
     XSTDOUT("-Xstdout", "opt.arg.file", "opt.Xstdout", EXTENDED, INFO) {
         @Override
-        public boolean process(OptionHelper helper, String option, String arg) {
+        public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
             try {
                 Log log = helper.getLog();
                 log.setWriters(new PrintWriter(new FileWriter(arg), true));
             } catch (java.io.IOException e) {
-                helper.error("err.error.writing.file", arg, e);
-                return true;
+                throw helper.newInvalidValueException("err.error.writing.file", arg, e);
             }
-            return super.process(helper, option, arg);
+            super.process(helper, option, arg);
         }
     },
 
@@ -507,11 +489,10 @@
 
     PLUGIN("-Xplugin:", "opt.arg.plugin", "opt.plugin", EXTENDED, BASIC) {
         @Override
-        public boolean process(OptionHelper helper, String option) {
+        public void process(OptionHelper helper, String option) {
             String p = option.substring(option.indexOf(':') + 1).trim();
             String prev = helper.get(PLUGIN);
             helper.put(PLUGIN.primaryName, (prev == null) ? p : prev + '\0' + p);
-            return false;
         }
     },
 
@@ -519,22 +500,22 @@
 
     DEBUG("--debug:", null, HIDDEN, BASIC) {
         @Override
-        public boolean process(OptionHelper helper, String option) {
-            return HiddenGroup.DEBUG.process(helper, option);
+        public void process(OptionHelper helper, String option) throws InvalidValueException {
+            HiddenGroup.DEBUG.process(helper, option);
         }
     },
 
     SHOULDSTOP("--should-stop:", null, HIDDEN, BASIC) {
         @Override
-        public boolean process(OptionHelper helper, String option) {
-            return HiddenGroup.SHOULDSTOP.process(helper, option);
+        public void process(OptionHelper helper, String option) throws InvalidValueException {
+            HiddenGroup.SHOULDSTOP.process(helper, option);
         }
     },
 
     DIAGS("--diags:", null, HIDDEN, BASIC) {
         @Override
-        public boolean process(OptionHelper helper, String option) {
-            return HiddenGroup.DIAGS.process(helper, option);
+        public void process(OptionHelper helper, String option) throws InvalidValueException {
+            HiddenGroup.DIAGS.process(helper, option);
         }
     },
 
@@ -548,33 +529,29 @@
             return s.startsWith(primaryName);
         }
         @Override
-        public boolean process(OptionHelper helper, String option) {
-            return process(helper, option, option.substring(primaryName.length()));
+        public void process(OptionHelper helper, String option) {
+            process(helper, option, option.substring(primaryName.length()));
         }
 
         @Override
-        public boolean process(OptionHelper helper, String option, String arg) {
+        public void process(OptionHelper helper, String option, String arg) {
             int eq = arg.indexOf('=');
             String key = (eq < 0) ? arg : arg.substring(0, eq);
             String value = (eq < 0) ? arg : arg.substring(eq+1);
             helper.put(key, value);
-            return false;
         }
     },
 
     ADD_EXPORTS("--add-exports", "opt.arg.addExports", "opt.addExports", EXTENDED, BASIC) {
         @Override
-        public boolean process(OptionHelper helper, String option, String arg) {
+        public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
             if (arg.isEmpty()) {
-                helper.error("err.no.value.for.option", option);
-                return true;
+                throw helper.newInvalidValueException("err.no.value.for.option", option);
             } else if (getPattern().matcher(arg).matches()) {
                 String prev = helper.get(ADD_EXPORTS);
                 helper.put(ADD_EXPORTS.primaryName, (prev == null) ? arg : prev + '\0' + arg);
-                return false;
             } else {
-                helper.error("err.bad.value.for.option", option, arg);
-                return true;
+                throw helper.newInvalidValueException("err.bad.value.for.option", option, arg);
             }
         }
 
@@ -586,17 +563,14 @@
 
     ADD_READS("--add-reads", "opt.arg.addReads", "opt.addReads", EXTENDED, BASIC) {
         @Override
-        public boolean process(OptionHelper helper, String option, String arg) {
+        public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
             if (arg.isEmpty()) {
-                helper.error("err.no.value.for.option", option);
-                return true;
+                throw helper.newInvalidValueException("err.no.value.for.option", option);
             } else if (getPattern().matcher(arg).matches()) {
                 String prev = helper.get(ADD_READS);
                 helper.put(ADD_READS.primaryName, (prev == null) ? arg : prev + '\0' + arg);
-                return false;
             } else {
-                helper.error("err.bad.value.for.option", option, arg);
-                return true;
+                throw helper.newInvalidValueException("err.bad.value.for.option", option, arg);
             }
         }
 
@@ -608,14 +582,12 @@
 
     XMODULE("-Xmodule:", "opt.arg.module", "opt.module", EXTENDED, BASIC) {
         @Override
-        public boolean process(OptionHelper helper, String option, String arg) {
+        public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
             String prev = helper.get(XMODULE);
             if (prev != null) {
-                helper.error("err.option.too.many", XMODULE.primaryName);
-                return true;
+                throw helper.newInvalidValueException("err.option.too.many", XMODULE.primaryName);
             }
             helper.put(XMODULE.primaryName, arg);
-            return false;
         }
     },
 
@@ -623,19 +595,16 @@
 
     ADD_MODULES("--add-modules", "opt.arg.addmods", "opt.addmods", STANDARD, BASIC) {
         @Override
-        public boolean process(OptionHelper helper, String option, String arg) {
+        public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
             if (arg.isEmpty()) {
-                helper.error("err.no.value.for.option", option);
-                return true;
+                throw helper.newInvalidValueException("err.no.value.for.option", option);
             } else if (getPattern().matcher(arg).matches()) {
                 String prev = helper.get(ADD_MODULES);
                 // since the individual values are simple names, we can simply join the
                 // values of multiple --add-modules options with ','
                 helper.put(ADD_MODULES.primaryName, (prev == null) ? arg : prev + ',' + arg);
-                return false;
             } else {
-                helper.error("err.bad.value.for.option", option, arg);
-                return true;
+                throw helper.newInvalidValueException("err.bad.value.for.option", option, arg);
             }
         }
 
@@ -647,16 +616,13 @@
 
     LIMIT_MODULES("--limit-modules", "opt.arg.limitmods", "opt.limitmods", STANDARD, BASIC) {
         @Override
-        public boolean process(OptionHelper helper, String option, String arg) {
+        public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
             if (arg.isEmpty()) {
-                helper.error("err.no.value.for.option", option);
-                return true;
+                throw helper.newInvalidValueException("err.no.value.for.option", option);
             } else if (getPattern().matcher(arg).matches()) {
                 helper.put(LIMIT_MODULES.primaryName, arg); // last one wins
-                return false;
             } else {
-                helper.error("err.bad.value.for.option", option, arg);
-                return true;
+                throw helper.newInvalidValueException("err.bad.value.for.option", option, arg);
             }
         }
 
@@ -670,7 +636,7 @@
     // It's actually implemented by the CommandLine class.
     AT("@", "opt.arg.file", "opt.AT", STANDARD, INFO, ArgKind.ADJACENT) {
         @Override
-        public boolean process(OptionHelper helper, String option) {
+        public void process(OptionHelper helper, String option) {
             throw new AssertionError("the @ flag should be caught by CommandLine.");
         }
     },
@@ -690,22 +656,19 @@
             }
         }
         @Override
-        public boolean process(OptionHelper helper, String option) {
+        public void process(OptionHelper helper, String option) throws InvalidValueException {
             if (option.endsWith(".java") ) {
                 Path p = Paths.get(option);
                 if (!Files.exists(p)) {
-                    helper.error("err.file.not.found", p);
-                    return true;
+                    throw helper.newInvalidValueException("err.file.not.found", p);
                 }
                 if (!Files.isRegularFile(p)) {
-                    helper.error("err.file.not.file", p);
-                    return true;
+                    throw helper.newInvalidValueException("err.file.not.file", p);
                 }
                 helper.addFile(p);
             } else {
                 helper.addClassName(option);
             }
-            return false;
         }
     },
 
@@ -714,24 +677,44 @@
     INHERIT_RUNTIME_ENVIRONMENT("--inherit-runtime-environment", "opt.inherit_runtime_environment",
             EXTENDED, BASIC) {
         @Override
-        public boolean process(OptionHelper helper, String option) {
+        public void process(OptionHelper helper, String option) throws InvalidValueException {
             try {
                 Class.forName(JDK9Wrappers.VMHelper.VM_CLASSNAME);
                 String[] runtimeArgs = JDK9Wrappers.VMHelper.getRuntimeArguments();
                 for (String arg : runtimeArgs) {
+                    System.err.println("runtime arg: " + arg);
                     // Handle any supported runtime options; ignore all others.
                     // The runtime arguments always use the single token form, e.g. "--name=value".
                     for (Option o : getSupportedRuntimeOptions()) {
                         if (o.matches(arg)) {
-                            o.handleOption(helper, arg, Collections.emptyIterator());
+                            switch (o) {
+                                case ADD_MODULES:
+                                    int eq = arg.indexOf('=');
+                                    Assert.check(eq > 0, () -> ("invalid runtime option:" + arg));
+                                    // --add-modules=ALL-DEFAULT is not supported at compile-time
+                                    // so remove it from list, and only process the rest
+                                    // if the set is non-empty.
+                                    // Note that --add-modules=ALL-DEFAULT is automatically added
+                                    // by the standard javac launcher.
+                                    String mods = Arrays.stream(arg.substring(eq + 1).split(","))
+                                            .filter(s -> !s.isEmpty() && !s.equals("ALL-DEFAULT"))
+                                            .collect(Collectors.joining(","));
+                                    if (!mods.isEmpty()) {
+                                        String updatedArg = arg.substring(0, eq + 1) + mods;
+                                        o.handleOption(helper, updatedArg, Collections.emptyIterator());
+                                    }
+                                    break;
+                                default:
+                                    o.handleOption(helper, arg, Collections.emptyIterator());
+                                    break;
+                            }
                             break;
                         }
                     }
                 }
             } catch (ClassNotFoundException | SecurityException e) {
-                helper.error("err.cannot.access.runtime.env");
+                throw helper.newInvalidValueException("err.cannot.access.runtime.env");
             }
-            return false;
         }
 
         private Option[] getSupportedRuntimeOptions() {
@@ -748,6 +731,23 @@
     };
 
     /**
+     * This exception is thrown when an invalid value is given for an option.
+     * The detail string gives a detailed, localized message, suitable for use
+     * in error messages reported to the user.
+     */
+    public static class InvalidValueException extends Exception {
+        private static final long serialVersionUID = -1;
+
+        public InvalidValueException(String msg) {
+            super(msg);
+        }
+
+        public InvalidValueException(String msg, Throwable cause) {
+            super(msg, cause);
+        }
+    }
+
+    /**
      * The kind of argument, if any, accepted by this option. The kind is augmented
      * by characters in the name of the option.
      */
@@ -831,14 +831,13 @@
             this.text = text;
         }
 
-        public boolean process(OptionHelper helper, String option) {
+        public void process(OptionHelper helper, String option) throws InvalidValueException {
             String p = option.substring(option.indexOf(':') + 1).trim();
             String[] subOptions = p.split(";");
             for (String subOption : subOptions) {
                 subOption = text + "." + subOption.trim();
                 XD.process(helper, subOption, subOption);
             }
-            return false;
         }
 
         static boolean skip(String name) {
@@ -1038,7 +1037,7 @@
      * @return true if the operation was successful, and false otherwise
      * @implNote The return value is the opposite of that used by {@link #process}.
      */
-    public boolean handleOption(OptionHelper helper, String arg, Iterator<String> rest) {
+    public void handleOption(OptionHelper helper, String arg, Iterator<String> rest) throws InvalidValueException {
         if (hasArg()) {
             String option;
             String operand;
@@ -1051,15 +1050,14 @@
                 operand = arg.substring(sep + 1);
             } else {
                 if (!rest.hasNext()) {
-                    helper.error("err.req.arg", arg);
-                    return false;
+                    throw helper.newInvalidValueException("err.req.arg", arg);
                 }
                 option = arg;
                 operand = rest.next();
             }
-            return !process(helper, option, operand);
+            process(helper, option, operand);
         } else {
-            return !process(helper, arg);
+            process(helper, arg);
         }
     }
 
@@ -1068,14 +1066,14 @@
      * or which contains an argument within it, following a separator.
      * @param helper a helper to provide access to the environment
      * @param option the option to be processed
-     * @return true if an error occurred
+     * @throws InvalidValueException if an error occurred
      */
-    public boolean process(OptionHelper helper, String option) {
+    public void process(OptionHelper helper, String option) throws InvalidValueException {
         if (argKind == ArgKind.NONE) {
-            return process(helper, primaryName, option);
+            process(helper, primaryName, option);
         } else {
             int sep = findSeparator(option);
-            return process(helper, primaryName, option.substring(sep + 1));
+            process(helper, primaryName, option.substring(sep + 1));
         }
     }
 
@@ -1085,9 +1083,8 @@
      * @param option the option to be processed
      * @param arg the value to associate with the option, or a default value
      *  to be used if the option does not otherwise take an argument.
-     * @return true if an error occurred
      */
-    public boolean process(OptionHelper helper, String option, String arg) {
+    public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
         if (choices != null) {
             if (choiceKind == ChoiceKind.ONEOF) {
                 // some clients like to see just one of option+choice set
@@ -1110,7 +1107,6 @@
         helper.put(primaryName, arg);
         if (group == OptionGroup.FILEMANAGER)
             helper.handleFileManagerOption(this, arg);
-        return false;
     }
 
     /**
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/OptionHelper.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/OptionHelper.java	Wed Nov 23 19:15:26 2016 +0000
@@ -43,29 +43,55 @@
 
 public abstract class OptionHelper {
 
-    /** Get the current value of an option. */
+    /**
+     * Get the current value of an option.
+     * @param option the option
+     * @return the value of the option
+     */
     public abstract String get(Option option);
 
-    /** Set the value of an option. */
+    /**
+     * Set the value of an option.
+     * @param name the primary name of the option
+     * @param value the value for the option
+     */
     public abstract void put(String name, String value);
 
-    /** Remove any prior value for an option. */
+    /**
+     * Remove any prior value for an option.
+     * @param name the primary name of the option
+     */
     public abstract void remove(String name);
 
-    /** Handle a file manager option. */
+    /**
+     * Handle a file manager option.
+     * @param option the option
+     * @param value the value for the option
+     * @return true if the option was handled successfully, and false otherwise
+     */
     public abstract boolean handleFileManagerOption(Option option, String value);
 
-    /** Get access to the Log for the compilation. */
+    /**
+     * Get access to the Log for the compilation.
+     * @return the log
+     */
     public abstract Log getLog();
 
-    /** Get the name of the tool, such as "javac", to be used in info like -help. */
+    /**
+     * Get the name of the tool, such as "javac", to be used in info like -help.
+     * @return the name of the tool
+     */
     public abstract String getOwnName();
 
-    /** Report an error. */
-    abstract void error(String key, Object... args);
-
-    /** Report an error. */
-    abstract void error(JCDiagnostic.Error error);
+    /**
+     * Returns a new InvalidValueException, with a localized detail message.
+     * @param key the resource key for the message
+     * @param args the arguments, if any, for the resource string
+     * @return the InvalidValueException
+     */
+    Option.InvalidValueException newInvalidValueException(String key, Object... args) {
+        return new Option.InvalidValueException(getLog().localize(PrefixKind.JAVAC, key, args));
+    }
 
     /** Record a file to be compiled. */
     abstract void addFile(Path p);
@@ -112,16 +138,6 @@
         }
 
         @Override
-        void error(String key, Object... args) {
-            throw new IllegalArgumentException(log.localize(PrefixKind.JAVAC, key, args));
-        }
-
-        @Override
-        void error(JCDiagnostic.Error error) {
-            throw new IllegalArgumentException(log.localize(error));
-        }
-
-        @Override
         public void addFile(Path p) {
             throw new IllegalArgumentException(p.toString());
         }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Wed Nov 23 19:15:26 2016 +0000
@@ -2848,6 +2848,10 @@
 compiler.warn.bad.name.for.option=\
     bad name in value for {0} option: ''{1}''
 
+# 0: option name, 1: string
+compiler.err.bad.name.for.option=\
+    bad name in value for {0} option: ''{1}''
+
 # 0: option name, 1: symbol
 compiler.warn.module.for.option.not.found=\
     module name in {0} option not found: {1}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SmartFileManager.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SmartFileManager.java	Wed Nov 23 19:15:26 2016 +0000
@@ -204,8 +204,8 @@
     }
 
     @Override @DefinedBy(Api.COMPILER)
-    public Location getModuleLocation(Location location, JavaFileObject fo, String pkgName) throws IOException {
-        return super.getModuleLocation(location, locUnwrap(fo), pkgName);
+    public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
+        return super.getLocationForModule(location, locUnwrap(fo), pkgName);
     }
 
     private static String packageNameFromFileName(String fn) {
--- a/langtools/src/jdk.compiler/share/classes/jdk/internal/shellsupport/doc/JavadocFormatter.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/jdk/internal/shellsupport/doc/JavadocFormatter.java	Wed Nov 23 19:15:26 2016 +0000
@@ -246,7 +246,7 @@
 
         @Override @DefinedBy(Api.COMPILER_TREE)
         public Object visitStartElement(StartElementTree node, Object p) {
-            switch (HtmlTag.get(node.getName())) {
+            switch (getHtmlTag(node.getName())) {
                 case P:
                     if (lastNode!= null && lastNode.getKind() == DocTree.Kind.START_ELEMENT &&
                         HtmlTag.get(((StartElementTree) lastNode).getName()) == HtmlTag.LI) {
@@ -397,7 +397,7 @@
         }
 
         private void handleEndElement(Name name) {
-            switch (HtmlTag.get(name)) {
+            switch (getHtmlTag(name)) {
                 case BLOCKQUOTE:
                     indent -= INDENT;
                     break;
@@ -629,6 +629,12 @@
         }
     }
 
+    private static HtmlTag getHtmlTag(Name name) {
+        HtmlTag tag = HtmlTag.get(name);
+
+        return tag != null ? tag : HtmlTag.HTML; //using HtmlTag.HTML as default no-op value
+    }
+
     private static Map<StartElementTree, Integer> countTableColumns(DocCommentTree dct) {
         Map<StartElementTree, Integer> result = new IdentityHashMap<>();
 
@@ -639,7 +645,7 @@
 
             @Override @DefinedBy(Api.COMPILER_TREE)
             public Void visitStartElement(StartElementTree node, Void p) {
-                switch (HtmlTag.get(node.getName())) {
+                switch (getHtmlTag(node.getName())) {
                     case TABLE: currentTable = node; break;
                     case TR:
                         currentMaxColumns = Math.max(currentMaxColumns, currentRowColumns);
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocTool.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocTool.java	Wed Nov 23 19:15:26 2016 +0000
@@ -393,7 +393,7 @@
                 for (ModuleSymbol msym : modules.allModules()) {
                     PackageSymbol p = syms.getPackage(msym, pack);
                     if (p != null && !p.members().isEmpty()) {
-                        return fm.getModuleLocation(location, msym.name.toString());
+                        return fm.getLocationForModule(location, msym.name.toString());
                     }
                 }
 
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/Start.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/Start.java	Wed Nov 23 19:15:26 2016 +0000
@@ -45,6 +45,7 @@
 import com.sun.tools.javac.main.CommandLine;
 import com.sun.tools.javac.main.Option;
 import com.sun.tools.javac.file.BaseFileManager;
+import com.sun.tools.javac.main.Arguments;
 import com.sun.tools.javac.main.OptionHelper;
 import com.sun.tools.javac.main.OptionHelper.GrumpyHelper;
 import com.sun.tools.javac.platform.PlatformDescription;
@@ -309,12 +310,16 @@
                 if (o == ToolOption.LOCALE && i > 0)
                     usageError("main.locale_first");
 
-                if (o.hasArg) {
-                    oneArg(argv, i++);
-                    o.process(this, argv[i]);
-                } else {
-                    setOption(arg);
-                    o.process(this);
+                try {
+                    if (o.hasArg) {
+                        oneArg(argv, i++);
+                        o.process(this, argv[i]);
+                    } else {
+                        setOption(arg);
+                        o.process(this);
+                    }
+                } catch (Option.InvalidValueException e) {
+                    usageError("main.option.invalid.value", e.getMessage());
                 }
             } else if (arg.equals("-XDaccessInternalAPI")) {
                 // pass this hidden option down to the doclet, if it wants it
@@ -367,6 +372,11 @@
             ((BaseFileManager) fileManager).handleOptions(fileManagerOpts);
         }
 
+        Arguments arguments = Arguments.instance(context);
+        arguments.init(messager.programName);
+        arguments.allowEmpty();
+        arguments.validate();
+
         String platformString = compOpts.get("--release");
 
         if (platformString != null) {
@@ -560,7 +570,7 @@
 
     @Override
     OptionHelper getOptionHelper() {
-        return new GrumpyHelper(null) {
+        return new GrumpyHelper(messager) {
             @Override
             public String get(com.sun.tools.javac.main.Option option) {
                 return compOpts.get(option);
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ToolOption.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ToolOption.java	Wed Nov 23 19:15:26 2016 +0000
@@ -31,6 +31,7 @@
 
 import com.sun.tools.javac.code.Flags;
 import com.sun.tools.javac.main.Option;
+import com.sun.tools.javac.main.Option.InvalidValueException;
 import com.sun.tools.javac.main.OptionHelper;
 import com.sun.tools.javac.util.ListBuffer;
 import com.sun.tools.javac.util.Options;
@@ -141,14 +142,14 @@
 
     ADD_MODULES("--add-modules", true) {
         @Override
-        public void process(Helper helper, String arg) {
+        public void process(Helper helper, String arg) throws InvalidValueException {
             Option.ADD_MODULES.process(helper.getOptionHelper(), opt, arg);
         }
     },
 
     LIMIT_MODULES("--limit-modules", true) {
         @Override
-        public void process(Helper helper, String arg) {
+        public void process(Helper helper, String arg) throws InvalidValueException {
             Option.LIMIT_MODULES.process(helper.getOptionHelper(), opt, arg);
         }
     },
@@ -191,28 +192,28 @@
 
     ADD_READS("--add-reads", true) {
         @Override
-        public void process(Helper helper, String arg) {
+        public void process(Helper helper, String arg) throws InvalidValueException {
             Option.ADD_READS.process(helper.getOptionHelper(), opt, arg);
         }
     },
 
     ADD_EXPORTS("--add-exports", true) {
         @Override
-        public void process(Helper helper, String arg) {
+        public void process(Helper helper, String arg) throws InvalidValueException {
             Option.ADD_EXPORTS.process(helper.getOptionHelper(), opt, arg);
         }
     },
 
     XMODULE("-Xmodule:", false) {
         @Override
-        public void process(Helper helper, String arg) {
+        public void process(Helper helper, String arg) throws InvalidValueException {
             Option.XMODULE.process(helper.getOptionHelper(), arg);
         }
     },
 
     PATCH_MODULE("--patch-module", true) {
         @Override
-        public void process(Helper helper, String arg) {
+        public void process(Helper helper, String arg) throws InvalidValueException {
             Option.PATCH_MODULE.process(helper.getOptionHelper(), opt, arg);
         }
     },
@@ -356,7 +357,7 @@
         this.hasArg = hasArg;
     }
 
-    void process(Helper helper, String arg) { }
+    void process(Helper helper, String arg) throws Option.InvalidValueException { }
 
     void process(Helper helper) { }
 
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/resources/javadoc.properties	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/resources/javadoc.properties	Wed Nov 23 19:15:26 2016 +0000
@@ -126,6 +126,7 @@
 main.release.bootclasspath.conflict=option {0} cannot be used together with -release
 main.unsupported.release.version=release version {0} not supported
 main.release.not.standard.file.manager=-release option specified, but the provided JavaFileManager is not a StandardJavaFileManager.
+main.option.invalid.value={0}
 tag.illegal_char_in_arr_dim=Tag {0}: Syntax Error in array dimension, method parameters: {1}
 tag.illegal_see_tag=Tag {0}: Syntax Error in method parameters: {1}
 tag.missing_comma_space=Tag {0}: Missing comma or space in method parameters: {1}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/IndexBuilder.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/IndexBuilder.java	Wed Nov 23 19:15:26 2016 +0000
@@ -166,6 +166,7 @@
         adjustIndexMap(utils.getFields(te));
         adjustIndexMap(utils.getMethods(te));
         adjustIndexMap(utils.getConstructors(te));
+        adjustIndexMap(utils.getEnumConstants(te));
     }
 
 
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java	Wed Nov 23 19:15:26 2016 +0000
@@ -816,7 +816,7 @@
     private Location getModuleLocation(Location location, String msymName)
             throws ToolException {
         try {
-            return fm.getModuleLocation(location, msymName);
+            return fm.getLocationForModule(location, msymName);
         } catch (IOException ioe) {
             String text = messager.getText("main.doclet_could_not_get_location", msymName);
             throw new ToolException(ERROR, text, ioe);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java	Wed Nov 23 19:15:26 2016 +0000
@@ -51,6 +51,7 @@
 import com.sun.tools.javac.api.JavacTrees;
 import com.sun.tools.javac.file.BaseFileManager;
 import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.main.Arguments;
 import com.sun.tools.javac.main.CommandLine;
 import com.sun.tools.javac.main.OptionHelper;
 import com.sun.tools.javac.main.OptionHelper.GrumpyHelper;
@@ -59,6 +60,7 @@
 import com.sun.tools.javac.util.ClientCodeException;
 import com.sun.tools.javac.util.Context;
 import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Log.WriterKind;
 import com.sun.tools.javac.util.Options;
 
 import jdk.javadoc.doclet.Doclet;
@@ -325,9 +327,14 @@
         if (argv.length > 0 && "-Xold".equals(argv[0])) {
             warn("main.legacy_api");
             String[] nargv = Arrays.copyOfRange(argv, 1, argv.length);
-            return com.sun.tools.javadoc.Main.execute(nargv) == 0
-                    ? OK
-                    : ERROR;
+            int rc = com.sun.tools.javadoc.Main.execute(
+                    messager.programName,
+                    messager.getWriter(WriterKind.ERROR),
+                    messager.getWriter(WriterKind.WARNING),
+                    messager.getWriter(WriterKind.NOTICE),
+                    "com.sun.tools.doclets.standard.Standard",
+                    nargv);
+            return (rc == 0) ? OK : ERROR;
         }
         return begin(Arrays.asList(argv), Collections.<JavaFileObject> emptySet());
     }
@@ -400,9 +407,14 @@
             }
             warn("main.legacy_api");
             String[] array = options.toArray(new String[options.size()]);
-            return com.sun.tools.javadoc.Main.execute(array) == 0
-                    ? OK
-                    : ERROR;
+            int rc = com.sun.tools.javadoc.Main.execute(
+                    messager.programName,
+                    messager.getWriter(WriterKind.ERROR),
+                    messager.getWriter(WriterKind.WARNING),
+                    messager.getWriter(WriterKind.NOTICE),
+                    "com.sun.tools.doclets.standard.Standard",
+                    array);
+            return (rc == 0) ? OK : ERROR;
         }
 
         Result result = OK;
@@ -410,6 +422,11 @@
             result = parseAndExecute(options, fileObjects)
                     ? OK
                     : ERROR;
+        } catch (com.sun.tools.javac.main.Option.InvalidValueException e) {
+            messager.printError(e.getMessage());
+            Throwable t = e.getCause();
+            dumpStack(t == null ? e : t);
+            return ERROR;
         } catch (OptionException toe) {
             if (toe.message != null)
                 messager.printError(toe.message);
@@ -482,8 +499,8 @@
      * Main program - internal
      */
     @SuppressWarnings("unchecked")
-    private boolean parseAndExecute(List<String> argList,
-            Iterable<? extends JavaFileObject> fileObjects) throws ToolException, OptionException {
+    private boolean parseAndExecute(List<String> argList, Iterable<? extends JavaFileObject> fileObjects)
+            throws ToolException, OptionException, com.sun.tools.javac.main.Option.InvalidValueException {
         long tm = System.currentTimeMillis();
 
         List<String> javaNames = new ArrayList<>();
@@ -491,11 +508,19 @@
         compOpts = Options.instance(context);
 
         // Make sure no obsolete source/target messages are reported
-        com.sun.tools.javac.main.Option.XLINT.process(getOptionHelper(), "-Xlint:-options");
+        try {
+            com.sun.tools.javac.main.Option.XLINT_CUSTOM.process(getOptionHelper(), "-Xlint:-options");
+        } catch (com.sun.tools.javac.main.Option.InvalidValueException ignore) {
+        }
 
         doclet.init(locale, messager);
         parseArgs(argList, javaNames);
 
+        Arguments arguments = Arguments.instance(context);
+        arguments.init(ProgramName);
+        arguments.allowEmpty();
+        arguments.validate();
+
         if (fileManager instanceof BaseFileManager) {
             ((BaseFileManager) fileManager).handleOptions(fileManagerOpts);
         }
@@ -805,7 +830,7 @@
     }
 
     private void parseArgs(List<String> args, List<String> javaNames) throws ToolException,
-            OptionException {
+            OptionException, com.sun.tools.javac.main.Option.InvalidValueException {
         for (int i = 0 ; i < args.size() ; i++) {
             String arg = args.get(i);
             ToolOption o = ToolOption.get(arg);
@@ -929,7 +954,7 @@
 
     @Override
     OptionHelper getOptionHelper() {
-        return new GrumpyHelper(null) {
+        return new GrumpyHelper(messager) {
             @Override
             public String get(com.sun.tools.javac.main.Option option) {
                 return compOpts.get(option);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOption.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOption.java	Wed Nov 23 19:15:26 2016 +0000
@@ -35,6 +35,7 @@
 import javax.lang.model.element.ElementKind;
 
 import com.sun.tools.javac.main.Option;
+import com.sun.tools.javac.main.Option.InvalidValueException;
 import com.sun.tools.javac.main.Option.OptionKind;
 import com.sun.tools.javac.main.OptionHelper;
 import com.sun.tools.javac.util.Options;
@@ -56,70 +57,70 @@
 
     BOOTCLASSPATH("-bootclasspath", STANDARD, true) {
         @Override
-        public void process(Helper helper, String arg) {
+        public void process(Helper helper, String arg) throws InvalidValueException {
             Option.BOOT_CLASS_PATH.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
 
     CLASS_PATH("--class-path -classpath -cp", STANDARD, true) {
         @Override
-        public void process(Helper helper, String arg) {
+        public void process(Helper helper, String arg) throws InvalidValueException {
             Option.CLASS_PATH.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
 
     EXTDIRS("-extdirs", STANDARD, true) {
         @Override
-        public void process(Helper helper, String arg) {
+        public void process(Helper helper, String arg) throws InvalidValueException {
             Option.EXTDIRS.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
 
     SOURCE_PATH("--source-path -sourcepath", STANDARD, true) {
         @Override
-        public void process(Helper helper, String arg) {
+        public void process(Helper helper, String arg) throws InvalidValueException {
             Option.SOURCE_PATH.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
 
     MODULE_SOURCE_PATH("--module-source-path", STANDARD, true) {
         @Override
-        public void process(Helper helper, String arg) {
+        public void process(Helper helper, String arg) throws InvalidValueException {
             Option.MODULE_SOURCE_PATH.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
 
     UPGRADE_MODULE_PATH("--upgrade-module-path", STANDARD, true) {
         @Override
-        public void process(Helper helper, String arg) {
+        public void process(Helper helper, String arg) throws InvalidValueException {
             Option.UPGRADE_MODULE_PATH.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
 
     SYSTEM("--system", STANDARD, true) {
         @Override
-        public void process(Helper helper, String arg) {
+        public void process(Helper helper, String arg) throws InvalidValueException {
             Option.SYSTEM.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
 
     MODULE_PATH("--module-path -p", STANDARD, true) {
         @Override
-        public void process(Helper helper, String arg) {
+        public void process(Helper helper, String arg) throws InvalidValueException {
             Option.MODULE_PATH.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
 
     ADD_MODULES("--add-modules", STANDARD, true) {
         @Override
-        public void process(Helper helper, String arg) {
+        public void process(Helper helper, String arg) throws InvalidValueException {
             Option.ADD_MODULES.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
 
     LIMIT_MODULES("--limit-modules", STANDARD, true) {
         @Override
-        public void process(Helper helper, String arg) {
+        public void process(Helper helper, String arg) throws InvalidValueException {
             Option.LIMIT_MODULES.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
@@ -133,63 +134,63 @@
 
     ENCODING("-encoding", STANDARD, true) {
         @Override
-        public void process(Helper helper, String arg) {
+        public void process(Helper helper, String arg) throws InvalidValueException {
             Option.ENCODING.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
 
     RELEASE("--release", STANDARD, true) {
         @Override
-        public void process(Helper helper, String arg) {
+        public void process(Helper helper, String arg) throws InvalidValueException {
             Option.RELEASE.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
 
     SOURCE("-source", STANDARD, true) {
         @Override
-        public void process(Helper helper, String arg) {
+        public void process(Helper helper, String arg) throws InvalidValueException {
             Option.SOURCE.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
 
     XMAXERRS("-Xmaxerrs", EXTENDED, true) {
         @Override
-        public void process(Helper helper, String arg) {
+        public void process(Helper helper, String arg) throws InvalidValueException {
             Option.XMAXERRS.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
 
     XMAXWARNS("-Xmaxwarns", EXTENDED, true) {
         @Override
-        public void process(Helper helper, String arg) {
+        public void process(Helper helper, String arg) throws InvalidValueException {
             Option.XMAXWARNS.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
 
     ADD_READS("--add-reads", EXTENDED, true) {
         @Override
-        public void process(Helper helper, String arg) {
+        public void process(Helper helper, String arg) throws InvalidValueException {
             Option.ADD_READS.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
 
     ADD_EXPORTS("--add-exports", EXTENDED, true) {
         @Override
-        public void process(Helper helper, String arg) {
+        public void process(Helper helper, String arg) throws InvalidValueException {
             Option.ADD_EXPORTS.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
 
     XMODULE("-Xmodule:", EXTENDED, false) {
         @Override
-        public void process(Helper helper, String arg) {
+        public void process(Helper helper, String arg) throws InvalidValueException {
             Option.XMODULE.process(helper.getOptionHelper(), arg);
         }
     },
 
     PATCH_MODULE("--patch-module", EXTENDED, true) {
         @Override
-        public void process(Helper helper, String arg) {
+        public void process(Helper helper, String arg) throws InvalidValueException {
             Option.PATCH_MODULE.process(helper.getOptionHelper(), primaryName, arg);
         }
     },
@@ -388,7 +389,7 @@
         this.hasSuffix = lastChar == ':' || lastChar == '=';
     }
 
-    void process(Helper helper, String arg) throws OptionException { }
+    void process(Helper helper, String arg) throws OptionException, Option.InvalidValueException { }
 
     void process(Helper helper) throws OptionException { }
 
--- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/javap/JavapTask.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/javap/JavapTask.java	Wed Nov 23 19:15:26 2016 +0000
@@ -910,7 +910,7 @@
             StandardLocation.MODULE_PATH
         };
         for (Location segment: locns) {
-            for (Set<Location> set: fileManager.listModuleLocations(segment)) {
+            for (Set<Location> set: fileManager.listLocationsForModules(segment)) {
                 Location result = null;
                 for (Location l: set) {
                     String name = fileManager.inferModuleName(l);
--- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java	Wed Nov 23 19:15:26 2016 +0000
@@ -537,8 +537,9 @@
             config.splitPackages().entrySet()
                 .stream()
                 .sorted(Map.Entry.comparingByKey())
-                .forEach(e -> System.out.format("split package: %s %s%n", e.getKey(),
-                                                e.getValue().toString()));
+                .forEach(e -> log.println(getMessage("split.package",
+                                                     e.getKey(),
+                                                     e.getValue().toString())));
 
             // check if any module specified in --require is missing
             Stream.concat(options.addmods.stream(), options.requires.stream())
@@ -745,8 +746,12 @@
 
                 if (!jdkInternals.isEmpty()) {
                     log.println();
-                    log.format("%-40s %s%n", "JDK Internal API", "Suggested Replacement");
-                    log.format("%-40s %s%n", "----------------", "---------------------");
+                    String internalApiTitle = getMessage("internal.api.column.header");
+                    String replacementApiTitle = getMessage("public.api.replacement.column.header");
+                    log.format("%-40s %s%n", internalApiTitle, replacementApiTitle);
+                    log.format("%-40s %s%n",
+                               internalApiTitle.replaceAll(".", "-"),
+                               replacementApiTitle.replaceAll(".", "-"));
                     jdkInternals.entrySet().stream()
                         .forEach(e -> {
                             String key = e.getKey();
@@ -800,12 +805,13 @@
 
             log.println();
             if (!options.requires.isEmpty())
-                log.format("Inverse transitive dependences on %s%n", options.requires);
+                log.println(getMessage("inverse.transitive.dependencies.on",
+                    options.requires));
             else
-                log.format("Inverse transitive dependences matching %s%n",
+                log.println(getMessage("inverse.transitive.dependencies.matching",
                     options.regex != null
                         ? options.regex.toString()
-                        : "packages " + options.packageNames);
+                        : "packages " + options.packageNames));
 
             analyzer.inverseDependences().stream()
                 .sorted(Comparator.comparing(this::sortPath))
@@ -870,7 +876,7 @@
             boolean ok = builder.run();
 
             if (!ok && !options.nowarning) {
-                log.println("ERROR: missing dependencies");
+                reportError("err.missing.dependences");
                 builder.visitMissingDeps(
                     new Analyzer.Visitor() {
                         @Override
--- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/resources/jdeps.properties	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/resources/jdeps.properties	Wed Nov 23 19:15:26 2016 +0000
@@ -176,6 +176,7 @@
 err.command.set={0} and {1} options are specified.
 err.unknown.option=unknown option: {0}
 err.missing.arg=no value given for {0}
+err.missing.dependences=missing dependencies
 err.invalid.arg.for.option=invalid argument for option: {0}
 err.option.after.class=option must be specified before classes: {0}
 err.genmoduleinfo.not.jarfile={0} is a modular JAR file that cannot be specified with the --generate-module-info option
@@ -201,5 +202,10 @@
 For the most recent update on JDK internal API replacements, please check:\n\
 {0}
 
+split.package=split package: {0} {1}\n
+inverse.transitive.dependencies.on=Inverse transitive dependences on {0}
+inverse.transitive.dependencies.matching=Inverse transitive dependences matching {0}
+internal.api.column.header=JDK Internal API
+public.api.replacement.column.header=Suggested Replacement
 artifact.not.found=not found
 jdeps.wiki.url=https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java	Wed Nov 23 19:15:26 2016 +0000
@@ -283,9 +283,9 @@
             if (firstInvocation) {
                 convertor = d -> d.signature();
             } else {
-                convertor = d -> formatter.formatJavadoc(d.signature(),
-                                                         d.javadoc() != null ? d.javadoc()
-                                                                             : repl.messageFormat("jshell.console.no.javadoc"));
+                convertor = d -> formatter.formatJavadoc(d.signature(), d.javadoc()) +
+                                 (d.javadoc() == null ? repl.messageFormat("jshell.console.no.javadoc")
+                                                      : "");
             }
             doc = repl.analysis.documentation(prefix + buffer, cursor + prefix.length(), !firstInvocation)
                                .stream()
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Wed Nov 23 19:15:26 2016 +0000
@@ -45,6 +45,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
@@ -1051,8 +1052,12 @@
     }
 
     static final CompletionProvider EMPTY_COMPLETION_PROVIDER = new FixedCompletionProvider();
-    private static final CompletionProvider KEYWORD_COMPLETION_PROVIDER = new FixedCompletionProvider("-all ", "-start ", "-history ");
-    private static final CompletionProvider RELOAD_OPTIONS_COMPLETION_PROVIDER = new FixedCompletionProvider("-restore", "-quiet");
+    private static final CompletionProvider SNIPPET_HISTORY_OPTION_COMPLETION_PROVIDER = new FixedCompletionProvider("-all", "-start ", "-history");
+    private static final CompletionProvider SAVE_OPTION_COMPLETION_PROVIDER = new FixedCompletionProvider("-all ", "-start ", "-history ");
+    private static final CompletionProvider SNIPPET_OPTION_COMPLETION_PROVIDER = new FixedCompletionProvider("-all", "-start " );
+    private static final CompletionProvider RELOAD_OPTIONS_COMPLETION_PROVIDER = new FixedCompletionProvider("-restore ", "-quiet ");
+    private static final CompletionProvider RESTORE_COMPLETION_PROVIDER = new FixedCompletionProvider("-restore");
+    private static final CompletionProvider QUIET_COMPLETION_PROVIDER = new FixedCompletionProvider("-quiet");
     private static final CompletionProvider SET_MODE_OPTIONS_COMPLETION_PROVIDER = new FixedCompletionProvider("-command", "-quiet", "-delete");
     private static final CompletionProvider FILE_COMPLETION_PROVIDER = fileCompletions(p -> true);
     private final Map<String, Command> commands = new LinkedHashMap<>();
@@ -1106,24 +1111,62 @@
                                     p.getFileName().toString().endsWith(".jar"));
     }
 
+    // Completion based on snippet supplier
     private CompletionProvider snippetCompletion(Supplier<Stream<? extends Snippet>> snippetsSupplier) {
         return (prefix, cursor, anchor) -> {
             anchor[0] = 0;
+            int space = prefix.lastIndexOf(' ');
+            Set<String> prior = new HashSet<>(Arrays.asList(prefix.split(" ")));
+            if (prior.contains("-all") || prior.contains("-history")) {
+                return Collections.emptyList();
+            }
+            String argPrefix = prefix.substring(space + 1);
             return snippetsSupplier.get()
+                        .filter(k -> !prior.contains(String.valueOf(k.id()))
+                                && (!(k instanceof DeclarationSnippet)
+                                     || !prior.contains(((DeclarationSnippet) k).name())))
                         .flatMap(k -> (k instanceof DeclarationSnippet)
-                                ? Stream.of(String.valueOf(k.id()), ((DeclarationSnippet) k).name())
-                                : Stream.of(String.valueOf(k.id())))
-                        .filter(k -> k.startsWith(prefix))
+                                ? Stream.of(String.valueOf(k.id()) + " ", ((DeclarationSnippet) k).name() + " ")
+                                : Stream.of(String.valueOf(k.id()) + " "))
+                        .filter(k -> k.startsWith(argPrefix))
                         .map(k -> new ArgSuggestion(k))
                         .collect(Collectors.toList());
         };
     }
 
-    private CompletionProvider snippetKeywordCompletion(Supplier<Stream<? extends Snippet>> snippetsSupplier) {
+    // Completion based on snippet supplier with -all -start (and sometimes -history) options
+    private CompletionProvider snippetWithOptionCompletion(CompletionProvider optionProvider,
+            Supplier<Stream<? extends Snippet>> snippetsSupplier) {
         return (code, cursor, anchor) -> {
             List<Suggestion> result = new ArrayList<>();
-            result.addAll(KEYWORD_COMPLETION_PROVIDER.completionSuggestions(code, cursor, anchor));
+            int pastSpace = code.lastIndexOf(' ') + 1; // zero if no space
+            if (pastSpace == 0) {
+                result.addAll(optionProvider.completionSuggestions(code, cursor, anchor));
+            }
             result.addAll(snippetCompletion(snippetsSupplier).completionSuggestions(code, cursor, anchor));
+            anchor[0] += pastSpace;
+            return result;
+        };
+    }
+
+    // Completion of help, commands and subjects
+    private CompletionProvider helpCompletion() {
+        return (code, cursor, anchor) -> {
+            List<Suggestion> result;
+            int pastSpace = code.indexOf(' ') + 1; // zero if no space
+            if (pastSpace == 0) {
+                result = new FixedCompletionProvider(commands.values().stream()
+                        .filter(cmd -> cmd.kind.showInHelp || cmd.kind == CommandKind.HELP_SUBJECT)
+                        .map(c -> c.command + " ")
+                        .toArray(size -> new String[size]))
+                        .completionSuggestions(code, cursor, anchor);
+            } else if (code.startsWith("/se")) {
+                result = new FixedCompletionProvider(SET_SUBCOMMANDS)
+                        .completionSuggestions(code.substring(pastSpace), cursor - pastSpace, anchor);
+            } else {
+                result = Collections.emptyList();
+            }
+            anchor[0] += pastSpace;
             return result;
         };
     }
@@ -1133,7 +1176,7 @@
             List<Suggestion> result = new ArrayList<>();
             int space = code.indexOf(' ');
             if (space == (-1)) {
-                result.addAll(KEYWORD_COMPLETION_PROVIDER.completionSuggestions(code, cursor, anchor));
+                result.addAll(SAVE_OPTION_COMPLETION_PROVIDER.completionSuggestions(code, cursor, anchor));
             }
             result.addAll(FILE_COMPLETION_PROVIDER.completionSuggestions(code.substring(space + 1), cursor - space - 1, anchor));
             anchor[0] += space + 1;
@@ -1143,9 +1186,25 @@
 
     private static CompletionProvider reloadCompletion() {
         return (code, cursor, anchor) -> {
-            List<Suggestion> result = new ArrayList<>();
+            CompletionProvider provider;
             int pastSpace = code.indexOf(' ') + 1; // zero if no space
-            result.addAll(RELOAD_OPTIONS_COMPLETION_PROVIDER.completionSuggestions(code.substring(pastSpace), cursor - pastSpace, anchor));
+            if (pastSpace == 0) {
+                provider = RELOAD_OPTIONS_COMPLETION_PROVIDER;
+            } else {
+                switch (code.substring(0, pastSpace - 1)) {
+                    case "-quiet":
+                        provider = RESTORE_COMPLETION_PROVIDER;
+                        break;
+                    case "-restore":
+                        provider = QUIET_COMPLETION_PROVIDER;
+                        break;
+                    default:
+                        provider = EMPTY_COMPLETION_PROVIDER;
+                        break;
+                }
+            }
+            List<Suggestion> result = provider.completionSuggestions(
+                    code.substring(pastSpace), cursor - pastSpace, anchor);
             anchor[0] += pastSpace;
             return result;
         };
@@ -1210,10 +1269,12 @@
     {
         registerCommand(new Command("/list",
                 arg -> cmdList(arg),
-                snippetKeywordCompletion(this::allSnippets)));
+                snippetWithOptionCompletion(SNIPPET_HISTORY_OPTION_COMPLETION_PROVIDER,
+                        this::allSnippets)));
         registerCommand(new Command("/edit",
                 arg -> cmdEdit(arg),
-                snippetCompletion(this::allSnippets)));
+                snippetWithOptionCompletion(SNIPPET_OPTION_COMPLETION_PROVIDER,
+                        this::allSnippets)));
         registerCommand(new Command("/drop",
                 arg -> cmdDrop(arg),
                 snippetCompletion(this::dropableSnippets),
@@ -1226,13 +1287,16 @@
                 FILE_COMPLETION_PROVIDER));
         registerCommand(new Command("/vars",
                 arg -> cmdVars(arg),
-                snippetKeywordCompletion(this::allVarSnippets)));
+                snippetWithOptionCompletion(SNIPPET_OPTION_COMPLETION_PROVIDER,
+                        this::allVarSnippets)));
         registerCommand(new Command("/methods",
                 arg -> cmdMethods(arg),
-                snippetKeywordCompletion(this::allMethodSnippets)));
+                snippetWithOptionCompletion(SNIPPET_OPTION_COMPLETION_PROVIDER,
+                        this::allMethodSnippets)));
         registerCommand(new Command("/types",
                 arg -> cmdTypes(arg),
-                snippetKeywordCompletion(this::allTypeSnippets)));
+                snippetWithOptionCompletion(SNIPPET_OPTION_COMPLETION_PROVIDER,
+                        this::allTypeSnippets)));
         registerCommand(new Command("/imports",
                 arg -> cmdImports(),
                 EMPTY_COMPLETION_PROVIDER));
@@ -1258,7 +1322,7 @@
                 CommandKind.HIDDEN));
         registerCommand(new Command("/help",
                 arg -> cmdHelp(arg),
-                EMPTY_COMPLETION_PROVIDER));
+                helpCompletion()));
         registerCommand(new Command("/set",
                 arg -> cmdSet(arg),
                 new ContinuousCompletionProvider(Map.of(
@@ -1276,7 +1340,7 @@
         registerCommand(new Command("/?",
                 "help.quest",
                 arg -> cmdHelp(arg),
-                EMPTY_COMPLETION_PROVIDER,
+                helpCompletion(),
                 CommandKind.NORMAL));
         registerCommand(new Command("/!",
                 "help.bang",
@@ -1962,6 +2026,8 @@
                 case ASSIGNMENT_SUBKIND:
                 case OTHER_EXPRESSION_SUBKIND:
                 case TEMP_VAR_EXPRESSION_SUBKIND:
+                case STATEMENT_SUBKIND:
+                case UNKNOWN_SUBKIND:
                     if (!src.endsWith(";")) {
                         src = src + ";";
                     }
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java	Wed Nov 23 19:15:26 2016 +0000
@@ -233,7 +233,7 @@
 
         // Declarations and type parameters (thus expressions)
         EXTENDS(TokenKind.EXTENDS, XEXPR|XDECL),  //  extends
-        COMMA(TokenKind.COMMA, XEXPR|XDECL|XTERM),  //  ,
+        COMMA(TokenKind.COMMA, XEXPR|XDECL),  //  ,
         AMP(TokenKind.AMP, XEXPR|XDECL),  //  &
         GT(TokenKind.GT, XEXPR|XDECL),  //  >
         LT(TokenKind.LT, XEXPR|XDECL1),  //  <
@@ -541,7 +541,10 @@
                         ct = new CT(TK.tokenKindToTK(prevTK, current.kind), advance());
                         break;
                 }
-                if (ct.kind.isStart() && !prevTK.isOkToTerminate()) {
+                // Detect an error if we are at starting position and the last
+                // token wasn't a terminating one.  Special case: within braces,
+                // comma can proceed semicolon, e.g. the values list in enum
+                if (ct.kind.isStart() && !prevTK.isOkToTerminate() && prevTK != COMMA) {
                     return new CT(ERROR, current, "No '" + prevTK + "' before '" + ct.kind + "'");
                 }
                 if (stack.isEmpty() || ct.kind.isError()) {
@@ -653,12 +656,7 @@
             }
             switch (token.kind) {
                 case EQ:
-                    // Check for array initializer
                     nextToken();
-                    if (token.kind == BRACES) {
-                        nextToken();
-                        return lastly(SEMI);
-                    }
                     return parseExpressionStatement();
                 case BRACES:
                 case SEMI:
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java	Wed Nov 23 19:15:26 2016 +0000
@@ -719,11 +719,11 @@
 
     /**
      * If there are classes to load, loads by calling the execution engine.
-     * @param classbytecoes names of the classes to load.
+     * @param classbytecodes names of the classes to load.
      */
-    private void load(Collection<ClassBytecodes> classbytecoes) {
-        if (!classbytecoes.isEmpty()) {
-            ClassBytecodes[] cbcs = classbytecoes.toArray(new ClassBytecodes[classbytecoes.size()]);
+    private void load(Collection<ClassBytecodes> classbytecodes) {
+        if (!classbytecodes.isEmpty()) {
+            ClassBytecodes[] cbcs = classbytecodes.toArray(new ClassBytecodes[classbytecodes.size()]);
             try {
                 state.executionControl().load(cbcs);
                 state.classTracker.markLoaded(cbcs);
@@ -731,6 +731,7 @@
                 state.classTracker.markLoaded(cbcs, ex.installed());
             } catch (NotImplementedException ex) {
                 state.debug(ex, "Seriously?!? load not implemented");
+                state.closeDown();
             } catch (EngineTerminationException ex) {
                 state.closeDown();
             }
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java	Wed Nov 23 19:15:26 2016 +0000
@@ -30,6 +30,7 @@
 import java.io.InputStream;
 import java.io.InterruptedIOException;
 import java.io.PrintStream;
+import java.net.InetAddress;
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -92,7 +93,6 @@
     final BiFunction<Snippet, Integer, String> idGenerator;
     final List<String> extraRemoteVMOptions;
     final List<String> extraCompilerOptions;
-    final ExecutionControl.Generator executionControlGenerator;
 
     private int nextKeyIndex = 1;
 
@@ -102,13 +102,13 @@
     private final Map<Subscription, Consumer<SnippetEvent>> keyStatusListeners = new HashMap<>();
     private boolean closed = false;
 
-    private ExecutionControl executionControl = null;
+    private final ExecutionControl executionControl;
     private SourceCodeAnalysisImpl sourceCodeAnalysis = null;
 
     private static final String L10N_RB_NAME    = "jdk.jshell.resources.l10n";
     private static ResourceBundle outputRB  = null;
 
-    JShell(Builder b) {
+    JShell(Builder b) throws IllegalStateException {
         this.in = b.in;
         this.out = b.out;
         this.err = b.err;
@@ -116,11 +116,18 @@
         this.idGenerator = b.idGenerator;
         this.extraRemoteVMOptions = b.extraRemoteVMOptions;
         this.extraCompilerOptions = b.extraCompilerOptions;
-        this.executionControlGenerator = b.executionControlGenerator==null
-                ? failOverExecutionControlGenerator(JdiDefaultExecutionControl.launch(),
-                        JdiDefaultExecutionControl.listen("localhost"),
-                        JdiDefaultExecutionControl.listen(null))
+        ExecutionControl.Generator executionControlGenerator = b.executionControlGenerator==null
+                ? failOverExecutionControlGenerator(
+                        JdiDefaultExecutionControl.listen(InetAddress.getLoopbackAddress().getHostAddress()),
+                        JdiDefaultExecutionControl.launch(),
+                        JdiDefaultExecutionControl.listen(null)
+                  )
                 : b.executionControlGenerator;
+        try {
+            executionControl = executionControlGenerator.generate(new ExecutionEnvImpl());
+        } catch (Throwable ex) {
+            throw new IllegalStateException("Launching JShell execution engine threw: " + ex.getMessage(), ex);
+        }
 
         this.maps = new SnippetMaps(this);
         this.keyMap = new KeyMap(this);
@@ -331,9 +338,10 @@
          * functionality. This creates a remote process for execution. It is
          * thus important to close the returned instance.
          *
+         * @throws IllegalStateException if the {@code JShell} instance could not be created.
          * @return the state engine
          */
-        public JShell build() {
+        public JShell build() throws IllegalStateException {
             return new JShell(this);
         }
     }
@@ -345,9 +353,10 @@
      * That is, create an instance of {@code JShell}.
      * <p>
      * Equivalent to {@link JShell#builder() JShell.builder()}{@link JShell.Builder#build() .build()}.
+     * @throws IllegalStateException if the {@code JShell} instance could not be created.
      * @return an instance of {@code JShell}.
      */
-    public static JShell create() {
+    public static JShell create() throws IllegalStateException {
         return builder().build();
     }
 
@@ -458,6 +467,7 @@
      * Note that the unnamed package is not accessible from the package in which
      * {@link JShell#eval(String)} code is placed.
      * @param path the path to add to the classpath.
+     * @throws IllegalStateException if this {@code JShell} instance is closed.
      */
     public void addToClasspath(String path) {
         // Compiler
@@ -504,7 +514,11 @@
     public void close() {
         if (!closed) {
             closeDown();
-            executionControl().close();
+            try {
+                executionControl().close();
+            } catch (Throwable ex) {
+                // don't care about exceptions on close
+            }
             if (sourceCodeAnalysis != null) {
                 sourceCodeAnalysis.close();
             }
@@ -733,14 +747,8 @@
     }
 
     // --- private / package-private implementation support ---
+
     ExecutionControl executionControl() {
-        if (executionControl == null) {
-            try {
-                executionControl =  executionControlGenerator.generate(new ExecutionEnvImpl());
-            } catch (Throwable ex) {
-                throw new InternalError("Launching execution engine threw: " + ex.getMessage(), ex);
-            }
-        }
         return executionControl;
     }
 
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/MemoryFileManager.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/MemoryFileManager.java	Wed Nov 23 19:15:26 2016 +0000
@@ -73,7 +73,7 @@
 
     // Upcoming Jigsaw
     private Method inferModuleNameMethod = null;
-    private Method listModuleLocationsMethod = null;
+    private Method listLocationsForModulesMethod = null;
 
     Iterable<? extends Path> getLocationAsPaths(Location loc) {
         return this.stdFileManager.getLocationAsPaths(loc);
@@ -203,13 +203,13 @@
     }
 
     // Make compatible with Jigsaw
-    public Iterable<Set<Location>> listModuleLocations(Location location) throws IOException {
+    public Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
         try {
-            if (listModuleLocationsMethod == null) {
-                listModuleLocationsMethod = JavaFileManager.class.getDeclaredMethod("listModuleLocations", Location.class);
+            if (listLocationsForModulesMethod == null) {
+                listLocationsForModulesMethod = JavaFileManager.class.getDeclaredMethod("listLocationsForModules", Location.class);
             }
             @SuppressWarnings("unchecked")
-            Iterable<Set<Location>> result = (Iterable<Set<Location>>) listModuleLocationsMethod.invoke(stdFileManager, location);
+            Iterable<Set<Location>> result = (Iterable<Set<Location>>) listLocationsForModulesMethod.invoke(stdFileManager, location);
             return result;
         } catch (NoSuchMethodException | SecurityException ex) {
             throw new InternalError("Cannot lookup JavaFileManager method", ex);
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java	Wed Nov 23 19:15:26 2016 +0000
@@ -102,11 +102,13 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
+
 import static java.util.stream.Collectors.collectingAndThen;
 import static java.util.stream.Collectors.joining;
 import static java.util.stream.Collectors.toCollection;
 import static java.util.stream.Collectors.toList;
 import static java.util.stream.Collectors.toSet;
+
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
 
@@ -129,6 +131,8 @@
 import static jdk.jshell.SourceCodeAnalysis.Completeness.DEFINITELY_INCOMPLETE;
 import static jdk.jshell.TreeDissector.printType;
 
+import static java.util.stream.Collectors.joining;
+
 /**
  * The concrete implementation of SourceCodeAnalysis.
  * @author Robert Field
@@ -1341,9 +1345,9 @@
                                 .collect(joining(" & "));
             }
             case FIELD:
-                return elementHeader(at, el.getEnclosingElement(), includeParameterNames, false) + "." + el.getSimpleName() + ":" + el.asType();
+                return appendDot(elementHeader(at, el.getEnclosingElement(), includeParameterNames, false)) + el.getSimpleName() + ":" + el.asType();
             case ENUM_CONSTANT:
-                return elementHeader(at, el.getEnclosingElement(), includeParameterNames, false) + "." + el.getSimpleName();
+                return appendDot(elementHeader(at, el.getEnclosingElement(), includeParameterNames, false)) + el.getSimpleName();
             case EXCEPTION_PARAMETER: case LOCAL_VARIABLE: case PARAMETER: case RESOURCE_VARIABLE:
                 return el.getSimpleName() + ":" + el.asType();
             case CONSTRUCTOR: case METHOD: {
@@ -1407,6 +1411,9 @@
                 return el.toString();
         }
     }
+    private String appendDot(String fqn) {
+        return fqn.isEmpty() ? fqn : fqn + ".";
+    }
     private TypeMirror unwrapArrayType(TypeMirror arrayType) {
         if (arrayType.getKind() == TypeKind.ARRAY) {
             return ((ArrayType)arrayType).getComponentType();
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiDefaultExecutionControl.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiDefaultExecutionControl.java	Wed Nov 23 19:15:26 2016 +0000
@@ -63,7 +63,10 @@
  */
 public class JdiDefaultExecutionControl extends JdiExecutionControl {
 
-    private static final String REMOTE_AGENT = RemoteExecutionControl.class.getName();
+    /**
+     * Default time-out expressed in milliseconds.
+     */
+    private static final int DEFAULT_TIMEOUT = 5000;
 
     private VirtualMachine vm;
     private Process process;
@@ -73,24 +76,60 @@
 
     /**
      * Creates an ExecutionControl instance based on a JDI
-     * {@code LaunchingConnector}.
+     * {@code LaunchingConnector}. Same as
+     * {@code JdiDefaultExecutionControl.create(defaultRemoteAgent(), true, null, defaultTimeout())}.
      *
      * @return the generator
      */
     public static ExecutionControl.Generator launch() {
-        return env -> create(env, true, null);
+        return create(defaultRemoteAgent(), true, null, defaultTimeout());
     }
 
     /**
      * Creates an ExecutionControl instance based on a JDI
-     * {@code ListeningConnector}.
+     * {@code ListeningConnector}. Same as
+     * {@code JdiDefaultExecutionControl.create(defaultRemoteAgent(), false, host, defaultTimeout())}.
      *
      * @param host explicit hostname to use, if null use discovered
      * hostname, applies to listening only (!isLaunch)
      * @return the generator
      */
     public static ExecutionControl.Generator listen(String host) {
-        return env -> create(env, false, host);
+        return create(defaultRemoteAgent(), false, host, defaultTimeout());
+    }
+
+    /**
+     * Creates a JDI based ExecutionControl instance.
+     *
+     * @param remoteAgent the remote agent to launch
+     * @param isLaunch does JDI do the launch? That is, LaunchingConnector,
+     * otherwise we start explicitly and use ListeningConnector
+     * @param host explicit hostname to use, if null use discovered
+     * hostname, applies to listening only (!isLaunch)
+     * @param timeout the start-up time-out in milliseconds
+     * @return the generator
+     */
+    public static ExecutionControl.Generator create(String remoteAgent,
+            boolean isLaunch, String host, int timeout) {
+        return env -> create(env, remoteAgent, isLaunch, host, timeout);
+    }
+
+    /**
+     * Default remote agent.
+     *
+     * @return the name of the standard remote agent
+     */
+    public static String defaultRemoteAgent() {
+        return RemoteExecutionControl.class.getName();
+    }
+
+    /**
+     * Default remote connection time-out
+     *
+     * @return time to wait for connection before failing, expressed in milliseconds.
+     */
+    public static int defaultTimeout() {
+        return DEFAULT_TIMEOUT;
     }
 
     /**
@@ -103,6 +142,7 @@
      *
      * @param env the context passed by
      * {@link jdk.jshell.spi.ExecutionControl#start(jdk.jshell.spi.ExecutionEnv) }
+     * @param remoteAgent the remote agent to launch
      * @param isLaunch does JDI do the launch? That is, LaunchingConnector,
      * otherwise we start explicitly and use ListeningConnector
      * @param host explicit hostname to use, if null use discovered
@@ -110,16 +150,16 @@
      * @return the channel
      * @throws IOException if there are errors in set-up
      */
-    private static ExecutionControl create(ExecutionEnv env,
-            boolean isLaunch, String host) throws IOException {
+    private static ExecutionControl create(ExecutionEnv env, String remoteAgent,
+            boolean isLaunch, String host, int timeout) throws IOException {
         try (final ServerSocket listener = new ServerSocket(0, 1, InetAddress.getLoopbackAddress())) {
-            // timeout after 60 seconds
-            listener.setSoTimeout(60000);
+            // timeout on I/O-socket
+            listener.setSoTimeout(timeout);
             int port = listener.getLocalPort();
 
             // Set-up the JDI connection
             JdiInitiator jdii = new JdiInitiator(port,
-                    env.extraRemoteVMOptions(), REMOTE_AGENT, isLaunch, host);
+                    env.extraRemoteVMOptions(), remoteAgent, isLaunch, host, timeout);
             VirtualMachine vm = jdii.vm();
             Process process = jdii.process();
 
@@ -197,7 +237,7 @@
                 for (ThreadReference thread : vm().allThreads()) {
                     // could also tag the thread (e.g. using name), to find it easier
                     for (StackFrame frame : thread.frames()) {
-                        if (REMOTE_AGENT.equals(frame.location().declaringType().name()) &&
+                        if (defaultRemoteAgent().equals(frame.location().declaringType().name()) &&
                                 (    "invoke".equals(frame.location().method().name())
                                 || "varValue".equals(frame.location().method().name()))) {
                             ObjectReference thiz = frame.thisObject();
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiInitiator.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiInitiator.java	Wed Nov 23 19:15:26 2016 +0000
@@ -25,6 +25,7 @@
 package jdk.jshell.execution;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -35,6 +36,13 @@
 import com.sun.jdi.connect.Connector;
 import com.sun.jdi.connect.LaunchingConnector;
 import com.sun.jdi.connect.ListeningConnector;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import com.sun.jdi.connect.IllegalConnectorArgumentsException;
 
 /**
  * Sets up a JDI connection, providing the resulting JDI {@link VirtualMachine}
@@ -42,6 +50,12 @@
  */
 public class JdiInitiator {
 
+    // factor for the timeout on all of connect
+    private static final double CONNECT_TIMEOUT_FACTOR = 1.5;
+
+    // Over-all connect time-out
+    private final int connectTimeout;
+
     private VirtualMachine vm;
     private Process process = null;
     private final Connector connector;
@@ -58,10 +72,12 @@
      * otherwise we start explicitly and use ListeningConnector
      * @param host explicit hostname to use, if null use discovered
      * hostname, applies to listening only (!isLaunch)
+     * @param timeout the start-up time-out in milliseconds
      */
     public JdiInitiator(int port, List<String> remoteVMOptions, String remoteAgent,
-            boolean isLaunch, String host) {
+            boolean isLaunch, String host, int timeout) {
         this.remoteAgent = remoteAgent;
+        this.connectTimeout = (int) (timeout * CONNECT_TIMEOUT_FACTOR);
         String connectorName
                 = isLaunch
                         ? "com.sun.jdi.CommandLineLaunch"
@@ -74,8 +90,11 @@
                 = isLaunch
                         ? launchArgs(port, String.join(" ", remoteVMOptions))
                         : new HashMap<>();
-        if (host != null && !isLaunch) {
-            argumentName2Value.put("localAddress", host);
+        if (!isLaunch) {
+            argumentName2Value.put("timeout", ""+timeout);
+            if (host != null && !isLaunch) {
+                argumentName2Value.put("localAddress", host);
+            }
         }
         this.connectorArgs = mergeConnectorArgs(connector, argumentName2Value);
         this.vm = isLaunch
@@ -106,13 +125,12 @@
     private VirtualMachine launchTarget() {
         LaunchingConnector launcher = (LaunchingConnector) connector;
         try {
-            VirtualMachine new_vm = launcher.launch(connectorArgs);
+            VirtualMachine new_vm = timedVirtualMachineCreation(() -> launcher.launch(connectorArgs), null);
             process = new_vm.process();
             return new_vm;
-        } catch (Exception ex) {
-            reportLaunchFail(ex, "launch");
+        } catch (Throwable ex) {
+            throw reportLaunchFail(ex, "launch");
         }
-        return null;
     }
 
     /**
@@ -140,15 +158,52 @@
             ProcessBuilder pb = new ProcessBuilder(args);
             process = pb.start();
 
-            // Forward out, err, and in
             // Accept the connection from the remote agent
-            vm = listener.accept(connectorArgs);
-            listener.stopListening(connectorArgs);
+            vm = timedVirtualMachineCreation(() -> listener.accept(connectorArgs),
+                    () -> process.waitFor());
             return vm;
-        } catch (Exception ex) {
-            reportLaunchFail(ex, "listen");
+        } catch (Throwable ex) {
+            if (process != null) {
+                process.destroyForcibly();
+            }
+            throw reportLaunchFail(ex, "listen");
+        } finally {
+            try {
+                listener.stopListening(connectorArgs);
+            } catch (IOException | IllegalConnectorArgumentsException ex) {
+                // ignore
+            }
         }
-        return null;
+    }
+
+    VirtualMachine timedVirtualMachineCreation(Callable<VirtualMachine> creator,
+            Callable<Integer> processComplete) throws Exception {
+        VirtualMachine result;
+        ExecutorService executor = Executors.newCachedThreadPool(runnable -> {
+            Thread thread = Executors.defaultThreadFactory().newThread(runnable);
+            thread.setDaemon(true);
+            return thread;
+        });
+        try {
+            Future<VirtualMachine> future = executor.submit(creator);
+            if (processComplete != null) {
+                executor.submit(() -> {
+                    Integer i = processComplete.call();
+                    future.cancel(true);
+                    return i;
+                });
+            }
+
+            try {
+                result = future.get(connectTimeout, TimeUnit.MILLISECONDS);
+            } catch (TimeoutException ex) {
+                future.cancel(true);
+                throw ex;
+            }
+        } finally {
+            executor.shutdownNow();
+        }
+        return result;
     }
 
     private Connector findConnector(String name) {
@@ -194,8 +249,10 @@
         return argumentName2Value;
     }
 
-    private void reportLaunchFail(Exception ex, String context) {
-        throw new InternalError("Failed remote " + context + ": " + connector +
+    private InternalError reportLaunchFail(Throwable ex, String context) {
+        return new InternalError("Failed remote " + context + ": "
+                + ex.toString()
+                + " @ " + connector +
                 " -- " + connectorArgs, ex);
     }
 
--- a/langtools/test/ProblemList.txt	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/test/ProblemList.txt	Wed Nov 23 19:15:26 2016 +0000
@@ -38,6 +38,9 @@
 
 jdk/jshell/EditorPadTest.java                                                   8161276    windows-all    Test set-up cannot press buttons
 jdk/jshell/ToolBasicTest.java                                                   8139873    generic-all    JShell tests failing
+jdk/jshell/ExternalEditorTest.java                                              8170108    generic-all
+jdk/jshell/ToolFormatTest.java                                                  8170216    solaris-sparcv9
+jdk/jshell/ReplaceTest.java                                                     8170216    solaris-sparcv9
 
 ###########################################################################
 #
--- a/langtools/test/jdk/internal/shellsupport/doc/JavadocFormatterTest.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/test/jdk/internal/shellsupport/doc/JavadocFormatterTest.java	Wed Nov 23 19:15:26 2016 +0000
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8131019
+ * @bug 8131019 8169561
  * @summary Test JavadocFormatter
  * @library /tools/lib
  * @modules jdk.compiler/jdk.internal.shellsupport.doc
@@ -388,6 +388,17 @@
         if (!Objects.equals(actual, expected)) {
             throw new AssertionError("Incorrect output: " + actual);
         }
+
+        //unknown HTML tag:
+        actual = new JavadocFormatter(66, false).formatJavadoc("test",
+                "1234 <unknown any any>1234</unknown> 1234");
+
+        expected = "test\n" +
+                   "1234 1234 1234\n";
+
+        if (!Objects.equals(actual, expected)) {
+            throw new AssertionError("Incorrect output: " + actual);
+        }
     }
 
 }
--- a/langtools/test/jdk/javadoc/doclet/testSearch/TestSearch.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testSearch/TestSearch.java	Wed Nov 23 19:15:26 2016 +0000
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8141492 8071982 8141636
+ * @bug 8141492 8071982 8141636 8147890
  * @summary Test the search feature of javadoc.
  * @author bpatel
  * @library ../lib
@@ -31,7 +31,6 @@
  * @build JavadocTester
  * @run main TestSearch
  */
-
 public class TestSearch extends JavadocTester {
 
     public static void main(String... args) throws Exception {
@@ -241,146 +240,160 @@
         // Test for search tags markup in index file.
         checkOutput("index-all.html", expectedOutput,
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg/package-summary.html#phrasewithspaces\">"
-                        + "phrase with spaces</a></span> - Search tag in pkg</dt>",
+                + "phrase with spaces</a></span> - Search tag in pkg</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg/package-summary.html#pkg\">"
-                        + "pkg</a></span> - Search tag in pkg</dt>",
+                + "pkg</a></span> - Search tag in pkg</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg/package-summary.html#pkg2.5\">"
-                        + "pkg2.5</a></span> - Search tag in pkg</dt>",
+                + "pkg2.5</a></span> - Search tag in pkg</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg/package-summary.html#r\">"
-                        + "r</a></span> - Search tag in pkg</dt>",
+                + "r</a></span> - Search tag in pkg</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg1/RegClass.html#searchphrase\">"
-                        + "search phrase</a></span> - Search tag in pkg1.RegClass</dt>",
+                + "search phrase</a></span> - Search tag in pkg1.RegClass</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg1/RegClass.html#SearchWordWithDescription\">"
-                        + "SearchWordWithDescription</a></span> - Search tag in pkg1.RegClass.CONSTANT_FIELD_1</dt>",
+                + "SearchWordWithDescription</a></span> - Search tag in pkg1.RegClass.CONSTANT_FIELD_1</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestAnnotationType.html#searchphrasewithdescdeprecated\">"
-                        + "search phrase with desc deprecated</a></span> - Search tag in pkg2.TestAnnotationType</dt>",
+                + "search phrase with desc deprecated</a></span> - Search tag in pkg2.TestAnnotationType</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestClass.html#SearchTagDeprecatedClass\">"
-                        + "SearchTagDeprecatedClass</a></span> - Search tag in pkg2.TestClass</dt>",
+                + "SearchTagDeprecatedClass</a></span> - Search tag in pkg2.TestClass</dt>",
+                "<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestEnum.html#searchphrasedeprecated\">"
+                + "search phrase deprecated</a></span> - Search tag in pkg2.TestEnum.ONE</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestEnum.html#searchphrasedeprecated\">"
-                        + "search phrase deprecated</a></span> - Search tag in pkg2.TestEnum.ONE</dt>",
-                "<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestEnum.html#searchphrasedeprecated\">"
-                        + "search phrase deprecated</a></span> - Search tag in pkg2.TestEnum.ONE</dt>",
+                + "search phrase deprecated</a></span> - Search tag in pkg2.TestEnum.ONE</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestError.html#SearchTagDeprecatedMethod\">"
-                        + "SearchTagDeprecatedMethod</a></span> - Search tag in pkg2.TestError</dt>",
+                + "SearchTagDeprecatedMethod</a></span> - Search tag in pkg2.TestError</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestError.html#SearchTagDeprecatedMethod\">"
-                        + "SearchTagDeprecatedMethod</a></span> - Search tag in pkg2.TestError</dt>",
+                + "SearchTagDeprecatedMethod</a></span> - Search tag in pkg2.TestError</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg/package-summary.html#SingleWord\">"
-                        + "SingleWord</a></span> - Search tag in pkg</dt>",
+                + "SingleWord</a></span> - Search tag in pkg</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg/AnotherClass.ModalExclusionType.html"
-                        + "#nested%7B@indexnested_tag_test%7D\">nested {@index nested_tag_test}</a></span> - "
-                        + "Search tag in pkg.AnotherClass.ModalExclusionType.NO_EXCLUDE</dt>",
+                + "#nested%7B@indexnested_tag_test%7D\">nested {@index nested_tag_test}</a></span> - "
+                + "Search tag in pkg.AnotherClass.ModalExclusionType.NO_EXCLUDE</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg/AnotherClass.ModalExclusionType.html"
-                        + "#html-span-see-/span-\">html &lt;span&gt; see &lt;/span&gt;</a></span> - Search "
-                        + "tag in pkg.AnotherClass.ModalExclusionType.APPLICATION_EXCLUDE</dt>",
+                + "#html-span-see-/span-\">html &lt;span&gt; see &lt;/span&gt;</a></span> - Search "
+                + "tag in pkg.AnotherClass.ModalExclusionType.APPLICATION_EXCLUDE</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg/AnotherClass.html#quoted\">quoted</a>"
-                        + "</span> - Search tag in pkg.AnotherClass.CONSTANT1</dt>");
+                + "</span> - Search tag in pkg.AnotherClass.CONSTANT1</dt>",
+                "<dt><span class=\"memberNameLink\"><a href=\"pkg2/TestEnum.html#ONE\">ONE</a></span> - "
+                + "pkg2.<a href=\"pkg2/TestEnum.html\" title=\"enum in pkg2\">TestEnum</a></dt>",
+                "<dt><span class=\"memberNameLink\"><a href=\"pkg2/TestEnum.html#THREE\">THREE</a></span> - "
+                + "pkg2.<a href=\"pkg2/TestEnum.html\" title=\"enum in pkg2\">TestEnum</a></dt>",
+                "<dt><span class=\"memberNameLink\"><a href=\"pkg2/TestEnum.html#TWO\">TWO</a></span> - "
+                + "pkg2.<a href=\"pkg2/TestEnum.html\" title=\"enum in pkg2\">TestEnum</a></dt>");
         checkOutput("index-all.html", true,
                 "<div class=\"block\"><span class=\"deprecationComment\">class_test1 passes. Search tag"
-                        + " <a id=\"SearchTagDeprecatedClass\">SearchTagDeprecatedClass</a></span></div>",
+                + " <a id=\"SearchTagDeprecatedClass\">SearchTagDeprecatedClass</a></span></div>",
                 "<div class=\"block\"><span class=\"deprecationComment\">error_test3 passes. Search tag for\n"
-                        + " method <a id=\"SearchTagDeprecatedMethod\">SearchTagDeprecatedMethod</a></span></div>");
+                + " method <a id=\"SearchTagDeprecatedMethod\">SearchTagDeprecatedMethod</a></span></div>");
     }
 
     void checkSplitIndex() {
         // Test for search tags markup in split index file.
-        checkOutput("index-files/index-12.html", true,
+        checkOutput("index-files/index-13.html", true,
                 "<dt><span class=\"searchTagLink\"><a href=\"../pkg1/RegClass.html#searchphrase\">"
-                        + "search phrase</a></span> - Search tag in pkg1.RegClass</dt>",
+                + "search phrase</a></span> - Search tag in pkg1.RegClass</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"../pkg1/RegClass.html#SearchWordWithDescription\">"
-                        + "SearchWordWithDescription</a></span> - Search tag in pkg1.RegClass.CONSTANT_FIELD_1</dt>",
+                + "SearchWordWithDescription</a></span> - Search tag in pkg1.RegClass.CONSTANT_FIELD_1</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"../pkg2/TestAnnotationType.html#searchphrasewithdescdeprecated\">"
-                        + "search phrase with desc deprecated</a></span> - Search tag in pkg2.TestAnnotationType</dt>",
+                + "search phrase with desc deprecated</a></span> - Search tag in pkg2.TestAnnotationType</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"../pkg2/TestClass.html#SearchTagDeprecatedClass\">"
-                        + "SearchTagDeprecatedClass</a></span> - Search tag in pkg2.TestClass</dt>",
+                + "SearchTagDeprecatedClass</a></span> - Search tag in pkg2.TestClass</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"../pkg2/TestEnum.html#searchphrasedeprecated\">"
-                        + "search phrase deprecated</a></span> - Search tag in pkg2.TestEnum.ONE</dt>",
+                + "search phrase deprecated</a></span> - Search tag in pkg2.TestEnum.ONE</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"../pkg2/TestEnum.html#searchphrasedeprecated\">"
-                        + "search phrase deprecated</a></span> - Search tag in pkg2.TestEnum.ONE</dt>",
+                + "search phrase deprecated</a></span> - Search tag in pkg2.TestEnum.ONE</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"../pkg2/TestError.html#SearchTagDeprecatedMethod\">"
-                        + "SearchTagDeprecatedMethod</a></span> - Search tag in pkg2.TestError</dt>",
+                + "SearchTagDeprecatedMethod</a></span> - Search tag in pkg2.TestError</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"../pkg2/TestError.html#SearchTagDeprecatedMethod\">"
-                        + "SearchTagDeprecatedMethod</a></span> - Search tag in pkg2.TestError</dt>",
+                + "SearchTagDeprecatedMethod</a></span> - Search tag in pkg2.TestError</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"../pkg/package-summary.html#SingleWord\">"
-                        + "SingleWord</a></span> - Search tag in pkg</dt>");
-        checkOutput("index-files/index-9.html", true,
+                + "SingleWord</a></span> - Search tag in pkg</dt>");
+        checkOutput("index-files/index-10.html", true,
                 "<dt><span class=\"searchTagLink\"><a href=\"../pkg/package-summary.html#phrasewithspaces\">"
-                        + "phrase with spaces</a></span> - Search tag in pkg</dt>",
+                + "phrase with spaces</a></span> - Search tag in pkg</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"../pkg/package-summary.html#pkg\">"
-                        + "pkg</a></span> - Search tag in pkg</dt>",
+                + "pkg</a></span> - Search tag in pkg</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"../pkg/package-summary.html#pkg2.5\">"
-                        + "pkg2.5</a></span> - Search tag in pkg</dt>");
-        checkOutput("index-files/index-11.html", true,
+                + "pkg2.5</a></span> - Search tag in pkg</dt>");
+        checkOutput("index-files/index-12.html", true,
                 "<dt><span class=\"searchTagLink\"><a href=\"../pkg/package-summary.html#r\">"
-                        + "r</a></span> - Search tag in pkg</dt>");
+                + "r</a></span> - Search tag in pkg</dt>");
         checkOutput("index-files/index-8.html", true,
                 "<dt><span class=\"searchTagLink\"><a href=\"../pkg/AnotherClass.ModalExclusionType.html"
-                        + "#nested%7B@indexnested_tag_test%7D\">nested {@index nested_tag_test}</a></span> - "
-                        + "Search tag in pkg.AnotherClass.ModalExclusionType.NO_EXCLUDE</dt>");
+                + "#nested%7B@indexnested_tag_test%7D\">nested {@index nested_tag_test}</a></span> - "
+                + "Search tag in pkg.AnotherClass.ModalExclusionType.NO_EXCLUDE</dt>");
         checkOutput("index-files/index-5.html", true,
                 "<dt><span class=\"searchTagLink\"><a href=\"../pkg/AnotherClass.ModalExclusionType.html"
-                        + "#html-span-see-/span-\">html &lt;span&gt; see &lt;/span&gt;</a></span> - Search "
-                        + "tag in pkg.AnotherClass.ModalExclusionType.APPLICATION_EXCLUDE</dt>");
-        checkOutput("index-files/index-10.html", true,
+                + "#html-span-see-/span-\">html &lt;span&gt; see &lt;/span&gt;</a></span> - Search "
+                + "tag in pkg.AnotherClass.ModalExclusionType.APPLICATION_EXCLUDE</dt>");
+        checkOutput("index-files/index-11.html", true,
                 "<dt><span class=\"searchTagLink\"><a href=\"../pkg/AnotherClass.html#quoted\">quoted</a>"
-                        + "</span> - Search tag in pkg.AnotherClass.CONSTANT1</dt>");
+                + "</span> - Search tag in pkg.AnotherClass.CONSTANT1</dt>");
+        checkOutput("index-files/index-9.html", true,
+                "<dt><span class=\"memberNameLink\"><a href=\"../pkg2/TestEnum.html#ONE\">ONE</a>"
+                + "</span> - pkg2.<a href=\"../pkg2/TestEnum.html\" title=\"enum in pkg2\">TestEnum</a></dt>");
+        checkOutput("index-files/index-14.html", true,
+                "<dt><span class=\"memberNameLink\"><a href=\"../pkg2/TestEnum.html#THREE\">THREE</a></span> - "
+                + "pkg2.<a href=\"../pkg2/TestEnum.html\" title=\"enum in pkg2\">TestEnum</a></dt>",
+                "<dt><span class=\"memberNameLink\"><a href=\"../pkg2/TestEnum.html#TWO\">TWO</a></span> - "
+                + "pkg2.<a href=\"../pkg2/TestEnum.html\" title=\"enum in pkg2\">TestEnum</a></dt>");
     }
 
     void checkIndexNoComment() {
         // Test for search tags markup in index file when javadoc is executed with -nocomment.
         checkOutput("index-all.html", false,
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg/package-summary.html#phrasewithspaces\">"
-                        + "phrase with spaces</a></span> - Search tag in pkg</dt>",
+                + "phrase with spaces</a></span> - Search tag in pkg</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg/package-summary.html#pkg\">"
-                        + "pkg</a></span> - Search tag in pkg</dt>",
+                + "pkg</a></span> - Search tag in pkg</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg/package-summary.html#pkg2.5\">"
-                        + "pkg2.5</a></span> - Search tag in pkg</dt>",
+                + "pkg2.5</a></span> - Search tag in pkg</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg/package-summary.html#r\">"
-                        + "r</a></span> - Search tag in pkg</dt>",
+                + "r</a></span> - Search tag in pkg</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg1/RegClass.html#searchphrase\">"
-                        + "search phrase</a></span> - Search tag in pkg1.RegClass</dt>",
+                + "search phrase</a></span> - Search tag in pkg1.RegClass</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg1/RegClass.html#SearchWordWithDescription\">"
-                        + "SearchWordWithDescription</a></span> - Search tag in pkg1.RegClass.CONSTANT_FIELD_1</dt>",
+                + "SearchWordWithDescription</a></span> - Search tag in pkg1.RegClass.CONSTANT_FIELD_1</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestAnnotationType.html#searchphrasewithdescdeprecated\">"
-                        + "search phrase with desc deprecated</a></span> - Search tag in pkg2.TestAnnotationType</dt>",
+                + "search phrase with desc deprecated</a></span> - Search tag in pkg2.TestAnnotationType</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestClass.html#SearchTagDeprecatedClass\">"
-                        + "SearchTagDeprecatedClass</a></span> - Search tag in pkg2.TestClass</dt>",
+                + "SearchTagDeprecatedClass</a></span> - Search tag in pkg2.TestClass</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg/package-summary.html#SingleWord\">"
-                        + "SingleWord</a></span> - Search tag in pkg</dt>",
+                + "SingleWord</a></span> - Search tag in pkg</dt>",
                 "<div class=\"block\"><span class=\"deprecationComment\">class_test1 passes. Search tag"
-                        + " <a id=\"SearchTagDeprecatedClass\">SearchTagDeprecatedClass</a></span></div>",
+                + " <a id=\"SearchTagDeprecatedClass\">SearchTagDeprecatedClass</a></span></div>",
                 "<div class=\"block\"><span class=\"deprecationComment\">error_test3 passes. Search tag for\n"
-                        + " method <a id=\"SearchTagDeprecatedMethod\">SearchTagDeprecatedMethod</a></span></div>");
+                + " method <a id=\"SearchTagDeprecatedMethod\">SearchTagDeprecatedMethod</a></span></div>");
         checkOutput("index-all.html", true,
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestEnum.html#searchphrasedeprecated\">"
-                        + "search phrase deprecated</a></span> - Search tag in pkg2.TestEnum.ONE</dt>",
+                + "search phrase deprecated</a></span> - Search tag in pkg2.TestEnum.ONE</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestError.html#SearchTagDeprecatedMethod\">"
-                        + "SearchTagDeprecatedMethod</a></span> - Search tag in pkg2.TestError</dt>");
+                + "SearchTagDeprecatedMethod</a></span> - Search tag in pkg2.TestError</dt>");
     }
 
     void checkIndexNoDeprecated() {
         // Test for search tags markup in index file when javadoc is executed using -nodeprecated.
         checkOutput("index-all.html", true,
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg/package-summary.html#phrasewithspaces\">"
-                        + "phrase with spaces</a></span> - Search tag in pkg</dt>",
+                + "phrase with spaces</a></span> - Search tag in pkg</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg1/RegClass.html#searchphrase\">"
-                        + "search phrase</a></span> - Search tag in pkg1.RegClass</dt>",
+                + "search phrase</a></span> - Search tag in pkg1.RegClass</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg1/RegClass.html#SearchWordWithDescription\">"
-                        + "SearchWordWithDescription</a></span> - Search tag in pkg1.RegClass.CONSTANT_FIELD_1</dt>",
+                + "SearchWordWithDescription</a></span> - Search tag in pkg1.RegClass.CONSTANT_FIELD_1</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg/package-summary.html#SingleWord\">"
-                        + "SingleWord</a></span> - Search tag in pkg</dt>");
+                + "SingleWord</a></span> - Search tag in pkg</dt>");
         checkOutput("index-all.html", false,
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestAnnotationType.html#searchphrasewithdescdeprecated\">"
-                        + "search phrase with desc deprecated</a></span> - Search tag in pkg2.TestAnnotationType</dt>",
+                + "search phrase with desc deprecated</a></span> - Search tag in pkg2.TestAnnotationType</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestClass.html#SearchTagDeprecatedClass\">"
-                        + "SearchTagDeprecatedClass</a></span> - Search tag in pkg2.TestClass</dt>",
+                + "SearchTagDeprecatedClass</a></span> - Search tag in pkg2.TestClass</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestEnum.html#searchphrasedeprecated\">"
-                        + "search phrase deprecated</a></span> - Search tag in pkg2.TestEnum.ONE</dt>",
+                + "search phrase deprecated</a></span> - Search tag in pkg2.TestEnum.ONE</dt>",
                 "<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestError.html#SearchTagDeprecatedMethod\">"
-                        + "SearchTagDeprecatedMethod</a></span> - Search tag in pkg2.TestError</dt>",
+                + "SearchTagDeprecatedMethod</a></span> - Search tag in pkg2.TestError</dt>",
                 "<div class=\"block\"><span class=\"deprecationComment\">class_test1 passes. Search tag"
-                        + " <a id=\"SearchTagDeprecatedClass\">SearchTagDeprecatedClass</a></span></div>",
+                + " <a id=\"SearchTagDeprecatedClass\">SearchTagDeprecatedClass</a></span></div>",
                 "<div class=\"block\"><span class=\"deprecationComment\">error_test3 passes. Search tag for\n"
-                        + " method <a id=\"SearchTagDeprecatedMethod\">SearchTagDeprecatedMethod</a></span></div>");
+                + " method <a id=\"SearchTagDeprecatedMethod\">SearchTagDeprecatedMethod</a></span></div>");
     }
 
     void checkJavaFXOutput() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/BadOptionsTest.java	Wed Nov 23 19:15:26 2016 +0000
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8169676
+ * @summary boolean result of Option.process is often ignored
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ * @modules jdk.compiler/com.sun.tools.javac.main
+ * @modules jdk.javadoc/jdk.javadoc.internal.api
+ * @modules jdk.javadoc/jdk.javadoc.internal.tool
+ * @library /tools/lib
+ * @build toolbox.JavacTask toolbox.JavadocTask toolbox.TestRunner toolbox.ToolBox
+ * @run main BadOptionsTest
+ */
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.Set;
+
+import javax.lang.model.SourceVersion;
+
+import jdk.javadoc.doclet.Doclet;
+import jdk.javadoc.doclet.DocletEnvironment;
+import jdk.javadoc.doclet.Reporter;
+
+import toolbox.JavadocTask;
+import toolbox.ModuleBuilder;
+import toolbox.Task;
+import toolbox.TestRunner;
+import toolbox.ToolBox;
+
+/*
+ * This is primarily a test of the error reporting mechanisms
+ * for bad options provided by javac and utilized by javadoc.
+ * It is not an exhaustive test of all bad option forms detected
+ * by javac/javadoc.
+ */
+public class BadOptionsTest extends TestRunner {
+
+    public static void main(String... args) throws Exception {
+        BadOptionsTest t = new BadOptionsTest();
+        t.runTests();
+    }
+
+    private final ToolBox tb = new ToolBox();
+    private final Path src = Paths.get("src");
+
+    BadOptionsTest() throws IOException {
+        super(System.err);
+        init();
+    }
+
+    void init() throws IOException {
+        tb.writeJavaFiles(src,
+                "public class C { }");
+
+    }
+
+    @Test
+    public void testAddModulesEmptyArg() {
+        Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
+                .options("--add-modules=")
+                .files(src.resolve("C.java"))
+                .run(Task.Expect.FAIL)
+                .writeAll();
+        checkFound(result.getOutput(Task.OutputKind.DIRECT),
+                "javadoc: error - no value for --add-modules option");
+        checkNotFound(result, "Exception", "at jdk.javadoc/");
+    }
+
+    @Test
+    public void testAddModulesBadName() {
+        Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
+                .options("-quiet",
+                        "--add-modules", "123")
+                .files(src.resolve("C.java"))
+                .run(Task.Expect.FAIL)
+                .writeAll();
+        checkFound(result.getOutput(Task.OutputKind.DIRECT),
+                "error: bad name in value for --add-modules option: '123'");
+        checkNotFound(result, "Exception", "at jdk.javadoc/");
+    }
+
+    @Test
+    public void testAddExportsEmptyArg() {
+        Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
+                .options("--add-exports=")
+                .files(src.resolve("C.java"))
+                .run(Task.Expect.FAIL)
+                .writeAll();
+        checkFound(result.getOutput(Task.OutputKind.DIRECT),
+                "javadoc: error - no value for --add-exports option");
+        checkNotFound(result, "Exception", "at jdk.javadoc/");
+    }
+
+    @Test
+    public void testAddExportsBadArg() {
+        Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
+                .options("--add-exports=m/p")
+                .files(src.resolve("C.java"))
+                .run(Task.Expect.FAIL)
+                .writeAll();
+        checkFound(result.getOutput(Task.OutputKind.DIRECT),
+                "javadoc: error - bad value for --add-exports option");
+        checkNotFound(result, "Exception", "at jdk.javadoc/");
+    }
+
+    @Test
+    public void testAddExportsBadName() {
+        Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
+                .options("--add-exports", "m!/p1=m2")
+                .files(src.resolve("C.java"))
+                .run()
+                .writeAll();
+        checkFound(result.getOutput(Task.OutputKind.DIRECT),
+                "warning: bad name in value for --add-exports option: 'm!'");
+        checkNotFound(result, "Exception", "at jdk.javadoc/");
+    }
+
+    private void checkFound(String log, String... expect) {
+        for (String e : expect) {
+            if (!log.contains(e)) {
+                error("Expected string not found: '" + e + "'");
+            }
+        }
+    }
+
+    private void checkNotFound(Task.Result result, String... unexpected) {
+        for (Task.OutputKind k : Task.OutputKind.values()) {
+            String r = result.getOutput(k);
+            for (String u : unexpected) {
+                if (r.contains(u)) {
+                    error("Unexpected string found: '" + u + "'");
+                }
+            }
+        }
+    }
+}
--- a/langtools/test/jdk/jshell/CommandCompletionTest.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/test/jdk/jshell/CommandCompletionTest.java	Wed Nov 23 19:15:26 2016 +0000
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8144095 8164825
+ * @bug 8144095 8164825 8169818 8153402
  * @summary Test Command Completion
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.main
@@ -61,12 +61,13 @@
     public void testList() {
         test(false, new String[] {"--no-startup"},
                 a -> assertCompletion(a, "/l|", false, "/list "),
-                a -> assertCompletion(a, "/list |", false, "-all ", "-history ", "-start "),
-                a -> assertCompletion(a, "/list -h|", false, "-history "),
+                a -> assertCompletion(a, "/list |", false, "-all", "-history", "-start "),
+                a -> assertCompletion(a, "/list -h|", false, "-history"),
                 a -> assertCompletion(a, "/list q|", false),
                 a -> assertVariable(a, "int", "xray"),
-                a -> assertCompletion(a, "/list |", false, "-all ", "-history ", "-start ", "1", "xray"),
-                a -> assertCompletion(a, "/list x|", false, "xray")
+                a -> assertCompletion(a, "/list |", false, "-all", "-history", "-start ", "1 ", "xray "),
+                a -> assertCompletion(a, "/list x|", false, "xray "),
+                a -> assertCompletion(a, "/list xray |", false)
         );
     }
 
@@ -76,8 +77,8 @@
                 a -> assertClass(a, "class cTest {}", "class", "cTest"),
                 a -> assertMethod(a, "int mTest() { return 0; }", "()I", "mTest"),
                 a -> assertVariable(a, "int", "fTest"),
-                a -> assertCompletion(a, "/drop |", false, "1", "2", "3", "cTest", "fTest", "mTest"),
-                a -> assertCompletion(a, "/drop f|", false, "fTest")
+                a -> assertCompletion(a, "/drop |", false, "1 ", "2 ", "3 ", "cTest ", "fTest ", "mTest "),
+                a -> assertCompletion(a, "/drop f|", false, "fTest ")
         );
     }
 
@@ -88,8 +89,54 @@
                 a -> assertClass(a, "class cTest {}", "class", "cTest"),
                 a -> assertMethod(a, "int mTest() { return 0; }", "()I", "mTest"),
                 a -> assertVariable(a, "int", "fTest"),
-                a -> assertCompletion(a, "/edit |", false, "1", "2", "3", "cTest", "fTest", "mTest"),
-                a -> assertCompletion(a, "/edit f|", false, "fTest")
+                a -> assertCompletion(a, "/edit |", false,
+                        "-all" , "-start " , "1 ", "2 ", "3 ", "cTest ", "fTest ", "mTest "),
+                a -> assertCompletion(a, "/edit cTest |", false,
+                        "2 ", "3 ", "fTest ", "mTest "),
+                a -> assertCompletion(a, "/edit 1 fTest |", false,
+                        "2 ", "mTest "),
+                a -> assertCompletion(a, "/edit f|", false, "fTest "),
+                a -> assertCompletion(a, "/edit mTest f|", false, "fTest ")
+        );
+    }
+
+    public void testHelp() {
+        assertCompletion("/help |", false,
+                "/! ", "/-<n> ", "/<id> ", "/? ", "/classpath ", "/drop ",
+                "/edit ", "/exit ", "/help ", "/history ", "/imports ",
+                "/list ", "/methods ", "/open ", "/reload ", "/reset ",
+                "/save ", "/set ", "/types ", "/vars ", "intro ", "shortcuts ");
+        assertCompletion("/? |", false,
+                "/! ", "/-<n> ", "/<id> ", "/? ", "/classpath ", "/drop ",
+                "/edit ", "/exit ", "/help ", "/history ", "/imports ",
+                "/list ", "/methods ", "/open ", "/reload ", "/reset ",
+                "/save ", "/set ", "/types ", "/vars ", "intro ", "shortcuts ");
+        assertCompletion("/help /s|", false,
+                "/save ", "/set ");
+        assertCompletion("/help /set |", false,
+                "editor", "feedback", "format", "mode", "prompt", "start", "truncation");
+        assertCompletion("/help /edit |", false);
+    }
+
+    public void testReload() {
+        assertCompletion("/reload |", false, "-quiet ", "-restore ");
+        assertCompletion("/reload -restore |", false, "-quiet");
+        assertCompletion("/reload -quiet |", false, "-restore");
+        assertCompletion("/reload -restore -quiet |", false);
+    }
+
+    public void testVarsMethodsTypes() {
+        test(false, new String[]{"--no-startup"},
+                a -> assertCompletion(a, "/v|", false, "/vars "),
+                a -> assertCompletion(a, "/m|", false, "/methods "),
+                a -> assertCompletion(a, "/t|", false, "/types "),
+                a -> assertClass(a, "class cTest {}", "class", "cTest"),
+                a -> assertMethod(a, "int mTest() { return 0; }", "()I", "mTest"),
+                a -> assertVariable(a, "int", "fTest"),
+                a -> assertCompletion(a, "/vars |", false, "-all", "-start ", "3 ", "fTest "),
+                a -> assertCompletion(a, "/meth |", false, "-all", "-start ", "2 ", "mTest "),
+                a -> assertCompletion(a, "/typ |", false, "-all", "-start ", "1 ", "cTest "),
+                a -> assertCompletion(a, "/var f|", false, "fTest ")
         );
     }
 
--- a/langtools/test/jdk/jshell/CompletenessTest.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/test/jdk/jshell/CompletenessTest.java	Wed Nov 23 19:15:26 2016 +0000
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8149524 8131024 8165211 8080071 8130454 8167343 8129559
+ * @bug 8149524 8131024 8165211 8080071 8130454 8167343 8129559 8114842
  * @summary Test SourceCodeAnalysis
  * @build KullaTesting TestingInputStream
  * @run testng CompletenessTest
@@ -118,6 +118,10 @@
         "baz: while (true) if (t()) printf('-'); else break baz",
         "java.util.function.IntFunction<int[]> ggg = int[]::new",
         "List<? extends Object> l",
+        "int[] m = {1, 2}",
+        "int[] m = {1, 2}, n = null",
+        "int[] m = {1, 2}, n",
+        "int[] m = {1, 2}, n = {3, 4}",
     };
 
     static final String[] considered_incomplete = new String[] {
@@ -177,6 +181,11 @@
         "void f()",
         "void f() throws E",
         "@A(",
+        "int n = 4,",
+        "int n,",
+        "int[] m = {1, 2},",
+        "int[] m = {1, 2}, n = {3, 4},",
+        "Map<String,"
     };
 
     static final String[] unknown = new String[] {
@@ -315,5 +324,7 @@
         assertStatus("if (t) if ", DEFINITELY_INCOMPLETE, "if (t) if"); //Bug
         assertStatus("int m() {} dfd", COMPLETE, "int m() {}");
         assertStatus("int p = ", DEFINITELY_INCOMPLETE, "int p ="); //Bug
+        assertStatus("int[] m = {1, 2}, n = new int[0];  int i;", COMPLETE,
+                     "int[] m = {1, 2}, n = new int[0];");
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/jshell/DyingRemoteAgent.java	Wed Nov 23 19:15:26 2016 +0000
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import jdk.jshell.JShell;
+import jdk.jshell.execution.JdiDefaultExecutionControl;
+import jdk.jshell.execution.RemoteExecutionControl;
+import static jdk.jshell.execution.JdiDefaultExecutionControl.defaultTimeout;
+
+class DyingRemoteAgent extends RemoteExecutionControl {
+
+    static final boolean INFRA_VERIFY = false;
+
+    public static void main(String[] args) throws Exception {
+        if (INFRA_VERIFY) {
+            RemoteExecutionControl.main(args);
+        } else {
+            System.exit(1);
+        }
+    }
+
+    static JShell state(boolean isLaunch, String host) {
+        return JShell.builder().executionEngine(
+                JdiDefaultExecutionControl.create(
+                        DyingRemoteAgent.class.getName(),
+                        isLaunch,
+                        host,
+                        defaultTimeout())).build();
+    }
+}
--- a/langtools/test/jdk/jshell/EditorTestBase.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/test/jdk/jshell/EditorTestBase.java	Wed Nov 23 19:15:26 2016 +0000
@@ -125,7 +125,6 @@
         );
     }
 
-    @Test(enabled = false) // TODO 8163816
     public void testEditClass1() {
         testEditor(
                 a -> assertClass(a, "class A {}", "class", "A"),
@@ -163,7 +162,6 @@
         );
     }
 
-    @Test(enabled = false) // TODO 8163816
     public void testEditMethod1() {
         testEditor(
                 a -> assertMethod(a, "void f() {}", "()void", "f"),
@@ -247,6 +245,18 @@
         );
     }
 
+    @Test
+    public void testStatementMush() {
+        testEditor(
+                a -> assertCommand(a, "System.out.println(\"Hello\")",
+                        "", "", null, "Hello\n", ""),
+                a -> assertEditOutput(a, "/ed", "b ==> 10", () -> {
+                    writeSource(getSource() + "\nint b = 10");
+                    exit();
+                })
+        );
+    }
+
     public static ExecutorService getExecutor() {
         if (executor == null) {
             executor = Executors.newSingleThreadExecutor();
--- a/langtools/test/jdk/jshell/ExternalEditorTest.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/test/jdk/jshell/ExternalEditorTest.java	Wed Nov 23 19:15:26 2016 +0000
@@ -24,7 +24,7 @@
 /*
  * @test
  * @summary Testing external editor.
- * @bug 8143955 8080843
+ * @bug 8143955 8080843 8163816 8143006
  * @modules jdk.jshell/jdk.internal.jshell.tool
  * @build ReplToolTesting CustomEditor EditorTestBase
  * @run testng ExternalEditorTest
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/jshell/FailOverExecutionControlDyingLaunchTest.java	Wed Nov 23 19:15:26 2016 +0000
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8131029 8160127 8159935 8169519
+ * @summary Test that fail-over works for fail-over ExecutionControl generators.
+ * @modules jdk.jshell/jdk.jshell.execution
+ *          jdk.jshell/jdk.jshell.spi
+ * @build KullaTesting ExecutionControlTestBase
+ * @run testng FailOverExecutionControlDyingLaunchTest
+ */
+
+import org.testng.annotations.Test;
+import org.testng.annotations.BeforeMethod;
+import jdk.jshell.execution.JdiDefaultExecutionControl;
+import static jdk.jshell.execution.JdiDefaultExecutionControl.defaultTimeout;
+import static jdk.jshell.execution.Util.failOverExecutionControlGenerator;
+
+@Test
+public class FailOverExecutionControlDyingLaunchTest extends ExecutionControlTestBase {
+
+    @BeforeMethod
+    @Override
+    public void setUp() {
+        setUp(builder -> builder.executionEngine(failOverExecutionControlGenerator(
+                JdiDefaultExecutionControl.create(
+                        DyingRemoteAgent.class.getName(),
+                        true,
+                        null,
+                        defaultTimeout()),
+                JdiDefaultExecutionControl.launch())));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/jshell/FailOverExecutionControlHangingLaunchTest.java	Wed Nov 23 19:15:26 2016 +0000
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8131029 8160127 8159935 8169519
+ * @summary Test that fail-over works for fail-over ExecutionControl generators.
+ * @modules jdk.jshell/jdk.jshell.execution
+ *          jdk.jshell/jdk.jshell.spi
+ * @build KullaTesting ExecutionControlTestBase
+ * @run testng FailOverExecutionControlHangingLaunchTest
+ */
+
+import org.testng.annotations.Test;
+import org.testng.annotations.BeforeMethod;
+import jdk.jshell.execution.JdiDefaultExecutionControl;
+import static jdk.jshell.execution.JdiDefaultExecutionControl.defaultTimeout;
+import static jdk.jshell.execution.Util.failOverExecutionControlGenerator;
+
+@Test
+public class FailOverExecutionControlHangingLaunchTest extends ExecutionControlTestBase {
+
+    @BeforeMethod
+    @Override
+    public void setUp() {
+        setUp(builder -> builder.executionEngine(failOverExecutionControlGenerator(
+                JdiDefaultExecutionControl.create(
+                        HangingRemoteAgent.class.getName(),
+                        true,
+                        null,
+                        defaultTimeout()),
+                JdiDefaultExecutionControl.launch())));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/jshell/FailOverExecutionControlHangingListenTest.java	Wed Nov 23 19:15:26 2016 +0000
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8131029 8160127 8159935 8169519
+ * @summary Test that fail-over works for fail-over ExecutionControl generators.
+ * @modules jdk.jshell/jdk.jshell.execution
+ *          jdk.jshell/jdk.jshell.spi
+ * @build KullaTesting ExecutionControlTestBase
+ * @run testng FailOverExecutionControlHangingListenTest
+ */
+
+import java.net.InetAddress;
+import org.testng.annotations.Test;
+import org.testng.annotations.BeforeMethod;
+import jdk.jshell.execution.JdiDefaultExecutionControl;
+import static jdk.jshell.execution.JdiDefaultExecutionControl.defaultTimeout;
+import static jdk.jshell.execution.Util.failOverExecutionControlGenerator;
+
+@Test
+public class FailOverExecutionControlHangingListenTest extends ExecutionControlTestBase {
+
+    @BeforeMethod
+    @Override
+    public void setUp() {
+        String loopback = InetAddress.getLoopbackAddress().getHostAddress();
+        setUp(builder -> builder.executionEngine(failOverExecutionControlGenerator(
+                JdiDefaultExecutionControl.create(
+                        HangingRemoteAgent.class.getName(),
+                        false,
+                        loopback,
+                        defaultTimeout()),
+                JdiDefaultExecutionControl.listen(loopback))));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/jshell/HangingRemoteAgent.java	Wed Nov 23 19:15:26 2016 +0000
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import jdk.jshell.JShell;
+import jdk.jshell.execution.JdiDefaultExecutionControl;
+import jdk.jshell.execution.RemoteExecutionControl;
+
+/**
+ * Hang for three minutes (long enough to cause a timeout).
+ */
+class HangingRemoteAgent extends RemoteExecutionControl {
+
+    private static final long DELAY = 4000L;
+    private static final int TIMEOUT = 2000;
+    private static final boolean INFRA_VERIFY = false;
+
+    public static void main(String[] args) throws Exception {
+        if (INFRA_VERIFY) {
+            RemoteExecutionControl.main(args);
+        } else {
+            long end = System.currentTimeMillis() + DELAY;
+            long remaining;
+            while ((remaining = end - System.currentTimeMillis()) > 0L) {
+                try {
+                    Thread.sleep(remaining);
+                } catch (InterruptedException ex) {
+                    // loop again
+                }
+            }
+        }
+    }
+
+    static JShell state(boolean isLaunch, String host) {
+        return JShell.builder().executionEngine(
+                JdiDefaultExecutionControl.create(
+                        HangingRemoteAgent.class.getName(),
+                        isLaunch,
+                        host,
+                        TIMEOUT)).build();
+    }
+
+}
--- a/langtools/test/jdk/jshell/JavadocTest.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/test/jdk/jshell/JavadocTest.java	Wed Nov 23 19:15:26 2016 +0000
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8131019
+ * @bug 8131019 8169561
  * @summary Test Javadoc
  * @library /tools/lib
  * @modules jdk.compiler/com.sun.tools.javac.api
@@ -65,6 +65,11 @@
         assertJavadoc("clz.undef|");
     }
 
+    public void testVariableInRepl() {
+        assertEval("Object o;");
+        assertSignature("o|", "o:java.lang.Object");
+    }
+
     private void prepareZip() {
         String clazz =
                 "package test;\n" +
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/jshell/JdiBadOptionLaunchExecutionControlTest.java	Wed Nov 23 19:15:26 2016 +0000
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8169519 8166581
+ * @summary Tests for JDI connector failure
+ * @modules jdk.jshell/jdk.jshell jdk.jshell/jdk.jshell.spi jdk.jshell/jdk.jshell.execution
+ * @run testng JdiBadOptionLaunchExecutionControlTest
+ */
+
+import org.testng.annotations.Test;
+import jdk.jshell.JShell;
+import jdk.jshell.execution.JdiDefaultExecutionControl;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+@Test
+public class JdiBadOptionLaunchExecutionControlTest {
+
+    private static final String EXPECTED_ERROR =
+            "Launching JShell execution engine threw: Failed remote launch: java.util.concurrent.ExecutionException: com.sun.jdi.connect.VMStartException: VM initialization failed";
+
+    public void badOptionLaunchTest() {
+        try {
+            JShell.builder()
+                    .executionEngine(JdiDefaultExecutionControl.launch())
+                    .remoteVMOptions("-BadBadOption")
+                    .build();
+        } catch (IllegalStateException ex) {
+            assertTrue(ex.getMessage().startsWith(EXPECTED_ERROR), ex.getMessage());
+            return;
+        }
+        fail("Expected IllegalStateException");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/jshell/JdiBadOptionListenExecutionControlTest.java	Wed Nov 23 19:15:26 2016 +0000
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8169519 8166581
+ * @summary Tests for JDI connector failure
+ * @modules jdk.jshell/jdk.jshell jdk.jshell/jdk.jshell.spi jdk.jshell/jdk.jshell.execution
+ * @run testng JdiBadOptionListenExecutionControlTest
+ */
+
+import org.testng.annotations.Test;
+import jdk.jshell.JShell;
+import jdk.jshell.execution.JdiDefaultExecutionControl;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+@Test
+public class JdiBadOptionListenExecutionControlTest {
+
+    private static final String EXPECTED_ERROR =
+            "Launching JShell execution engine threw: Failed remote listen:";
+
+    public void badOptionListenTest() {
+        try {
+            JShell.builder()
+                    .executionEngine(JdiDefaultExecutionControl.listen(null))
+                    .remoteVMOptions("-BadBadOption")
+                    .build();
+        } catch (IllegalStateException ex) {
+            assertTrue(ex.getMessage().startsWith(EXPECTED_ERROR), ex.getMessage());
+            return;
+        }
+        fail("Expected IllegalStateException");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/jshell/JdiBogusHostListenExecutionControlTest.java	Wed Nov 23 19:15:26 2016 +0000
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8169519
+ * @summary Tests for JDI connector failure
+ * @modules jdk.jshell/jdk.jshell jdk.jshell/jdk.jshell.spi jdk.jshell/jdk.jshell.execution
+ * @run testng JdiBogusHostListenExecutionControlTest
+ */
+
+import org.testng.annotations.Test;
+import jdk.jshell.JShell;
+import jdk.jshell.execution.JdiDefaultExecutionControl;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+@Test
+public class JdiBogusHostListenExecutionControlTest {
+
+    private static final String EXPECTED_ERROR =
+            "Launching JShell execution engine threw: Failed remote listen: java.net.SocketException: Unresolved address @ com.sun.jdi.SocketListe";
+
+    public void badOptionListenTest() {
+        try {
+            JShell.builder()
+                    .executionEngine(JdiDefaultExecutionControl.listen("BattyRumbleBuckets-Snurfle-99-Blip"))
+                    .build();
+        } catch (IllegalStateException ex) {
+            assertTrue(ex.getMessage().startsWith(EXPECTED_ERROR), ex.getMessage());
+            return;
+        }
+        fail("Expected IllegalStateException");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/jshell/JdiFailingLaunchExecutionControlTest.java	Wed Nov 23 19:15:26 2016 +0000
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8169519
+ * @summary Tests for JDI connector failure
+ * @modules jdk.jshell/jdk.jshell jdk.jshell/jdk.jshell.spi jdk.jshell/jdk.jshell.execution
+ * @build DyingRemoteAgent
+ * @run testng JdiFailingLaunchExecutionControlTest
+ */
+
+import org.testng.annotations.Test;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+@Test
+public class JdiFailingLaunchExecutionControlTest {
+
+    private static final String EXPECTED_ERROR =
+            "Launching JShell execution engine threw: Accept timed out";
+
+    public void failLaunchTest() {
+        try {
+            System.err.printf("Unexpected return value: %s\n", DyingRemoteAgent.state(true, null).eval("33;"));
+        } catch (IllegalStateException ex) {
+            assertTrue(ex.getMessage().startsWith(EXPECTED_ERROR), ex.getMessage());
+            return;
+        }
+        fail("Expected IllegalStateException");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/jshell/JdiFailingListenExecutionControlTest.java	Wed Nov 23 19:15:26 2016 +0000
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8169519
+ * @summary Tests for JDI connector failure
+ * @modules jdk.jshell/jdk.jshell jdk.jshell/jdk.jshell.spi jdk.jshell/jdk.jshell.execution
+ * @build DyingRemoteAgent
+ * @run testng JdiFailingListenExecutionControlTest
+ */
+
+import org.testng.annotations.Test;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+@Test
+public class JdiFailingListenExecutionControlTest {
+
+    private static final String EXPECTED_ERROR =
+            "Launching JShell execution engine threw: Accept timed out";
+
+    public void failListenTest() {
+        try {
+            System.err.printf("Unexpected return value: %s\n", DyingRemoteAgent.state(true, null).eval("33;"));
+        } catch (IllegalStateException ex) {
+            assertTrue(ex.getMessage().startsWith(EXPECTED_ERROR), ex.getMessage());
+            return;
+        }
+        fail("Expected IllegalStateException");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/jshell/JdiHangingLaunchExecutionControlTest.java	Wed Nov 23 19:15:26 2016 +0000
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8169519
+ * @summary Tests for JDI connector timeout failure
+ * @modules jdk.jshell/jdk.jshell jdk.jshell/jdk.jshell.spi jdk.jshell/jdk.jshell.execution
+ * @build HangingRemoteAgent
+ * @run testng JdiHangingLaunchExecutionControlTest
+ */
+
+import org.testng.annotations.Test;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+@Test
+public class JdiHangingLaunchExecutionControlTest {
+
+    private static final String EXPECTED_ERROR =
+            "Launching JShell execution engine threw: Accept timed out";
+
+    public void hangLaunchTimeoutTest() {
+        try {
+            System.err.printf("Unexpected return value: %s\n",
+                    HangingRemoteAgent.state(true, null).eval("33;"));
+        } catch (IllegalStateException ex) {
+            assertTrue(ex.getMessage().startsWith(EXPECTED_ERROR), ex.getMessage());
+            return;
+        }
+        fail("Expected IllegalStateException");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/jshell/JdiHangingListenExecutionControlTest.java	Wed Nov 23 19:15:26 2016 +0000
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8169519
+ * @summary Tests for JDI connector timeout failure
+ * @modules jdk.jshell/jdk.jshell jdk.jshell/jdk.jshell.spi jdk.jshell/jdk.jshell.execution
+ * @build HangingRemoteAgent
+ * @run testng JdiHangingListenExecutionControlTest
+ */
+
+import org.testng.annotations.Test;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+@Test
+public class JdiHangingListenExecutionControlTest {
+
+    private static final String EXPECTED_ERROR =
+            "Launching JShell execution engine threw: Accept timed out";
+
+    public void hangListenTimeoutTest() {
+        try {
+            System.err.printf("Unexpected return value: %s\n",
+                    HangingRemoteAgent.state(false, null).eval("33;"));
+        } catch (IllegalStateException ex) {
+            assertTrue(ex.getMessage().startsWith(EXPECTED_ERROR), ex.getMessage());
+            return;
+        }
+        fail("Expected IllegalStateException");
+    }
+}
--- a/langtools/test/jdk/jshell/ReplToolTesting.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/test/jdk/jshell/ReplToolTesting.java	Wed Nov 23 19:15:26 2016 +0000
@@ -476,7 +476,7 @@
         code = code.replace("|", "");
         assertTrue(cursor > -1, "'|' not found: " + code);
         List<Suggestion> completions =
-                js.commandCompletionSuggestions(code, cursor, new int[1]); //XXX: ignoring anchor for now
+                js.commandCompletionSuggestions(code, cursor, new int[] {-1}); //XXX: ignoring anchor for now
         return completions.stream()
                           .filter(s -> isSmart == s.matchesType())
                           .map(s -> s.continuation())
--- a/langtools/test/jdk/jshell/StartOptionTest.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/test/jdk/jshell/StartOptionTest.java	Wed Nov 23 19:15:26 2016 +0000
@@ -22,7 +22,7 @@
  */
 
 /*
- * @test 8151754 8080883 8160089
+ * @test 8151754 8080883 8160089 8166581
  * @summary Testing start-up options.
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.main
@@ -48,6 +48,7 @@
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
 
 @Test
 public class StartOptionTest {
@@ -135,6 +136,17 @@
         start("", "Argument to startup missing.", "--no-startup", "--startup");
     }
 
+    public void testStartupFailedOption() throws Exception {
+        try {
+            start("", "", "-R-hoge-foo-bar");
+        } catch (IllegalStateException ex) {
+            String s = ex.getMessage();
+            assertTrue(s.startsWith("Launching JShell execution engine threw: Failed remote"), s);
+            return;
+        }
+        fail("Expected IllegalStateException");
+    }
+
     public void testStartupUnknown() throws Exception {
         start("", "File 'UNKNOWN' for '--startup' is not found.", "--startup", "UNKNOWN");
     }
--- a/langtools/test/jdk/jshell/UserJdiUserRemoteTest.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/test/jdk/jshell/UserJdiUserRemoteTest.java	Wed Nov 23 19:15:26 2016 +0000
@@ -118,6 +118,7 @@
 class MyExecutionControl extends JdiExecutionControl {
 
     private static final String REMOTE_AGENT = MyRemoteExecutionControl.class.getName();
+    private static final int TIMEOUT = 2000;
 
     private VirtualMachine vm;
     private Process process;
@@ -147,8 +148,8 @@
      */
     static ExecutionControl make(ExecutionEnv env, UserJdiUserRemoteTest test) throws IOException {
         try (final ServerSocket listener = new ServerSocket(0)) {
-            // timeout after 60 seconds
-            listener.setSoTimeout(60000);
+            // timeout for socket
+            listener.setSoTimeout(TIMEOUT);
             int port = listener.getLocalPort();
 
             // Set-up the JDI connection
@@ -158,7 +159,7 @@
                     + System.getProperty("path.separator")
                     + System.getProperty("user.dir"));
             JdiInitiator jdii = new JdiInitiator(port,
-                    opts, REMOTE_AGENT, true, null);
+                    opts, REMOTE_AGENT, true, null, TIMEOUT);
             VirtualMachine vm = jdii.vm();
             Process process = jdii.process();
 
--- a/langtools/test/tools/javac/6410653/T6410653.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/test/tools/javac/6410653/T6410653.java	Wed Nov 23 19:15:26 2016 +0000
@@ -31,6 +31,7 @@
  */
 
 import java.lang.reflect.Field;
+import java.lang.reflect.Module;
 import java.io.File;
 import java.io.ByteArrayOutputStream;
 import javax.tools.*;
@@ -39,9 +40,9 @@
     public static void main(String... args) throws Exception {
         File testSrc = new File(System.getProperty("test.src"));
         String source = new File(testSrc, "T6410653.java").getPath();
-        ClassLoader cl = ToolProvider.getSystemToolClassLoader();
         Tool compiler = ToolProvider.getSystemJavaCompiler();
-        Class<?> log = Class.forName("com.sun.tools.javac.util.Log", true, cl);
+        Module compilerModule = compiler.getClass().getModule();
+        Class<?> log = Class.forName(compilerModule, "com.sun.tools.javac.util.Log");
         Field useRawMessages = log.getDeclaredField("useRawMessages");
         useRawMessages.setAccessible(true);
         useRawMessages.setBoolean(null, true);
--- a/langtools/test/tools/javac/T8003967/DetectMutableStaticFields.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/test/tools/javac/T8003967/DetectMutableStaticFields.java	Wed Nov 23 19:15:26 2016 +0000
@@ -170,7 +170,7 @@
             ConstantPoolException,
             InvalidDescriptor {
         JavaFileManager.Location location =
-                fm.getModuleLocation(StandardLocation.SYSTEM_MODULES, moduleName);
+                fm.getLocationForModule(StandardLocation.SYSTEM_MODULES, moduleName);
         if (location == null)
             throw new AssertionError("can't find module " + moduleName);
 
--- a/langtools/test/tools/javac/api/T6397104.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/test/tools/javac/api/T6397104.java	Wed Nov 23 19:15:26 2016 +0000
@@ -73,8 +73,8 @@
             if (hasLocation) {
                 for (Location location : StandardLocation.values()) {
                     System.err.format("  location:%s, moduleLocn:%b%n",
-                        location, location.isModuleLocation());
-                    if (location.isModuleLocation()) {
+                        location, location.isModuleOrientedLocation());
+                    if (!location.isOutputLocation()) {
                         continue;
                     }
                     fm.setLocation(location, Arrays.asList(new File(".")));
--- a/langtools/test/tools/javac/api/TestClientCodeWrapper.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/test/tools/javac/api/TestClientCodeWrapper.java	Wed Nov 23 19:15:26 2016 +0000
@@ -62,7 +62,7 @@
             defaultFileManager = fm;
 
             for (Method m: getMethodsExcept(JavaFileManager.class,
-                        "close", "getJavaFileForInput", "getModuleLocation", "getServiceLoader")) {
+                        "close", "getJavaFileForInput", "getLocationForModule", "getServiceLoader")) {
                 test(m);
             }
 
@@ -401,15 +401,15 @@
         }
 
         @Override
-        public Location getModuleLocation(Location location, String moduleName) throws IOException {
-            throwUserExceptionIfNeeded(fileManagerMethod, "getModuleLocation");
-            return super.getModuleLocation(location, moduleName);
+        public Location getLocationForModule(Location location, String moduleName) throws IOException {
+            throwUserExceptionIfNeeded(fileManagerMethod, "getLocationForModule");
+            return super.getLocationForModule(location, moduleName);
         }
 
         @Override
-        public Location getModuleLocation(Location location, JavaFileObject fo, String pkgName) throws IOException {
-            throwUserExceptionIfNeeded(fileManagerMethod, "getModuleLocation");
-            return super.getModuleLocation(location, fo, pkgName);
+        public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
+            throwUserExceptionIfNeeded(fileManagerMethod, "getLocationForModule");
+            return super.getLocationForModule(location, fo, pkgName);
         }
 
         @Override
@@ -419,9 +419,9 @@
         }
 
         @Override
-        public Iterable<Set<Location>> listModuleLocations(Location location) throws IOException {
-            throwUserExceptionIfNeeded(fileManagerMethod, "listModuleLocations");
-            return super.listModuleLocations(location);
+        public Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
+            throwUserExceptionIfNeeded(fileManagerMethod, "listLocationsForModules");
+            return super.listLocationsForModules(location);
         }
 
         public FileObject wrap(FileObject fo) {
--- a/langtools/test/tools/javac/api/ToolProvider/ToolProviderTest.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/test/tools/javac/api/ToolProvider/ToolProviderTest.java	Wed Nov 23 19:15:26 2016 +0000
@@ -55,6 +55,8 @@
 
         Objects.requireNonNull(ToolProvider.getSystemDocumentationTool());
         Objects.requireNonNull(ToolProvider.getSystemJavaCompiler());
-        Objects.requireNonNull(ToolProvider.getSystemToolClassLoader());
+        if (ToolProvider.getSystemToolClassLoader() != null) {
+            throw new AssertionError("unexpected value for getSystemToolClassLoader");
+        }
     }
 }
--- a/langtools/test/tools/javac/diags/examples/BadNameForOption.java	Wed Nov 23 16:16:36 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.warn.bad.name.for.option
-// options: --add-exports Bad!Name/p=java.base
-
-class BadNameForOption { }
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/BadNameForOption_Error.java	Wed Nov 23 19:15:26 2016 +0000
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.bad.name.for.option
+// options: --add-modules Bad!Name
+
+class BadNameForOption { }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/BadNameForOption_Warning.java	Wed Nov 23 19:15:26 2016 +0000
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.warn.bad.name.for.option
+// options: --add-exports Bad!Name/p=java.base
+
+class BadNameForOption { }
+
--- a/langtools/test/tools/javac/modules/AddModulesTest.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/test/tools/javac/modules/AddModulesTest.java	Wed Nov 23 19:15:26 2016 +0000
@@ -126,12 +126,12 @@
                          "--add-modules", "BadModule!")
                 .outdir(classes)
                 .files(findJavaFiles(src))
-                .run()
+                .run(Task.Expect.FAIL)
                 .writeAll()
                 .getOutput(Task.OutputKind.DIRECT);
 
         checkOutputContains(log,
-            "- compiler.warn.bad.name.for.option: --add-modules, BadModule!");
+            "- compiler.err.bad.name.for.option: --add-modules, BadModule!");
     }
 
     @Test
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/modules/AllDefaultTest.java	Wed Nov 23 19:15:26 2016 +0000
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 0000000
+ * @summary Test use of ALL-DEFAULT token
+ * @library /tools/lib
+ * @modules
+ *      jdk.compiler/com.sun.tools.javac.api
+ *      jdk.compiler/com.sun.tools.javac.main
+ * @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask toolbox.JavaTask ModuleTestBase
+ * @run main AllDefaultTest
+ */
+
+import java.nio.file.Path;
+
+import toolbox.JavacTask;
+import toolbox.Task;
+
+public class AllDefaultTest extends ModuleTestBase {
+    public static void main(String... args) throws Exception {
+        AllDefaultTest t = new AllDefaultTest();
+        t.runTests();
+    }
+
+    @Test
+    public void testCompileTime_notAllowed(Path base) throws Exception {
+        tb.writeJavaFiles(base, "class C { }");
+        String out = new JavacTask(tb)
+                .options("-XDrawDiagnostics",
+                        "--add-modules=ALL-DEFAULT")
+                .files(tb.findJavaFiles(base))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+
+        if (!out.contains("- compiler.err.bad.name.for.option: --add-modules, ALL-DEFAULT")) {
+            error("expected text not found");
+        }
+    }
+
+    @Test
+    public void testRuntimeTime_ignored_1(Path base) throws Exception {
+        tb.writeJavaFiles(base, "class C { }");
+        new JavacTask(tb, Task.Mode.EXEC)
+                .options("-XDrawDiagnostics",
+                        "-J--add-modules=ALL-DEFAULT",
+                        "--inherit-runtime-environment")
+                .files(tb.findJavaFiles(base))
+                .run()
+                .writeAll();
+    }
+
+    @Test
+    public void testRuntimeTime_ignored_2(Path base) throws Exception {
+        tb.writeJavaFiles(base, "class C { }");
+        new JavacTask(tb, Task.Mode.EXEC)
+                .options("-XDrawDiagnostics",
+                        "-J--add-modules=jdk.compiler",
+                        "--inherit-runtime-environment")
+                .files(tb.findJavaFiles(base))
+                .run()
+                .writeAll();
+    }
+}
--- a/langtools/test/tools/javac/modules/LimitModulesTest.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/test/tools/javac/modules/LimitModulesTest.java	Wed Nov 23 19:15:26 2016 +0000
@@ -144,11 +144,11 @@
                          "--limit-modules", "BadModule!")
                 .outdir(classes)
                 .files(findJavaFiles(src))
-                .run()
+                .run(Task.Expect.FAIL)
                 .writeAll()
                 .getOutput(Task.OutputKind.DIRECT);
 
-        if (!log.contains("- compiler.warn.bad.name.for.option: --limit-modules, BadModule!"))
+        if (!log.contains("- compiler.err.bad.name.for.option: --limit-modules, BadModule!"))
             throw new Exception("expected output not found");
     }
 
--- a/langtools/test/tools/javac/options/release/ReleaseOptionClashes.java	Wed Nov 23 16:16:36 2016 +0000
+++ b/langtools/test/tools/javac/options/release/ReleaseOptionClashes.java	Wed Nov 23 19:15:26 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -82,6 +82,6 @@
         compiler.run(null, null, System.out, options.toArray(new String[0]));
     }
 
-    ClassLoader cl = ToolProvider.getSystemToolClassLoader();
     Tool compiler = ToolProvider.getSystemJavaCompiler();
+    ClassLoader cl = compiler.getClass().getClassLoader();
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/BadOptionsTest.java	Wed Nov 23 19:15:26 2016 +0000
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8169676
+ * @summary boolean result of Option.process is often ignored
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ * @modules jdk.compiler/com.sun.tools.javac.main
+ * @modules jdk.javadoc/jdk.javadoc.internal.api
+ * @modules jdk.javadoc/jdk.javadoc.internal.tool
+ * @library /tools/lib
+ * @build toolbox.JavacTask toolbox.JavadocTask toolbox.TestRunner toolbox.ToolBox
+ * @run main BadOptionsTest
+ */
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.Set;
+
+import javax.lang.model.SourceVersion;
+
+import jdk.javadoc.doclet.Doclet;
+import jdk.javadoc.doclet.DocletEnvironment;
+import jdk.javadoc.doclet.Reporter;
+
+import toolbox.JavadocTask;
+import toolbox.ModuleBuilder;
+import toolbox.Task;
+import toolbox.TestRunner;
+import toolbox.ToolBox;
+
+/*
+ * This is primarily a test of the error reporting mechanisms
+ * for bad options provided by javac and utilized by javadoc.
+ * It is not an exhaustive test of all bad option forms detected
+ * by javac/javadoc.
+ */
+public class BadOptionsTest extends TestRunner {
+
+    public static void main(String... args) throws Exception {
+        BadOptionsTest t = new BadOptionsTest();
+        t.runTests();
+    }
+
+    private final ToolBox tb = new ToolBox();
+    private final Path src = Paths.get("src");
+
+    BadOptionsTest() throws IOException {
+        super(System.err);
+        init();
+    }
+
+    void init() throws IOException {
+        tb.writeJavaFiles(src,
+                "public class C { }");
+
+    }
+
+    @Test
+    public void testAddModulesEmptyArg() {
+        Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
+                .options("-Xold",
+                        "--add-modules", "")
+                .files(src.resolve("C.java"))
+                .run(Task.Expect.FAIL)
+                .writeAll();
+        checkFound(result.getOutput(Task.OutputKind.DIRECT),
+                "javadoc: error - no value for --add-modules option");
+        checkNotFound(result, "Exception", "at jdk.javadoc/");
+    }
+
+    @Test
+    public void testAddModulesBadName() {
+        Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
+                .options("-Xold", "-quiet",
+                        "--add-modules", "123")
+                .files(src.resolve("C.java"))
+                .run(Task.Expect.FAIL)
+                .writeAll();
+        checkFound(result.getOutput(Task.OutputKind.DIRECT),
+                "error: bad name in value for --add-modules option: '123'");
+        checkNotFound(result, "Exception", "at jdk.javadoc/");
+    }
+
+    @Test
+    public void testAddExportsEmptyArg() {
+        Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
+                .options("-Xold",
+                        "--add-exports", "")
+                .files(src.resolve("C.java"))
+                .run(Task.Expect.FAIL)
+                .writeAll();
+        checkFound(result.getOutput(Task.OutputKind.DIRECT),
+                "javadoc: error - no value for --add-exports option");
+        checkNotFound(result, "Exception", "at jdk.javadoc/");
+    }
+
+    @Test
+    public void testAddExportsBadArg() {
+        Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
+                .options("-Xold",
+                        "--add-exports", "m/p")
+                .files(src.resolve("C.java"))
+                .run(Task.Expect.FAIL)
+                .writeAll();
+        checkFound(result.getOutput(Task.OutputKind.DIRECT),
+                "javadoc: error - bad value for --add-exports option");
+        checkNotFound(result, "Exception", "at jdk.javadoc/");
+    }
+
+    @Test
+    public void testAddExportsBadName() {
+        Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
+                .options("-Xold",
+                        "--add-exports", "m!/p1=m2")
+                .files(src.resolve("C.java"))
+                .run()
+                .writeAll();
+        checkFound(result.getOutput(Task.OutputKind.DIRECT),
+                "warning: bad name in value for --add-exports option: 'm!'");
+        checkNotFound(result, "Exception", "at jdk.javadoc/");
+    }
+
+    private void checkFound(String log, String... expect) {
+        for (String e : expect) {
+            if (!log.contains(e)) {
+                error("Expected string not found: '" + e + "'");
+            }
+        }
+    }
+
+    private void checkNotFound(Task.Result result, String... unexpected) {
+        for (Task.OutputKind k : Task.OutputKind.values()) {
+            String r = result.getOutput(k);
+            for (String u : unexpected) {
+                if (r.contains(u)) {
+                    error("Unexpected string found: '" + u + "'");
+                }
+            }
+        }
+    }
+}