Merge
authorlana
Thu, 20 Oct 2016 20:01:40 +0000
changeset 41636 086a3c7a6b56
parent 41627 66c9d5c2a08c (current diff)
parent 41635 cb3d04878117 (diff)
child 41637 7b24b4c32ee6
Merge
langtools/test/tools/javac/T8029102/WarnSerializableLambdaTest.java
langtools/test/tools/javac/T8029102/WarnSerializableLambdaTest.out
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Oct 20 20:01:40 2016 +0000
@@ -2398,6 +2398,7 @@
         try {
             if (needsRecovery && isSerializable(pt())) {
                 localEnv.info.isSerializable = true;
+                localEnv.info.isLambda = true;
             }
             List<Type> explicitParamTypes = null;
             if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) {
@@ -2969,7 +2970,7 @@
                 }
 
                 if (isTargetSerializable) {
-                    chk.checkElemAccessFromSerializableLambda(that);
+                    chk.checkAccessFromSerializableElement(that, true);
                 }
             }
 
@@ -3364,7 +3365,7 @@
         }
 
         if (env.info.isSerializable) {
-            chk.checkElemAccessFromSerializableLambda(tree);
+            chk.checkAccessFromSerializableElement(tree, env.info.isLambda);
         }
 
         result = checkId(tree, env1.enclClass.sym.type, sym, env, resultInfo);
@@ -3507,7 +3508,7 @@
         }
 
         if (env.info.isSerializable) {
-            chk.checkElemAccessFromSerializableLambda(tree);
+            chk.checkAccessFromSerializableElement(tree, env.info.isLambda);
         }
 
         env.info.selectSuper = selectSuperPrev;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java	Thu Oct 20 20:01:40 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
@@ -56,10 +56,15 @@
      */
     boolean selectSuper = false;
 
-    /** Is the current target of lambda expression or method reference serializable?
+    /** Is the current target of lambda expression or method reference serializable or is this a
+     *  serializable class?
      */
     boolean isSerializable = false;
 
+    /** Is this a lambda environment?
+     */
+    boolean isLambda = false;
+
     /** Is this a speculative attribution environment?
      */
     boolean isSpeculative = false;
@@ -117,6 +122,7 @@
         info.returnResult = returnResult;
         info.defaultSuperCallSite = defaultSuperCallSite;
         info.isSerializable = isSerializable;
+        info.isLambda = isLambda;
         info.isSpeculative = isSpeculative;
         info.isAnonymousDiamond = isAnonymousDiamond;
         info.isNewClass = isNewClass;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java	Thu Oct 20 20:01:40 2016 +0000
@@ -87,7 +87,7 @@
     private final JavaFileManager fileManager;
     private final Source source;
     private final Profile profile;
-    private final boolean warnOnAccessToSensitiveMembers;
+    private final boolean warnOnAnyAccessToMembers;
 
     // The set of lint options currently in effect. It is initialized
     // from the context, and then is set/reset as needed by Attr as it
@@ -131,7 +131,7 @@
         allowStrictMethodClashCheck = source.allowStrictMethodClashCheck();
         allowPrivateSafeVarargs = source.allowPrivateSafeVarargs();
         allowDiamondWithAnonymousClassCreation = source.allowDiamondWithAnonymousClassCreation();
-        warnOnAccessToSensitiveMembers = options.isSet("warnOnAccessToSensitiveMembers");
+        warnOnAnyAccessToMembers = options.isSet("warnOnAccessToMembers");
 
         Target target = Target.instance(context);
         syntheticNameChar = target.syntheticNameChar();
@@ -2605,8 +2605,11 @@
         }
     }
 
-    void checkElemAccessFromSerializableLambda(final JCTree tree) {
-        if (warnOnAccessToSensitiveMembers) {
+    void checkAccessFromSerializableElement(final JCTree tree, boolean isLambda) {
+        if (warnOnAnyAccessToMembers ||
+            (lint.isEnabled(LintCategory.SERIAL) &&
+            !lint.isSuppressed(LintCategory.SERIAL) &&
+            isLambda)) {
             Symbol sym = TreeInfo.symbol(tree);
             if (!sym.kind.matches(KindSelector.VAL_MTH)) {
                 return;
@@ -2622,9 +2625,16 @@
             }
 
             if (!types.isSubtype(sym.owner.type, syms.serializableType) &&
-                    isEffectivelyNonPublic(sym)) {
-                log.warning(tree.pos(),
-                        "access.to.sensitive.member.from.serializable.element", sym);
+                isEffectivelyNonPublic(sym)) {
+                if (isLambda) {
+                    if (belongsToRestrictedPackage(sym)) {
+                        log.warning(LintCategory.SERIAL, tree.pos(),
+                            "access.to.member.from.serializable.lambda", sym);
+                    }
+                } else {
+                    log.warning(tree.pos(),
+                        "access.to.member.from.serializable.element", sym);
+                }
             }
         }
     }
@@ -2643,6 +2653,14 @@
         return false;
     }
 
+    private boolean belongsToRestrictedPackage(Symbol sym) {
+        String fullName = sym.packge().fullname.toString();
+        return fullName.startsWith("java.") ||
+                fullName.startsWith("javax.") ||
+                fullName.startsWith("sun.") ||
+                fullName.contains(".internal.");
+    }
+
     /** Report a conflict between a user symbol and a synthetic symbol.
      */
     private void syntheticError(DiagnosticPosition pos, Symbol sym) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu Oct 20 20:01:40 2016 +0000
@@ -1712,8 +1712,12 @@
     Redundant {0} annotation. {1}
 
 # 0: symbol
-compiler.warn.access.to.sensitive.member.from.serializable.element=\
-    access to sensitive member {0} from serializable element can be publicly accessible to untrusted code
+compiler.warn.access.to.member.from.serializable.element=\
+    access to member {0} from serializable element can be publicly accessible to untrusted code
+
+# 0: symbol
+compiler.warn.access.to.member.from.serializable.lambda=\
+    access to member {0} from serializable lambda can be publicly accessible to untrusted code
 
 #####
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties	Thu Oct 20 20:01:40 2016 +0000
@@ -220,7 +220,8 @@
     Warn about use of raw types.
 
 javac.opt.Xlint.desc.serial=\
-    Warn about Serializable classes that do not provide a serial version ID.
+    Warn about Serializable classes that do not provide a serial version ID. \n\
+\                             Also warn about access to non-public members from a serializable element.
 
 javac.opt.Xlint.desc.static=\
     Warn about accessing a static member using an instance.
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java	Thu Oct 20 20:01:40 2016 +0000
@@ -353,11 +353,12 @@
     protected Content getFramesJavaScript() {
         HtmlTree script = HtmlTree.SCRIPT();
         String scriptCode = DocletConstants.NL +
-                "    targetPage = \"\" + window.location.search;" + DocletConstants.NL +
-                "    if (targetPage != \"\" && targetPage != \"undefined\")" + DocletConstants.NL +
-                "        targetPage = targetPage.substring(1);" + DocletConstants.NL +
-                "    if (targetPage.indexOf(\":\") != -1 || (targetPage != \"\" && !validURL(targetPage)))" + DocletConstants.NL +
-                "        targetPage = \"undefined\";" + DocletConstants.NL +
+                "    tmpTargetPage = \"\" + window.location.search;" + DocletConstants.NL +
+                "    if (tmpTargetPage != \"\" && tmpTargetPage != \"undefined\")" + DocletConstants.NL +
+                "        tmpTargetPage = tmpTargetPage.substring(1);" + DocletConstants.NL +
+                "    if (tmpTargetPage.indexOf(\":\") != -1 || (tmpTargetPage != \"\" && !validURL(tmpTargetPage)))" + DocletConstants.NL +
+                "        tmpTargetPage = \"undefined\";" + DocletConstants.NL +
+                "    targetPage = tmpTargetPage;" + DocletConstants.NL +
                 "    function validURL(url) {" + DocletConstants.NL +
                 "        try {" + DocletConstants.NL +
                 "            url = decodeURIComponent(url);" + DocletConstants.NL +
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlWriter.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlWriter.java	Thu Oct 20 20:01:40 2016 +0000
@@ -234,11 +234,12 @@
     protected Content getFramesJavaScript() {
         HtmlTree scriptTree = HtmlTree.SCRIPT();
         String scriptCode = "\n" +
-                "    targetPage = \"\" + window.location.search;\n" +
-                "    if (targetPage != \"\" && targetPage != \"undefined\")\n" +
-                "        targetPage = targetPage.substring(1);\n" +
-                "    if (targetPage.indexOf(\":\") != -1 || (targetPage != \"\" && !validURL(targetPage)))\n" +
-                "        targetPage = \"undefined\";\n" +
+                "    tmpTargetPage = \"\" + window.location.search;\n" +
+                "    if (tmpTargetPage != \"\" && tmpTargetPage != \"undefined\")\n" +
+                "        tmpTargetPage = tmpTargetPage.substring(1);\n" +
+                "    if (tmpTargetPage.indexOf(\":\") != -1 || (tmpTargetPage != \"\" && !validURL(tmpTargetPage)))\n" +
+                "        tmpTargetPage = \"undefined\";\n" +
+                "    targetPage = tmpTargetPage;\n" +
                 "    function validURL(url) {\n" +
                 "        try {\n" +
                 "            url = decodeURIComponent(url);\n" +
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java	Thu Oct 20 20:01:40 2016 +0000
@@ -308,9 +308,7 @@
     public CommentUtils cmtUtils;
 
     /**
-     * A sorted set of packages specified on the command-line merged with a
-     * collection of packages that contain the classes specified on the
-     * command-line.
+     * A sorted set of included packages.
      */
     public SortedSet<PackageElement> packages = null;
 
@@ -399,10 +397,8 @@
 
     private void initPackages() {
         packages = new TreeSet<>(utils.makePackageComparator());
-        packages.addAll(getSpecifiedPackages());
-        for (TypeElement aClass : getSpecifiedClasses()) {
-            packages.add(utils.containingPackage(aClass));
-        }
+        // add all the included packages
+        packages.addAll(docEnv.getIncludedPackageElements());
     }
 
     public Set<Doclet.Option> getSupportedOptions() {
@@ -647,7 +643,7 @@
         if (docencoding == null) {
             docencoding = encoding;
         }
-        typeElementCatalog = new TypeElementCatalog(getSpecifiedClasses(), this);
+        typeElementCatalog = new TypeElementCatalog(docEnv.getIncludedTypeElements(), this);
         initTagletManager(customTagStrs);
         groups.stream().forEach((grp) -> {
             group.checkPackageGroups(grp.value1, grp.value2);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java	Thu Oct 20 20:01:40 2016 +0000
@@ -587,18 +587,28 @@
     }
 
     private Set<PackageElement> computeModulePackages() throws ToolException {
-        final AccessKind accessValue = accessFilter.getAccessValue(ElementKind.PACKAGE);
+        AccessKind accessValue = accessFilter.getAccessValue(ElementKind.PACKAGE);
         final boolean documentAllModulePackages = (accessValue == AccessKind.PACKAGE ||
                 accessValue == AccessKind.PRIVATE);
 
+        accessValue = accessFilter.getAccessValue(ElementKind.MODULE);
+        final boolean moduleDetailedMode = (accessValue == AccessKind.PACKAGE ||
+                accessValue == AccessKind.PRIVATE);
         Set<PackageElement> expandedModulePackages = new LinkedHashSet<>();
 
         for (ModuleElement mdle : specifiedModuleElements) {
-            // add all exported packages belonging to a specified module
-            if (specifiedModuleElements.contains(mdle)) {
+            if (documentAllModulePackages) { // include all packages
+                List<PackageElement> packages = ElementFilter.packagesIn(mdle.getEnclosedElements());
+                expandedModulePackages.addAll(packages);
+                expandedModulePackages.addAll(getAllModulePackages(mdle));
+            } else { // selectively include required packages
                 List<ExportsDirective> exports = ElementFilter.exportsIn(mdle.getDirectives());
                 for (ExportsDirective export : exports) {
-                    expandedModulePackages.add(export.getPackage());
+                    // add if fully exported or add qualified exports only if desired
+                    if (export.getTargetModules() == null
+                            || documentAllModulePackages || moduleDetailedMode) {
+                        expandedModulePackages.add(export.getPackage());
+                    }
                 }
             }
 
@@ -613,27 +623,6 @@
                     }
                 }
             }
-
-            if (!documentAllModulePackages) {
-                List<ExportsDirective> exports = ElementFilter.exportsIn(mdle.getDirectives());
-                // check exported packages
-                for (ExportsDirective export : exports) {
-                    List<? extends ModuleElement> targetModules = export.getTargetModules();
-                    if (targetModules == null) { // no qualified exports, add 'em all
-                        expandedModulePackages.add(export.getPackage());
-                    } else { // qualified export, add only if target module is being considered
-                        for (ModuleElement target : targetModules) {
-                            if (specifiedModuleElements.contains(target)) {
-                                expandedModulePackages.add(export.getPackage());
-                            }
-                        }
-                    }
-                }
-            } else { // add all exported and module private packages
-                List<PackageElement> packages = ElementFilter.packagesIn(mdle.getEnclosedElements());
-                expandedModulePackages.addAll(packages);
-                expandedModulePackages.addAll(getAllModulePackages(mdle));
-            }
         }
         return expandedModulePackages;
     }
@@ -668,8 +657,7 @@
             if (!mdle.isUnnamed())
                 imodules.add(mdle);
             PackageElement pkg = toolEnv.elements.getPackageOf(klass);
-            if (!pkg.isUnnamed())
-                ipackages.add(pkg);
+            ipackages.add(pkg);
             addAllClasses(iclasses, klass, true);
         });
 
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ArgTokenizer.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ArgTokenizer.java	Thu Oct 20 20:01:40 2016 +0000
@@ -30,7 +30,6 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.stream.Stream;
 import static java.util.stream.Collectors.toList;
 
 /**
@@ -78,7 +77,12 @@
         while (true) {
             nextToken();
             if (sval != null && !isQuoted() && sval.startsWith("-")) {
-                foundOption(sval);
+                // allow POSIX getopt() option format,
+                // to be consistent with command-line
+                String opt = sval.startsWith("--")
+                        ? sval.substring(1)
+                        : sval;
+                foundOption(opt);
             } else {
                 break;
             }
@@ -104,28 +108,13 @@
         }
     }
 
-    String[] next(String... strings) {
-        return next(Arrays.stream(strings));
-    }
-
-    String[] next(Stream<String> stream) {
-        next();
-        if (sval == null) {
-            return null;
-        }
-        String[] matches = stream
-                .filter(s -> s.startsWith(sval))
-                .toArray(size -> new String[size]);
-        return matches;
-    }
-
     /**
      * Set the allowed options. Must be called before any options would be read
      * and before calling any of the option functionality below.
      */
     void allowedOptions(String... opts) {
         for (String opt : opts) {
-            options.put(opt, false);
+            options.putIfAbsent(opt, false);
         }
     }
 
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java	Thu Oct 20 20:01:40 2016 +0000
@@ -31,6 +31,7 @@
 import java.awt.event.ActionListener;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InterruptedIOException;
 import java.io.PrintStream;
 import java.io.UncheckedIOException;
 import java.lang.reflect.Method;
@@ -61,6 +62,8 @@
 import jdk.internal.jline.console.history.MemoryHistory;
 import jdk.internal.jline.extra.EditingHistory;
 import jdk.internal.jshell.tool.StopDetectingInputStream.State;
+import jdk.internal.misc.Signal;
+import jdk.internal.misc.Signal.Handler;
 
 class ConsoleIOContext extends IOContext {
 
@@ -170,6 +173,21 @@
                 bind(shortcuts + computer.shortcut, (ActionListener) evt -> fixes(computer));
             }
         }
+        try {
+            Signal.handle(new Signal("CONT"), new Handler() {
+                @Override public void handle(Signal sig) {
+                    try {
+                        in.getTerminal().reset();
+                        in.redrawLine();
+                        in.flush();
+                    } catch (Exception ex) {
+                        ex.printStackTrace();
+                    }
+                }
+            });
+        } catch (IllegalArgumentException ignored) {
+            //the CONT signal does not exist on this platform
+        }
     }
 
     @Override
@@ -390,7 +408,7 @@
     private int inputBytesPointer;
 
     @Override
-    public synchronized int readUserInput() {
+    public synchronized int readUserInput() throws IOException {
         while (inputBytes == null || inputBytes.length <= inputBytesPointer) {
             boolean prevHandleUserInterrupt = in.getHandleUserInterrupt();
             History prevHistory = in.getHistory();
@@ -401,12 +419,8 @@
                 in.setHistory(userInputHistory);
                 inputBytes = (in.readLine("") + System.getProperty("line.separator")).getBytes();
                 inputBytesPointer = 0;
-            } catch (IOException ex) {
-                ex.printStackTrace();
-                return -1;
             } catch (UserInterruptException ex) {
-                repl.state.stop();
-                return -1;
+                throw new InterruptedIOException();
             } finally {
                 in.setHistory(prevHistory);
                 in.setHandleUserInterrupt(prevHandleUserInterrupt);
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java	Thu Oct 20 20:01:40 2016 +0000
@@ -28,16 +28,26 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Objects;
+import java.util.Set;
+import java.util.StringJoiner;
+import java.util.function.BiConsumer;
+import java.util.function.BinaryOperator;
+import java.util.function.Consumer;
 import java.util.function.Function;
+import java.util.function.Supplier;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.stream.Collector;
 import static java.util.stream.Collectors.joining;
 import static java.util.stream.Collectors.toMap;
 import static jdk.internal.jshell.tool.ContinuousCompletionProvider.PERFECT_MATCHER;
@@ -114,8 +124,8 @@
         return mode.getContinuationPrompt(nextId);
     }
 
-    public boolean setFeedback(MessageHandler messageHandler, ArgTokenizer at) {
-        return new Setter(messageHandler, at).setFeedback();
+    public boolean setFeedback(MessageHandler messageHandler, ArgTokenizer at, Consumer<String> retainer) {
+        return new Setter(messageHandler, at).setFeedback(retainer);
     }
 
     public boolean setFormat(MessageHandler messageHandler, ArgTokenizer at) {
@@ -126,22 +136,14 @@
         return new Setter(messageHandler, at).setTruncation();
     }
 
-    public boolean setMode(MessageHandler messageHandler, ArgTokenizer at) {
-        return new Setter(messageHandler, at).setMode();
+    public boolean setMode(MessageHandler messageHandler, ArgTokenizer at, Consumer<String> retainer) {
+        return new Setter(messageHandler, at).setMode(retainer);
     }
 
     public boolean setPrompt(MessageHandler messageHandler, ArgTokenizer at) {
         return new Setter(messageHandler, at).setPrompt();
     }
 
-    public String retainFeedback(MessageHandler messageHandler, ArgTokenizer at) {
-        return new Setter(messageHandler, at).retainFeedback();
-    }
-
-    public String retainMode(MessageHandler messageHandler, ArgTokenizer at) {
-        return new Setter(messageHandler, at).retainMode();
-    }
-
     public boolean restoreEncodedModes(MessageHandler messageHandler, String encoded) {
         return new Setter(messageHandler, new ArgTokenizer("<init>", "")).restoreEncodedModes(encoded);
     }
@@ -177,6 +179,15 @@
             selectorMap.put(e.name().toLowerCase(Locale.US), e);
     }
 
+    private static class SelectorSets {
+        Set<FormatCase> cc;
+        Set<FormatAction> ca;
+        Set<FormatWhen> cw;
+        Set<FormatResolve> cr;
+        Set<FormatUnresolved> cu;
+        Set<FormatErrors> ce;
+    }
+
     /**
      * Holds all the context of a mode mode
      */
@@ -197,12 +208,32 @@
         String continuationPrompt = ">> ";
 
         static class Setting {
+
             final long enumBits;
             final String format;
+
             Setting(long enumBits, String format) {
                 this.enumBits = enumBits;
                 this.format = format;
             }
+
+            @Override
+            public boolean equals(Object o) {
+                if (o instanceof Setting) {
+                    Setting ing = (Setting) o;
+                    return enumBits == ing.enumBits && format.equals(ing.format);
+                } else {
+                    return false;
+                }
+            }
+
+            @Override
+            public int hashCode() {
+                int hash = 7;
+                hash = 67 * hash + (int) (this.enumBits ^ (this.enumBits >>> 32));
+                hash = 67 * hash + Objects.hashCode(this.format);
+                return hash;
+            }
         }
 
         /**
@@ -274,6 +305,25 @@
             }
         }
 
+        @Override
+        public boolean equals(Object o) {
+            if (o instanceof Mode) {
+                Mode m = (Mode) o;
+                return name.equals((m.name))
+                        && commandFluff == m.commandFluff
+                        && prompt.equals((m.prompt))
+                        && continuationPrompt.equals((m.continuationPrompt))
+                        && cases.equals((m.cases));
+            } else {
+                return false;
+            }
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hashCode(name);
+        }
+
         /**
          * Set if this mode displays informative/confirmational messages on
          * commands.
@@ -308,13 +358,17 @@
             return String.join(RECORD_SEPARATOR, el);
         }
 
-        private boolean add(String field, Setting ing) {
-            List<Setting> settings =  cases.computeIfAbsent(field, k -> new ArrayList<>());
+        private void add(String field, Setting ing) {
+            List<Setting> settings = cases.get(field);
             if (settings == null) {
-                return false;
+                settings = new ArrayList<>();
+                cases.put(field, settings);
+            } else {
+                // remove obscured settings
+                long mask = ~ing.enumBits;
+                settings.removeIf(t -> (t.enumBits & mask) == 0);
             }
             settings.add(ing);
-            return true;
         }
 
         void set(String field,
@@ -465,6 +519,37 @@
         return res;
     }
 
+    private static SelectorSets unpackEnumbits(long enumBits) {
+        class Unpacker {
+
+            SelectorSets u = new SelectorSets();
+            long b = enumBits;
+
+            <E extends Enum<E>> Set<E> unpackEnumbits(E[] values) {
+                Set<E> c = new HashSet<>();
+                for (int i = 0; i < values.length; ++i) {
+                    if ((b & (1 << i)) != 0) {
+                        c.add(values[i]);
+                    }
+                }
+                b >>>= values.length;
+                return c;
+            }
+
+            SelectorSets unpack() {
+                // inverseof the order they were packed
+                u.ce = unpackEnumbits(FormatErrors.values());
+                u.cu = unpackEnumbits(FormatUnresolved.values());
+                u.cr = unpackEnumbits(FormatResolve.values());
+                u.cw = unpackEnumbits(FormatWhen.values());
+                u.ca = unpackEnumbits(FormatAction.values());
+                u.cc = unpackEnumbits(FormatCase.values());
+                return u;
+            }
+        }
+        return new Unpacker().unpack();
+    }
+
     interface Selector<E extends Enum<E> & Selector<E>> {
         SelectorCollector<E> collector(Setter.SelectorList sl);
         String doc();
@@ -675,31 +760,197 @@
         Setter(MessageHandler messageHandler, ArgTokenizer at) {
             this.messageHandler = messageHandler;
             this.at = at;
+            at.allowedOptions("-retain");
         }
 
         void fluff(String format, Object... args) {
             messageHandler.fluff(format, args);
         }
 
+        void hard(String format, Object... args) {
+            messageHandler.hard(format, args);
+        }
+
         void fluffmsg(String messageKey, Object... args) {
             messageHandler.fluffmsg(messageKey, args);
         }
 
+        void hardmsg(String messageKey, Object... args) {
+            messageHandler.hardmsg(messageKey, args);
+        }
+
+        boolean showFluff() {
+            return messageHandler.showFluff();
+        }
+
         void errorat(String messageKey, Object... args) {
+            if (!valid) {
+                // no spew of errors
+                return;
+            }
+            valid = false;
             Object[] a2 = Arrays.copyOf(args, args.length + 2);
             a2[args.length] = at.whole();
             messageHandler.errormsg(messageKey, a2);
         }
 
+        String selectorsToString(SelectorSets u) {
+            StringBuilder sb = new StringBuilder();
+            selectorToString(sb, u.cc, FormatCase.values());
+            selectorToString(sb, u.ca, FormatAction.values());
+            selectorToString(sb, u.cw, FormatWhen.values());
+            selectorToString(sb, u.cr, FormatResolve.values());
+            selectorToString(sb, u.cu, FormatUnresolved.values());
+            selectorToString(sb, u.ce, FormatErrors.values());
+            return sb.toString();
+        }
+
+        private <E extends Enum<E>> void selectorToString(StringBuilder sb, Set<E> c, E[] values) {
+            if (!c.containsAll(Arrays.asList(values))) {
+                sb.append(c.stream()
+                        .sorted((x, y) -> x.ordinal() - y.ordinal())
+                        .map(v -> v.name().toLowerCase(Locale.US))
+                        .collect(new Collector<CharSequence, StringJoiner, String>() {
+                            @Override
+                            public BiConsumer<StringJoiner, CharSequence> accumulator() {
+                                return StringJoiner::add;
+                            }
+
+                            @Override
+                            public Supplier<StringJoiner> supplier() {
+                                return () -> new StringJoiner(",", (sb.length() == 0)? "" : "-", "")
+                                        .setEmptyValue("");
+                            }
+
+                            @Override
+                            public BinaryOperator<StringJoiner> combiner() {
+                                return StringJoiner::merge;
+                            }
+
+                            @Override
+                            public Function<StringJoiner, String> finisher() {
+                                return StringJoiner::toString;
+                            }
+
+                            @Override
+                            public Set<Characteristics> characteristics() {
+                                return Collections.emptySet();
+                            }
+                        }));
+            }
+        }
+
+        // Show format settings -- in a predictable order, for testing...
+        void showFormatSettings(Mode sm, String f) {
+            if (sm == null) {
+                modeMap.entrySet().stream()
+                        .sorted((es1, es2) -> es1.getKey().compareTo(es2.getKey()))
+                        .forEach(m -> showFormatSettings(m.getValue(), f));
+            } else {
+                sm.cases.entrySet().stream()
+                        .filter(ec -> (f == null)
+                            ? !ec.getKey().equals(TRUNCATION_FIELD)
+                            : ec.getKey().equals(f))
+                        .sorted((ec1, ec2) -> ec1.getKey().compareTo(ec2.getKey()))
+                        .forEach(ec -> {
+                            ec.getValue().forEach(s -> {
+                                hard("/set format %s %s %s %s",
+                                        sm.name, ec.getKey(), toStringLiteral(s.format),
+                                        selectorsToString(unpackEnumbits(s.enumBits)));
+
+                            });
+                        });
+            }
+        }
+
+        void showTruncationSettings(Mode sm) {
+            if (sm == null) {
+                modeMap.values().forEach(m -> showTruncationSettings(m));
+            } else {
+                List<Mode.Setting> trunc = sm.cases.get(TRUNCATION_FIELD);
+                if (trunc != null) {
+                    trunc.forEach(s -> {
+                        hard("/set truncation %s %s %s",
+                                sm.name, s.format,
+                                selectorsToString(unpackEnumbits(s.enumBits)));
+                    });
+                }
+            }
+        }
+
+        void showPromptSettings(Mode sm) {
+            if (sm == null) {
+                modeMap.values().forEach(m -> showPromptSettings(m));
+            } else {
+                hard("/set prompt %s %s %s",
+                        sm.name,
+                        toStringLiteral(sm.prompt),
+                        toStringLiteral(sm.continuationPrompt));
+            }
+        }
+
+        void showModeSettings(String umode, String msg) {
+            if (umode == null) {
+                modeMap.values().forEach(n -> showModeSettings(n));
+            } else {
+                Mode m;
+                String retained = retainedMap.get(umode);
+                if (retained == null) {
+                    m = searchForMode(umode, msg);
+                    if (m == null) {
+                        return;
+                    }
+                    umode = m.name;
+                    retained = retainedMap.get(umode);
+                } else {
+                    m = modeMap.get(umode);
+                }
+                if (retained != null) {
+                    Mode rm = new Mode(encodedModeIterator(retained));
+                    showModeSettings(rm);
+                    hard("/set mode -retain %s", umode);
+                    if (m != null && !m.equals(rm)) {
+                        hard("");
+                        showModeSettings(m);
+                    }
+                } else {
+                    showModeSettings(m);
+                }
+            }
+        }
+
+        void showModeSettings(Mode sm) {
+            hard("/set mode %s %s",
+                    sm.name, sm.commandFluff ? "-command" : "-quiet");
+            showPromptSettings(sm);
+            showFormatSettings(sm, null);
+            showTruncationSettings(sm);
+        }
+
+        void showFeedbackSetting() {
+            if (retainedCurrentMode != null) {
+                hard("/set feedback -retain %s", retainedCurrentMode.name);
+            }
+            if (mode != retainedCurrentMode) {
+                hard("/set feedback %s", mode.name);
+            }
+        }
+
         // For /set prompt <mode> "<prompt>" "<continuation-prompt>"
         boolean setPrompt() {
             Mode m = nextMode();
+            String prompt = nextFormat();
+            String continuationPrompt = nextFormat();
+            checkOptionsAndRemainingInput();
+            if (valid && prompt == null) {
+                showPromptSettings(m);
+                return valid;
+            }
             if (valid && m.readOnly) {
                 errorat("jshell.err.not.valid.with.predefined.mode", m.name);
-                valid = false;
+            } else if (continuationPrompt == null) {
+                errorat("jshell.err.continuation.prompt.required");
             }
-            String prompt = valid ? nextFormat() : null;
-            String continuationPrompt = valid ? nextFormat() : null;
             if (valid) {
                 m.setPrompts(prompt, continuationPrompt);
             } else {
@@ -714,210 +965,210 @@
          *
          * @return true if successful
          */
-        boolean setMode() {
-            at.allowedOptions("-command", "-quiet", "-delete");
-            String umode = nextModeIdentifier();
-            Mode om = null;
-            String omode = at.next();
-            if (valid && omode != null) {
-                om = toMode(omode);
-            }
-            checkOptionsAndRemainingInput();
-            boolean commandOption = at.hasOption("-command");
-            boolean quietOption = at.hasOption("-quiet");
-            boolean deleteOption = at.hasOption("-delete");
-            // Only one (or zero) of the options can be used
-            if (valid && at.optionCount() > 1) {
-                errorat("jshell.err.conflicting.options");
-                valid = false;
-            }
-            if (valid) {
-                Mode m = modeMap.get(umode);
-                if (m != null && m.readOnly) {
-                    // Cannot make changes to a the built-in modes
-                    errorat("jshell.err.not.valid.with.predefined.mode", m.name);
-                    valid = false;
-                } else if (deleteOption) {
-                    if (m == null) {
+        boolean setMode(Consumer<String> retainer) {
+            class SetMode {
+
+                final String umode;
+                final String omode;
+                final boolean commandOption;
+                final boolean quietOption;
+                final boolean deleteOption;
+                final boolean retainOption;
+
+                SetMode() {
+                    at.allowedOptions("-command", "-quiet", "-delete", "-retain");
+                    umode = nextModeIdentifier();
+                    omode = nextModeIdentifier();
+                    checkOptionsAndRemainingInput();
+                    commandOption = at.hasOption("-command");
+                    quietOption = at.hasOption("-quiet");
+                    deleteOption = at.hasOption("-delete");
+                    retainOption = at.hasOption("-retain");
+                }
+
+                void delete() {
+                    // Note: delete, for safety reasons, does NOT do name matching
+                    if (commandOption || quietOption) {
+                        errorat("jshell.err.conflicting.options");
+                    } else if (!(retainOption ? retainedMap : modeMap).containsKey(umode)) {
                         // Cannot delete a mode that does not exist
                         errorat("jshell.err.mode.unknown", umode);
-                        valid = false;
-                    } else if (mode.name.equals(m.name)) {
+                    } else if (omode != null) {
+                        // old mode is for creation
+                        errorat("jshell.err.unexpected.at.end", omode);
+                    } else if (mode.name.equals(umode)) {
                         // Cannot delete the current mode out from under us
                         errorat("jshell.err.cannot.delete.current.mode", umode);
-                        valid = false;
+                    } else if (retainOption && retainedCurrentMode != null &&
+                             retainedCurrentMode.name.equals(umode)) {
+                        // Cannot delete the retained mode or re-start will have an error
+                        errorat("jshell.err.cannot.delete.retained.mode", umode);
                     } else {
-                        // Remove the mode
-                        modeMap.remove(umode);
+                        Mode m = modeMap.get(umode);
+                        if (m != null && m.readOnly) {
+                            errorat("jshell.err.not.valid.with.predefined.mode", umode);
+                        } else {
+                            // Remove the mode
+                            modeMap.remove(umode);
+                            if (retainOption) {
+                                // Remove the retained mode
+                                retainedMap.remove(umode);
+                                updateRetainedModes();
+                            }
+                        }
                     }
-                } else {
-                    if (om != null || m == null) {
-                        // We are copying and existing mode and/or creating a
-                        // brand-new mode -- in either case create from scratch
-                        m = (om != null)
-                                ? new Mode(umode, om)
-                                : new Mode(umode);
-                        modeMap.put(umode, m);
-                        fluffmsg("jshell.msg.feedback.new.mode", m.name);
-                        // Set the current mode by name, in case we just smashed
-                        // the current mode
-                        if (umode.equals(mode.name)) {
-                            mode = modeMap.get(mode.name);
+                }
+
+                void retain() {
+                    if (commandOption || quietOption) {
+                        errorat("jshell.err.conflicting.options");
+                    } else if (omode != null) {
+                        // old mode is for creation
+                        errorat("jshell.err.unexpected.at.end", omode);
+                    } else {
+                        Mode m = modeMap.get(umode);
+                        if (m == null) {
+                            // can only retain existing modes
+                            errorat("jshell.err.mode.unknown", umode);
+                        } else if (m.readOnly) {
+                            errorat("jshell.err.not.valid.with.predefined.mode", umode);
+                        } else {
+                            // Add to local cache of retained current encodings
+                            retainedMap.put(m.name, m.encode());
+                            updateRetainedModes();
                         }
                     }
-                    if (commandOption || quietOption || om == null) {
-                        // set command fluff, if explicit, or wholly new
-                        m.setCommandFluff(!quietOption);
+                }
+
+                void updateRetainedModes() {
+                    // Join all the retained encodings
+                    String encoded = String.join(RECORD_SEPARATOR, retainedMap.values());
+                    // Retain it
+                    retainer.accept(encoded);
+                }
+
+                void create() {
+                    if (commandOption && quietOption) {
+                        errorat("jshell.err.conflicting.options");
+                    } else if (!commandOption && !quietOption) {
+                        errorat("jshell.err.mode.creation");
+                    } else if (modeMap.containsKey(umode)) {
+                        // Mode already exists
+                        errorat("jshell.err.mode.exists", umode);
+                    } else {
+                        Mode om = searchForMode(omode);
+                        if (valid) {
+                            // We are copying an existing mode and/or creating a
+                            // brand-new mode -- in either case create from scratch
+                            Mode m = (om != null)
+                                    ? new Mode(umode, om)
+                                    : new Mode(umode);
+                            modeMap.put(umode, m);
+                            fluffmsg("jshell.msg.feedback.new.mode", m.name);
+                            m.setCommandFluff(commandOption);
+                        }
                     }
                 }
+
+                boolean set() {
+                    if (valid && !commandOption && !quietOption && !deleteOption &&
+                            omode == null && !retainOption) {
+                        // Not a creation, deletion, or retain -- show mode(s)
+                        showModeSettings(umode, "jshell.err.mode.creation");
+                    } else if (valid && umode == null) {
+                        errorat("jshell.err.missing.mode");
+                    } else if (valid && deleteOption) {
+                        delete();
+                    } else if (valid && retainOption) {
+                        retain();
+                    } else if (valid) {
+                        create();
+                    }
+                    if (!valid) {
+                        fluffmsg("jshell.msg.see", "/help /set mode");
+                    }
+                    return valid;
+                }
             }
-            if (!valid) {
-                fluffmsg("jshell.msg.see", "/help /set mode");
-            }
-            return valid;
+            return new SetMode().set();
         }
 
-        // For /set feedback <mode>
-        boolean setFeedback() {
+        // For /set format <mode> <field> "<format>" <selector>...
+        boolean setFormat() {
             Mode m = nextMode();
-            if (valid) {
-                mode = m;
-                fluffmsg("jshell.msg.feedback.mode", mode.name);
+            String field = toIdentifier(next(), "jshell.err.field.name");
+            String format = nextFormat();
+            if (valid && format == null) {
+                if (field != null && m != null && !m.cases.containsKey(field)) {
+                    errorat("jshell.err.field.name", field);
+                } else {
+                    showFormatSettings(m, field);
+                }
             } else {
-                fluffmsg("jshell.msg.see", "/help /set feedback");
-                printFeedbackModes();
+                installFormat(m, field, format, "/help /set format");
             }
             return valid;
         }
 
-        // For /set format <mode> "<format>" <selector>...
-        boolean setFormat() {
-            Mode m = nextMode();
-            if (valid && m.readOnly) {
-                errorat("jshell.err.not.valid.with.predefined.mode", m.name);
-                valid = false;
-            }
-            String field = valid
-                    ? toIdentifier(at.next(), "jshell.err.missing.field", "jshell.err.field.name")
-                    : null;
-            String format = valid ? nextFormat() : null;
-            return installFormat(m, field, format, "/help /set format");
-        }
-
         // For /set truncation <mode> <length> <selector>...
         boolean setTruncation() {
             Mode m = nextMode();
-            if (valid && m.readOnly) {
-                errorat("jshell.err.not.valid.with.predefined.mode", m.name);
-                valid = false;
-            }
-            String length = at.next();
+            String length = next();
             if (length == null) {
-                errorat("jshell.err.truncation.expected.length");
-                valid = false;
+                showTruncationSettings(m);
             } else {
                 try {
                     // Assure that integer format is correct
                     Integer.parseUnsignedInt(length);
                 } catch (NumberFormatException ex) {
                     errorat("jshell.err.truncation.length.not.integer", length);
-                    valid = false;
                 }
+                // install length into an internal format field
+                installFormat(m, TRUNCATION_FIELD, length, "/help /set truncation");
             }
-            // install length into an internal format field
-            return installFormat(m, TRUNCATION_FIELD, length, "/help /set truncation");
-        }
-
-        String retainFeedback() {
-            String umode = at.next();
-            if (umode != null) {
-                toModeIdentifier(umode);
-                Mode m = valid ? toMode(umode) : null;
-                if (valid && !m.readOnly && !retainedMap.containsKey(m.name)) {
-                    errorat("jshell.err.retained.feedback.mode.must.be.retained.or.predefined");
-                    valid = false;
-                }
-                if (valid) {
-                    mode = m;
-                    retainedCurrentMode = m;
-                    fluffmsg("jshell.msg.feedback.mode", mode.name);
-                } else {
-                    fluffmsg("jshell.msg.see", "/help /retain feedback");
-                    return null;
-                }
-            }
-            return mode.name;
+            return valid;
         }
 
-        /**
-         * Retain (or delete from retention) a previously set mode.
-         *
-         * @return all retained modes encoded into a String
-         */
-        String retainMode() {
-            at.allowedOptions("-delete");
-            String umode = nextModeIdentifier();
-            // -delete is the only valid option, fail for anything else
+        // For /set feedback <mode>
+        boolean setFeedback(Consumer<String> retainer) {
+            String umode = next();
             checkOptionsAndRemainingInput();
-            boolean deleteOption = at.hasOption("-delete");
-            // Lookup the mode
-            Mode m;
-            if (!valid) {
-                m = null;
-                // Skip this stuff, we have failed already
-            } else if (deleteOption) {
-                // If delete, allow for deleting, from retention, a mode that
-                // has been locally deleted but is retained.
-                // Also require the full name.
-                m = modeMap.get(umode);
-                if (m == null && !retainedMap.containsKey(umode)) {
-                    errorat("jshell.err.mode.unknown", umode);
-                    valid = false;
-                }
-            } else {
-                // For retain do normal lookup and checking
-                m = toMode(umode);
-            }
-
-            // Built-in modes cannot be retained or deleted
-            if (valid && m != null && m.readOnly) {
-                errorat("jshell.err.not.valid.with.predefined.mode", umode);
-                valid = false;
+            boolean retainOption = at.hasOption("-retain");
+            if (valid && umode == null && !retainOption) {
+                showFeedbackSetting();
+                hard("");
+                showFeedbackModes();
+                return true;
             }
             if (valid) {
-                if (deleteOption) {
-                    if (mode.name.equals(umode)) {
-                        // Cannot delete the current mode out from under us
-                        errorat("jshell.err.cannot.delete.current.mode", umode);
-                        valid = false;
-                    } else if (retainedCurrentMode != null && retainedCurrentMode.name.equals(umode)) {
-                        // Cannot delete the retained mode or re-start has error
-                        errorat("jshell.err.cannot.delete.retained.mode", umode);
-                        valid = false;
-                    } else {
-                        // Delete the mode
-                        modeMap.remove(umode);
-                        retainedMap.remove(umode);
+                Mode m = umode == null
+                        ? mode
+                        : searchForMode(toModeIdentifier(umode));
+                if (valid && retainOption && !m.readOnly && !retainedMap.containsKey(m.name)) {
+                    errorat("jshell.err.retained.feedback.mode.must.be.retained.or.predefined");
+                }
+                if (valid) {
+                    if (umode != null) {
+                        mode = m;
+                        fluffmsg("jshell.msg.feedback.mode", mode.name);
                     }
-                } else {
-                    // Retain the current encoding
-                    retainedMap.put(m.name, m.encode());
+                    if (retainOption) {
+                        retainedCurrentMode = m;
+                        retainer.accept(m.name);
+                    }
                 }
             }
-            if (valid) {
-                // Join all the retained encodings
-                return String.join(RECORD_SEPARATOR, retainedMap.values());
-            } else {
-                fluffmsg("jshell.msg.see", "/help /retain mode");
-                return null;
+            if (!valid) {
+                fluffmsg("jshell.msg.see", "/help /set feedback");
+                return false;
             }
+            return true;
         }
 
         boolean restoreEncodedModes(String allEncoded) {
             try {
                 // Iterate over each record in each encoded mode
-                String[] ms = allEncoded.split(RECORD_SEPARATOR);
-                Iterator<String> itr = Arrays.asList(ms).iterator();
+                Iterator<String> itr = encodedModeIterator(allEncoded);
                 while (itr.hasNext()) {
                     // Reconstruct the encoded mode
                     Mode m = new Mode(itr);
@@ -934,50 +1185,60 @@
             }
         }
 
+        Iterator<String> encodedModeIterator(String encoded) {
+            String[] ms = encoded.split(RECORD_SEPARATOR);
+            return Arrays.asList(ms).iterator();
+        }
+
         // install the format of a field under parsed selectors
-        boolean installFormat(Mode m, String field, String format, String help) {
+        void installFormat(Mode m, String field, String format, String help) {
             String slRaw;
             List<SelectorList> slList = new ArrayList<>();
-            while (valid && (slRaw = at.next()) != null) {
+            while (valid && (slRaw = next()) != null) {
                 SelectorList sl = new SelectorList();
                 sl.parseSelectorList(slRaw);
                 slList.add(sl);
             }
+            checkOptionsAndRemainingInput();
             if (valid) {
-                if (slList.isEmpty()) {
+                if (m.readOnly) {
+                    errorat("jshell.err.not.valid.with.predefined.mode", m.name);
+                } else if (slList.isEmpty()) {
                     // No selectors specified, then always the format
                     m.set(field, ALWAYS, format);
                 } else {
                     // Set the format of the field for specified selector
                     slList.stream()
                             .forEach(sl -> m.set(field,
-                                sl.cases.getSet(), sl.actions.getSet(), sl.whens.getSet(),
-                                sl.resolves.getSet(), sl.unresolvedCounts.getSet(), sl.errorCounts.getSet(),
-                                format));
+                            sl.cases.getSet(), sl.actions.getSet(), sl.whens.getSet(),
+                            sl.resolves.getSet(), sl.unresolvedCounts.getSet(), sl.errorCounts.getSet(),
+                            format));
                 }
             } else {
                 fluffmsg("jshell.msg.see", help);
             }
-            return valid;
         }
 
         void checkOptionsAndRemainingInput() {
-            if (!valid) {
-                return;
-            }
             String junk = at.remainder();
             if (!junk.isEmpty()) {
                 errorat("jshell.err.unexpected.at.end", junk);
-                valid = false;
             } else {
                 String bad = at.badOptions();
                 if (!bad.isEmpty()) {
                     errorat("jshell.err.unknown.option", bad);
-                    valid = false;
                 }
             }
         }
 
+        String next() {
+            String s = at.next();
+            if (s == null) {
+                checkOptionsAndRemainingInput();
+            }
+            return s;
+        }
+
         /**
          * Check that the specified string is an identifier (Java identifier).
          * If null display the missing error. If it is not an identifier,
@@ -985,45 +1246,41 @@
          *
          * @param id the string to check, MUST be the most recently retrieved
          * token from 'at'.
-         * @param missing the resource error to display if null
+         * @param missing null for no null error, otherwise the resource error to display if id is null
          * @param err the resource error to display if not an identifier
          * @return the identifier string, or null if null or not an identifier
          */
-        String toIdentifier(String id, String missing, String err) {
-            if (id == null) {
-                errorat(missing);
-                valid = false;
+        private String toIdentifier(String id, String err) {
+            if (!valid || id == null) {
                 return null;
             }
             if (at.isQuoted() ||
                     !id.codePoints().allMatch(cp -> Character.isJavaIdentifierPart(cp))) {
                 errorat(err, id);
-                valid = false;
                 return null;
             }
             return id;
         }
 
-        String toModeIdentifier(String id) {
-            return toIdentifier(id, "jshell.err.missing.mode", "jshell.err.mode.name");
+        private String toModeIdentifier(String id) {
+            return toIdentifier(id, "jshell.err.mode.name");
         }
 
-        String nextModeIdentifier() {
-            return toModeIdentifier(at.next());
+        private String nextModeIdentifier() {
+            return toModeIdentifier(next());
         }
 
-        Mode nextMode() {
+        private Mode nextMode() {
             String umode = nextModeIdentifier();
-            return toMode(umode);
+            return searchForMode(umode);
         }
 
-        Mode toMode(String umode) {
-            if (!valid) {
-                return null;
-            }
-            if (umode == null) {
-                errorat("jshell.err.missing.mode");
-                valid = false;
+        private Mode searchForMode(String umode) {
+            return searchForMode(umode, null);
+        }
+
+        private Mode searchForMode(String umode, String msg) {
+            if (!valid || umode == null) {
                 return null;
             }
             Mode m = modeMap.get(umode);
@@ -1038,39 +1295,101 @@
             if (matches.length == 1) {
                 return matches[0];
             } else {
-                valid = false;
+                if (msg != null) {
+                    hardmsg(msg, "");
+                }
                 if (matches.length == 0) {
                     errorat("jshell.err.feedback.does.not.match.mode", umode);
                 } else {
                     errorat("jshell.err.feedback.ambiguous.mode", umode);
                 }
-                printFeedbackModes();
+                if (showFluff()) {
+                    showFeedbackModes();
+                }
                 return null;
             }
         }
 
-        void printFeedbackModes() {
-            fluffmsg("jshell.msg.feedback.mode.following");
+        void showFeedbackModes() {
+            if (!retainedMap.isEmpty()) {
+                hardmsg("jshell.msg.feedback.retained.mode.following");
+                retainedMap.keySet().stream()
+                        .sorted()
+                        .forEach(mk -> hard("   %s", mk));
+            }
+            hardmsg("jshell.msg.feedback.mode.following");
             modeMap.keySet().stream()
-                    .forEach(mk -> fluff("   %s", mk));
+                    .sorted()
+                    .forEach(mk -> hard("   %s", mk));
+        }
+
+        // Read and test if the format string is correctly
+        private String nextFormat() {
+            return toFormat(next());
         }
 
         // Test if the format string is correctly
-        final String nextFormat() {
-            String format = at.next();
-            if (format == null) {
-                errorat("jshell.err.feedback.expected.format");
-                valid = false;
+        private String toFormat(String format) {
+            if (!valid || format == null) {
                 return null;
             }
             if (!at.isQuoted()) {
                 errorat("jshell.err.feedback.must.be.quoted", format);
-                valid = false;
-                return null;
+               return null;
             }
             return format;
         }
 
+        // Convert to a quoted string
+        private String toStringLiteral(String s) {
+            StringBuilder sb = new StringBuilder();
+            sb.append('"');
+            final int length = s.length();
+            for (int offset = 0; offset < length;) {
+                final int codepoint = s.codePointAt(offset);
+
+                switch (codepoint) {
+                    case '\b':
+                        sb.append("\\b");
+                        break;
+                    case '\t':
+                        sb.append("\\t");
+                        break;
+                    case '\n':
+                        sb.append("\\n");
+                        break;
+                    case '\f':
+                        sb.append("\\f");
+                        break;
+                    case '\r':
+                        sb.append("\\r");
+                        break;
+                    case '\"':
+                        sb.append("\\\"");
+                        break;
+                    case '\'':
+                        sb.append("\\'");
+                        break;
+                    case '\\':
+                        sb.append("\\\\");
+                        break;
+                    default:
+                        if (codepoint < 040) {
+                            sb.append(String.format("\\%o", codepoint));
+                        } else {
+                            sb.appendCodePoint(codepoint);
+                        }
+                        break;
+                }
+
+                // do something with the codepoint
+                offset += Character.charCount(codepoint);
+
+            }
+            sb.append('"');
+            return sb.toString();
+        }
+
         class SelectorList {
 
             SelectorCollector<FormatCase> cases = new SelectorCollector<>(FormatCase.all);
@@ -1088,19 +1407,16 @@
                             Selector<?> sel = selectorMap.get(as);
                             if (sel == null) {
                                 errorat("jshell.err.feedback.not.a.valid.selector", as, s);
-                                valid = false;
                                 return;
                             }
                             SelectorCollector<?> collector = sel.collector(this);
                             if (lastCollector == null) {
                                 if (!collector.isEmpty()) {
                                     errorat("jshell.err.feedback.multiple.sections", as, s);
-                                    valid = false;
                                     return;
                                 }
                             } else if (collector != lastCollector) {
                                 errorat("jshell.err.feedback.different.selector.kinds", as, s);
-                                valid = false;
                                 return;
                             }
                             collector.add(sel);
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/IOContext.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/IOContext.java	Thu Oct 20 20:01:40 2016 +0000
@@ -54,7 +54,7 @@
 
     public abstract void replaceLastHistoryEntry(String source);
 
-    public abstract int readUserInput();
+    public abstract int readUserInput() throws IOException;
 
     class InputInterruptedException extends Exception {
         private static final long serialVersionUID = 1L;
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Thu Oct 20 20:01:40 2016 +0000
@@ -204,12 +204,13 @@
     JShell state = null;
     Subscription shutdownSubscription = null;
 
+    static final EditorSetting BUILT_IN_EDITOR = new EditorSetting(null, false);
+
     private boolean debug = false;
     public boolean testPrompt = false;
     private String cmdlineClasspath = null;
     private String startup = null;
-    private String[] editor = null;
-    private boolean editorWait = false;
+    private EditorSetting editor = BUILT_IN_EDITOR;
 
     // Commands and snippets which should be replayed
     private List<String> replayableHistory;
@@ -273,7 +274,8 @@
      * @param format printf format
      * @param args printf args
      */
-    void hard(String format, Object... args) {
+    @Override
+    public void hard(String format, Object... args) {
         rawout(feedback.getPre() + format + feedback.getPost(), args);
     }
 
@@ -288,6 +290,15 @@
     }
 
     /**
+     * Should optional informative be displayed?
+     * @return true if they should be displayed
+     */
+    @Override
+    public boolean showFluff() {
+        return feedback.shouldDisplayCommandFluff() && interactive();
+    }
+
+    /**
      * Optional output
      *
      * @param format printf format
@@ -295,7 +306,7 @@
      */
     @Override
     public void fluff(String format, Object... args) {
-        if (feedback.shouldDisplayCommandFluff() && interactive()) {
+        if (showFluff()) {
             hard(format, args);
         }
     }
@@ -307,7 +318,7 @@
      * @param args printf args
      */
     void fluffRaw(String format, Object... args) {
-        if (feedback.shouldDisplayCommandFluff() && interactive()) {
+        if (showFluff()) {
             rawout(format, args);
         }
     }
@@ -389,7 +400,8 @@
      * @param key the resource key
      * @param args
      */
-    void hardmsg(String key, Object... args) {
+    @Override
+    public void hardmsg(String key, Object... args) {
         cmdout.println(prefix(messageFormat(key, args)));
     }
 
@@ -428,7 +440,7 @@
      */
     @Override
     public void fluffmsg(String key, Object... args) {
-        if (feedback.shouldDisplayCommandFluff() && interactive()) {
+        if (showFluff()) {
             hardmsg(key, args);
         }
     }
@@ -502,16 +514,9 @@
         }
 
         // Read retained editor setting (if any)
-        String editorString = prefs.get(EDITOR_KEY, "");
-        if (editorString == null || editorString.isEmpty()) {
-            editor = null;
-        } else {
-            char waitMarker = editorString.charAt(0);
-            if (waitMarker == '-' || waitMarker == '*') {
-                editorWait = waitMarker == '-';
-                editorString = editorString.substring(1);
-            }
-            editor = editorString.split(RECORD_SEPARATOR);
+        editor = EditorSetting.fromPrefs(prefs);
+        if (editor == null) {
+            editor = BUILT_IN_EDITOR;
         }
 
         resetState(); // Initialize
@@ -681,9 +686,24 @@
         }
 
         @Override
+        public void hard(String format, Object... args) {
+            //ignore
+        }
+
+        @Override
+        public void hardmsg(String messageKey, Object... args) {
+            //ignore
+        }
+
+        @Override
         public void errormsg(String messageKey, Object... args) {
             startmsg(messageKey, args);
         }
+
+        @Override
+        public boolean showFluff() {
+            return false;
+        }
     }
 
     private void resetState() {
@@ -745,7 +765,7 @@
         startUpRun(getResourceString("startup.feedback"));
         // These predefined modes are read-only
         feedback.markModesReadOnly();
-        // Restore user defined modes retained on previous run with /retain mode
+        // Restore user defined modes retained on previous run with /set mode -retain
         String encoded = prefs.get(MODE_KEY, null);
         if (encoded != null && !encoded.isEmpty()) {
             if (!feedback.restoreEncodedModes(initmh, encoded)) {
@@ -755,7 +775,7 @@
         }
         if (commandLineFeedbackMode != null) {
             // The feedback mode to use was specified on the command line, use it
-            if (!feedback.setFeedback(initmh, new ArgTokenizer("--feedback", commandLineFeedbackMode))) {
+            if (!setFeedback(initmh, new ArgTokenizer("--feedback", commandLineFeedbackMode))) {
                 regenerateOnDeath = false;
             }
             commandLineFeedbackMode = null;
@@ -763,8 +783,8 @@
             String fb = prefs.get(FEEDBACK_KEY, null);
             if (fb != null) {
                 // Restore the feedback mode to use that was retained
-                // on a previous run with /retain feedback
-                feedback.retainFeedback(initmh, new ArgTokenizer("/retain feedback", fb));
+                // on a previous run with /set feedback -retain
+                setFeedback(initmh, new ArgTokenizer("previous retain feedback", "-retain " + fb));
             }
         }
     }
@@ -1227,14 +1247,6 @@
                         "editor", fileCompletions(Files::isExecutable),
                         "start", FILE_COMPLETION_PROVIDER),
                         STARTSWITH_MATCHER)));
-        registerCommand(new Command("/retain",
-                arg -> cmdRetain(arg),
-                new ContinuousCompletionProvider(Map.of(
-                        "feedback", feedback.modeCompletions(),
-                        "mode", feedback.modeCompletions(),
-                        "editor", fileCompletions(Files::isExecutable),
-                        "start", FILE_COMPLETION_PROVIDER),
-                        STARTSWITH_MATCHER)));
         registerCommand(new Command("/?",
                 "help.quest",
                 arg -> cmdHelp(arg),
@@ -1293,9 +1305,6 @@
     private static final String[] SET_SUBCOMMANDS = new String[]{
         "format", "truncation", "feedback", "mode", "prompt", "editor", "start"};
 
-    private static final String[] RETAIN_SUBCOMMANDS = new String[]{
-        "feedback", "mode", "editor", "start"};
-
     final boolean cmdSet(String arg) {
         String cmd = "/set";
         ArgTokenizer at = new ArgTokenizer(cmd, arg.trim());
@@ -1304,95 +1313,61 @@
             return false;
         }
         switch (which) {
+            case "_retain": {
+                errormsg("jshell.err.setting.to.retain.must.be.specified", at.whole());
+                return false;
+            }
+            case "_blank": {
+                // show top-level settings
+                new SetEditor().set();
+                showSetStart();
+                setFeedback(this, at); // no args so shows feedback setting
+                hardmsg("jshell.msg.set.show.mode.settings");
+                return true;
+            }
             case "format":
                 return feedback.setFormat(this, at);
             case "truncation":
                 return feedback.setTruncation(this, at);
             case "feedback":
-                return feedback.setFeedback(this, at);
+                return setFeedback(this, at);
             case "mode":
-                return feedback.setMode(this, at);
+                return feedback.setMode(this, at,
+                        retained -> prefs.put(MODE_KEY, retained));
             case "prompt":
                 return feedback.setPrompt(this, at);
             case "editor":
-                return setEditor(at, true);
+                return new SetEditor(at).set();
             case "start":
-                return setStart(cmd, at, true);
+                return setStart(at);
             default:
                 errormsg("jshell.err.arg", cmd, at.val());
                 return false;
         }
     }
 
-    final boolean cmdRetain(String arg) {
-        String cmd = "/retain";
-        ArgTokenizer at = new ArgTokenizer(cmd, arg.trim());
-        String which = subCommand(cmd, at, RETAIN_SUBCOMMANDS);
-        if (which == null) {
-            return false;
-        }
-        switch (which) {
-            case "feedback": {
-                String fb = feedback.retainFeedback(this, at);
-                if (fb != null) {
-                    // If a feedback mode has been set now, or in the past, retain it
-                    prefs.put(FEEDBACK_KEY, fb);
-                    return true;
-                }
-                return false;
-            }
-            case "mode":
-                String retained = feedback.retainMode(this, at);
-                if (retained != null) {
-                    // Retain this mode and all previously retained modes
-                    prefs.put(MODE_KEY, retained);
-                    return true;
-                }
-                return false;
-            case "editor":
-                if (!setEditor(at, false)) {
-                    return false;
-                }
-                // retain editor setting
-                prefs.put(EDITOR_KEY, (editor == null)
-                        ? ""
-                        : (editorWait? "-" : "*") + String.join(RECORD_SEPARATOR, editor));
-                return true;
-            case "start": {
-                if (!setStart(cmd, at, false)) {
-                    return false;
-                }
-                // retain startup setting
-                prefs.put(STARTUP_KEY, startup);
-                return true;
-            }
-            default:
-                errormsg("jshell.err.arg", cmd, at.val());
-                return false;
-        }
+    boolean setFeedback(MessageHandler messageHandler, ArgTokenizer at) {
+        return feedback.setFeedback(messageHandler, at,
+                fb -> prefs.put(FEEDBACK_KEY, fb));
     }
 
-    // Print the help doc for the specified sub-command
-    boolean printSubCommandHelp(String cmd, ArgTokenizer at, String helpPrefix, String[] subs) {
-        String which = subCommand(cmd, at, subs);
-        if (which == null) {
-            return false;
+    // Find which, if any, sub-command matches.
+    // Return null on error
+    String subCommand(String cmd, ArgTokenizer at, String[] subs) {
+        at.allowedOptions("-retain");
+        String sub = at.next();
+        if (sub == null) {
+            // No sub-command was given
+            return at.hasOption("-retain")
+                    ? "_retain"
+                    : "_blank";
         }
-        hardrb(helpPrefix + which);
-        return true;
-    }
-
-    // Find which, if any, sub-command matches
-    String subCommand(String cmd, ArgTokenizer at, String[] subs) {
-        String[] matches = at.next(subs);
-        if (matches == null) {
-            // No sub-command was given
-            errormsg("jshell.err.sub.arg", cmd);
-            return null;
-        }
+        String[] matches = Arrays.stream(subs)
+                .filter(s -> s.startsWith(sub))
+                .toArray(size -> new String[size]);
         if (matches.length == 0) {
             // There are no matching sub-commands
-            errormsg("jshell.err.arg", cmd, at.val());
+            errormsg("jshell.err.arg", cmd, sub);
             fluffmsg("jshell.msg.use.one.of", Arrays.stream(subs)
                     .collect(Collectors.joining(", "))
             );
@@ -1400,7 +1375,7 @@
         }
         if (matches.length > 1) {
             // More than one sub-command matches the initial characters provided
-            errormsg("jshell.err.sub.ambiguous", cmd, at.val());
+            errormsg("jshell.err.sub.ambiguous", cmd, sub);
             fluffmsg("jshell.msg.use.one.of", Arrays.stream(matches)
                     .collect(Collectors.joining(", "))
             );
@@ -1409,67 +1384,219 @@
         return matches[0];
     }
 
-    // The sub-command:  /set editor <editor-command-line>>
-    boolean setEditor(ArgTokenizer at, boolean argsRequired) {
-        at.allowedOptions("-default", "-wait");
-        String prog = at.next();
-        List<String> ed = new ArrayList<>();
-        while (at.val() != null) {
-            ed.add(at.val());
-            at.nextToken();
+    static class EditorSetting {
+
+        static String BUILT_IN_REP = "-default";
+        static char WAIT_PREFIX = '-';
+        static char NORMAL_PREFIX = '*';
+
+        final String[] cmd;
+        final boolean wait;
+
+        EditorSetting(String[] cmd, boolean wait) {
+            this.wait = wait;
+            this.cmd = cmd;
+        }
+
+        // returns null if not stored in preferences
+        static EditorSetting fromPrefs(Preferences prefs) {
+            // Read retained editor setting (if any)
+            String editorString = prefs.get(EDITOR_KEY, "");
+            if (editorString == null || editorString.isEmpty()) {
+                return null;
+            } else if (editorString.equals(BUILT_IN_REP)) {
+                return BUILT_IN_EDITOR;
+            } else {
+                boolean wait = false;
+                char waitMarker = editorString.charAt(0);
+                if (waitMarker == WAIT_PREFIX || waitMarker == NORMAL_PREFIX) {
+                    wait = waitMarker == WAIT_PREFIX;
+                    editorString = editorString.substring(1);
+                }
+                String[] cmd = editorString.split(RECORD_SEPARATOR);
+                return new EditorSetting(cmd, wait);
+            }
+        }
+
+        void toPrefs(Preferences prefs) {
+            prefs.put(EDITOR_KEY, (this == BUILT_IN_EDITOR)
+                    ? BUILT_IN_REP
+                    : (wait ? WAIT_PREFIX : NORMAL_PREFIX) + String.join(RECORD_SEPARATOR, cmd));
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o instanceof EditorSetting) {
+                EditorSetting ed = (EditorSetting) o;
+                return Arrays.equals(cmd, ed.cmd) && wait == ed.wait;
+            } else {
+                return false;
+            }
+        }
+
+        @Override
+        public int hashCode() {
+            int hash = 7;
+            hash = 71 * hash + Arrays.deepHashCode(this.cmd);
+            hash = 71 * hash + (this.wait ? 1 : 0);
+            return hash;
         }
+    }
+
+    class SetEditor {
+
+        private final ArgTokenizer at;
+        private final String[] command;
+        private final boolean hasCommand;
+        private final boolean defaultOption;
+        private final boolean waitOption;
+        private final boolean retainOption;
+
+        SetEditor(ArgTokenizer at) {
+            at.allowedOptions("-default", "-wait", "-retain");
+            String prog = at.next();
+            List<String> ed = new ArrayList<>();
+            while (at.val() != null) {
+                ed.add(at.val());
+                at.nextToken();  // so that options are not interpreted as jshell options
+            }
+            this.at = at;
+            this.command = ed.toArray(new String[ed.size()]);
+            this.hasCommand = command.length > 0;
+            this.defaultOption = at.hasOption("-default");
+            this.waitOption = at.hasOption("-wait");
+            this.retainOption = at.hasOption("-retain");
+        }
+
+        SetEditor() {
+            this(new ArgTokenizer("", ""));
+        }
+
+        boolean set() {
+            if (!check()) {
+                return false;
+            }
+            if (!hasCommand && !defaultOption && !retainOption) {
+                // No settings or -retain, so this is a query
+                EditorSetting retained = EditorSetting.fromPrefs(prefs);
+                if (retained != null) {
+                    // retained editor is set
+                    hard("/set editor -retain %s", format(retained));
+                }
+                if (retained == null || !retained.equals(editor)) {
+                    // editor is not retained or retained is different from set
+                    hard("/set editor %s", format(editor));
+                }
+                return true;
+            }
+            install();
+            if (retainOption) {
+                editor.toPrefs(prefs);
+                fluffmsg("jshell.msg.set.editor.retain", format(editor));
+            }
+            return true;
+        }
+
+        private boolean check() {
+            if (!checkOptionsAndRemainingInput(at)) {
+                return false;
+            }
+            if (hasCommand && defaultOption) {
+                errormsg("jshell.err.default.option.or.program", at.whole());
+                return false;
+            }
+            if (waitOption && !hasCommand) {
+                errormsg("jshell.err.wait.applies.to.external.editor", at.whole());
+                return false;
+            }
+            return true;
+        }
+
+        private void install() {
+            if (hasCommand) {
+                editor = new EditorSetting(command, waitOption);
+            } else if (defaultOption) {
+                editor = BUILT_IN_EDITOR;
+            } else {
+                return;
+            }
+            fluffmsg("jshell.msg.set.editor.set", format(editor));
+        }
+
+        private String format(EditorSetting ed) {
+            if (ed == BUILT_IN_EDITOR) {
+                return "-default";
+            } else {
+                Stream<String> elems = Arrays.stream(ed.cmd);
+                if (ed.wait) {
+                    elems = Stream.concat(Stream.of("-wait"), elems);
+                }
+                return elems.collect(joining(" "));
+            }
+        }
+    }
+
+    // The sub-command:  /set start <start-file>
+    boolean setStart(ArgTokenizer at) {
+        at.allowedOptions("-default", "-none", "-retain");
+        String fn = at.next();
         if (!checkOptionsAndRemainingInput(at)) {
             return false;
         }
         boolean defaultOption = at.hasOption("-default");
-        boolean waitOption = at.hasOption("-wait");
-        if (prog != null) {
-            if (defaultOption) {
-                errormsg("jshell.err.default.option.or.program", at.whole());
+        boolean noneOption = at.hasOption("-none");
+        boolean retainOption = at.hasOption("-retain");
+        boolean hasFile = fn != null;
+
+        int argCount = (defaultOption ? 1 : 0) + (noneOption ? 1 : 0) + (hasFile ? 1 : 0);
+        if (argCount > 1) {
+            errormsg("jshell.err.option.or.filename", at.whole());
+            return false;
+        }
+        if (argCount == 0 && !retainOption) {
+            // no options or filename, show current setting
+            showSetStart();
+            return true;
+        }
+        if (hasFile) {
+            String init = readFile(fn, "/set start");
+            if (init == null) {
                 return false;
             }
-            editor = ed.toArray(new String[ed.size()]);
-            editorWait = waitOption;
-            fluffmsg("jshell.msg.set.editor.set", prog);
+            startup = init;
         } else if (defaultOption) {
-            if (waitOption) {
-                errormsg("jshell.err.wait.applies.to.external.editor", at.whole());
-                return false;
-            }
-            editor = null;
-        } else if (argsRequired) {
-            errormsg("jshell.err.set.editor.arg");
-            return false;
+            startup = DEFAULT_STARTUP;
+        } else if (noneOption) {
+            startup = "";
+        }
+        if (retainOption) {
+            // retain startup setting
+            prefs.put(STARTUP_KEY, startup);
         }
         return true;
     }
 
-    // The sub-command:  /set start <start-file>
-    boolean setStart(String cmd, ArgTokenizer at, boolean argsRequired) {
-        at.allowedOptions("-default", "-none");
-        String fn = at.next();
-        if (!checkOptionsAndRemainingInput(at)) {
-            return false;
+    void showSetStart() {
+        String retained = prefs.get(STARTUP_KEY, null);
+        if (retained != null) {
+            showSetStart(true, retained);
         }
-        int argCount = at.optionCount() + ((fn != null) ? 1 : 0);
-        if (argCount > 1 || argsRequired && argCount == 0) {
-            errormsg("jshell.err.option.or.filename", at.whole());
-            return false;
+        if (retained == null || !startup.equals(retained)) {
+            showSetStart(false, startup);
         }
-        if (fn != null) {
-            String init = readFile(fn, cmd + " start");
-            if (init == null) {
-                return false;
-            } else {
-                startup = init;
-                return true;
-            }
-        } else if (at.hasOption("-default")) {
-            startup = DEFAULT_STARTUP;
-        } else if (at.hasOption("-none")) {
-            startup = "";
+    }
+
+    void showSetStart(boolean isRetained, String start) {
+        String cmd = "/set start" + (isRetained ? " -retain " : " ");
+        String stset;
+        if (start.equals(DEFAULT_STARTUP)) {
+            stset = cmd + "-default";
+        } else if (start.isEmpty()) {
+            stset = cmd + "-none";
+        } else {
+            stset = prefix("startup.jsh:\n" + start + "\n" + cmd + "startup.jsh", "");
         }
-        return true;
+        hard(stset);
     }
 
     boolean cmdClasspath(String arg) {
@@ -1559,17 +1686,18 @@
             Command[] matches = commands.values().stream()
                     .filter(c -> c.command.startsWith(subject))
                     .toArray(size -> new Command[size]);
-            at.mark();
-            String sub = at.next();
-            if (sub != null && matches.length == 1) {
+            if (matches.length == 1) {
                 String cmd = matches[0].command;
-                switch (cmd) {
-                    case "/set":
-                        at.rewind();
-                        return printSubCommandHelp(cmd, at, "help.set.", SET_SUBCOMMANDS);
-                    case "/retain":
-                        at.rewind();
-                        return printSubCommandHelp(cmd, at, "help.retain.", RETAIN_SUBCOMMANDS);
+                if (cmd.equals("/set")) {
+                    // Print the help doc for the specified sub-command
+                    String which = subCommand(cmd, at, SET_SUBCOMMANDS);
+                    if (which == null) {
+                        return false;
+                    }
+                    if (!which.equals("_blank")) {
+                        hardrb("help.set." + which);
+                        return true;
+                    }
                 }
             }
             if (matches.length > 0) {
@@ -1813,7 +1941,7 @@
         String src = sb.toString();
         Consumer<String> saveHandler = new SaveHandler(src, srcSet);
         Consumer<String> errorHandler = s -> hard("Edit Error: %s", s);
-        if (editor == null) {
+        if (editor == BUILT_IN_EDITOR) {
             try {
                 EditPad.edit(errorHandler, src, saveHandler);
             } catch (RuntimeException ex) {
@@ -1822,8 +1950,8 @@
                 return false;
             }
         } else {
-            ExternalEditor.edit(editor, errorHandler, src, saveHandler, input,
-                    editorWait, this::hardrb);
+            ExternalEditor.edit(editor.cmd, errorHandler, src, saveHandler, input,
+                    editor.wait, this::hardrb);
         }
         return true;
     }
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/MessageHandler.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/MessageHandler.java	Thu Oct 20 20:01:40 2016 +0000
@@ -37,5 +37,11 @@
 
     void fluffmsg(String messageKey, Object... args);
 
+    void hard(String format, Object... args);
+
+    void hardmsg(String messageKey, Object... args);
+
     void errormsg(String messageKey, Object... args);
+
+    boolean showFluff();
 }
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties	Thu Oct 20 20:01:40 2016 +0000
@@ -52,12 +52,17 @@
 
 jshell.err.no.such.command.or.snippet.id = No such command or snippet id: {0}
 jshell.err.command.ambiguous = Command: ''{0}'' is ambiguous: {1}
-jshell.err.set.editor.arg = The ''/set editor'' command requires a path argument
 jshell.msg.set.editor.set = Editor set to: {0}
+jshell.msg.set.editor.retain = Editor setting retained: {0}
 jshell.err.cant.launch.editor = Cannot launch editor -- unexpected exception: {0}
 jshell.msg.try.set.editor = Try /set editor to use external editor.
 jshell.msg.press.return.to.leave.edit.mode = Press return to leave edit mode.
-jshell.err.wait.applies.to.external.editor = -wait applies to external editors, cannot be used with -default
+jshell.err.wait.applies.to.external.editor = -wait applies to external editors
+
+jshell.err.setting.to.retain.must.be.specified = The setting to retain must be specified -- {0}
+jshell.msg.set.show.mode.settings = \nTo show mode settings use ''/set prompt'', ''/set truncation'', ...\n\
+or use ''/set mode'' followed by the feedback mode name.
+jshell.err.continuation.prompt.required = Continuation prompt required -- {0}
 
 jshell.msg.try.command.without.args = Try ''{0}'' without arguments.
 jshell.msg.no.active = There are no active definitions.
@@ -104,12 +109,10 @@
 jshell.err.mode.name = Expected a feedback mode name: {0}
 jshell.err.missing.mode = Missing the feedback mode -- {0}
 jshell.err.field.name = Expected a field name: {0} -- {1}
-jshell.err.missing.field = Missing the field name -- {0}
 jshell.err.mode.unknown = No feedback mode named: {0} -- {1}
 
 jshell.err.feedback.does.not.match.mode = Does not match any current feedback mode: {0} -- {1}
 jshell.err.feedback.ambiguous.mode = Matches more then one current feedback mode: {0} -- {1}
-jshell.err.feedback.expected.format = Expected format missing -- {0}
 jshell.err.feedback.must.be.quoted = Format ''{0}'' must be quoted -- {1}
 jshell.err.feedback.not.a.valid.selector = Not a valid selector ''{0}'' in ''{1}'' -- {2}
 jshell.err.feedback.multiple.sections = Selector kind in multiple sections of selector list ''{0}'' in ''{1}'' -- {2}
@@ -117,22 +120,25 @@
 
 jshell.msg.feedback.new.mode = Created new feedback mode: {0}
 jshell.msg.feedback.mode = Feedback mode: {0}
-jshell.msg.feedback.mode.following = The feedback mode should be one of the following:
+jshell.msg.feedback.mode.following = Available feedback modes:
+jshell.msg.feedback.retained.mode.following = Retained feedback modes:
+jshell.err.mode.creation = To create a new mode either the -command or the -quiet option must be used -- {0}
+jshell.err.mode.exists = Mode to be created already exists: {0} -- {1}
 
 jshell.err.truncation.expected.length = Expected truncation length -- {0}
 jshell.err.truncation.length.not.integer = Truncation length must be an integer: {0} -- {1}
 
 jshell.err.not.valid.with.predefined.mode = Not valid with a predefined mode: {0} -- {1}
 jshell.err.retained.feedback.mode.must.be.retained.or.predefined = \
-''/retain feedback <mode>'' requires that <mode> is predefined or has been retained with ''/retain mode'' -- {0}
+''/set feedback -retain <mode>'' requires that <mode> is predefined or has been retained with ''/set mode -retain'' -- {0}
 
 jshell.err.unknown.option = Unknown option: {0} -- {1}
 jshell.err.default.option.or.program = Specify -default option or program, not both -- {0}
-jshell.err.option.or.filename = Specify either one option or a startup file name -- {0}
+jshell.err.option.or.filename = Specify no more than one of -default, -none, or a startup file name -- {0}
 jshell.err.unexpected.at.end = Unexpected arguments at end of command: {0} -- {1}
 jshell.err.conflicting.options = Conflicting options -- {0}
 jshell.err.cannot.delete.current.mode = The current feedback mode ''{0}'' cannot be deleted, use ''/set feedback'' first -- {1}
-jshell.err.cannot.delete.retained.mode = The retained feedback mode ''{0}'' cannot be deleted, use ''/retain feedback'' first -- {1}
+jshell.err.cannot.delete.retained.mode = The retained feedback mode ''{0}'' cannot be deleted, use ''/set feedback -retain'' first -- {1}
 jshell.err.may.not.specify.options.and.snippets = Options and snippets must not both be used: {0}
 jshell.err.no.such.snippets = No such snippet: {0}
 jshell.err.the.snippet.cannot.be.used.with.this.command = This command does not accept the snippet ''{0}'' : {1}
@@ -374,36 +380,20 @@
      The contents of the specified <file> become the default start-up snippets and commands.\n\n\
 /set feedback <mode>\n\t\
      Set the feedback mode describing displayed feedback for entered snippets and commands.\n\n\
-/set mode <mode> [<old-mode>] [-command|-quiet|-delete]\n\t\
+/set mode <mode> [<old-mode>] -command|-quiet|-delete\n\t\
      Create or update a user-defined feedback mode, optionally copying from an existing mode.\n\n\
 /set prompt <mode> "<prompt>" "<continuation-prompt>"\n\t\
      Set the displayed prompts for a given feedback mode.\n\n\
 /set truncation <mode> <length> <selector>...\n\t\
-     Set the maximum length of a displayed value\n\
+     Set the maximum length of a displayed value.\n\n\
 /set format <mode> <field> "<format>" <selector>...\n\t\
-     Configure a feedback mode by setting the format of a field when the selector matchs.\n\n\
+     Configure a feedback mode by setting the format of a field when the selector matches.\n\n\
+/set\n\t\
+     Show editor, start, and feedback settings as /set commands.\n\t\
+     To show the settings of any of the above, omit the set value.\n\n\
 To get more information about one of these forms, use /help with the form specified.\n\
 For example:   /help /set format
 
-help.retain.summary = retain jshell configuration information for subsequent sessions
-help.retain.args = editor|start|feedback|mode
-help.retain =\
-Retain jshell configuration information for future invocations of the jshell tool,\n\
-including: the external editor to use, the start-up definitions to use, the\n\
-configuration of a feedback mode, or the feedback mode to use.\n\
-\n\
-/retain editor [<command> <optional-arg>...]\n\t\
-     Specify the command to launch for the /edit command.\n\t\
-     The <command> is an operating system dependent string.\n\n\
-/retain start [<file>]\n\t\
-     The contents of the specified <file> become the default start-up snippets and commands.\n\n\
-/retain feedback [<mode>]\n\t\
-     Set the feedback mode describing displayed feedback for entered snippets and commands.\n\n\
-/retain mode <mode>\n\t\
-     Create a user-defined feedback mode, optionally copying from an existing mode.\n\n\
-To get more information about one of these forms, use /help with the form specified.\n\
-For example:   /help /retain feedback
-
 help.quest.summary = get information about jshell
 help.quest.args = [<command>|<subject>]
 help.quest =\
@@ -467,11 +457,24 @@
         possible fully qualified names based on the content of the specified classpath.\n\t\t\
         The "<fix-shortcut>" is either Alt-F1 or Alt-Enter, depending on the platform.
 
+help.set._retain = \
+The '-retain' option saves a setting so that it is used in future sessions.\n\
+The -retain option can be used on the following forms of /set:\n\n\t\
+/set editor -retain\n\t\
+/set start -retain\n\t\
+/set feedback -retain\n\t\
+/set mode -retain\n\n\
+See these commands for more detail -- for example /help /set editor
+
 help.set.format = \
-Set the format for reporting a snippet event.\n\
+Set the format for reporting a snippet event:\n\
 \n\t\
 /set format <mode> <field> "<format>" <selector>...\n\
 \n\
+Show the format settings:\n\
+\n\t\
+/set format [<mode> [<field>]]\n\
+\n\
 Where <mode> is the name of a previously defined feedback mode -- see '/help /set mode'.\n\
 Where <field> is the name of context-specific format to define.\n\
 Where <format> is a quoted string which will be the value of the field if one of\n\
@@ -541,13 +544,24 @@
 /set format myformat action 'Update replaced' replaced-update\n\t\
 /set format myformat display '{pre}{action} class {name}{post}' class-ok\n\t\
 /set format myformat display '{pre}{action} variable {name}, reset to null{post}' replaced-vardecl,varinit-ok-update\n\n\
-Note that subsequent selectors for a field may overwrite some or all of previous used selectors -- last one wins\n
+Note that subsequent selectors for a field may overwrite some or all of previous used selectors -- last one wins\n\
+\n\
+The form without <format> shows the current format settings.\n\
+When the <mode> is specified only the format settings for that mode are shown.\n\
+When both the <mode> and <field> are specified only the format settings for that\n\
+mode and field are shown.  Example:\n\t\
+/set format myformat\n\
+shows the format settings for the mode myformat\n
 
 help.set.truncation = \
-Set the max length a displayed value.\n\
+Set the max length of a displayed value:\n\
 \n\t\
 /set truncation <mode> <length> <selector>...\n\
 \n\
+Show the current truncation settings:\n\
+\n\t\
+/set truncation [<mode>]\n\
+\n\
 Where <mode> is the name of a previously defined feedback mode -- see '/help /set mode'.\n\
 Where <length> is an unsigned integer representing a maximum length.\n\
 Where <selector> is only needed if you wish to fine-tune value truncation length\n\
@@ -571,46 +585,108 @@
 /set trunc mymode 80\n\t\
 /set truncation mymode 45 expression\n\t\
 /set truncation mymode 0 vardecl-modified,replaced\n\n\
-Note that subsequent selectors for a field may overwrite some or all of previous used selectors -- last one wins\n
+Note that subsequent selectors for a field may overwrite some or all of previous used selectors -- last one wins\n\
+\n\
+The form without <length> shows the truncation settings.\n\
+When the <mode> is specified only the truncation settings for that mode are shown.\n\
+Example:\n\t\
+/set truncation myformat\n\
+shows the truncation settings for the mode myformat\n
 
 help.set.feedback = \
-Set the feedback mode describing displayed feedback for entered snippets and commands.\n\
+Set the feedback mode describing displayed feedback for entered snippets and commands:\n\
+\n\t\
+/set feedback [-retain] <mode>\n\
+\n\
+Retain the current feedback mode for future sessions:\n\
 \n\t\
-/set feedback <mode>\n\
+/set feedback -retain\n\
+\n\
+Show the feedback mode and list available modes:\n\
+\n\t\
+/set feedback\n\
 \n\
 Where <mode> is the name of a previously defined feedback mode.\n\
 You may use just enough letters to make it unique.\n\
 User-defined modes can be added, see '/help /set mode'\n\
-Currently defined feedback modes:\n
+\n\
+When the -retain option is used, the setting will be used in this and future\n\
+runs of the jshell tool.\n\
+\n\
+The form without <mode> or -retain displays the current feedback mode and available modes.\n
 
 help.set.mode = \
-Create a user-defined feedback mode, optionally copying from an existing mode.\n\
+Create a user-defined feedback mode, optionally copying from an existing mode:\n\
 \n\t\
 /set mode <mode> [<old-mode>] [-command|-quiet|-delete]\n\
+Retain a user-defined feedback mode for future sessions:\n\
+\n\t\
+/set mode -retain <mode>\n\
+\n\
+Delete a user-defined feedback mode:\n\
+\n\t\
+/set mode -delete [-retain] <mode>\n\
+\n\
+Show feedback mode settings:\n\
+\n\t\
+/set mode [<mode>]\n\
 \n\
 Where <new-mode> is the name of a mode you wish to create.\n\
 Where <old-mode> is the name of a previously defined feedback mode.\n\
 If <old-mode> is present, its settings are copied to the new mode.\n\
 '-command' vs '-quiet' determines if informative/verifying command feedback is displayed.\n\
 \n\
-Once the new mode is created, use '/set format' and '/set prompt' to configure it.\n\
-Use '/set feedback' to use the new mode.\n\
+Once the new mode is created, use '/set format', '/set prompt' and '/set truncation'\n\
+to configure it.  Use '/set feedback' to use the new mode.\n\
+\n\
+When the -retain option is used, the mode (including its component prompt, format,\n\
+and truncation settings) will be used in this and future runs of the jshell tool.\n\
+When both -retain and -delete are used, the mode is deleted from the current\n\
+and future sessions.\n\
+\n\
+The form without options shows the mode settings.\n\
+When the <mode> is specified only the mode settings for that mode are shown.\n\
+Note: the settings for the mode include the settings for prompt, format, and\n\
+truncation -- so these are displayed as well.\n\
+Example:\n\t\
+/set mode myformat\n\
+shows the mode, prompt, format, and truncation settings for the mode myformat\n
 
 help.set.prompt = \
-Set the prompts.  Both the normal prompt and the continuation-prompt must be set.\n\
+Set the prompts.  Both the normal prompt and the continuation-prompt must be set:\n\
 \n\t\
 /set prompt <mode> \"<prompt>\" \"<continuation-prompt>\"\n\
 \n\
+Show the normal prompt and the continuation-prompts:\n\
+\n\t\
+/set prompt [<mode>]\n\
+\n\
 Where <mode> is the name of a previously defined feedback mode.\n\
 Where <prompt> and <continuation-prompt> are quoted strings printed as input prompts;\n\
 Both may optionally contain '%s' which will be substituted with the next snippet id --\n\
 note that what is entered may not be assigned that id, for example it may be an error or command.\n\
-The continuation-prompt is used on the second and subsequent lines of a multi-line snippet.\n
+The continuation-prompt is used on the second and subsequent lines of a multi-line snippet.\n\
+\n\
+The form without <prompt> shows the currently set prompts.\n\
+When the <mode> is specified only the prompts for that mode are shown.\n\
+Example:\n\t\
+/set prompt myformat\n\
+shows the prompts set for the mode myformat\n
 
 help.set.editor =\
-Specify the command to launch for the /edit command.\n\
+Specify the command to launch for the /edit command:\n\
+\n\t\
+/set editor [-retain] [-wait] <command>\n\
 \n\t\
-/set editor [-wait] <command>|-default\n\
+/set editor [-retain] [-retain] -default\n\
+\n\
+Retain the current editor setting for future sessions:\n\
+\n\t\
+/set editor -retain\n\
+\n\
+Show the command to launch for the /edit command:\n\
+\n\t\
+/set editor\n\
 \n\
 The <command> is an operating system dependent string.\n\
 The <command> may include space-separated arguments (such as flags)\n\n\
@@ -622,12 +698,29 @@
 flags should be used to prevent immediate exit, or the -wait option should be used to\n\
 prompt the user to indicate when edit mode should end.\n\n\
 Note: while in edit mode no command inputs are seen.  After leaving edit mode changes\n\
-to the edited snippets are not seen.
+to the edited snippets are not seen.\n\
+\n\
+When the -retain option is used, the setting will be used in this and future\n\
+runs of the jshell tool.\n\
+\n\
+The form without <command> or options shows the editor setting.\n
 
 help.set.start =\
-Set the start-up configuration -- a sequence of snippets and commands read at start-up.\n\
+Set the start-up configuration -- a sequence of snippets and commands read at start-up:\n\
+\n\t\
+/set start [-retain] <file>\n\
+\n\t\
+/set start [-retain] -default\n\
 \n\t\
-/set start <file>|-default|-none\n\
+/set start [-retain] -none\n\
+\n\
+Retain the start-up configuration for future sessions:\n\
+\n\t\
+/set start -retain\n\
+\n\
+Show the start-up setting:\n\
+\n\t\
+/set start\n\
 \n\
 The contents of the specified <file> become the start-up snippets and commands used\n\
 when the /reset or /reload commands are used in this session.\n\
@@ -637,59 +730,14 @@
 or commands will be used.\n\
 This command is good for testing the start-up settings.  To retain them for future\n\
 runs of the jshell tool use the command:\n\t\
-/retain start\n
-
-help.retain.feedback = \
-Retain which feedback mode to use for displayed feedback for entered snippets and commands.\n\
-This feedback mode will be used in this and future sessions of the jshell tool.\n\
-\n\t\
-/retain feedback [<mode>]\n\
-\n\
-Where <mode> is the name of a previously defined feedback mode.\n\
-You may use just enough letters to make it unique.\n\
-If the <mode> is not specified, this command retains the current mode (as set\n\
-with the most recent /set feedback or /retain feedback command.)\n\
-
-help.retain.mode = \
-Retain the existence and configuration of a user-defined feedback mode.\n\
-This mode will be available in this and future sessions of the jshell tool.
-\n\t\
-/retain mode <mode>\n\
+/set start -retain\n\
 \n\
-Where <mode> is the name of a mode you wish to retain.\n\
-The <mode> must previously have been created with /set mode and\n\
-configured as desired with /set prompt, /set format, and /set truncation.\n
-
-help.retain.editor =\
-Retain the command to launch for the /edit command.  This command will be invoked when\n\
-the /edit command is used in this and future sessions of the jshell tool.\n\
-\n\t\
-/retain editor [<command>|-default]\n\
+When the -retain option is used, the setting will be used in this and future\n\
+runs of the jshell tool.\n\
 \n\
-If <command> is specified, it is an operating system dependent string which\n\
-may include space-separated arguments (such as flags). When /edit is used, the\n\
-temporary file to edit will be appended as the last argument.\n\
-If instead the -default option is specified, the built-in default editor will be used.\n\
-If neither is specified, the editor set in the last /set editor or /retain editor\n\
-command will be used.\n\
-The editor will be retained and used in this and future runs of the jshell tool.
-
-help.retain.start =\
-Retain the start-up configuration -- a sequence of snippets and commands read\n\
-at start-up.\n\
-\n\t\
-/retain start [<file>|-default|-none]\n\
-\n\
-If <file> is specified, the contents of the specified <file> become the\n\
-start-up snippets\n\
-and commands.\n\
-If instead the -default option is specified, the predefined start-up snippets\n\
-will be the start-up.\n\
-If the -none option is used, the start-up will be empty -- no start-up snippets\n\
-or commands will be used.\n\
-If none of these is specified, the start-up is the last specified in a\n\
-''/set start'' or ''/retain start'' command.\n\
-The start-up will be retained and used when the jshell tool is started or reset
+The form without <file> or options shows the start-up setting.\n\
+Note: if the start-up was last set from a file, this is shown with the\n\
+contents of the file followed by a 'set start' command.
 
 startup.feedback = \
 /set mode verbose -command    \n\
@@ -773,6 +821,8 @@
 \n\
 /set mode silent -quiet    \n\
 /set prompt silent '-> ' '>> '    \n\
+/set truncation silent 80\n\
+/set truncation silent 1000                                                                  varvalue,expression\n\
 /set format silent pre '|  '    \n\
 /set format silent post '%n'    \n\
 /set format silent errorpre '|  '    \n\
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java	Thu Oct 20 20:01:40 2016 +0000
@@ -28,6 +28,7 @@
 import jdk.jshell.spi.ExecutionControl;
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
+import java.io.InterruptedIOException;
 import java.io.PrintStream;
 import java.text.MessageFormat;
 import java.util.ArrayList;
@@ -167,6 +168,10 @@
          * user input cannot use {@code System.in} as the input stream for
          * the remote process.
          * <p>
+         * The {@code read} method of the {@code InputStream} may throw the {@link InterruptedIOException}
+         * to signal the user canceled the input. The currently running snippet will be automatically
+         * {@link JShell#stop() stopped}.
+         * <p>
          * The default, if this is not set, is to provide an empty input stream
          * -- {@code new ByteArrayInputStream(new byte[0])}.
          *
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/PipeInputStream.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/PipeInputStream.java	Thu Oct 20 20:01:40 2016 +0000
@@ -42,7 +42,7 @@
 
     @Override
     public synchronized int read() throws IOException {
-        if (start == end) {
+        if (start == end && !closed) {
             inputNeeded();
         }
         while (start == end) {
@@ -62,6 +62,32 @@
         }
     }
 
+    @Override
+    public synchronized int read(byte[] b, int off, int len) throws IOException {
+        if (b == null) {
+            throw new NullPointerException();
+        } else if (off < 0 || len < 0 || len > b.length - off) {
+            throw new IndexOutOfBoundsException();
+        } else if (len == 0) {
+            return 0;
+        }
+
+        int c = read();
+        if (c == -1) {
+            return -1;
+        }
+        b[off] = (byte)c;
+
+        int totalRead = 1;
+        while (totalRead < len && start != end) {
+            int r = read();
+            if (r == (-1))
+                break;
+            b[off + totalRead++] = (byte) r;
+        }
+        return totalRead;
+    }
+
     protected void inputNeeded() throws IOException {}
 
     private synchronized void write(int b) {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/Util.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/Util.java	Thu Oct 20 20:01:40 2016 +0000
@@ -28,6 +28,7 @@
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InterruptedIOException;
 import java.io.ObjectInput;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutput;
@@ -42,6 +43,7 @@
 
 import com.sun.jdi.VirtualMachine;
 import jdk.jshell.spi.ExecutionControl;
+import jdk.jshell.spi.ExecutionControl.ExecutionControlException;
 
 
 /**
@@ -54,6 +56,10 @@
  */
 public class Util {
 
+    private static final int TAG_DATA = 0;
+    private static final int TAG_CLOSED = 1;
+    private static final int TAG_EXCEPTION = 2;
+
     // never instanciated
     private Util() {}
 
@@ -131,6 +137,25 @@
                     inputSignal.write('1');
                     inputSignal.flush();
                 }
+                @Override
+                public synchronized int read() throws IOException {
+                    int tag = super.read();
+                    switch (tag) {
+                        case TAG_DATA: return super.read();
+                        case TAG_CLOSED: close(); return -1;
+                        case TAG_EXCEPTION:
+                            int len = (super.read() << 0) + (super.read() << 8) + (super.read() << 16) + (super.read() << 24);
+                            byte[] message = new byte[len];
+                            for (int i = 0; i < len; i++) {
+                                message[i] = (byte) super.read();
+                            }
+                            throw new IOException(new String(message, "UTF-8"));
+                        case -1:
+                            return -1;
+                        default:
+                            throw new IOException("Internal error: unrecognized message tag: " + tag);
+                    }
+                }
             };
             inputs.put(e.getKey(), inputPipe.createOutput());
             e.getValue().accept(inputPipe);
@@ -163,6 +188,7 @@
     public static ExecutionControl remoteInputOutput(InputStream input, OutputStream output,
             Map<String, OutputStream> outputStreamMap, Map<String, InputStream> inputStreamMap,
             BiFunction<ObjectInput, ObjectOutput, ExecutionControl> factory) throws IOException {
+        ExecutionControl[] result = new ExecutionControl[1];
         Map<String, OutputStream> augmentedStreamMap = new HashMap<>(outputStreamMap);
         ObjectOutput commandOut = new ObjectOutputStream(Util.multiplexingOutputStream("$command", output));
         for (Entry<String, InputStream> e : inputStreamMap.entrySet()) {
@@ -172,7 +198,28 @@
                 @Override
                 public void write(int b) throws IOException {
                     //value ignored, just a trigger to read from the input
-                    inTarget.write(in.read());
+                    try {
+                        int r = in.read();
+                        if (r == (-1)) {
+                            inTarget.write(TAG_CLOSED);
+                        } else {
+                            inTarget.write(new byte[] {TAG_DATA, (byte) r});
+                        }
+                    } catch (InterruptedIOException exc) {
+                        try {
+                            result[0].stop();
+                        } catch (ExecutionControlException ex) {
+                            debug(ex, "$" + e.getKey() + "-input-requested.write");
+                        }
+                    } catch (IOException exc) {
+                        byte[] message = exc.getMessage().getBytes("UTF-8");
+                        inTarget.write(TAG_EXCEPTION);
+                        inTarget.write((message.length >>  0) & 0xFF);
+                        inTarget.write((message.length >>  8) & 0xFF);
+                        inTarget.write((message.length >> 16) & 0xFF);
+                        inTarget.write((message.length >> 24) & 0xFF);
+                        inTarget.write(message);
+                    }
                 }
             });
         }
@@ -180,7 +227,7 @@
         OutputStream commandInTarget = commandIn.createOutput();
         augmentedStreamMap.put("$command", commandInTarget);
         new DemultiplexInput(input, augmentedStreamMap, Arrays.asList(commandInTarget)).start();
-        return factory.apply(new ObjectInputStream(commandIn), commandOut);
+        return result[0] = factory.apply(new ObjectInputStream(commandIn), commandOut);
     }
 
     /**
@@ -198,4 +245,13 @@
         }
     }
 
+    /**
+     * Log a serious unexpected internal exception.
+     *
+     * @param ex the exception
+     * @param where a description of the context of the exception
+     */
+    private static void debug(Throwable ex, String where) {
+        // Reserved for future logging
+    }
 }
--- a/langtools/test/Makefile	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/test/Makefile	Thu Oct 20 20:01:40 2016 +0000
@@ -157,11 +157,6 @@
 	-refvmoptions:-Xbootclasspath/p:$(TESTBOOTCLASSPATH)
 endif
 
-ifeq ($(ARCH_DATA_MODEL),32)
-  # Set the GC options for test vms
-  JTREG_GC_OPTION = -vmoption:-XX:+UseSerialGC
-  JTREG_OPTIONS += $(JTREG_GC_OPTION)
-endif
 # Set the max memory for jtreg target test JVMs
 JTREG_TESTVM_MEMORY_OPTION = -vmoption:-Xmx768m
 JTREG_OPTIONS += $(JTREG_TESTVM_MEMORY_OPTION)
@@ -256,6 +251,17 @@
 JCK_COMPILER_OUTPUT_DIR = $(ABS_TEST_OUTPUT_DIR)/jck-compiler
 JCK_RUNTIME_OUTPUT_DIR = $(ABS_TEST_OUTPUT_DIR)/jck-runtime-Xcompile
 
+# Is the test JVM 32-bit?
+DATA_MODEL := \
+	$(shell $(JT_JAVA)/bin/java -XshowSettings:properties -version 2>&1 | \
+		grep 'sun\.arch\.data\.model' | \
+		awk '{print $$3}')
+ifeq ($(DATA_MODEL), 32)
+  # Set the GC options for test vms having a smaller address space
+  JTREG_GC_OPTION = -vmoption:-XX:+UseSerialGC
+  JTREG_OPTIONS += $(JTREG_GC_OPTION)
+endif
+
 # Default make rule -- warning, may take a while
 all: $(JPRT_CLEAN) jtreg-tests jck-compiler-tests jck-runtime-tests $(JPRT_ARCHIVE_BUNDLE) all-summary
 	@echo "Testing completed successfully"
--- a/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java	Thu Oct 20 20:01:40 2016 +0000
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug      4665566 4855876 7025314 8012375 8015997 8016328 8024756
+ * @bug      4665566 4855876 7025314 8012375 8015997 8016328 8024756 8151921
  * @summary  Verify that the output has the right javascript.
  * @author   jamieh
  * @library  ../lib
@@ -54,11 +54,12 @@
 
         checkOutput("index.html", true,
                 "<script type=\"text/javascript\">\n"
-                + "    targetPage = \"\" + window.location.search;\n"
-                + "    if (targetPage != \"\" && targetPage != \"undefined\")\n"
-                + "        targetPage = targetPage.substring(1);\n"
-                + "    if (targetPage.indexOf(\":\") != -1 || (targetPage != \"\" && !validURL(targetPage)))\n"
-                + "        targetPage = \"undefined\";\n"
+                + "    tmpTargetPage = \"\" + window.location.search;\n"
+                + "    if (tmpTargetPage != \"\" && tmpTargetPage != \"undefined\")\n"
+                + "        tmpTargetPage = tmpTargetPage.substring(1);\n"
+                + "    if (tmpTargetPage.indexOf(\":\") != -1 || (tmpTargetPage != \"\" && !validURL(tmpTargetPage)))\n"
+                + "        tmpTargetPage = \"undefined\";\n"
+                + "    targetPage = tmpTargetPage;\n"
                 + "    function validURL(url) {\n"
                 + "        try {\n"
                 + "            url = decodeURIComponent(url);\n"
--- a/langtools/test/jdk/javadoc/doclet/testJavascript/TestJavascript.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testJavascript/TestJavascript.java	Thu Oct 20 20:01:40 2016 +0000
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug      4665566 4855876 7025314 8012375 8015997 8016328 8024756 8148985
+ * @bug      4665566 4855876 7025314 8012375 8015997 8016328 8024756 8148985 8151921
  * @summary  Verify that the output has the right javascript.
  * @author   jamieh
  * @library  ../lib
@@ -54,11 +54,12 @@
 
         checkOutput("index.html", true,
                 "<script type=\"text/javascript\">\n"
-                + "    targetPage = \"\" + window.location.search;\n"
-                + "    if (targetPage != \"\" && targetPage != \"undefined\")\n"
-                + "        targetPage = targetPage.substring(1);\n"
-                + "    if (targetPage.indexOf(\":\") != -1 || (targetPage != \"\" && !validURL(targetPage)))\n"
-                + "        targetPage = \"undefined\";\n"
+                + "    tmpTargetPage = \"\" + window.location.search;\n"
+                + "    if (tmpTargetPage != \"\" && tmpTargetPage != \"undefined\")\n"
+                + "        tmpTargetPage = tmpTargetPage.substring(1);\n"
+                + "    if (tmpTargetPage.indexOf(\":\") != -1 || (tmpTargetPage != \"\" && !validURL(tmpTargetPage)))\n"
+                + "        tmpTargetPage = \"undefined\";\n"
+                + "    targetPage = tmpTargetPage;\n"
                 + "    function validURL(url) {\n"
                 + "        try {\n"
                 + "            url = decodeURIComponent(url);\n"
--- a/langtools/test/jdk/javadoc/tool/modules/FilterOptions.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/test/jdk/javadoc/tool/modules/FilterOptions.java	Thu Oct 20 20:01:40 2016 +0000
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 8159305
+ * @bug 8159305 8167383
  * @summary Tests elements filtering options
  * @modules
  *      jdk.javadoc/jdk.javadoc.internal.api
@@ -73,6 +73,10 @@
                 "--module", "m1", "--show-module-contents", "api");
 
         checkModuleMode("API");
+        checkModulesSpecified("m1");
+        checkModulesIncluded("m1");
+        checkPackagesIncluded("pub");
+        checkPackagesNotIncluded("pro", "pqe");
     }
 
     @Test
@@ -81,6 +85,10 @@
                 "--module", "m1", "--show-module-contents", "all");
 
         checkModuleMode("ALL");
+        checkModulesSpecified("m1");
+        checkModulesIncluded("m1");
+        checkPackagesIncluded("pub", "pqe");
+        checkPackagesNotIncluded("pro");
     }
 
     @Test
@@ -92,6 +100,7 @@
         checkModulesSpecified("m1");
         checkModulesIncluded("m1");
         checkPackagesIncluded("pub");
+        checkPackagesNotIncluded("pqe", "pro");
         checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
     }
 
@@ -102,9 +111,10 @@
                 "--show-packages", "all");
         checkModulesSpecified("m1");
         checkModulesIncluded("m1");
-        checkPackagesIncluded("pub", "pro");
+        checkPackagesIncluded("pub", "pqe", "pro");
 
         checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested",
+                           "pqe.A", "pqe.A.ProtectedNested", "pqe.A.PublicNested",
                            "pro.A", "pro.A.ProtectedNested", "pro.A.PublicNested");
     }
 
@@ -221,6 +231,7 @@
         checkModulesSpecified("m1");
         checkModulesIncluded("m1");
         checkPackagesIncluded("pub");
+        checkPackagesNotIncluded("pqe", "pro");
         checkTypesIncluded("pub.A", "pub.A.PublicNested");
 
         checkMembers(Visibility.PUBLIC);
@@ -235,6 +246,7 @@
         checkModulesSpecified("m1");
         checkModulesIncluded("m1");
         checkPackagesIncluded("pub");
+        checkPackagesNotIncluded("pqe", "pro");
         checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
 
         checkMembers(Visibility.PROTECTED);
@@ -250,6 +262,7 @@
         checkModulesSpecified("m1");
         checkModulesIncluded("m1");
         checkPackagesIncluded("pub");
+        checkPackagesNotIncluded("pqe", "pro");
         checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
 
         checkMembers(Visibility.PROTECTED);
@@ -264,10 +277,10 @@
         checkModuleMode("ALL");
         checkModulesSpecified("m1");
         checkModulesIncluded("m1");
-        checkPackagesIncluded("pub");
-        checkPackagesIncluded("pro");
+        checkPackagesIncluded("pub", "pqe", "pro");
         checkTypesIncluded("pub.B", "pub.B.Nested", "pub.B.ProtectedNested", "pub.B.PublicNested",
                            "pub.A", "pub.A.Nested", "pub.A.ProtectedNested", "pub.A.PublicNested",
+                           "pqe.A", "pqe.A.Nested", "pqe.A.ProtectedNested", "pqe.A.PublicNested",
                            "pro.B", "pro.B.Nested", "pro.B.ProtectedNested", "pro.B.PublicNested",
                            "pro.A", "pro.A.Nested", "pro.A.ProtectedNested", "pro.A.PublicNested");
 
@@ -283,12 +296,13 @@
         checkModuleMode("ALL");
         checkModulesSpecified("m1");
         checkModulesIncluded("m1");
-        checkPackagesIncluded("pub");
-        checkPackagesIncluded("pro");
+        checkPackagesIncluded("pub", "pqe", "pro");
         checkTypesIncluded("pub.B", "pub.B.PrivateNested", "pub.B.Nested", "pub.B.ProtectedNested",
                            "pub.B.PublicNested",
                            "pub.A", "pub.A.PrivateNested", "pub.A.Nested", "pub.A.ProtectedNested",
                            "pub.A.PublicNested",
+                           "pqe.A", "pqe.A.PrivateNested", "pqe.A.Nested", "pqe.A.ProtectedNested",
+                           "pqe.A.PublicNested",
                            "pro.B", "pro.B.PrivateNested", "pro.B.Nested", "pro.B.ProtectedNested",
                            "pro.B.PublicNested",
                            "pro.A", "pro.A.PrivateNested", "pro.A.Nested", "pro.A.ProtectedNested",
@@ -365,8 +379,17 @@
                 .classes(createClass("pub", "B", false))
                 .classes(createClass("pro", "A", true))
                 .classes(createClass("pro", "B", false))
+                .classes(createClass("pqe", "A", true))
                 .exports("pub")
+                .exportsTo("pqe", "m2")
                 .write(src);
+
+        ModuleBuilder mb2 = new ModuleBuilder(tb, "m2");
+        mb2.comment("The second module")
+                .classes(createClass("m2pub", "A", true))
+                .requires("m1")
+                .write(src);
+
         return src.toString();
     }
 
--- a/langtools/test/jdk/javadoc/tool/modules/Modules.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/test/jdk/javadoc/tool/modules/Modules.java	Thu Oct 20 20:01:40 2016 +0000
@@ -222,7 +222,10 @@
                 .classes("package pkg2; /** @see pkg1.A */ public class B { }")
                 .write(src);
 
+        Path out = base.resolve("out-1");
+        Files.createDirectories(out);
         String log = new JavadocTask(tb)
+                .outdir(out)
                 .options("--module-source-path", src.toString(),
                         "--module-path", modulePath.toString(),
                         "--module", "m2")
@@ -233,7 +236,10 @@
             throw new Exception("Error not found");
         }
 
+        out = base.resolve("out-2");
+        Files.createDirectories(out);
         new JavadocTask(tb)
+                .outdir(out)
                 .options("--module-source-path", src.toString(),
                         "--module-path", modulePath.toString(),
                         "--add-modules", "m1",
--- a/langtools/test/jdk/jshell/CommandCompletionTest.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/test/jdk/jshell/CommandCompletionTest.java	Thu Oct 20 20:01:40 2016 +0000
@@ -54,7 +54,7 @@
 
     public void testCommand() {
         assertCompletion("/deb|", false);
-        assertCompletion("/re|", false, "/reload ", "/reset ", "/retain ");
+        assertCompletion("/re|", false, "/reload ", "/reset ");
         assertCompletion("/h|", false, "/help ", "/history ");
     }
 
@@ -195,34 +195,6 @@
         );
     }
 
-    public void testRetain() throws IOException {
-        List<String> p1 = listFiles(Paths.get(""));
-        FileSystems.getDefault().getRootDirectories().forEach(s -> p1.add(s.toString()));
-        Collections.sort(p1);
-
-        String[] modes = {"concise ", "normal ", "silent ", "verbose "};
-        test(false, new String[] {"--no-startup"},
-                a -> assertCompletion(a, "/ret|", false, "/retain "),
-                a -> assertCompletion(a, "/retain |", false, "editor ", "feedback ", "mode ", "start "),
-
-                // /retain editor
-                a -> assertCompletion(a, "/retain e|", false, "editor "),
-                a -> assertCompletion(a, "/retain editor |", false, p1.toArray(new String[p1.size()])),
-
-                // /retain feedback
-                a -> assertCompletion(a, "/retain fe|", false, "feedback "),
-                a -> assertCompletion(a, "/retain fe |", false, modes),
-
-                // /retain mode
-                a -> assertCompletion(a, "/retain mo|", false, "mode "),
-                a -> assertCompletion(a, "/retain mo |", false, modes),
-
-                // /retain start
-                a -> assertCompletion(a, "/retain st|", false, "start "),
-                a -> assertCompletion(a, "/retain st |", false, p1.toArray(new String[p1.size()]))
-        );
-    }
-
     private void createIfNeeded(Path file) throws IOException {
         if (!Files.exists(file))
             Files.createFile(file);
--- a/langtools/test/jdk/jshell/ExternalEditorTest.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/test/jdk/jshell/ExternalEditorTest.java	Thu Oct 20 20:01:40 2016 +0000
@@ -193,7 +193,6 @@
     @Test
     public void setUnknownEditor() {
         test(
-                a -> assertCommand(a, "/set editor", "|  The '/set editor' command requires a path argument"),
                 a -> assertCommand(a, "/set editor UNKNOWN", "|  Editor set to: UNKNOWN"),
                 a -> assertCommand(a, "int a;", null),
                 a -> assertCommandOutputStartsWith(a, "/ed 1",
--- a/langtools/test/jdk/jshell/KullaTesting.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/test/jdk/jshell/KullaTesting.java	Thu Oct 20 20:01:40 2016 +0000
@@ -21,7 +21,10 @@
  * questions.
  */
 
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
 import java.io.PrintStream;
 import java.io.StringWriter;
 import java.lang.reflect.Method;
@@ -83,7 +86,7 @@
 
     private SourceCodeAnalysis analysis = null;
     private JShell state = null;
-    private TestingInputStream inStream = null;
+    private InputStream inStream = null;
     private ByteArrayOutputStream outStream = null;
     private ByteArrayOutputStream errStream = null;
 
@@ -106,7 +109,11 @@
     }
 
     public void setInput(String s) {
-        inStream.setInput(s);
+        setInput(new ByteArrayInputStream(s.getBytes()));
+    }
+
+    public void setInput(InputStream in) {
+        inStream = in;
     }
 
     public String getOutput() {
@@ -159,11 +166,27 @@
     }
 
     public void setUp(Consumer<JShell.Builder> bc) {
-        inStream = new TestingInputStream();
+        InputStream in = new InputStream() {
+            @Override
+            public int read() throws IOException {
+                assertNotNull(inStream);
+                return inStream.read();
+            }
+            @Override
+            public int read(byte[] b) throws IOException {
+                assertNotNull(inStream);
+                return inStream.read(b);
+            }
+            @Override
+            public int read(byte[] b, int off, int len) throws IOException {
+                assertNotNull(inStream);
+                return inStream.read(b, off, len);
+            }
+        };
         outStream = new ByteArrayOutputStream();
         errStream = new ByteArrayOutputStream();
         JShell.Builder builder = JShell.builder()
-                .in(inStream)
+                .in(in)
                 .out(new PrintStream(outStream))
                 .err(new PrintStream(errStream));
         bc.accept(builder);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/jshell/PipeInputStreamTest.java	Thu Oct 20 20:01:40 2016 +0000
@@ -0,0 +1,71 @@
+/*
+ * 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 8167461
+ * @summary Verify PipeInputStream works.
+ * @modules jdk.compiler/com.sun.tools.javac.util
+ *          jdk.jshell
+ * @run testng PipeInputStreamTest
+ */
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+import org.testng.annotations.Test;
+
+import com.sun.tools.javac.util.Pair;
+
+import static org.testng.Assert.*;
+
+@Test
+public class PipeInputStreamTest {
+
+    public void testReadArrayNotBlocking() throws Exception {
+        Pair<InputStream, OutputStream> streams = createPipeStream();
+        InputStream in = streams.fst;
+        OutputStream out = streams.snd;
+        out.write('a');
+        byte[] data = new byte[12];
+        assertEquals(in.read(data), 1);
+        assertEquals(data[0], 'a');
+        out.write('a'); out.write('b'); out.write('c');
+        assertEquals(in.read(data), 3);
+        assertEquals(data[0], 'a');
+        assertEquals(data[1], 'b');
+        assertEquals(data[2], 'c');
+    }
+
+    private Pair<InputStream, OutputStream> createPipeStream() throws Exception {
+        Class<?> pipeStreamClass = Class.forName("jdk.jshell.execution.PipeInputStream");
+        Constructor<?> c = pipeStreamClass.getDeclaredConstructor();
+        c.setAccessible(true);
+        Object pipeStream = c.newInstance();
+        Method createOutputStream = pipeStreamClass.getDeclaredMethod("createOutput");
+        createOutputStream.setAccessible(true);
+        return Pair.of((InputStream) pipeStream, (OutputStream) createOutputStream.invoke(pipeStream));
+    }
+
+}
--- a/langtools/test/jdk/jshell/ToolBasicTest.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/test/jdk/jshell/ToolBasicTest.java	Thu Oct 20 20:01:40 2016 +0000
@@ -431,12 +431,12 @@
                     (a) -> assertMethod(a, "void f() {}", "()V", "f"),
                     (a) -> assertImport(a, "import java.util.stream.*;", "", "java.util.stream.*"),
                     (a) -> assertCommand(a, "/save " + startUpFile.toString(), null),
-                    (a) -> assertCommand(a, "/retain start " + startUpFile.toString(), null)
+                    (a) -> assertCommand(a, "/set start -retain " + startUpFile.toString(), null)
             );
             Path unknown = compiler.getPath("UNKNOWN");
             test(
-                    (a) -> assertCommandOutputStartsWith(a, "/retain start " + unknown.toString(),
-                            "|  File '" + unknown + "' for '/retain start' is not found.")
+                    (a) -> assertCommandOutputStartsWith(a, "/set start -retain " + unknown.toString(),
+                            "|  File '" + unknown + "' for '/set start' is not found.")
             );
             test(false, new String[0],
                     (a) -> {
--- a/langtools/test/jdk/jshell/ToolCommandOptionTest.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/test/jdk/jshell/ToolCommandOptionTest.java	Thu Oct 20 20:01:40 2016 +0000
@@ -23,7 +23,7 @@
 
  /*
  * @test
- * @bug 8157395 8157393 8157517 8158738  8167128
+ * @bug 8157395 8157393 8157517 8158738 8167128 8163840
  * @summary Tests of jshell comand options, and undoing operations
  * @modules jdk.jshell/jdk.internal.jshell.tool
  * @build ToolCommandOptionTest ReplToolTesting
@@ -128,46 +128,73 @@
                 (a) -> assertCommand(a, "/set editor prog",
                         "|  Editor set to: prog"),
                 (a) -> assertCommand(a, "/set editor prog -default",
-                        "|  Editor set to: prog"),
+                        "|  Editor set to: prog -default"),
+                (a) -> assertCommand(a, "/set editor",
+                        "|  /set editor prog -default"),
                 (a) -> assertCommand(a, "/se ed prog -furball",
-                        "|  Editor set to: prog"),
+                        "|  Editor set to: prog -furball"),
+                (a) -> assertCommand(a, "/set editor",
+                        "|  /set editor prog -furball"),
                 (a) -> assertCommand(a, "/set editor prog arg1 -furball arg3 -default arg4",
-                        "|  Editor set to: prog"),
+                        "|  Editor set to: prog arg1 -furball arg3 -default arg4"),
+                (a) -> assertCommand(a, "/set editor",
+                        "|  /set editor prog arg1 -furball arg3 -default arg4"),
                 (a) -> assertCommand(a, "/set editor -default",
-                        ""),
+                        "|  Editor set to: -default"),
                 (a) -> assertCommand(a, "/se edi -def",
-                        ""),
+                        "|  Editor set to: -default"),
                 (a) -> assertCommand(a, "/set editor",
-                        "|  The '/set editor' command requires a path argument")
+                        "|  /set editor -default")
         );
     }
 
     public void retainEditorTest() {
         test(
-                (a) -> assertCommand(a, "/retain editor -furball",
-                        "|  Unknown option: -furball -- /retain editor -furball"),
-                (a) -> assertCommand(a, "/retain editor -furball prog",
-                        "|  Unknown option: -furball -- /retain editor -furball prog"),
-                (a) -> assertCommand(a, "/retain editor -furball -mattress",
-                        "|  Unknown option: -furball -mattress -- /retain editor -furball -mattress"),
-                (a) -> assertCommand(a, "/retain editor -default prog",
-                        "|  Specify -default option or program, not both -- /retain editor -default prog"),
-                (a) -> assertCommand(a, "/retain editor -default -wait",
-                        "|  -wait applies to external editors, cannot be used with -default"),
-                (a) -> assertCommand(a, "/retain editor prog",
-                        "|  Editor set to: prog"),
-                (a) -> assertCommand(a, "/retain editor prog -default",
-                        "|  Editor set to: prog"),
-                (a) -> assertCommand(a, "/ret ed prog -furball",
-                        "|  Editor set to: prog"),
-                (a) -> assertCommand(a, "/retain editor prog arg1 -furball arg3 -default arg4",
-                        "|  Editor set to: prog"),
-                (a) -> assertCommand(a, "/retain editor -default",
-                        ""),
-                (a) -> assertCommand(a, "/reta edi -def",
-                        ""),
-                (a) -> assertCommand(a, "/retain editor",
-                        "")
+                (a) -> assertCommand(a, "/set editor -retain -furball",
+                        "|  Unknown option: -furball -- /set editor -retain -furball"),
+                (a) -> assertCommand(a, "/set editor -retain -furball prog",
+                        "|  Unknown option: -furball -- /set editor -retain -furball prog"),
+                (a) -> assertCommand(a, "/set editor -retain -furball -mattress",
+                        "|  Unknown option: -furball -mattress -- /set editor -retain -furball -mattress"),
+                (a) -> assertCommand(a, "/set editor -retain -default prog",
+                        "|  Specify -default option or program, not both -- /set editor -retain -default prog"),
+                (a) -> assertCommand(a, "/set editor -retain -wait",
+                        "|  -wait applies to external editors"),
+                (a) -> assertCommand(a, "/set editor -retain -default -wait",
+                        "|  -wait applies to external editors"),
+                (a) -> assertCommand(a, "/set editor -retain prog",
+                        "|  Editor set to: prog\n" +
+                        "|  Editor setting retained: prog"),
+                (a) -> assertCommand(a, "/set editor",
+                        "|  /set editor -retain prog"),
+                (a) -> assertCommand(a, "/se ed other",
+                        "|  Editor set to: other"),
+                (a) -> assertCommand(a, "/set editor",
+                        "|  /set editor -retain prog\n" +
+                        "|  /set editor other"),
+                (a) -> assertCommand(a, "/set editor -retain prog -default",
+                        "|  Editor set to: prog -default\n" +
+                        "|  Editor setting retained: prog -default"),
+                (a) -> assertCommand(a, "/set editor",
+                        "|  /set editor -retain prog -default"),
+                (a) -> assertCommand(a, "/se ed -retain prog -furball",
+                        "|  Editor set to: prog -furball\n" +
+                        "|  Editor setting retained: prog -furball"),
+                (a) -> assertCommand(a, "/set editor -retain prog arg1 -furball arg3 -default arg4",
+                        "|  Editor set to: prog arg1 -furball arg3 -default arg4\n" +
+                        "|  Editor setting retained: prog arg1 -furball arg3 -default arg4"),
+                (a) -> assertCommand(a, "/set editor",
+                        "|  /set editor -retain prog arg1 -furball arg3 -default arg4"),
+                (a) -> assertCommand(a, "/set editor -retain -default",
+                        "|  Editor set to: -default\n" +
+                        "|  Editor setting retained: -default"),
+                (a) -> assertCommand(a, "/set editor",
+                        "|  /set editor -retain -default"),
+                (a) -> assertCommand(a, "/se e -ret -def",
+                        "|  Editor set to: -default\n" +
+                        "|  Editor setting retained: -default"),
+                (a) -> assertCommand(a, "/set editor -retain",
+                        "|  Editor setting retained: -default")
         );
     }
 
@@ -182,45 +209,56 @@
                 (a) -> assertCommand(a, "/set start -furball -mattress",
                         "|  Unknown option: -furball -mattress -- /set start -furball -mattress"),
                 (a) -> assertCommand(a, "/set start foo -default",
-                        "|  Specify either one option or a startup file name -- /set start foo -default"),
+                        "|  Specify no more than one of -default, -none, or a startup file name -- /set start foo -default"),
                 (a) -> assertCommand(a, "/set start frfg",
                         "|  File 'frfg' for '/set start' is not found."),
                 (a) -> assertCommand(a, "/set start -default",
                         ""),
+                (a) -> assertCommand(a, "/set start",
+                        "|  /set start -default"),
                 (a) -> assertCommand(a, "/se sta -no",
                         ""),
                 (a) -> assertCommand(a, "/set start",
-                        "|  Specify either one option or a startup file name -- /set start")
+                        "|  /set start -none")
         );
     }
 
     public void retainStartTest() {
         test(
-                (a) -> assertCommand(a, "/retain start -furball",
-                        "|  Unknown option: -furball -- /retain start -furball"),
-                (a) -> assertCommand(a, "/retain start -furball pyle",
-                        "|  Unknown option: -furball -- /retain start -furball pyle"),
-                (a) -> assertCommand(a, "/ret st pyle -furball",
-                        "|  Unknown option: -furball -- /retain st pyle -furball"),
-                (a) -> assertCommand(a, "/retain start -furball -mattress",
-                        "|  Unknown option: -furball -mattress -- /retain start -furball -mattress"),
-                (a) -> assertCommand(a, "/retain start foo -default",
-                        "|  Specify either one option or a startup file name -- /retain start foo -default"),
-                (a) -> assertCommand(a, "/retain start frfg",
-                        "|  File 'frfg' for '/retain start' is not found."),
-                (a) -> assertCommand(a, "/retain start -default",
+                (a) -> assertCommand(a, "/set start -retain -furball",
+                        "|  Unknown option: -furball -- /set start -retain -furball"),
+                (a) -> assertCommand(a, "/set start -retain -furball pyle",
+                        "|  Unknown option: -furball -- /set start -retain -furball pyle"),
+                (a) -> assertCommand(a, "/se st -re pyle -furball",
+                        "|  Unknown option: -furball -- /set st -re pyle -furball"),
+                (a) -> assertCommand(a, "/set start -retain -furball -mattress",
+                        "|  Unknown option: -furball -mattress -- /set start -retain -furball -mattress"),
+                (a) -> assertCommand(a, "/set start -retain foo -default",
+                        "|  Specify no more than one of -default, -none, or a startup file name -- /set start -retain foo -default"),
+                (a) -> assertCommand(a, "/set start -retain -default foo",
+                        "|  Specify no more than one of -default, -none, or a startup file name -- /set start -retain -default foo"),
+                (a) -> assertCommand(a, "/set start -retain frfg",
+                        "|  File 'frfg' for '/set start' is not found."),
+                (a) -> assertCommand(a, "/set start -retain -default",
                         ""),
-                (a) -> assertCommand(a, "/ret sta -no",
+                (a) -> assertCommand(a, "/set start",
+                        "|  /set start -retain -default"),
+                (a) -> assertCommand(a, "/set sta -no",
                         ""),
-                (a) -> assertCommand(a, "/retain start",
-                        "")
+                (a) -> assertCommand(a, "/set start",
+                        "|  /set start -retain -default\n" +
+                        "|  /set start -none"),
+                (a) -> assertCommand(a, "/se st -ret",
+                        ""),
+                (a) -> assertCommand(a, "/se sta",
+                        "|  /set start -retain -none")
         );
     }
 
     public void setModeTest() {
         test(
-                (a) -> assertCommandOutputStartsWith(a, "/set mode",
-                        "|  Missing the feedback mode"),
+                (a) -> assertCommandOutputContains(a, "/set mode",
+                        "|  /set format verbose unresolved"),
                 (a) -> assertCommandOutputStartsWith(a, "/set mode *",
                         "|  Expected a feedback mode name: *"),
                 (a) -> assertCommandOutputStartsWith(a, "/set mode -quiet",
@@ -229,11 +267,13 @@
                         "|  Expected a feedback mode name: *"),
                 (a) -> assertCommandOutputStartsWith(a, "/set mode amode normal thing",
                         "|  Unexpected arguments at end of command: thing"),
-                (a) -> assertCommand(a, "/set mode mymode",
+                (a) -> assertCommandOutputStartsWith(a, "/set mode mymode",
+                        "|  To create a new mode either the -command or the -quiet option must be used"),
+                (a) -> assertCommand(a, "/set mode mymode -command",
                         "|  Created new feedback mode: mymode"),
                 (a) -> assertCommand(a, "/set mode mymode -delete",
                         ""),
-                (a) -> assertCommand(a, "/set mode mymode normal",
+                (a) -> assertCommand(a, "/set mode mymode normal -command",
                         "|  Created new feedback mode: mymode"),
                 (a) -> assertCommand(a, "/set mode -del mymode",
                         ""),
@@ -245,18 +285,33 @@
                         "|  Conflicting options"),
                 (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -d",
                         "|  No feedback mode named: mymode"),
-                (a) -> assertCommandOutputStartsWith(a, "/set mode normal",
-                        "|  Not valid with a predefined mode: normal"),
+                (a) -> assertCommandOutputStartsWith(a, "/set mode normal -c",
+                        "|  Mode to be created already exists: normal"),
                 (a) -> assertCommand(a, "/se mo -c mymode",
                         "|  Created new feedback mode: mymode"),
+                (a) -> assertCommandOutputStartsWith(a, "/set mode mymode",
+                        "|  /set mode mymode -command"),
                 (a) -> assertCommand(a, "/set feedback mymode",
                         "|  Feedback mode: mymode"),
+                (a) -> assertCommand(a, "/se fe",
+                        "|  /set feedback mymode\n" +
+                        "|  \n" +
+                        "|  Available feedback modes:\n" +
+                        "|     concise\n" +
+                        "|     mymode\n" +
+                        "|     normal\n" +
+                        "|     silent\n" +
+                        "|     verbose"),
                 (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -delete",
                         "|  The current feedback mode 'mymode' cannot be deleted"),
                 (a) -> assertCommand(a, "/set feedback no",
                         "|  Feedback mode: normal"),
                 (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -delete",
                         ""),
+                (a) -> assertCommandOutputStartsWith(a, "/set mode mymode",
+                        "|  To create a new mode either the -command or the -quiet option must be used -- \n" +
+                        "|  Does not match any current feedback mode: mymode -- /set mode mymode\n" +
+                        "|  Available feedback modes:"),
                 (a) -> assertCommandCheckOutput(a, "/set feedback",
                         (s) -> assertFalse(s.contains("mymode"), "Didn't delete: " + s))
         );
@@ -272,8 +327,20 @@
                         ""),
                 (a) -> assertCommand(a, "45",
                         "blurb"),
-                (a) -> assertCommand(a, "/set mode mymode normal",
+                (a) -> assertCommandOutputStartsWith(a, "/set mode mymode normal",
+                        "|  To create a new mode either the -command or the -quiet option must be used"),
+                (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -command normal",
+                        "|  Mode to be created already exists: mymode"),
+                (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -delete",
+                        "|  The current feedback mode 'mymode' cannot be deleted, use '/set feedback' first"),
+                (a) -> assertCommand(a, "/set feedback normal",
+                        "|  Feedback mode: normal"),
+                (a) -> assertCommand(a, "/set mode mymode -delete",
+                        ""),
+                (a) -> assertCommand(a, "/set mode mymode -command normal",
                         "|  Created new feedback mode: mymode"),
+                (a) -> assertCommand(a, "/set feedback mymode",
+                        "|  Feedback mode: mymode"),
                 (a) -> assertCommandOutputContains(a, "45",
                         " ==> 45")
         );
@@ -281,67 +348,89 @@
 
     public void retainModeTest() {
         test(
-                (a) -> assertCommandOutputStartsWith(a, "/retain mode",
+                (a) -> assertCommandOutputStartsWith(a, "/set mode -retain",
                         "|  Missing the feedback mode"),
-                (a) -> assertCommandOutputStartsWith(a, "/retain mode *",
+                (a) -> assertCommandOutputStartsWith(a, "/set mode -retain *",
                         "|  Expected a feedback mode name: *"),
-                (a) -> assertCommandOutputStartsWith(a, "/retain mode amode normal",
+                (a) -> assertCommandOutputStartsWith(a, "/set mode -retain amode normal",
                         "|  Unexpected arguments at end of command: normal"),
-                (a) -> assertCommandOutputStartsWith(a, "/retain mode mymode",
-                        "|  Does not match any current feedback mode: mymode"),
-                (a) -> assertCommandOutputStartsWith(a, "/retain mode mymode -delete",
+                (a) -> assertCommandOutputStartsWith(a, "/set mode -retain mymode",
                         "|  No feedback mode named: mymode"),
-                (a) -> assertCommandOutputStartsWith(a, "/retain mode -d mymode",
+                (a) -> assertCommandOutputStartsWith(a, "/set mode -retain mymode -delete",
+                        "|  No feedback mode named: mymode"),
+                (a) -> assertCommandOutputStartsWith(a, "/set mode -retain -d mymode",
                         "|  No feedback mode named: mymode"),
-                (a) -> assertCommandOutputStartsWith(a, "/retain mode normal",
+                (a) -> assertCommandOutputStartsWith(a, "/set mode -retain normal",
                         "|  Not valid with a predefined mode: normal"),
-                (a) -> assertCommand(a, "/set mode mymode verbose",
+                (a) -> assertCommand(a, "/set mode mymode verbose -command",
                         "|  Created new feedback mode: mymode"),
-                (a) -> assertCommand(a, "/retain mode mymode",
+                (a) -> assertCommand(a, "/set mode -retain mymode",
                         ""),
                 (a) -> assertCommand(a, "/set mode mymode -delete",
                         ""),
-                (a) -> assertCommand(a, "/retain mode mymode -delete",
+                (a) -> assertCommand(a, "/set mode -retain mymode -delete",
                         ""),
-                (a) -> assertCommand(a, "/set mode kmode normal",
+                (a) -> assertCommand(a, "/set mode kmode normal -command",
                         "|  Created new feedback mode: kmode"),
-                (a) -> assertCommand(a, "/retain mode kmode",
+                (a) -> assertCommand(a, "/set mode -retain kmode",
                         ""),
                 (a) -> assertCommand(a, "/set mode kmode -delete",
                         ""),
-                (a) -> assertCommand(a, "/set mode tmode normal",
+                (a) -> assertCommand(a, "/set mode tmode normal -command",
                         "|  Created new feedback mode: tmode"),
-                (a) -> assertCommandOutputStartsWith(a, "/retain feedback tmode",
-                        "|  '/retain feedback <mode>' requires that <mode> is predefined or has been retained with '/retain mode'"),
+                (a) -> assertCommandOutputStartsWith(a, "/set feedback -retain tmode",
+                        "|  '/set feedback -retain <mode>' requires that <mode> is predefined or has been retained with '/set mode -retain'"),
                 (a) -> assertCommand(a, "/set format tmode display 'YES'",
                         ""),
                 (a) -> assertCommand(a, "/set feedback tmode",
                         "|  Feedback mode: tmode"),
                 (a) -> assertCommand(a, "45",
                         "YES"),
-                (a) -> assertCommand(a, "/retain mode tmode",
+                (a) -> assertCommand(a, "/set mode -retain tmode",
                         ""),
-                (a) -> assertCommand(a, "/retain feedback tmode",
+                (a) -> assertCommand(a, "/set feedback -retain tmode",
                         "|  Feedback mode: tmode"),
                 (a) -> assertCommand(a, "/set format tmode display 'blurb'",
                         ""),
+                (a) -> assertCommand(a, "/set format tmode display",
+                        "|  /set format tmode display \"blurb\""),
+                (a) -> assertCommandOutputContains(a, "/set mode tmode",
+                        "|  /set format tmode display \"YES\""),
                 (a) -> assertCommand(a, "45",
                         "blurb")
         );
         test(
+                (a) -> assertCommand(a, "/set format tmode display",
+                        "|  /set format tmode display \"YES\""),
+                (a) -> assertCommandOutputContains(a, "/set mode tmode",
+                        "|  /set format tmode display \"YES\""),
                 (a) -> assertCommand(a, "45",
                         "YES"),
                 (a) -> assertCommand(a, "/set feedback kmode",
                         "|  Feedback mode: kmode"),
-                (a) -> assertCommandOutputStartsWith(a, "/retain mode kmode -delete",
+                (a) -> assertCommand(a, "/set feedback",
+                        "|  /set feedback -retain tmode\n" +
+                        "|  /set feedback kmode\n" +
+                        "|  \n" +
+                        "|  Retained feedback modes:\n" +
+                        "|     kmode\n" +
+                        "|     tmode\n" +
+                        "|  Available feedback modes:\n" +
+                        "|     concise\n" +
+                        "|     kmode\n" +
+                        "|     normal\n" +
+                        "|     silent\n" +
+                        "|     tmode\n" +
+                        "|     verbose"),
+                (a) -> assertCommandOutputStartsWith(a, "/set mode -retain kmode -delete",
                         "|  The current feedback mode 'kmode' cannot be deleted"),
-                (a) -> assertCommandOutputStartsWith(a, "/retain mode tmode -delete",
+                (a) -> assertCommandOutputStartsWith(a, "/set mode -retain tmode -delete",
                         "|  The retained feedback mode 'tmode' cannot be deleted"),
-                (a) -> assertCommand(a, "/retain feedback normal",
+                (a) -> assertCommand(a, "/set feedback -retain normal",
                         "|  Feedback mode: normal"),
-                (a) -> assertCommand(a, "/retain mode tmode -delete",
+                (a) -> assertCommand(a, "/set mode -retain tmode -delete",
                         ""),
-                (a) -> assertCommandOutputStartsWith(a, "/retain mode kmode -delete",
+                (a) -> assertCommandOutputStartsWith(a, "/set mode -retain kmode -delete",
                         "")
         );
         test(
--- a/langtools/test/jdk/jshell/ToolFormatTest.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/test/jdk/jshell/ToolFormatTest.java	Thu Oct 20 20:01:40 2016 +0000
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8148316 8148317 8151755 8152246 8153551 8154812 8157261
+ * @bug 8148316 8148317 8151755 8152246 8153551 8154812 8157261 8163840
  * @summary Tests for output customization
  * @library /tools/lib
  * @modules jdk.compiler/com.sun.tools.javac.api
@@ -33,10 +33,17 @@
  * @build KullaTesting TestingInputStream toolbox.ToolBox Compiler
  * @run testng ToolFormatTest
  */
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 import org.testng.annotations.Test;
+import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
 
 @Test
 public class ToolFormatTest extends ReplToolTesting {
@@ -81,6 +88,58 @@
         }
     }
 
+    public void testSetFormatOverride() {
+        test(
+                (a) -> assertCommand(a, "/set mode tm -c", "|  Created new feedback mode: tm"),
+                (a) -> assertCommand(a, "/se fo tm x \"aaa\"", ""),
+                (a) -> assertCommand(a, "/se fo tm x \"bbb\" class,method-added", ""),
+                (a) -> assertCommand(a, "/se fo tm x",
+                        "|  /set format tm x \"aaa\" \n" +
+                        "|  /set format tm x \"bbb\" class,method-added"),
+                (a) -> assertCommand(a, "/se fo tm x \"ccc\" class,method-added,modified", ""),
+                (a) -> assertCommand(a, "/se fo tm x \"ddd\" class,method-added", ""),
+                (a) -> assertCommand(a, "/se fo tm x \"eee\" method-added", ""),
+                (a) -> assertCommand(a, "/se fo tm x",
+                        "|  /set format tm x \"aaa\" \n" +
+                        "|  /set format tm x \"ccc\" class,method-added,modified\n" +
+                        "|  /set format tm x \"ddd\" class,method-added\n" +
+                        "|  /set format tm x \"eee\" method-added"),
+                (a) -> assertCommand(a, "/se fo tm x \"EEE\" method-added,replaced", ""),
+                (a) -> assertCommand(a, "/se fo tm x",
+                        "|  /set format tm x \"aaa\" \n" +
+                        "|  /set format tm x \"ccc\" class,method-added,modified\n" +
+                        "|  /set format tm x \"ddd\" class,method-added\n" +
+                        "|  /set format tm x \"EEE\" method-added,replaced"),
+                (a) -> assertCommand(a, "/se fo tm x \"fff\" method-added,replaced-ok", ""),
+                (a) -> assertCommand(a, "/se fo tm x",
+                        "|  /set format tm x \"aaa\" \n" +
+                        "|  /set format tm x \"ccc\" class,method-added,modified\n" +
+                        "|  /set format tm x \"ddd\" class,method-added\n" +
+                        "|  /set format tm x \"EEE\" method-added,replaced\n" +
+                        "|  /set format tm x \"fff\" method-added,replaced-ok"),
+                (a) -> assertCommand(a, "/se fo tm x \"ggg\" method-ok", ""),
+                (a) -> assertCommand(a, "/se fo tm x",
+                        "|  /set format tm x \"aaa\" \n" +
+                        "|  /set format tm x \"ccc\" class,method-added,modified\n" +
+                        "|  /set format tm x \"ddd\" class,method-added\n" +
+                        "|  /set format tm x \"EEE\" method-added,replaced\n" +
+                        "|  /set format tm x \"ggg\" method-ok"),
+                (a) -> assertCommand(a, "/se fo tm x \"hhh\" method", ""),
+                (a) -> assertCommand(a, "/se fo tm x",
+                        "|  /set format tm x \"aaa\" \n" +
+                        "|  /set format tm x \"ccc\" class,method-added,modified\n" +
+                        "|  /set format tm x \"ddd\" class,method-added\n" +
+                        "|  /set format tm x \"hhh\" method"),
+                (a) -> assertCommand(a, "/se fo tm x \"iii\" method,class", ""),
+                (a) -> assertCommand(a, "/se fo tm x",
+                        "|  /set format tm x \"aaa\" \n" +
+                        "|  /set format tm x \"iii\" class,method"),
+                (a) -> assertCommand(a, "/se fo tm x \"jjj\"", ""),
+                (a) -> assertCommand(a, "/se fo tm x",
+                        "|  /set format tm x \"jjj\"")
+        );
+    }
+
     public void testSetFormatSelector() {
         List<ReplTest> tests = new ArrayList<>();
         tests.add((a) -> assertCommandOutputStartsWith(a, "/set mode ate -quiet",
@@ -167,8 +226,14 @@
                     (a) -> assertCommandOutputStartsWith(a, "/set feedback test", ""),
                     (a) -> assertCommand(a, "/set format test display '{type}:{value}' primary", ""),
                     (a) -> assertCommand(a, "/set truncation test 20", ""),
+                    (a) -> assertCommand(a, "/set truncation test", "|  /set truncation test 20"),
+                    (a) -> assertCommandOutputContains(a, "/set truncation", "/set truncation test 20"),
                     (a) -> assertCommand(a, "/set trunc test 10 varvalue", ""),
                     (a) -> assertCommand(a, "/set trunc test 3 assignment", ""),
+                    (a) -> assertCommandOutputContains(a, "/set truncation",
+                            "/set truncation test 10 varvalue"),
+                    (a) -> assertCommandOutputContains(a, "/set truncation test",
+                            "/set truncation test 10 varvalue"),
                     (a) -> assertCommand(a, "String r = s", "String:\"ABACABADABACABA ..."),
                     (a) -> assertCommand(a, "r", "String:\"ABACA ..."),
                     (a) -> assertCommand(a, "r=s", "String:\"AB")
@@ -201,6 +266,45 @@
         );
     }
 
+    public void testPrompt() {
+        test(
+                (a) -> assertCommand(a, "/set mode tp -quiet", "|  Created new feedback mode: tp"),
+                (a) -> assertCommand(a, "/set prompt tp 'aaa' 'bbb'", ""),
+                (a) -> assertCommand(a, "/set prompt tp",
+                        "|  /set prompt tp \"aaa\" \"bbb\""),
+                (a) -> assertCommandOutputContains(a, "/set prompt",
+                        "|  /set prompt tp \"aaa\" \"bbb\""),
+                (a) -> assertCommand(a, "/set mode -retain tp", ""),
+                (a) -> assertCommand(a, "/set prompt tp 'ccc' 'ddd'", ""),
+                (a) -> assertCommand(a, "/set prompt tp",
+                        "|  /set prompt tp \"ccc\" \"ddd\""),
+                (a) -> assertCommandCheckOutput(a, "/set mode tp",
+                        (s) -> {
+                            try {
+                                BufferedReader rdr = new BufferedReader(new StringReader(s));
+                                assertEquals(rdr.readLine(), "|  /set mode tp -quiet",
+                                        "|  /set mode tp -quiet");
+                                assertEquals(rdr.readLine(), "|  /set prompt tp \"aaa\" \"bbb\"",
+                                        "|  /set prompt tp \"aaa\" \"bbb\"");
+                                String l = rdr.readLine();
+                                while (l.startsWith("|  /set format tp ")) {
+                                    l = rdr.readLine();
+                                }
+                                assertEquals(l, "|  /set mode -retain tp",
+                                        "|  /set mode -retain tp");
+                                assertEquals(rdr.readLine(), "|  ",
+                                        "|  ");
+                                assertEquals(rdr.readLine(), "|  /set mode tp -quiet",
+                                        "|  /set mode tp -quiet");
+                                assertEquals(rdr.readLine(), "|  /set prompt tp \"ccc\" \"ddd\"",
+                                        "|  /set prompt tp \"ccc\" \"ddd\"");
+                            } catch (IOException ex) {
+                                fail("threw " + ex);
+                            }
+                        })
+        );
+    }
+
     public void testShowFeedbackModes() {
         test(
                 (a) -> assertCommandOutputContains(a, "/set feedback", "normal")
@@ -216,7 +320,8 @@
                     (a) -> assertCommand(a, "/se fee nmq2", ""),
                     (a) -> assertCommand(a, "/set mode nmc -command normal", ""),
                     (a) -> assertCommandOutputStartsWith(a, "/set feedback nmc", "|  Feedback mode: nmc"),
-                    (a) -> assertCommandOutputStartsWith(a, "/set mode nm", "|  Created new feedback mode: nm"),
+                    (a) -> assertCommandOutputStartsWith(a, "/set mode nm -command",
+                            "|  Created new feedback mode: nm"),
                     (a) -> assertCommandOutputStartsWith(a, "/set feedback nm", "|  Feedback mode: nm"),
                     (a) -> assertCommandOutputStartsWith(a, "/set feedback normal", "|  Feedback mode: normal")
             );
@@ -231,37 +336,35 @@
             test(
                     (a) -> assertCommandOutputStartsWith(a, "/set mode tee -command foo",
                             "|  Does not match any current feedback mode: foo"),
-                    (a) -> assertCommandOutputStartsWith(a, "/set mode tee flurb",
+                    (a) -> assertCommandOutputStartsWith(a, "/set mode tee -quiet flurb",
                             "|  Does not match any current feedback mode: flurb"),
-                    (a) -> assertCommandOutputStartsWith(a, "/set mode tee",
+                    (a) -> assertCommandOutputStartsWith(a, "/set mode -command tee",
                             "|  Created new feedback mode: tee"),
-                    (a) -> assertCommandOutputStartsWith(a, "/set mode verbose",
-                            "|  Not valid with a predefined mode: verbose"),
+                    (a) -> assertCommandOutputStartsWith(a, "/set mode verbose -command",
+                            "|  Mode to be created already exists: verbose"),
                     (a) -> assertCommandOutputStartsWith(a, "/set mode te -command normal",
                             "|  Created new feedback mode: te"),
                     (a) -> assertCommand(a, "/set format te errorpre 'ERROR: '", ""),
                     (a) -> assertCommandOutputStartsWith(a, "/set feedback te",
                             ""),
-                    (a) -> assertCommandOutputStartsWith(a, "/set ",
-                            "ERROR: The '/set' command requires a sub-command"),
                     (a) -> assertCommandOutputStartsWith(a, "/set xyz",
                             "ERROR: Invalid '/set' argument: xyz"),
                     (a) -> assertCommandOutputStartsWith(a, "/set f",
                             "ERROR: Ambiguous sub-command argument to '/set': f"),
                     (a) -> assertCommandOutputStartsWith(a, "/set feedback",
-                            "ERROR: Missing the feedback mode"),
+                            "|  /set feedback te"),
                     (a) -> assertCommandOutputStartsWith(a, "/set feedback xyz",
                             "ERROR: Does not match any current feedback mode"),
-                    (a) -> assertCommandOutputStartsWith(a, "/set format",
-                            "ERROR: Missing the feedback mode"),
+                    (a) -> assertCommandOutputStartsWith(a, "/set feed",
+                            "|  /set feedback te"),
                     (a) -> assertCommandOutputStartsWith(a, "/set format xyz",
                             "ERROR: Does not match any current feedback mode"),
                     (a) -> assertCommandOutputStartsWith(a, "/set format t",
                             "ERROR: Matches more then one current feedback mode: t"),
-                    (a) -> assertCommandOutputStartsWith(a, "/set format te",
-                            "ERROR: Missing the field name"),
+                    (a) -> assertCommandOutputStartsWith(a, "/set format qqq",
+                            "ERROR: Does not match any current feedback mode: qqq"),
                     (a) -> assertCommandOutputStartsWith(a, "/set format te fld",
-                            "ERROR: Expected format missing"),
+                            "ERROR: Expected a field name:"),
                     (a) -> assertCommandOutputStartsWith(a, "/set format te fld aaa",
                             "ERROR: Format 'aaa' must be quoted"),
                     (a) -> assertCommandOutputStartsWith(a, "/set format te fld 'aaa' frog",
@@ -274,30 +377,28 @@
                             "ERROR: Different selector kinds in same sections of"),
                     (a) -> assertCommandOutputStartsWith(a, "/set trunc te 20x",
                             "ERROR: Truncation length must be an integer: 20x"),
-                    (a) -> assertCommandOutputStartsWith(a, "/set trunc te",
-                            "ERROR: Expected truncation length"),
+                    (a) -> assertCommandOutputStartsWith(a, "/set trunc qaz",
+                            "ERROR: Does not match any current feedback mode: qaz -- /set trunc qaz"),
                     (a) -> assertCommandOutputStartsWith(a, "/set truncation te 111 import,added",
                             "ERROR: Different selector kinds in same sections of"),
-                    (a) -> assertCommandOutputStartsWith(a, "/set mode",
+                    (a) -> assertCommandOutputContains(a, "/set mode",
+                            "|  /set truncation verbose"),
+                    (a) -> assertCommandOutputStartsWith(a, "/set mode -command",
                             "ERROR: Missing the feedback mode"),
                     (a) -> assertCommandOutputStartsWith(a, "/set mode x -quiet y",
                             "ERROR: Does not match any current feedback mode"),
                     (a) -> assertCommandOutputStartsWith(a, "/set prompt",
-                            "ERROR: Missing the feedback mode"),
+                            "|  /set prompt"),
                     (a) -> assertCommandOutputStartsWith(a, "/set prompt te",
-                            "ERROR: Expected format missing"),
+                            "|  /set prompt te "),
                     (a) -> assertCommandOutputStartsWith(a, "/set prompt te aaa xyz",
                             "ERROR: Format 'aaa' must be quoted"),
                     (a) -> assertCommandOutputStartsWith(a, "/set prompt te 'aaa' xyz",
                             "ERROR: Format 'xyz' must be quoted"),
-                    (a) -> assertCommandOutputStartsWith(a, "/set prompt",
-                            "ERROR: Missing the feedback mode"),
-                    (a) -> assertCommandOutputStartsWith(a, "/set prompt te",
-                            "ERROR: Expected format missing"),
                     (a) -> assertCommandOutputStartsWith(a, "/set prompt te aaa",
                             "ERROR: Format 'aaa' must be quoted"),
                     (a) -> assertCommandOutputStartsWith(a, "/set prompt te 'aaa'",
-                            "ERROR: Expected format missing"),
+                            "ERROR: Continuation prompt required"),
                     (a) -> assertCommandOutputStartsWith(a, "/set feedback normal",
                             "|  Feedback mode: normal")
             );
--- a/langtools/test/jdk/jshell/ToolLocaleMessageTest.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/test/jdk/jshell/ToolLocaleMessageTest.java	Thu Oct 20 20:01:40 2016 +0000
@@ -106,10 +106,11 @@
                     (a) -> assertCommandOK(a, "/set feedback test", "test"),
 
                     (a) -> assertCommandFail(a, "/list zebra"),
-                    (a) -> assertCommandFail(a, "/set editor", "/set editor"),
+                    (a) -> assertCommandFail(a, "/set editor -rot", "/set editor -rot"),
                     (a) -> assertCommandFail(a, "/set snowball", "/set", "snowball"),
-                    (a) -> assertCommandFail(a, "/set", "/set", "/help"),
-                    (a) -> assertCommandFail(a, "/set f", "feedback"),
+                    (a) -> assertCommandOK(a, "/set", "|  /set feedback test", "verbose"),
+                    (a) -> assertCommandFail(a, "/set f", "/set"),
+                    (a) -> assertCommandOK(a, "/set fe", "|  /set feedback test"),
                     (a) -> assertCommandFail(a, "/classpath", "/classpath"),
                     (a) -> assertCommandFail(a, "/help rabbits", "rabbits"),
                     (a) -> assertCommandFail(a, "/drop"),
@@ -164,27 +165,20 @@
                     (a) -> assertCommandOK(a, "/set format te errorpre 'ERROR: '"),
                     (a) -> assertCommandOK(a, "/set feedback te"),
 
-                    (a) -> assertCommandFail(a, "/set "),
                     (a) -> assertCommandFail(a, "/set xyz", "xyz"),
                     (a) -> assertCommandFail(a, "/set f", "/set", "f"),
-                    (a) -> assertCommandFail(a, "/set feedback"),
                     (a) -> assertCommandFail(a, "/set feedback xyz"),
-                    (a) -> assertCommandFail(a, "/set format"),
                     (a) -> assertCommandFail(a, "/set format xyz"),
                     (a) -> assertCommandFail(a, "/set format t"),
-                    (a) -> assertCommandFail(a, "/set format te"),
                     (a) -> assertCommandFail(a, "/set format te fld"),
                     (a) -> assertCommandFail(a, "/set format te fld aaa", "aaa"),
                     (a) -> assertCommandFail(a, "/set format te fld 'aaa' frog"),
                     (a) -> assertCommandFail(a, "/set format te fld 'aaa' import-frog"),
                     (a) -> assertCommandFail(a, "/set format te fld 'aaa' import-import"),
                     (a) -> assertCommandFail(a, "/set format te fld 'aaa' import,added"),
-                    (a) -> assertCommandFail(a, "/set mode"),
                     (a) -> assertCommandFail(a, "/set mode x xyz"),
                     (a) -> assertCommandFail(a, "/set mode x -quiet y"),
                     (a) -> assertCommandFail(a, "/set mode tee -command foo", "foo"),
-                    (a) -> assertCommandFail(a, "/set prompt"),
-                    (a) -> assertCommandFail(a, "/set prompt te"),
                     (a) -> assertCommandFail(a, "/set prompt te aaa xyz", "aaa"),
                     (a) -> assertCommandFail(a, "/set prompt te 'aaa' xyz", "xyz"),
                     (a) -> assertCommandFail(a, "/set prompt te aaa"),
--- a/langtools/test/jdk/jshell/ToolRetainTest.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/test/jdk/jshell/ToolRetainTest.java	Thu Oct 20 20:01:40 2016 +0000
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8157200
+ * @bug 8157200 8163840
  * @summary Tests of what information is retained across jshell tool runs
  * @modules jdk.jshell/jdk.internal.jshell.tool
  * @build ToolRetainTest ReplToolTesting
@@ -41,10 +41,12 @@
                 (a) -> assertCommand(a, "/set feedback trm", ""),
                 (a) -> assertCommand(a, "/set format trm display '{name}:{value}'", ""),
                 (a) -> assertCommand(a, "int x = 45", "x:45"),
-                (a) -> assertCommand(a, "/retain mode trm", ""),
+                (a) -> assertCommand(a, "/set mode -retain trm", ""),
                 (a) -> assertCommand(a, "/exit", "")
         );
         test(
+                (a) -> assertCommandOutputContains(a, "/set mode trm",
+                        "/set format trm display \"{name}:{value}\""),
                 (a) -> assertCommand(a, "/set feedback trm", ""),
                 (a) -> assertCommand(a, "int x = 45", "x:45")
         );
@@ -53,21 +55,25 @@
     public void testRetain2Mode() {
         test(
                 (a) -> assertCommand(a, "/set mode trm1 -quiet", "|  Created new feedback mode: trm1"),
-                (a) -> assertCommand(a, "/retain mode trm1", ""),
-                (a) -> assertCommand(a, "/retain feedback trm1", ""),
+                (a) -> assertCommand(a, "/set mode -retain trm1", ""),
+                (a) -> assertCommand(a, "/set feedback -retain trm1", ""),
                 (a) -> assertCommand(a, "/set format trm1 display '{name}:{value}'", ""),
                 (a) -> assertCommand(a, "int x = 66", "x:66"),
-                (a) -> assertCommand(a, "/retain mode trm1", ""),
+                (a) -> assertCommand(a, "/set mode -retain trm1", ""),
                 (a) -> assertCommand(a, "/exit", "")
         );
         test(
                 (a) -> assertCommand(a, "/set mode trm2 -quiet", ""),
                 (a) -> assertCommand(a, "/set format trm2 display '{name}={value}'", ""),
                 (a) -> assertCommand(a, "int x = 45", "x:45"),
-                (a) -> assertCommand(a, "/retain mode trm2", ""),
+                (a) -> assertCommand(a, "/set mode -retain trm2", ""),
                 (a) -> assertCommand(a, "/exit", "")
         );
         test(
+                (a) -> assertCommandOutputContains(a, "/set mode trm1",
+                        "/set format trm1 display \"{name}:{value}\""),
+                (a) -> assertCommand(a, "/set format trm2 display",
+                        "|  /set format trm2 display \"{name}={value}\""),
                 (a) -> assertCommand(a, "int x = 99", "x:99"),
                 (a) -> assertCommand(a, "/set feedback trm2", ""),
                 (a) -> assertCommand(a, "int z = 77", "z=77")
@@ -76,31 +82,48 @@
 
     public void testRetainFeedback() {
         test(
-                (a) -> assertCommand(a, "/retain feedback verbose", "|  Feedback mode: verbose"),
+                (a) -> assertCommand(a, "/set feedback -retain verbose", "|  Feedback mode: verbose"),
                 (a) -> assertCommand(a, "/exit", "")
         );
         test(
+                (a) -> assertCommandOutputStartsWith(a, "/set feedback",
+                        "|  /set feedback -retain verbose\n" +
+                        "|  \n" +
+                        "|  "),
                 (a) -> assertCommandOutputContains(a, "int h =8", "|  created variable h : int")
         );
     }
 
     public void testRetainFeedbackBlank() {
+        String feedbackOut =
+                        "|  /set feedback -retain verbose\n" +
+                        "|  \n" +
+                        "|  Available feedback modes:\n" +
+                        "|     concise\n" +
+                        "|     normal\n" +
+                        "|     silent\n" +
+                        "|     verbose";
         test(
                 (a) -> assertCommand(a, "/set feedback verbose", "|  Feedback mode: verbose"),
-                (a) -> assertCommand(a, "/retain feedback", ""),
+                (a) -> assertCommand(a, "/set feedback -retain", ""),
+                (a) -> assertCommand(a, "/set feedback", feedbackOut),
                 (a) -> assertCommand(a, "/exit", "")
         );
         test(
+                (a) -> assertCommand(a, "/set feedback", feedbackOut),
                 (a) -> assertCommandOutputContains(a, "int qw = 5", "|  created variable qw : int")
         );
     }
 
     public void testRetainEditor() {
         test(
-                (a) -> assertCommand(a, "/retain editor nonexistent", "|  Editor set to: nonexistent"),
+                (a) -> assertCommand(a, "/set editor -retain nonexistent",
+                        "|  Editor set to: nonexistent\n" +
+                        "|  Editor setting retained: nonexistent"),
                 (a) -> assertCommand(a, "/exit", "")
         );
         test(
+                (a) -> assertCommand(a, "/set editor", "|  /set editor -retain nonexistent"),
                 (a) -> assertCommandOutputContains(a, "int h =8", ""),
                 (a) -> assertCommandOutputContains(a, "/edit h", "Edit Error:")
         );
@@ -109,7 +132,7 @@
     public void testRetainEditorBlank() {
         test(
                 (a) -> assertCommand(a, "/set editor nonexistent", "|  Editor set to: nonexistent"),
-                (a) -> assertCommand(a, "/retain editor", ""),
+                (a) -> assertCommand(a, "/set editor -retain", "|  Editor setting retained: nonexistent"),
                 (a) -> assertCommand(a, "/exit", "")
         );
         test(
@@ -120,22 +143,25 @@
 
     public void testRetainModeNeg() {
         test(
-                (a) -> assertCommandOutputStartsWith(a, "/retain mode verbose",
+                (a) -> assertCommandOutputStartsWith(a, "/set mode -retain verbose",
                         "|  Not valid with a predefined mode"),
-                (a) -> assertCommandOutputStartsWith(a, "/retain mode ????",
+                (a) -> assertCommandOutputStartsWith(a, "/set mode -retain ????",
                         "|  Expected a feedback mode name: ????")
         );
     }
 
     public void testRetainFeedbackNeg() {
         test(
-                (a) -> assertCommandOutputStartsWith(a, "/retain feedback babble1",
+                (a) -> assertCommandOutputStartsWith(a, "/set feedback -retain babble1",
                         "|  Does not match any current feedback mode"),
-                (a) -> assertCommand(a, "/set mode trfn",
+                (a) -> assertCommandOutputStartsWith(a, "/set mode trfn",
+                        "|  To create a new mode either the -command or the -quiet option must be used -- \n" +
+                        "|  Does not match any current feedback mode: trfn -- /set mode trfn"),
+                (a) -> assertCommand(a, "/set mode trfn -command",
                         "|  Created new feedback mode: trfn"),
-                (a) -> assertCommandOutputContains(a, "/retain feedback trfn",
+                (a) -> assertCommandOutputContains(a, "/set feedback -retain trfn",
                         "is predefined or has been retained"),
-                (a) -> assertCommandOutputStartsWith(a, "/retain feedback !!!!",
+                (a) -> assertCommandOutputStartsWith(a, "/set feedback -retain !!!!",
                         "|  Expected a feedback mode name: !!!!")
         );
     }
--- a/langtools/test/jdk/jshell/ToolSimpleTest.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/test/jdk/jshell/ToolSimpleTest.java	Thu Oct 20 20:01:40 2016 +0000
@@ -193,8 +193,8 @@
                         "|  '/save' requires a filename argument."),
                 (a) -> assertCommand(a, "/open",
                         "|  '/open' requires a filename argument."),
-                (a) -> assertCommand(a, "/set start",
-                        "|  Specify either one option or a startup file name -- /set start")
+                (a) -> assertCommandOutputStartsWith(a, "/drop",
+                        "|  In the /drop argument, please specify an import, variable, method, or class to drop.")
         );
     }
 
--- a/langtools/test/jdk/jshell/UserInputTest.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/test/jdk/jshell/UserInputTest.java	Thu Oct 20 20:01:40 2016 +0000
@@ -23,12 +23,15 @@
 
 /*
  * @test
- * @bug 8131023
+ * @bug 8131023 8167461
  * @summary Verify that the user's code can read System.in
  * @build KullaTesting TestingInputStream
  * @run testng UserInputTest
  */
 
+import java.io.IOException;
+import java.io.InputStream;
+
 import org.testng.annotations.Test;
 
 @Test
@@ -37,8 +40,61 @@
     public void testReadInput() {
         setInput("AB\n");
         assertEval("System.in.read()", "65");
-        setInput("BC\n");
-        assertEval("System.in.read()", "66");
+        setInput("CD\n");
+        assertEval("System.in.read()", "67");
+    }
+
+    public void testScanner() {
+        assertEval("import java.util.Scanner;");
+        assertEval("Scanner s = new Scanner(System.in);");
+        setInput("12\n");
+        assertEval("s.nextInt();", "12");
     }
 
+    public void testClose() {
+        setInput(new InputStream() {
+            private final byte[] data = new byte[] {0, 1, 2};
+            private int cursor;
+            @Override public int read() throws IOException {
+                if (cursor < data.length) {
+                    return data[cursor++];
+                } else {
+                    return -1;
+                }
+            }
+        });
+        assertEval("int read;", "0");
+        assertEval("System.in.read();", "0");
+        assertEval("System.in.read();", "1");
+        assertEval("System.in.read();", "2");
+        assertEval("System.in.read();", "-1");
+        assertEval("System.in.read();", "-1");
+        assertEval("System.in.read();", "-1");
+    }
+
+    public void testException() {
+        setInput(new InputStream() {
+            private final int[] data = new int[] {0, 1, -2, 2};
+            private int cursor;
+            @Override public int read() throws IOException {
+                if (cursor < data.length) {
+                    int d = data[cursor++];
+                    if (d == (-2)) {
+                        throw new IOException("Crashed");
+                    }
+                    return d;
+                } else {
+                    return -1;
+                }
+            }
+        });
+        assertEval("int read;", "0");
+        assertEval("System.in.read();", "0");
+        assertEval("System.in.read();", "1");
+        assertEval("java.io.IOException e;");
+        assertEval("try { System.in.read(); } catch (java.io.IOException exc) { e = exc; }");
+        assertEval("e", "java.io.IOException: Crashed");
+        assertEval("System.in.read();", "2");
+        assertEval("System.in.read();", "-1");
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8029102/WarnSerializableElementTest.java	Thu Oct 20 20:01:40 2016 +0000
@@ -0,0 +1,241 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8029102
+ * @summary Enhance compiler warnings for Lambda
+ *     Checks that the warning for accessing non public members of a class is
+ *     fired correctly.
+ * @compile/fail/ref=WarnSerializableElementTest.out -XDrawDiagnostics -Werror -XDwarnOnAccessToMembers WarnSerializableElementTest.java
+ */
+
+import java.io.Serializable;
+
+public class WarnSerializableElementTest {
+
+    void warnLambda() throws Exception {
+        SAM t3 = (SAM & Serializable)WarnSerializableElementTest::packageClassMethod;
+        SAM t4 = (SAM & Serializable)WarnSerializableElementTest::protectedClassMethod;
+        SAM t5 = (SAM & Serializable)WarnSerializableElementTest::privateClassMethod;
+
+        WarnSerializableElementTest test = new WarnSerializableElementTest();
+        SAM t6 = (SAM & Serializable)test::packageInstanceMethod;
+        SAM t7 = (SAM & Serializable)test::protectedInstanceMethod;
+        SAM t8 = (SAM & Serializable)test::privateInstanceMethod;
+
+        SAM t9 = (SAM & Serializable) c -> {
+
+            WarnSerializableElementTest.staticPackageField = "";
+            WarnSerializableElementTest.staticProtectedField = "";
+            WarnSerializableElementTest.staticPrivateField = "";
+
+            packageField = "";
+            protectedField = "";
+            privateField = "";
+
+            WarnSerializableElementTest.packageClassMethod(null);
+            WarnSerializableElementTest.protectedClassMethod(null);
+            WarnSerializableElementTest.privateClassMethod(null);
+
+            packageInstanceMethod(null);
+            protectedInstanceMethod(null);
+            privateInstanceMethod(null);
+
+            PrivateClass.effectivelyNonPublicStaticField = "";
+            PrivateClass.effectivelyNonPublicClassMethod();
+
+            PrivateClass p = new PrivateClass();
+            p.effectivelyNonPublicInstanceField = "";
+            p.effectivelyNonPublicInstanceMethod();
+
+            return null;
+        };
+    }
+
+    private void warnAnoInnerClass() throws Exception {
+        new SerializableDesc() {
+            public void m(Object param) throws Exception {
+                WarnSerializableElementTest.staticPackageField = "";
+                WarnSerializableElementTest.staticProtectedField = "";
+                WarnSerializableElementTest.staticPrivateField = "";
+
+                packageField = "";
+                protectedField = "";
+                privateField = "";
+
+                WarnSerializableElementTest.packageClassMethod(null);
+                WarnSerializableElementTest.protectedClassMethod(null);
+                WarnSerializableElementTest.privateClassMethod(null);
+
+                packageInstanceMethod(null);
+                protectedInstanceMethod(null);
+                privateInstanceMethod(null);
+
+                PrivateClass.effectivelyNonPublicStaticField = "";
+                PrivateClass.effectivelyNonPublicClassMethod();
+
+                PrivateClass p = new PrivateClass();
+                p.effectivelyNonPublicInstanceField = "";
+                p.effectivelyNonPublicInstanceMethod();
+            }
+        };
+    }
+
+    void dontWarnLambda() throws Exception {
+        SAM t1 = (SAM & Serializable)WarnSerializableElementTest::publicClassMethod;
+
+        WarnSerializableElementTest test = new WarnSerializableElementTest();
+        SAM t2 = (SAM & Serializable)test::publicInstanceMethod;
+
+        int[] buffer = {0};
+
+        SAM t3 = (SAM & Serializable) param -> {
+            Object localVar;
+            localVar = null;
+            param = null;
+
+            WarnSerializableElementTest.staticPublicField = "";
+            publicField = "";
+            WarnSerializableElementTest.publicClassMethod(null);
+            publicInstanceMethod(null);
+
+            PublicClass.effectivelyPublicStaticField = "";
+            PublicClass.effectivelyPublicClassMethod();
+
+            PublicClass p = new PublicClass();
+            p.effectivelyPublicInstanceField = "";
+            p.effectivelyPublicInstanceMethod();
+
+            int l = buffer.length;
+
+            return null;
+        };
+    }
+
+    private void dontWarnAnoInnerClass() throws Exception {
+        final int[] buffer = {0};
+        new SerializableDesc() {
+            public void m(Object param) throws Exception {
+                Object localVar;
+                localVar = null;
+                param = null;
+
+                WarnSerializableElementTest.staticPublicField = "";
+                publicField = "";
+                WarnSerializableElementTest.publicClassMethod(null);
+                publicInstanceMethod(null);
+
+                PublicClass.effectivelyPublicStaticField = "";
+                PublicClass.effectivelyPublicClassMethod();
+
+                PublicClass p = new PublicClass();
+                p.effectivelyPublicInstanceField = "";
+                p.effectivelyPublicInstanceMethod();
+
+                int l = buffer.length;
+            }
+        };
+    }
+
+    enum WarnEnum {
+        A {
+            public void m() throws Exception {
+                WarnSerializableElementTest.staticPackageField = "";
+                WarnSerializableElementTest.staticProtectedField = "";
+                WarnSerializableElementTest.staticPrivateField = "";
+
+                WarnSerializableElementTest test =
+                        new WarnSerializableElementTest();
+
+                test.packageField = "";
+                test.protectedField = "";
+                test.privateField = "";
+
+                WarnSerializableElementTest.packageClassMethod(null);
+                WarnSerializableElementTest.protectedClassMethod(null);
+                WarnSerializableElementTest.privateClassMethod(null);
+
+                test.packageInstanceMethod(null);
+                test.protectedInstanceMethod(null);
+                test.privateInstanceMethod(null);
+
+                PrivateClass.effectivelyNonPublicStaticField = "";
+                PrivateClass.effectivelyNonPublicClassMethod();
+
+                PrivateClass p = new PrivateClass();
+                p.effectivelyNonPublicInstanceField = "";
+                p.effectivelyNonPublicInstanceMethod();
+            }
+        };
+
+        public void m() throws Exception {}
+    }
+
+    static String staticPackageField;
+    static private String staticPrivateField;
+    static protected String staticProtectedField;
+    static public String staticPublicField;
+
+    String packageField;
+    private String privateField;
+    protected String protectedField;
+    public String publicField;
+
+    static Object packageClassMethod(String s) {
+        return null;
+    }
+
+    static private Object privateClassMethod(String s) {
+        return null;
+    }
+
+    static protected Object protectedClassMethod(String s) {
+        return null;
+    }
+
+    static public Object publicClassMethod(String s) {
+        return null;
+    }
+
+    Object packageInstanceMethod(String s) {
+        return null;
+    }
+
+    protected Object protectedInstanceMethod(String s) {
+        return null;
+    }
+
+    private Object privateInstanceMethod(String s) {
+        return null;
+    }
+
+    public Object publicInstanceMethod(String s) {
+        return null;
+    }
+
+    interface SAM {
+        Object apply(String s) throws Exception;
+    }
+
+    interface SAM2 {
+        Object apply(String arg1, String arg2);
+    }
+
+    class SerializableDesc implements Serializable {
+        public void m(Object param) throws Exception {}
+    }
+
+    static private class PrivateClass {
+        static public String effectivelyNonPublicStaticField;
+        public String effectivelyNonPublicInstanceField;
+
+        static public void effectivelyNonPublicClassMethod() {}
+        public void effectivelyNonPublicInstanceMethod() {}
+    }
+
+    static public class PublicClass {
+        static public String effectivelyPublicStaticField;
+        public String effectivelyPublicInstanceField;
+
+        static public void effectivelyPublicClassMethod() {}
+        public void effectivelyPublicInstanceMethod() {}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8029102/WarnSerializableElementTest.out	Thu Oct 20 20:01:40 2016 +0000
@@ -0,0 +1,35 @@
+WarnSerializableElementTest.java:56:44: compiler.warn.access.to.member.from.serializable.element: staticPackageField
+WarnSerializableElementTest.java:57:44: compiler.warn.access.to.member.from.serializable.element: staticProtectedField
+WarnSerializableElementTest.java:58:44: compiler.warn.access.to.member.from.serializable.element: staticPrivateField
+WarnSerializableElementTest.java:60:17: compiler.warn.access.to.member.from.serializable.element: packageField
+WarnSerializableElementTest.java:61:17: compiler.warn.access.to.member.from.serializable.element: protectedField
+WarnSerializableElementTest.java:62:17: compiler.warn.access.to.member.from.serializable.element: privateField
+WarnSerializableElementTest.java:64:44: compiler.warn.access.to.member.from.serializable.element: packageClassMethod(java.lang.String)
+WarnSerializableElementTest.java:65:44: compiler.warn.access.to.member.from.serializable.element: protectedClassMethod(java.lang.String)
+WarnSerializableElementTest.java:66:44: compiler.warn.access.to.member.from.serializable.element: privateClassMethod(java.lang.String)
+WarnSerializableElementTest.java:68:17: compiler.warn.access.to.member.from.serializable.element: packageInstanceMethod(java.lang.String)
+WarnSerializableElementTest.java:69:17: compiler.warn.access.to.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
+WarnSerializableElementTest.java:70:17: compiler.warn.access.to.member.from.serializable.element: privateInstanceMethod(java.lang.String)
+WarnSerializableElementTest.java:72:29: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicStaticField
+WarnSerializableElementTest.java:73:29: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicClassMethod()
+WarnSerializableElementTest.java:76:18: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicInstanceField
+WarnSerializableElementTest.java:77:18: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicInstanceMethod()
+WarnSerializableElementTest.java:141:44: compiler.warn.access.to.member.from.serializable.element: staticPackageField
+WarnSerializableElementTest.java:142:44: compiler.warn.access.to.member.from.serializable.element: staticProtectedField
+WarnSerializableElementTest.java:143:44: compiler.warn.access.to.member.from.serializable.element: staticPrivateField
+WarnSerializableElementTest.java:148:21: compiler.warn.access.to.member.from.serializable.element: packageField
+WarnSerializableElementTest.java:149:21: compiler.warn.access.to.member.from.serializable.element: protectedField
+WarnSerializableElementTest.java:150:21: compiler.warn.access.to.member.from.serializable.element: privateField
+WarnSerializableElementTest.java:152:44: compiler.warn.access.to.member.from.serializable.element: packageClassMethod(java.lang.String)
+WarnSerializableElementTest.java:153:44: compiler.warn.access.to.member.from.serializable.element: protectedClassMethod(java.lang.String)
+WarnSerializableElementTest.java:154:44: compiler.warn.access.to.member.from.serializable.element: privateClassMethod(java.lang.String)
+WarnSerializableElementTest.java:156:21: compiler.warn.access.to.member.from.serializable.element: packageInstanceMethod(java.lang.String)
+WarnSerializableElementTest.java:157:21: compiler.warn.access.to.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
+WarnSerializableElementTest.java:158:21: compiler.warn.access.to.member.from.serializable.element: privateInstanceMethod(java.lang.String)
+WarnSerializableElementTest.java:160:29: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicStaticField
+WarnSerializableElementTest.java:161:29: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicClassMethod()
+WarnSerializableElementTest.java:164:18: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicInstanceField
+WarnSerializableElementTest.java:165:18: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicInstanceMethod()
+- compiler.err.warnings.and.werror
+1 error
+32 warnings
--- a/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTest.java	Thu Oct 20 18:38:11 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,241 +0,0 @@
-/*
- * @test /nodynamiccopyright/
- * @bug 8029102
- * @summary Enhance compiler warnings for Lambda
- *     Checks that the warning for accessing non public members of a class is
- *     fired correctly.
- * @compile/fail/ref=WarnSerializableLambdaTest.out -XDrawDiagnostics -Werror -XDwarnOnAccessToSensitiveMembers WarnSerializableLambdaTest.java
- */
-
-import java.io.Serializable;
-
-public class WarnSerializableLambdaTest {
-
-    void warnLambda() throws Exception {
-        SAM t3 = (SAM & Serializable)WarnSerializableLambdaTest::packageClassMethod;
-        SAM t4 = (SAM & Serializable)WarnSerializableLambdaTest::protectedClassMethod;
-        SAM t5 = (SAM & Serializable)WarnSerializableLambdaTest::privateClassMethod;
-
-        WarnSerializableLambdaTest test = new WarnSerializableLambdaTest();
-        SAM t6 = (SAM & Serializable)test::packageInstanceMethod;
-        SAM t7 = (SAM & Serializable)test::protectedInstanceMethod;
-        SAM t8 = (SAM & Serializable)test::privateInstanceMethod;
-
-        SAM t9 = (SAM & Serializable) c -> {
-
-            WarnSerializableLambdaTest.staticPackageField = "";
-            WarnSerializableLambdaTest.staticProtectedField = "";
-            WarnSerializableLambdaTest.staticPrivateField = "";
-
-            packageField = "";
-            protectedField = "";
-            privateField = "";
-
-            WarnSerializableLambdaTest.packageClassMethod(null);
-            WarnSerializableLambdaTest.protectedClassMethod(null);
-            WarnSerializableLambdaTest.privateClassMethod(null);
-
-            packageInstanceMethod(null);
-            protectedInstanceMethod(null);
-            privateInstanceMethod(null);
-
-            PrivateClass.effectivelyNonPublicStaticField = "";
-            PrivateClass.effectivelyNonPublicClassMethod();
-
-            PrivateClass p = new PrivateClass();
-            p.effectivelyNonPublicInstanceField = "";
-            p.effectivelyNonPublicInstanceMethod();
-
-            return null;
-        };
-    }
-
-    private void warnAnoInnerClass() throws Exception {
-        new SerializableDesc() {
-            public void m(Object param) throws Exception {
-                WarnSerializableLambdaTest.staticPackageField = "";
-                WarnSerializableLambdaTest.staticProtectedField = "";
-                WarnSerializableLambdaTest.staticPrivateField = "";
-
-                packageField = "";
-                protectedField = "";
-                privateField = "";
-
-                WarnSerializableLambdaTest.packageClassMethod(null);
-                WarnSerializableLambdaTest.protectedClassMethod(null);
-                WarnSerializableLambdaTest.privateClassMethod(null);
-
-                packageInstanceMethod(null);
-                protectedInstanceMethod(null);
-                privateInstanceMethod(null);
-
-                PrivateClass.effectivelyNonPublicStaticField = "";
-                PrivateClass.effectivelyNonPublicClassMethod();
-
-                PrivateClass p = new PrivateClass();
-                p.effectivelyNonPublicInstanceField = "";
-                p.effectivelyNonPublicInstanceMethod();
-            }
-        };
-    }
-
-    void dontWarnLambda() throws Exception {
-        SAM t1 = (SAM & Serializable)WarnSerializableLambdaTest::publicClassMethod;
-
-        WarnSerializableLambdaTest test = new WarnSerializableLambdaTest();
-        SAM t2 = (SAM & Serializable)test::publicInstanceMethod;
-
-        int[] buffer = {0};
-
-        SAM t3 = (SAM & Serializable) param -> {
-            Object localVar;
-            localVar = null;
-            param = null;
-
-            WarnSerializableLambdaTest.staticPublicField = "";
-            publicField = "";
-            WarnSerializableLambdaTest.publicClassMethod(null);
-            publicInstanceMethod(null);
-
-            PublicClass.effectivelyPublicStaticField = "";
-            PublicClass.effectivelyPublicClassMethod();
-
-            PublicClass p = new PublicClass();
-            p.effectivelyPublicInstanceField = "";
-            p.effectivelyPublicInstanceMethod();
-
-            int l = buffer.length;
-
-            return null;
-        };
-    }
-
-    private void dontWarnAnoInnerClass() throws Exception {
-        final int[] buffer = {0};
-        new SerializableDesc() {
-            public void m(Object param) throws Exception {
-                Object localVar;
-                localVar = null;
-                param = null;
-
-                WarnSerializableLambdaTest.staticPublicField = "";
-                publicField = "";
-                WarnSerializableLambdaTest.publicClassMethod(null);
-                publicInstanceMethod(null);
-
-                PublicClass.effectivelyPublicStaticField = "";
-                PublicClass.effectivelyPublicClassMethod();
-
-                PublicClass p = new PublicClass();
-                p.effectivelyPublicInstanceField = "";
-                p.effectivelyPublicInstanceMethod();
-
-                int l = buffer.length;
-            }
-        };
-    }
-
-    enum WarnEnum {
-        A {
-            public void m() throws Exception {
-                WarnSerializableLambdaTest.staticPackageField = "";
-                WarnSerializableLambdaTest.staticProtectedField = "";
-                WarnSerializableLambdaTest.staticPrivateField = "";
-
-                WarnSerializableLambdaTest test =
-                        new WarnSerializableLambdaTest();
-
-                test.packageField = "";
-                test.protectedField = "";
-                test.privateField = "";
-
-                WarnSerializableLambdaTest.packageClassMethod(null);
-                WarnSerializableLambdaTest.protectedClassMethod(null);
-                WarnSerializableLambdaTest.privateClassMethod(null);
-
-                test.packageInstanceMethod(null);
-                test.protectedInstanceMethod(null);
-                test.privateInstanceMethod(null);
-
-                PrivateClass.effectivelyNonPublicStaticField = "";
-                PrivateClass.effectivelyNonPublicClassMethod();
-
-                PrivateClass p = new PrivateClass();
-                p.effectivelyNonPublicInstanceField = "";
-                p.effectivelyNonPublicInstanceMethod();
-            }
-        };
-
-        public void m() throws Exception {}
-    }
-
-    static String staticPackageField;
-    static private String staticPrivateField;
-    static protected String staticProtectedField;
-    static public String staticPublicField;
-
-    String packageField;
-    private String privateField;
-    protected String protectedField;
-    public String publicField;
-
-    static Object packageClassMethod(String s) {
-        return null;
-    }
-
-    static private Object privateClassMethod(String s) {
-        return null;
-    }
-
-    static protected Object protectedClassMethod(String s) {
-        return null;
-    }
-
-    static public Object publicClassMethod(String s) {
-        return null;
-    }
-
-    Object packageInstanceMethod(String s) {
-        return null;
-    }
-
-    protected Object protectedInstanceMethod(String s) {
-        return null;
-    }
-
-    private Object privateInstanceMethod(String s) {
-        return null;
-    }
-
-    public Object publicInstanceMethod(String s) {
-        return null;
-    }
-
-    interface SAM {
-        Object apply(String s) throws Exception;
-    }
-
-    interface SAM2 {
-        Object apply(String arg1, String arg2);
-    }
-
-    class SerializableDesc implements Serializable {
-        public void m(Object param) throws Exception {}
-    }
-
-    static private class PrivateClass {
-        static public String effectivelyNonPublicStaticField;
-        public String effectivelyNonPublicInstanceField;
-
-        static public void effectivelyNonPublicClassMethod() {}
-        public void effectivelyNonPublicInstanceMethod() {}
-    }
-
-    static public class PublicClass {
-        static public String effectivelyPublicStaticField;
-        public String effectivelyPublicInstanceField;
-
-        static public void effectivelyPublicClassMethod() {}
-        public void effectivelyPublicInstanceMethod() {}
-    }
-}
--- a/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTest.out	Thu Oct 20 18:38:11 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-WarnSerializableLambdaTest.java:15:38: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:16:38: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:17:38: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:20:38: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:21:38: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:22:38: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:26:39: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPackageField
-WarnSerializableLambdaTest.java:27:39: compiler.warn.access.to.sensitive.member.from.serializable.element: staticProtectedField
-WarnSerializableLambdaTest.java:28:39: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPrivateField
-WarnSerializableLambdaTest.java:30:13: compiler.warn.access.to.sensitive.member.from.serializable.element: packageField
-WarnSerializableLambdaTest.java:31:13: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedField
-WarnSerializableLambdaTest.java:32:13: compiler.warn.access.to.sensitive.member.from.serializable.element: privateField
-WarnSerializableLambdaTest.java:34:39: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:35:39: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:36:39: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:38:13: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:39:13: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:40:13: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:42:25: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicStaticField
-WarnSerializableLambdaTest.java:43:25: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicClassMethod()
-WarnSerializableLambdaTest.java:46:14: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceField
-WarnSerializableLambdaTest.java:47:14: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceMethod()
-WarnSerializableLambdaTest.java:56:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPackageField
-WarnSerializableLambdaTest.java:57:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticProtectedField
-WarnSerializableLambdaTest.java:58:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPrivateField
-WarnSerializableLambdaTest.java:60:17: compiler.warn.access.to.sensitive.member.from.serializable.element: packageField
-WarnSerializableLambdaTest.java:61:17: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedField
-WarnSerializableLambdaTest.java:62:17: compiler.warn.access.to.sensitive.member.from.serializable.element: privateField
-WarnSerializableLambdaTest.java:64:43: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:65:43: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:66:43: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:68:17: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:69:17: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:70:17: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:72:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicStaticField
-WarnSerializableLambdaTest.java:73:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicClassMethod()
-WarnSerializableLambdaTest.java:76:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceField
-WarnSerializableLambdaTest.java:77:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceMethod()
-WarnSerializableLambdaTest.java:141:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPackageField
-WarnSerializableLambdaTest.java:142:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticProtectedField
-WarnSerializableLambdaTest.java:143:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPrivateField
-WarnSerializableLambdaTest.java:148:21: compiler.warn.access.to.sensitive.member.from.serializable.element: packageField
-WarnSerializableLambdaTest.java:149:21: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedField
-WarnSerializableLambdaTest.java:150:21: compiler.warn.access.to.sensitive.member.from.serializable.element: privateField
-WarnSerializableLambdaTest.java:152:43: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:153:43: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:154:43: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:156:21: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:157:21: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:158:21: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:160:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicStaticField
-WarnSerializableLambdaTest.java:161:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicClassMethod()
-WarnSerializableLambdaTest.java:164:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceField
-WarnSerializableLambdaTest.java:165:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceMethod()
-- compiler.err.warnings.and.werror
-1 error
-54 warnings
--- a/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.java	Thu Oct 20 20:01:40 2016 +0000
@@ -4,7 +4,7 @@
  * @summary Enhance compiler warnings for Lambda
  *     Checks that the warning for accessing non public members of a class is
  *     fired correctly.
- * @compile/fail/ref=WarnSerializableLambdaTestb.out -XDrawDiagnostics -Werror -XDwarnOnAccessToSensitiveMembers WarnSerializableLambdaTestb.java
+ * @compile/fail/ref=WarnSerializableLambdaTestb.out -XDrawDiagnostics -Werror -XDwarnOnAccessToMembers WarnSerializableLambdaTestb.java
  */
 
 import java.io.Serializable;
--- a/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.out	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.out	Thu Oct 20 20:01:40 2016 +0000
@@ -1,7 +1,5 @@
-WarnSerializableLambdaTestb.java:14:69: compiler.warn.access.to.sensitive.member.from.serializable.element: test()
-WarnSerializableLambdaTestb.java:18:69: compiler.warn.access.to.sensitive.member.from.serializable.element: test()
-WarnSerializableLambdaTestb.java:36:40: compiler.warn.access.to.sensitive.member.from.serializable.element: j
-WarnSerializableLambdaTestb.java:50:25: compiler.warn.access.to.sensitive.member.from.serializable.element: r
+WarnSerializableLambdaTestb.java:36:40: compiler.warn.access.to.member.from.serializable.element: j
+WarnSerializableLambdaTestb.java:50:25: compiler.warn.access.to.member.from.serializable.element: r
 - compiler.err.warnings.and.werror
 1 error
-4 warnings
+2 warnings
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestc.java	Thu Oct 20 20:01:40 2016 +0000
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8026721
+ * @summary Enhance Lambda serialization
+ *     Checks that the warning for accessing non public members of a class is fired correctly.
+ * @compile -Xlint:serial -Werror WarnSerializableLambdaTestc.java
+ */
+
+import javax.tools.SimpleJavaFileObject;
+import java.io.Serializable;
+
+public class WarnSerializableLambdaTestc {
+    public interface SerializableIntf<T> extends Serializable {
+        String get(T o);
+    }
+
+    private void dontWarn() {
+        SerializableIntf<SimpleJavaFileObject> s = SimpleJavaFileObject::getName;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestc.out	Thu Oct 20 20:01:40 2016 +0000
@@ -0,0 +1,4 @@
+WarnSerializableLambdaTestc.java:18:52: compiler.warn.access.to.member.from.serializable.lambda
+- compiler.err.warnings.and.werror
+1 error
+1 warning
--- a/langtools/test/tools/javac/diags/CheckResourceKeys.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/test/tools/javac/diags/CheckResourceKeys.java	Thu Oct 20 20:01:40 2016 +0000
@@ -257,6 +257,8 @@
                 // ignore package and class names
                 if (cs.matches("(com|java|javax|jdk|sun)\\.[A-Za-z.]+"))
                     continue;
+                if (cs.matches("(java|javax|sun)\\."))
+                    continue;
                 // ignore debug flag names
                 if (cs.startsWith("debug."))
                     continue;
--- a/langtools/test/tools/javac/diags/examples.not-yet.txt	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/test/tools/javac/diags/examples.not-yet.txt	Thu Oct 20 20:01:40 2016 +0000
@@ -111,6 +111,7 @@
 compiler.err.cant.inherit.from.anon                     # error for subclass of anonymous class
 compiler.misc.bad.class.file                            # class file is malformed
 compiler.misc.bad.const.pool.entry                      # constant pool entry has wrong type
+compiler.warn.access.to.member.from.serializable.lambda # in order to generate it we need to modify a restricted package
 
 # The following module-related messages will have to stay on the not-yet list for various reasons:
 compiler.warn.locn.unknown.file.on.module.path                # Never issued ATM (short circuited with an if (false))
--- a/langtools/test/tools/javac/diags/examples/WarnSerializableLambda.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/test/tools/javac/diags/examples/WarnSerializableLambda.java	Thu Oct 20 20:01:40 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -21,21 +21,24 @@
  * questions.
  */
 
-// key: compiler.warn.access.to.sensitive.member.from.serializable.element
-// options: -XDwarnOnAccessToSensitiveMembers
+// key: compiler.warn.access.to.member.from.serializable.element
+// options: -XDwarnOnAccessToMembers
 
 import java.io.Serializable;
 
 public class WarnSerializableLambda {
-    interface SAM {
-        void apply(String s);
-    }
-
     private void m1() {
-        SAM s = (SAM & Serializable) c -> {
-            packageField = "";
+        new SerializableClass() {
+            @Override
+            public void m() {
+                packageField = "";
+            }
         };
     }
 
     String packageField;
+
+    class SerializableClass implements Serializable {
+        public void m() {}
+    }
 }
--- a/langtools/test/tools/lib/toolbox/JavadocTask.java	Thu Oct 20 18:38:11 2016 +0000
+++ b/langtools/test/tools/lib/toolbox/JavadocTask.java	Thu Oct 20 20:01:40 2016 +0000
@@ -38,7 +38,9 @@
 import java.util.stream.Stream;
 
 import javax.tools.DocumentationTool.DocumentationTask;
+import javax.tools.DocumentationTool;
 import javax.tools.JavaFileManager;
+import javax.tools.JavaFileManager.Location;
 import javax.tools.JavaFileObject;
 import javax.tools.StandardJavaFileManager;
 import javax.tools.StandardLocation;
@@ -303,7 +305,8 @@
             if (fileManager == null)
                 fileManager = internalFileManager = jdtool.getStandardFileManager(null, null, null);
             if (outdir != null)
-                setLocationFromPaths(StandardLocation.CLASS_OUTPUT, Collections.singletonList(outdir));
+                setLocationFromPaths(DocumentationTool.Location.DOCUMENTATION_OUTPUT,
+                        Collections.singletonList(outdir));
             if (classpath != null)
                 setLocationFromPaths(StandardLocation.CLASS_PATH, classpath);
             if (sourcepath != null)
@@ -326,7 +329,7 @@
         }
     }
 
-    private void setLocationFromPaths(StandardLocation location, List<Path> files) throws IOException {
+    private void setLocationFromPaths(Location location, List<Path> files) throws IOException {
         if (!(fileManager instanceof StandardJavaFileManager))
             throw new IllegalStateException("not a StandardJavaFileManager");
         ((StandardJavaFileManager) fileManager).setLocationFromPaths(location, files);