6769027: Source line should be displayed immediately after the first diagnostic line
authormcimadamore
Fri, 13 Feb 2009 11:57:33 +0000
changeset 2085 4792e12a8ca2
parent 1998 29b961506419
child 2086 cca2603eab0b
6769027: Source line should be displayed immediately after the first diagnostic line Summary: Added support for customizing diagnostic output via API/command line flags Reviewed-by: jjg
langtools/src/share/classes/com/sun/tools/javac/api/DiagnosticFormatter.java
langtools/src/share/classes/com/sun/tools/javac/api/Messages.java
langtools/src/share/classes/com/sun/tools/javac/main/OptionName.java
langtools/src/share/classes/com/sun/tools/javac/main/RecognizedOptions.java
langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java
langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java
langtools/src/share/classes/com/sun/tools/javac/util/LayoutCharacters.java
langtools/src/share/classes/com/sun/tools/javac/util/Log.java
langtools/src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java
langtools/test/tools/javac/6304921/T6304921.out
langtools/test/tools/javac/6668794/badClass/Test.java
langtools/test/tools/javac/6668794/badSource/Test.out
langtools/test/tools/javac/6758789/T6758789b.out
langtools/test/tools/javac/Diagnostics/6769027/T6769027.java
langtools/test/tools/javac/Diagnostics/6769027/tester.properties
langtools/test/tools/javac/ExtendArray.out
langtools/test/tools/javac/T5048776b.out
langtools/test/tools/javac/T6214885a.out
langtools/test/tools/javac/T6214885b.out
langtools/test/tools/javac/T6230128.out
langtools/test/tools/javac/annotations/6365854/test1.out
langtools/test/tools/javac/cast/6557182/T6557182.out
langtools/test/tools/javac/cast/6665356/T6665356.out
langtools/test/tools/javac/cast/6795580/T6795580.out
langtools/test/tools/javac/generics/6207386/T6207386.out
langtools/test/tools/javac/generics/inference/6315770/T6315770.out
langtools/test/tools/javac/generics/inference/6718364/T6718364.out
langtools/test/tools/javac/generics/typevars/6680106/T6680106.out
langtools/test/tools/javac/missingSuperRecovery/MissingSuperRecovery.out
langtools/test/tools/javac/unicode/UnicodeNewline.out
--- a/langtools/src/share/classes/com/sun/tools/javac/api/DiagnosticFormatter.java	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/DiagnosticFormatter.java	Fri Feb 13 11:57:33 2009 +0000
@@ -25,16 +25,18 @@
 package com.sun.tools.javac.api;
 
 import java.util.Locale;
+import java.util.Set;
 import javax.tools.Diagnostic;
+import com.sun.tools.javac.api.DiagnosticFormatter.*;
 
 /**
- * Provides simple functionalities for javac diagnostic formatting
+ * Provides simple functionalities for javac diagnostic formatting.
  * @param <D> type of diagnostic handled by this formatter
  */
 public interface DiagnosticFormatter<D extends Diagnostic<?>> {
 
     /**
-     * Whether the source code output for this diagnostic is to be displayed
+     * Whether the source code output for this diagnostic is to be displayed.
      *
      * @param diag diagnostic to be formatted
      * @return true if the source line this diagnostic refers to is to be displayed
@@ -42,7 +44,7 @@
     boolean displaySource(D diag);
 
     /**
-     * Format the contents of a diagnostics
+     * Format the contents of a diagnostics.
      *
      * @param diag the diagnostic to be formatted
      * @param l locale object to be used for i18n
@@ -115,4 +117,97 @@
          */
         OFFSET
     }
+
+    /**
+     * Get a list of all the enabled verbosity options.
+     * @return verbosity options
+     */
+    public Configuration getConfiguration();
+    //where
+
+    /**
+     * This interface provides functionalities for tuning the output of a
+     * diagnostic formatter in multiple ways.
+     */
+    interface Configuration {
+        /**
+         * Configure the set of diagnostic parts that should be displayed
+         * by the formatter.
+         * @param options options to set
+         */
+        public void setVisible(Set<DiagnosticPart> visibleParts);
+
+        /**
+         * Retrieve the set of diagnostic parts that should be displayed
+         * by the formatter.
+         * @return verbosity options
+         */
+        public Set<DiagnosticPart> getVisible();
+
+        //where
+        /**
+         * A given diagnostic message can be divided into sub-parts each of which
+         * might/might not be displayed by the formatter, according to the
+         * current configuration settings.
+         */
+        public enum DiagnosticPart {
+            /**
+             * Short description of the diagnostic - usually one line long.
+             */
+            SUMMARY,
+            /**
+             * Longer description that provides additional details w.r.t. the ones
+             * in the diagnostic's description.
+             */
+            DETAILS,
+            /**
+             * Source line the diagnostic refers to (if applicable).
+             */
+            SOURCE,
+            /**
+             * Subdiagnostics attached to a given multiline diagnostic.
+             */
+            SUBDIAGNOSTICS,
+            /**
+             * JLS paragraph this diagnostic might refer to (if applicable).
+             */
+            JLS;
+        }
+
+        /**
+         * Set a limit for multiline diagnostics.
+         * Note: Setting a limit has no effect if multiline diagnostics are either
+         * fully enabled or disabled.
+         *
+         * @param limit the kind of limit to be set
+         * @param value the limit value
+         */
+        public void setMultilineLimit(MultilineLimit limit, int value);
+
+        /**
+         * Get a multiline diagnostic limit.
+         *
+         * @param limit the kind of limit to be retrieved
+         * @return limit value or -1 if no limit is set
+         */
+        public int getMultilineLimit(MultilineLimit limit);
+        //where
+        /**
+         * A multiline limit control the verbosity of multiline diagnostics
+         * either by setting a maximum depth of nested multidiagnostics,
+         * or by limiting the amount of subdiagnostics attached to a given
+         * diagnostic (or both).
+         */
+        public enum MultilineLimit {
+            /**
+             * Controls the maximum depth of nested multiline diagnostics.
+             */
+            DEPTH,
+            /**
+             * Controls the maximum amount of subdiagnostics that are part of a
+             * given multiline diagnostic.
+             */
+            LENGTH;
+        }
+    }
 }
--- a/langtools/src/share/classes/com/sun/tools/javac/api/Messages.java	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/Messages.java	Fri Feb 13 11:57:33 2009 +0000
@@ -44,7 +44,7 @@
     void add(String bundleName) throws MissingResourceException;
 
     /**
-     * Get a localized formatted string
+     * Get a localized formatted string.
      * @param l locale in which the text is to be localized
      * @param key locale-independent message key
      * @param args misc message arguments
--- a/langtools/src/share/classes/com/sun/tools/javac/main/OptionName.java	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/OptionName.java	Fri Feb 13 11:57:33 2009 +0000
@@ -40,6 +40,7 @@
     G_CUSTOM("-g:"),
     XLINT("-Xlint"),
     XLINT_CUSTOM("-Xlint:"),
+    DIAGS("-XDdiags="),
     NOWARN("-nowarn"),
     VERBOSE("-verbose"),
     DEPRECATION("-deprecation"),
--- a/langtools/src/share/classes/com/sun/tools/javac/main/RecognizedOptions.java	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/RecognizedOptions.java	Fri Feb 13 11:57:33 2009 +0000
@@ -145,6 +145,7 @@
         TARGET,
         VERSION,
         FULLVERSION,
+        DIAGS,
         HELP,
         A,
         X,
@@ -372,6 +373,21 @@
                 return super.process(options, option);
             }
         },
+        new HiddenOption(DIAGS) {
+            @Override
+            public boolean process(Options options, String option) {
+                Option xd = getOptions(helper, EnumSet.of(XD))[0];
+                option = option.substring(option.indexOf('=') + 1);
+                String diagsOption = option.contains("%") ?
+                    "-XDdiagsFormat=" :
+                    "-XDdiags=";
+                diagsOption += option;
+                if (xd.matches(diagsOption))
+                    return xd.process(options, diagsOption);
+                else
+                    return false;
+            }
+        },
         new Option(HELP,                                        "opt.help") {
             @Override
             public boolean process(Options options, String option) {
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Fri Feb 13 11:57:33 2009 +0000
@@ -907,16 +907,16 @@
 
 compiler.err.prob.found.req=\
 {0}\n\
-found   : {1}\n\
-required: {2}
+required: {2}\n\
+found:    {1}
 compiler.warn.prob.found.req=\
 {0}\n\
-found   : {1}\n\
-required: {2}
+required: {2}\n\
+found:    {1}
 compiler.err.prob.found.req.1=\
 {0} {3}\n\
-found   : {1}\n\
-required: {2}
+required: {2}\n\
+found:    {1}
 
 ## The following are all possible strings for the first argument ({0}) of the
 ## above strings.
@@ -951,8 +951,8 @@
 
 compiler.err.type.found.req=\
 unexpected type\n\
-found   : {0}\n\
-required: {1}
+required: {1}\n\
+found:    {0}
 
 ## The following are all possible strings for the first argument ({0}) of the
 ## above string.
@@ -1003,7 +1003,7 @@
 compiler.err.unexpected.type=\
 unexpected type\n\
 required: {0}\n\
-found   : {1}
+found:    {1}
 
 ## The first argument {0} is a "kindname" (e.g. 'constructor', 'field', etc.)
 ## The second argument {1} is the non-resolved symbol
@@ -1026,17 +1026,17 @@
 ## The sixth argument {5} is the location type
 compiler.err.cant.resolve.location=\
     cannot find symbol\n\
-    symbol  : {0} {1}\n\
+    symbol:   {0} {1}\n\
     location: {4} {5}
 
 compiler.err.cant.resolve.location.args=\
     cannot find symbol\n\
-    symbol  : {0} {1}({3})\n\
+    symbol:   {0} {1}({3})\n\
     location: {4} {5}
 
 compiler.err.cant.resolve.location.args.params=\
     cannot find symbol\n\
-    symbol  : {0} <{2}>{1}({3})\n\
+    symbol:   {0} <{2}>{1}({3})\n\
     location: {4} {5}
 
 ## The following are all possible string for "kindname".
--- a/langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java	Fri Feb 13 11:57:33 2009 +0000
@@ -24,16 +24,23 @@
  */
 package com.sun.tools.javac.util;
 
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.EnumSet;
+import java.util.HashMap;
 import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
 import javax.tools.JavaFileObject;
 
 import com.sun.tools.javac.api.DiagnosticFormatter;
+import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.DiagnosticPart;
+import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.MultilineLimit;
+import com.sun.tools.javac.api.DiagnosticFormatter.PositionKind;
 import com.sun.tools.javac.api.Formattable;
-import com.sun.tools.javac.api.DiagnosticFormatter.PositionKind;
 import com.sun.tools.javac.file.JavacFileManager;
+
 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticType.*;
-import static com.sun.tools.javac.util.LayoutCharacters.*;
 
 /**
  * This abstract class provides a basic implementation of the functionalities that should be provided
@@ -50,35 +57,19 @@
 public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter<JCDiagnostic> {
 
     /**
-     * JavacMessages object used by this formatter for i18n
+     * JavacMessages object used by this formatter for i18n.
      */
     protected JavacMessages messages;
-    protected boolean showSource;
+    private SimpleConfiguration config;
+    protected int depth = 0;
 
     /**
-     * Initialize an AbstractDiagnosticFormatter by setting its JavacMessages object
+     * Initialize an AbstractDiagnosticFormatter by setting its JavacMessages object.
      * @param messages
      */
-    protected AbstractDiagnosticFormatter(JavacMessages messages, Options options, boolean showSource) {
-        this.messages = messages;
-        this.showSource = options.get("showSource") == null ? showSource :
-                          options.get("showSource").equals("true");
-    }
-
-    protected AbstractDiagnosticFormatter(JavacMessages messages, boolean showSource) {
+    protected AbstractDiagnosticFormatter(JavacMessages messages, SimpleConfiguration config) {
         this.messages = messages;
-        this.showSource = showSource;
-    }
-
-    public String formatMessage(JCDiagnostic d, Locale l) {
-        //this code should rely on the locale settings but it's not! See RFE 6443132
-        StringBuilder buf = new StringBuilder();
-        Collection<String> args = formatArguments(d, l);
-        buf.append(localize(l, d.getCode(), args.toArray()));
-        if (d.isMultiline()) {
-            buf.append(formatSubdiagnostics(d, l));
-        }
-        return buf.toString();
+        this.config = config;
     }
 
     public String formatKind(JCDiagnostic d, Locale l) {
@@ -96,8 +87,8 @@
         assert (d.getPosition() != Position.NOPOS);
         return String.valueOf(getPosition(d, pk));
     }
-    //WHERE
-    public long getPosition(JCDiagnostic d, PositionKind pk) {
+    //where
+    private long getPosition(JCDiagnostic d, PositionKind pk) {
         switch (pk) {
             case START: return d.getIntStartPosition();
             case END: return d.getIntEndPosition();
@@ -138,8 +129,17 @@
      * @return string representation of the diagnostic argument
      */
     protected String formatArgument(JCDiagnostic d, Object arg, Locale l) {
-        if (arg instanceof JCDiagnostic)
-            return format((JCDiagnostic)arg, l);
+        if (arg instanceof JCDiagnostic) {
+            String s = null;
+            depth++;
+            try {
+                s = formatMessage((JCDiagnostic)arg, l);
+            }
+            finally {
+                depth--;
+            }
+            return s;
+        }
         else if (arg instanceof Iterable<?>) {
             return formatIterable(d, (Iterable<?>)arg, l);
         }
@@ -171,45 +171,74 @@
     }
 
     /**
-     * Format all the subdiagnostics attached to a given diagnostic
+     * Format all the subdiagnostics attached to a given diagnostic.
      *
      * @param d diagnostic whose subdiagnostics are to be formatted
      * @param l locale object to be used for i18n
+     * @return list of all string representations of the subdiagnostics
+     */
+    protected List<String> formatSubdiagnostics(JCDiagnostic d, Locale l) {
+        List<String> subdiagnostics = List.nil();
+        int maxDepth = config.getMultilineLimit(MultilineLimit.DEPTH);
+        if (maxDepth == -1 || depth < maxDepth) {
+            depth++;
+            try {
+                int maxCount = config.getMultilineLimit(MultilineLimit.LENGTH);
+                int count = 0;
+                for (JCDiagnostic d2 : d.getSubdiagnostics()) {
+                    if (maxCount == -1 || count < maxCount) {
+                        subdiagnostics = subdiagnostics.append(formatSubdiagnostic(d, d2, l));
+                        count++;
+                    }
+                    else
+                        break;
+                }
+            }
+            finally {
+                depth--;
+            }
+        }
+        return subdiagnostics;
+    }
+
+    /**
+     * Format a subdiagnostics attached to a given diagnostic.
+     *
+     * @param parent multiline diagnostic whose subdiagnostics is to be formatted
+     * @param sub subdiagnostic to be formatted
+     * @param l locale object to be used for i18n
      * @return string representation of the subdiagnostics
      */
-    protected String formatSubdiagnostics(JCDiagnostic d, Locale l) {
-        StringBuilder buf = new StringBuilder();
-        for (JCDiagnostic d2 : d.getSubdiagnostics()) {
-            buf.append('\n');
-            String subdiagMsg = format(d2, l);
-            buf.append(indent(subdiagMsg, DiagInc));
-        }
-        return buf.toString();
+    protected String formatSubdiagnostic(JCDiagnostic parent, JCDiagnostic sub, Locale l) {
+        return formatMessage(sub, l);
     }
 
     /** Format the faulty source code line and point to the error.
      *  @param d The diagnostic for which the error line should be printed
      */
-    protected String formatSourceLine(JCDiagnostic d) {
+    protected String formatSourceLine(JCDiagnostic d, int nSpaces) {
         StringBuilder buf = new StringBuilder();
         DiagnosticSource source = d.getDiagnosticSource();
         int pos = d.getIntPosition();
-        if (d.getIntPosition() != Position.NOPOS) {
-            String line = (source == null ? null : source.getLine(pos));
-            if (line == null)
-                return "";
-            buf.append(line+"\n");
-            int col = source.getColumnNumber(pos, false);
+        if (d.getIntPosition() == Position.NOPOS)
+            throw new AssertionError();
+        String line = (source == null ? null : source.getLine(pos));
+        if (line == null)
+            return "";
+        buf.append(indent(line, nSpaces));
+        int col = source.getColumnNumber(pos, false);
+        if (config.isCaretEnabled()) {
+            buf.append("\n");
             for (int i = 0; i < col - 1; i++)  {
                 buf.append((line.charAt(i) == '\t') ? "\t" : " ");
             }
-            buf.append("^");
-         }
-         return buf.toString();
+            buf.append(indent("^", nSpaces));
+        }
+        return buf.toString();
     }
 
     /**
-     * Converts a String into a locale-dependent representation accordingly to a given locale
+     * Converts a String into a locale-dependent representation accordingly to a given locale.
      *
      * @param l locale object to be used for i18n
      * @param key locale-independent key used for looking up in a resource file
@@ -221,7 +250,9 @@
     }
 
     public boolean displaySource(JCDiagnostic d) {
-        return showSource && d.getType() != FRAGMENT;
+        return config.getVisible().contains(DiagnosticPart.SOURCE) &&
+                d.getType() != FRAGMENT &&
+                d.getIntPosition() != Position.NOPOS;
     }
 
     /**
@@ -245,7 +276,7 @@
 
     /**
      * Indent a string by prepending a given amount of empty spaces to each line
-     * of the string
+     * of the string.
      *
      * @param s the string to be indented
      * @param nSpaces the amount of spaces that should be prepended to each line
@@ -263,4 +294,114 @@
         }
         return buf.toString();
     }
+
+    public SimpleConfiguration getConfiguration() {
+        return config;
+    }
+
+    static public class SimpleConfiguration implements Configuration {
+
+        protected Map<MultilineLimit, Integer> multilineLimits;
+        protected EnumSet<DiagnosticPart> visibleParts;
+        protected boolean caretEnabled;
+
+        public SimpleConfiguration(Set<DiagnosticPart> parts) {
+            multilineLimits = new HashMap<MultilineLimit, Integer>();
+            setVisible(parts);
+            setMultilineLimit(MultilineLimit.DEPTH, -1);
+            setMultilineLimit(MultilineLimit.LENGTH, -1);
+            setCaretEnabled(true);
+        }
+
+        @SuppressWarnings("fallthrough")
+        public SimpleConfiguration(Options options, Set<DiagnosticPart> parts) {
+            this(parts);
+            String showSource = null;
+            if ((showSource = options.get("showSource")) != null) {
+                if (showSource.equals("true"))
+                    visibleParts.add(DiagnosticPart.SOURCE);
+                else if (showSource.equals("false"))
+                    visibleParts.remove(DiagnosticPart.SOURCE);
+            }
+            String diagOpts = options.get("diags");
+            if (diagOpts != null) {//override -XDshowSource
+                Collection<String> args = Arrays.asList(diagOpts.split(","));
+                if (args.contains("short")) {
+                    visibleParts.remove(DiagnosticPart.DETAILS);
+                    visibleParts.remove(DiagnosticPart.SUBDIAGNOSTICS);
+                }
+                if (args.contains("source"))
+                    visibleParts.add(DiagnosticPart.SOURCE);
+                if (args.contains("-source"))
+                    visibleParts.remove(DiagnosticPart.SOURCE);
+            }
+            String multiPolicy = null;
+            if ((multiPolicy = options.get("multilinePolicy")) != null) {
+                if (multiPolicy.equals("disabled"))
+                    visibleParts.remove(DiagnosticPart.SUBDIAGNOSTICS);
+                else if (multiPolicy.startsWith("limit:")) {
+                    String limitString = multiPolicy.substring("limit:".length());
+                    String[] limits = limitString.split(":");
+                    try {
+                        switch (limits.length) {
+                            case 2: {
+                                if (!limits[1].equals("*"))
+                                    setMultilineLimit(MultilineLimit.DEPTH, Integer.parseInt(limits[1]));
+                            }
+                            case 1: {
+                                if (!limits[0].equals("*"))
+                                    setMultilineLimit(MultilineLimit.LENGTH, Integer.parseInt(limits[0]));
+                            }
+                        }
+                    }
+                    catch(NumberFormatException ex) {
+                        setMultilineLimit(MultilineLimit.DEPTH, -1);
+                        setMultilineLimit(MultilineLimit.LENGTH, -1);
+                    }
+                }
+            }
+            String showCaret = null;
+            if (((showCaret = options.get("showCaret")) != null) &&
+                showCaret.equals("false"))
+                    setCaretEnabled(false);
+            else
+                setCaretEnabled(true);
+        }
+
+        public int getMultilineLimit(MultilineLimit limit) {
+            return multilineLimits.get(limit);
+        }
+
+        public EnumSet<DiagnosticPart> getVisible() {
+            return EnumSet.copyOf(visibleParts);
+        }
+
+        public void setMultilineLimit(MultilineLimit limit, int value) {
+            multilineLimits.put(limit, value < -1 ? -1 : value);
+        }
+
+
+        public void setVisible(Set<DiagnosticPart> diagParts) {
+            visibleParts = EnumSet.copyOf(diagParts);
+        }
+
+        /**
+         * Shows a '^' sign under the source line displayed by the formatter
+         * (if applicable).
+         *
+         * @param caretEnabled if true enables caret
+         */
+        public void setCaretEnabled(boolean caretEnabled) {
+            this.caretEnabled = caretEnabled;
+        }
+
+        /**
+         * Tells whether the caret display is active or not.
+         *
+         * @param caretEnabled if true the caret is enabled
+         */
+        public boolean isCaretEnabled() {
+            return caretEnabled;
+        }
+    }
 }
--- a/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java	Fri Feb 13 11:57:33 2009 +0000
@@ -25,13 +25,20 @@
 
 package com.sun.tools.javac.util;
 
+import java.util.Collection;
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
+import java.util.regex.Matcher;
 import javax.tools.JavaFileObject;
 
-import static com.sun.tools.javac.util.BasicDiagnosticFormatter.BasicFormatKind.*;
+import com.sun.tools.javac.util.AbstractDiagnosticFormatter.SimpleConfiguration;
+import com.sun.tools.javac.util.BasicDiagnosticFormatter.BasicConfiguration;
+
 import static com.sun.tools.javac.api.DiagnosticFormatter.PositionKind.*;
+import static com.sun.tools.javac.util.BasicDiagnosticFormatter.BasicConfiguration.*;
+import static com.sun.tools.javac.util.LayoutCharacters.*;
 
 /**
  * A basic formatter for diagnostic messages.
@@ -53,7 +60,7 @@
  */
 public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter {
 
-    protected Map<BasicFormatKind, String> availableFormats;
+    protected int currentIndentation = 0;
 
     /**
      * Create a basic formatter based on the supplied options.
@@ -62,21 +69,8 @@
      * @param msgs JavacMessages object used for i18n
      */
     @SuppressWarnings("fallthrough")
-    BasicDiagnosticFormatter(Options opts, JavacMessages msgs) {
-        super(msgs, opts, true);
-        initAvailableFormats();
-        String fmt = opts.get("diags");
-        if (fmt != null) {
-            String[] formats = fmt.split("\\|");
-            switch (formats.length) {
-                case 3:
-                    availableFormats.put(DEFAULT_CLASS_FORMAT, formats[2]);
-                case 2:
-                    availableFormats.put(DEFAULT_NO_POS_FORMAT, formats[1]);
-                default:
-                    availableFormats.put(DEFAULT_POS_FORMAT, formats[0]);
-            }
-        }
+    public BasicDiagnosticFormatter(Options options, JavacMessages msgs) {
+        super(msgs, new BasicConfiguration(options));
     }
 
     /**
@@ -85,15 +79,7 @@
      * @param msgs JavacMessages object used for i18n
      */
     public BasicDiagnosticFormatter(JavacMessages msgs) {
-        super(msgs, true);
-        initAvailableFormats();
-    }
-
-    public void initAvailableFormats() {
-        availableFormats = new HashMap<BasicFormatKind, String>();
-        availableFormats.put(DEFAULT_POS_FORMAT, "%f:%l:%_%t%m");
-        availableFormats.put(DEFAULT_NO_POS_FORMAT, "%p%m");
-        availableFormats.put(DEFAULT_CLASS_FORMAT, "%f:%_%t%m");
+        super(msgs, new BasicConfiguration());
     }
 
     public String format(JCDiagnostic d, Locale l) {
@@ -110,10 +96,55 @@
             }
             buf.append(meta ? formatMeta(c, d, l) : String.valueOf(c));
         }
-        if (displaySource(d)) {
-            buf.append("\n" + formatSourceLine(d));
+        if (depth == 0)
+            return addSourceLineIfNeeded(d, buf.toString());
+        else
+            return buf.toString();
+    }
+
+    public String formatMessage(JCDiagnostic d, Locale l) {
+        int prevIndentation = currentIndentation;
+        try {
+            StringBuilder buf = new StringBuilder();
+            Collection<String> args = formatArguments(d, l);
+            String msg = localize(l, d.getCode(), args.toArray());
+            String[] lines = msg.split("\n");
+            if (getConfiguration().getVisible().contains(DiagnosticPart.SUMMARY)) {
+                currentIndentation += getConfiguration().getIndentation(DiagnosticPart.SUMMARY);
+                buf.append(indent(lines[0], currentIndentation)); //summary
+            }
+            if (lines.length > 1 && getConfiguration().getVisible().contains(DiagnosticPart.DETAILS)) {
+                currentIndentation += getConfiguration().getIndentation(DiagnosticPart.DETAILS);
+                for (int i = 1;i < lines.length; i++) {
+                    buf.append("\n" + indent(lines[i], currentIndentation));
+                }
+            }
+            if (d.isMultiline() && getConfiguration().getVisible().contains(DiagnosticPart.SUBDIAGNOSTICS)) {
+                currentIndentation += getConfiguration().getIndentation(DiagnosticPart.SUBDIAGNOSTICS);
+                for (String sub : formatSubdiagnostics(d, l)) {
+                    buf.append("\n" + sub);
+                }
+            }
+            return buf.toString();
         }
-        return buf.toString();
+        finally {
+            currentIndentation = prevIndentation;
+        }
+    }
+
+    protected String addSourceLineIfNeeded(JCDiagnostic d, String msg) {
+        if (!displaySource(d))
+            return msg;
+        else {
+            BasicConfiguration conf = getConfiguration();
+            int indentSource = conf.getIndentation(DiagnosticPart.SOURCE);
+            String sourceLine = "\n" + formatSourceLine(d, indentSource);
+            boolean singleLine = msg.indexOf("\n") == -1;
+            if (singleLine || getConfiguration().getSourcePosition() == SourcePosition.BOTTOM)
+                return msg + sourceLine;
+            else
+                return msg.replaceFirst("\n", Matcher.quoteReplacement(sourceLine) + "\n");
+        }
     }
 
     protected String formatMeta(char c, JCDiagnostic d, Locale l) {
@@ -164,34 +195,199 @@
 
     private String selectFormat(JCDiagnostic d) {
         DiagnosticSource source = d.getDiagnosticSource();
-        String format = availableFormats.get(DEFAULT_NO_POS_FORMAT);
+        String format = getConfiguration().getFormat(BasicFormatKind.DEFAULT_NO_POS_FORMAT);
         if (source != null) {
             if (d.getIntPosition() != Position.NOPOS) {
-                format = availableFormats.get(DEFAULT_POS_FORMAT);
+                format = getConfiguration().getFormat(BasicFormatKind.DEFAULT_POS_FORMAT);
             } else if (source.getFile() != null &&
                        source.getFile().getKind() == JavaFileObject.Kind.CLASS) {
-                format = availableFormats.get(DEFAULT_CLASS_FORMAT);
+                format = getConfiguration().getFormat(BasicFormatKind.DEFAULT_CLASS_FORMAT);
             }
         }
         return format;
     }
 
-    /**
-     * This enum contains all the kinds of formatting patterns supported
-     * by a basic diagnostic formatter.
-     */
-    public enum BasicFormatKind {
+    @Override
+    public BasicConfiguration getConfiguration() {
+        return (BasicConfiguration)super.getConfiguration();
+    }
+
+    static public class BasicConfiguration extends SimpleConfiguration {
+
+        protected Map<DiagnosticPart, Integer> indentationLevels;
+        protected Map<BasicFormatKind, String> availableFormats;
+        protected SourcePosition sourcePosition;
+
+        @SuppressWarnings("fallthrough")
+        public BasicConfiguration(Options options) {
+            super(options, EnumSet.of(DiagnosticPart.SUMMARY,
+                            DiagnosticPart.DETAILS,
+                            DiagnosticPart.SUBDIAGNOSTICS,
+                            DiagnosticPart.SOURCE));
+            initFormat();
+            initIndentation();
+            String fmt = options.get("diagsFormat");
+            if (fmt != null) {
+                String[] formats = fmt.split("\\|");
+                switch (formats.length) {
+                    case 3:
+                        setFormat(BasicFormatKind.DEFAULT_CLASS_FORMAT, formats[2]);
+                    case 2:
+                        setFormat(BasicFormatKind.DEFAULT_NO_POS_FORMAT, formats[1]);
+                    default:
+                        setFormat(BasicFormatKind.DEFAULT_POS_FORMAT, formats[0]);
+                }
+            }
+            String sourcePosition = null;
+            if ((((sourcePosition = options.get("sourcePosition")) != null)) &&
+                    sourcePosition.equals("bottom"))
+                    setSourcePosition(SourcePosition.BOTTOM);
+            else
+                setSourcePosition(SourcePosition.AFTER_SUMMARY);
+            String indent = options.get("diagsIndentation");
+            if (indent != null) {
+                String[] levels = indent.split("\\|");
+                try {
+                    switch (levels.length) {
+                        case 5:
+                            setIndentation(DiagnosticPart.JLS,
+                                    Integer.parseInt(levels[4]));
+                        case 4:
+                            setIndentation(DiagnosticPart.SUBDIAGNOSTICS,
+                                    Integer.parseInt(levels[3]));
+                        case 3:
+                            setIndentation(DiagnosticPart.SOURCE,
+                                    Integer.parseInt(levels[2]));
+                        case 2:
+                            setIndentation(DiagnosticPart.DETAILS,
+                                    Integer.parseInt(levels[1]));
+                        default:
+                            setIndentation(DiagnosticPart.SUMMARY,
+                                    Integer.parseInt(levels[0]));
+                    }
+                }
+                catch (NumberFormatException ex) {
+                    initIndentation();
+                }
+            }
+        }
+
+        public BasicConfiguration() {
+            super(EnumSet.of(DiagnosticPart.SUMMARY,
+                  DiagnosticPart.DETAILS,
+                  DiagnosticPart.SUBDIAGNOSTICS,
+                  DiagnosticPart.SOURCE));
+            initFormat();
+            initIndentation();
+        }
+        //where
+        private void initFormat() {
+            availableFormats = new HashMap<BasicFormatKind, String>();
+            setFormat(BasicFormatKind.DEFAULT_POS_FORMAT, "%f:%l:%_%t%m");
+            setFormat(BasicFormatKind.DEFAULT_NO_POS_FORMAT, "%p%m");
+            setFormat(BasicFormatKind.DEFAULT_CLASS_FORMAT, "%f:%_%t%m");
+        }
+        //where
+        private void initIndentation() {
+            indentationLevels = new HashMap<DiagnosticPart, Integer>();
+            setIndentation(DiagnosticPart.SUMMARY, 0);
+            setIndentation(DiagnosticPart.DETAILS, DetailsInc);
+            setIndentation(DiagnosticPart.SUBDIAGNOSTICS, DiagInc);
+            setIndentation(DiagnosticPart.SOURCE, 0);
+        }
+
         /**
-        * A format string to be used for diagnostics with a given position.
-        */
-        DEFAULT_POS_FORMAT,
+         * Get the amount of spaces for a given indentation kind
+         * @param diagPart the diagnostic part for which the indentation is
+         * to be retrieved
+         * @return the amount of spaces used for the specified indentation kind
+         */
+        public int getIndentation(DiagnosticPart diagPart) {
+            return indentationLevels.get(diagPart);
+        }
+
+        /**
+         * Set the indentation level for various element of a given diagnostic -
+         * this might lead to more readable diagnostics
+         *
+         * @param indentationKind kind of indentation to be set
+         * @param nSpaces amount of spaces for the specified diagnostic part
+         */
+        public void setIndentation(DiagnosticPart diagPart, int nSpaces) {
+            indentationLevels.put(diagPart, nSpaces);
+        }
+
+        /**
+         * Set the source line positioning used by this formatter
+         *
+         * @param sourcePos a positioning value for source line
+         */
+        public void setSourcePosition(SourcePosition sourcePos) {
+            sourcePosition = sourcePos;
+        }
+
+        /**
+         * Get the source line positioning used by this formatter
+         *
+         * @return the positioning value used by this formatter
+         */
+        public SourcePosition getSourcePosition() {
+            return sourcePosition;
+        }
+        //where
         /**
-        * A format string to be used for diagnostics without a given position.
-        */
-        DEFAULT_NO_POS_FORMAT,
+         * A source positioning value controls the position (within a given
+         * diagnostic message) in which the source line the diagnostic refers to
+         * should be displayed (if applicable)
+         */
+        public enum SourcePosition {
+            /**
+             * Source line is displayed after the diagnostic message
+             */
+            BOTTOM,
+            /**
+             * Source line is displayed after the first line of the diagnostic
+             * message
+             */
+            AFTER_SUMMARY;
+        }
+
+        /**
+         * Set a metachar string for a specific format
+         *
+         * @param kind the format kind to be set
+         * @param s the metachar string specifying the format
+         */
+        public void setFormat(BasicFormatKind kind, String s) {
+            availableFormats.put(kind, s);
+        }
+
         /**
-        * A format string to be used for diagnostics regarding classfiles
-        */
-        DEFAULT_CLASS_FORMAT;
+         * Get a metachar string for a specific format
+         *
+         * @param sourcePos a positioning value for source line
+         */
+        public String getFormat(BasicFormatKind kind) {
+            return availableFormats.get(kind);
+        }
+        //where
+        /**
+         * This enum contains all the kinds of formatting patterns supported
+         * by a basic diagnostic formatter.
+         */
+        public enum BasicFormatKind {
+            /**
+            * A format string to be used for diagnostics with a given position.
+            */
+            DEFAULT_POS_FORMAT,
+            /**
+            * A format string to be used for diagnostics without a given position.
+            */
+            DEFAULT_NO_POS_FORMAT,
+            /**
+            * A format string to be used for diagnostics regarding classfiles
+            */
+            DEFAULT_CLASS_FORMAT;
+        }
     }
 }
--- a/langtools/src/share/classes/com/sun/tools/javac/util/LayoutCharacters.java	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/LayoutCharacters.java	Fri Feb 13 11:57:33 2009 +0000
@@ -39,9 +39,13 @@
      */
     final static int TabInc = 8;
 
-    /** Diagnostic standard indentation
+    /** Standard indentation for subdiagnostics
      */
-    final static int DiagInc = 2;
+    final static int DiagInc = 4;
+
+    /** Standard indentation for additional diagnostic lines
+     */
+    final static int DetailsInc = 2;
 
     /** Tabulator character.
      */
--- a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java	Fri Feb 13 11:57:33 2009 +0000
@@ -93,17 +93,17 @@
     protected DiagnosticListener<? super JavaFileObject> diagListener;
 
     /**
-     * Formatter for diagnostics
+     * Formatter for diagnostics.
      */
     private DiagnosticFormatter<JCDiagnostic> diagFormatter;
 
     /**
-     * Keys for expected diagnostics
+     * Keys for expected diagnostics.
      */
     public Set<String> expectDiagKeys;
 
     /**
-     * JavacMessages object used for localization
+     * JavacMessages object used for localization.
      */
     private JavacMessages messages;
 
@@ -206,6 +206,18 @@
         return source == null ? null : source.getFile();
     }
 
+    /** Get the current diagnostic formatter.
+     */
+    public DiagnosticFormatter<JCDiagnostic> getDiagnosticFormatter() {
+        return diagFormatter;
+    }
+
+    /** Set the current diagnostic formatter.
+     */
+    public void setDiagnosticFormatter(DiagnosticFormatter<JCDiagnostic> diagFormatter) {
+        this.diagFormatter = diagFormatter;
+    }
+
     /** Flush the logs
      */
     public void flush() {
--- a/langtools/src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java	Fri Feb 13 11:57:33 2009 +0000
@@ -24,9 +24,14 @@
  */
 package com.sun.tools.javac.util;
 
+import java.util.Collection;
+import java.util.EnumSet;
 import java.util.Locale;
 
+import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.*;
 import com.sun.tools.javac.api.Formattable;
+import com.sun.tools.javac.util.AbstractDiagnosticFormatter.SimpleConfiguration;
+
 import static com.sun.tools.javac.api.DiagnosticFormatter.PositionKind.*;
 
 /**
@@ -35,14 +40,17 @@
  * or not the source name and position are set. This formatter provides a standardized, localize-independent
  * implementation of a diagnostic formatter; as such, this formatter is best suited for testing purposes.
  */
-public class RawDiagnosticFormatter extends AbstractDiagnosticFormatter {
+public final class RawDiagnosticFormatter extends AbstractDiagnosticFormatter {
 
     /**
      * Create a formatter based on the supplied options.
      * @param msgs
      */
-    public RawDiagnosticFormatter(Options opts) {
-        super(null, opts, false);
+    public RawDiagnosticFormatter(Options options) {
+        super(null, new SimpleConfiguration(options,
+                EnumSet.of(DiagnosticPart.SUMMARY,
+                        DiagnosticPart.DETAILS,
+                        DiagnosticPart.SUBDIAGNOSTICS)));
     }
 
     //provide common default formats
@@ -62,7 +70,7 @@
             buf.append(' ');
             buf.append(formatMessage(d, null));
             if (displaySource(d))
-                buf.append("\n" + formatSourceLine(d));
+                buf.append("\n" + formatSourceLine(d, 0));
             return buf.toString();
         }
         catch (Exception e) {
@@ -71,6 +79,32 @@
         }
     }
 
+    public String formatMessage(JCDiagnostic d, Locale l) {
+        StringBuilder buf = new StringBuilder();
+        Collection<String> args = formatArguments(d, l);
+        buf.append(d.getCode());
+        String sep = ": ";
+        for (Object o : args) {
+            buf.append(sep);
+            buf.append(o);
+            sep = ", ";
+        }
+        if (d.isMultiline() && getConfiguration().getVisible().contains(DiagnosticPart.SUBDIAGNOSTICS)) {
+            List<String> subDiags = formatSubdiagnostics(d, null);
+            if (subDiags.nonEmpty()) {
+                sep = "";
+                buf.append(",{");
+                for (String sub : formatSubdiagnostics(d, null)) {
+                    buf.append(sep);
+                    buf.append("(" + sub + ")");
+                    sep = ",";
+                }
+                buf.append('}');
+            }
+        }
+        return buf.toString();
+    }
+
     @Override
     protected String formatArgument(JCDiagnostic diag, Object arg, Locale l) {
         String s;
@@ -83,31 +117,4 @@
         else
             return s;
     }
-
-    @Override
-    protected String formatSubdiagnostics(JCDiagnostic d, Locale l) {
-        StringBuilder buf = new StringBuilder();
-        String sep = "";
-        buf.append(",{");
-        for (JCDiagnostic d2 : d.getSubdiagnostics()) {
-            buf.append(sep);
-            buf.append("(" + format(d2, l) + ")");
-            sep = ",";
-        }
-        buf.append('}');
-        return buf.toString();
-    }
-
-    @Override
-    protected String localize(Locale l, String s, Object... args) {
-        StringBuffer buf = new StringBuffer();
-        buf.append(s);
-        String sep = ": ";
-        for (Object o : args) {
-            buf.append(sep);
-            buf.append(o);
-            sep = ", ";
-        }
-        return buf.toString();
-    }
 }
--- a/langtools/test/tools/javac/6304921/T6304921.out	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/test/tools/javac/6304921/T6304921.out	Fri Feb 13 11:57:33 2009 +0000
@@ -1,18 +1,18 @@
 T6304921.java:671/671/680: warning: [rawtypes] found raw type: java.util.ArrayList
-missing type parameters for generic class java.util.ArrayList<E>
         List<Integer> list = new ArrayList();
                                  ^
+  missing type parameters for generic class java.util.ArrayList<E>
 T6304921.java:667/667/682: warning: [unchecked] unchecked conversion
-found   : java.util.ArrayList
-required: java.util.List<java.lang.Integer>
         List<Integer> list = new ArrayList();
                              ^
+  required: java.util.List<java.lang.Integer>
+  found:    java.util.ArrayList
 error: warnings found and -Werror specified
 T6304921.java:727/733/737: cannot find symbol
-symbol  : variable orr
-location: class java.lang.System
         System.orr.println("abc"); // name not found
               ^
+  symbol:   variable orr
+  location: class java.lang.System
 T6304921.java:812/816/822: operator + cannot be applied to int,boolean
         return 123 + true; // bad binary expression
                    ^
--- a/langtools/test/tools/javac/6668794/badClass/Test.java	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/test/tools/javac/6668794/badClass/Test.java	Fri Feb 13 11:57:33 2009 +0000
@@ -54,8 +54,8 @@
             throw new Error("no diagnostics generated");
 
         String expected = "B.java:6:6: compiler.err.cant.access: p.A, " +
-            "(- compiler.misc.bad.class.file.header: A.class, " +
-            "(- compiler.misc.class.file.wrong.class: q.A))";
+            "(compiler.misc.bad.class.file.header: A.class, " +
+            "(compiler.misc.class.file.wrong.class: q.A))";
 
         if (!out[0].equals(expected)) {
             System.err.println("expected: " + expected);
--- a/langtools/test/tools/javac/6668794/badSource/Test.out	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/test/tools/javac/6668794/badSource/Test.out	Fri Feb 13 11:57:33 2009 +0000
@@ -1,1 +1,1 @@
-Test.java:10:6: compiler.err.cant.access: p.A, (- compiler.misc.bad.source.file.header: A.java, (- compiler.misc.file.doesnt.contain.class: p.A))
+Test.java:10:6: compiler.err.cant.access: p.A, (compiler.misc.bad.source.file.header: A.java, (compiler.misc.file.doesnt.contain.class: p.A))
--- a/langtools/test/tools/javac/6758789/T6758789b.out	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/test/tools/javac/6758789/T6758789b.out	Fri Feb 13 11:57:33 2009 +0000
@@ -1,4 +1,4 @@
-T6758789b.java:39:11: compiler.warn.prob.found.req: (- compiler.misc.unchecked.assign), T6758789a.Foo, T6758789a.Foo<X>
+T6758789b.java:39:11: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T6758789a.Foo, T6758789a.Foo<X>
 T6758789b.java:39:10: compiler.warn.unchecked.meth.invocation.applied: kindname.method, m, T6758789a.Foo<X>, T6758789a.Foo, kindname.class, T6758789a
 - compiler.err.warnings.and.werror
 1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/Diagnostics/6769027/T6769027.java	Fri Feb 13 11:57:33 2009 +0000
@@ -0,0 +1,499 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug     6769027
+ * @summary Source line should be displayed immediately after the first diagnostic line
+ * @author  Maurizio Cimadamore
+ * @run main/othervm T6769027
+ */
+import java.net.URI;
+import java.util.regex.Matcher;
+import javax.tools.*;
+import com.sun.tools.javac.util.*;
+
+public class T6769027 {
+
+    enum OutputKind {
+        RAW("rawDiagnostics","rawDiagnostics"),
+        BASIC("","");
+
+        String key;
+        String value;
+
+        void init(Options opts) {
+            opts.put(key, value);
+        }
+
+        OutputKind(String key, String value) {
+            this.key = key;
+            this.value = value;
+        }
+    }
+
+    enum CaretKind {
+        DEFAULT("", ""),
+        SHOW("showCaret","true"),
+        HIDE("showCaret","false");
+
+        String key;
+        String value;
+
+        void init(Options opts) {
+            opts.put(key, value);
+        }
+
+        CaretKind(String key, String value) {
+            this.key = key;
+            this.value = value;
+        }
+
+        boolean isEnabled() {
+            return this == DEFAULT || this == SHOW;
+        }
+    }
+
+    enum SourceLineKind {
+        DEFAULT("", ""),
+        AFTER_SUMMARY("sourcePosition", "top"),
+        BOTTOM("sourcePosition", "bottom");
+
+        String key;
+        String value;
+
+        void init(Options opts) {
+            opts.put(key, value);
+        }
+
+        SourceLineKind(String key, String value) {
+            this.key = key;
+            this.value = value;
+        }
+
+        boolean isAfterSummary() {
+            return this == DEFAULT || this == AFTER_SUMMARY;
+        }
+    }
+
+    enum XDiagsSource {
+        DEFAULT(""),
+        SOURCE("source"),
+        NO_SOURCE("-source");
+
+        String flag;
+
+        void init(Options opts) {
+            if (this != DEFAULT) {
+                String flags = opts.get("diags");
+                flags = flags == null ? flag : flags + "," + flag;
+                opts.put("diags", flags);
+            }
+        }
+
+        XDiagsSource(String flag) {
+            this.flag = flag;
+        }
+
+        String getOutput(CaretKind caretKind, IndentKind indent, OutputKind outKind) {
+            String spaces = (outKind == OutputKind.BASIC) ? indent.string : "";
+            return "\n" + spaces + "This is a source line" +
+                   (caretKind.isEnabled() ? "\n" + spaces + "     ^" : "");
+        }
+    }
+
+    enum XDiagsCompact {
+        DEFAULT(""),
+        COMPACT("short"),
+        NO_COMPACT("-short");
+
+        String flag;
+
+        void init(Options opts) {
+            if (this != DEFAULT) {
+                String flags = opts.get("diags");
+                flags = flags == null ? flag : flags + "," + flag;
+                opts.put("diags", flags);
+            }
+        }
+
+        XDiagsCompact(String flag) {
+            this.flag = flag;
+        }
+    }
+
+    enum ErrorKind {
+        SINGLE("single",
+            "compiler.err.single: Hello!",
+            "KXThis is a test error message Hello!"),
+        DOUBLE("double",
+            "compiler.err.double: Hello!",
+            "KXThis is a test error message.\n" +
+            "KXYThis is another line of the above error message Hello!");
+
+        String key;
+        String rawOutput;
+        String nonRawOutput;
+
+        String key() {
+            return key;
+        }
+
+        ErrorKind(String key, String rawOutput, String nonRawOutput) {
+            this.key = key;
+            this.rawOutput = rawOutput;
+            this.nonRawOutput = nonRawOutput;
+        }
+
+        String getOutput(OutputKind outKind, IndentKind summaryIndent, IndentKind detailsIndent) {
+            return outKind == OutputKind.RAW ?
+                rawOutput :
+                nonRawOutput.replace("X", summaryIndent.string).replace("Y", detailsIndent.string).replace("K", "");
+        }
+
+        String getOutput(OutputKind outKind, IndentKind summaryIndent, IndentKind detailsIndent, String indent) {
+            return outKind == OutputKind.RAW ?
+                rawOutput :
+                nonRawOutput.replace("X", summaryIndent.string).replace("Y", detailsIndent.string).replace("K", indent);
+        }
+    }
+
+    enum MultilineKind {
+        NONE(0),
+        DOUBLE(1),
+        NESTED(2),
+        DOUBLE_NESTED(3);
+
+        static String[][] rawTemplates = {
+            {"", ",{(E),(E)}", ",{(E,{(E)})}", ",{(E,{(E)}),(E,{(E)})}"}, //ENABLED
+            {"", "", "", "",""}, //DISABLED
+            {"", ",{(E)}", ",{(E,{(E)})}", ",{(E,{(E)})}"}, //LIMIT_LENGTH
+            {"", ",{(E),(E)}", ",{(E)}", ",{(E),(E)}"}, //LIMIT_DEPTH
+            {"", ",{(E)}", ",{(E)}", ",{(E)}"}}; //LIMIT_BOTH
+
+        static String[][] basicTemplates = {
+            {"", "\nE\nE", "\nE\nQ", "\nE\nQ\nE\nQ"}, //ENABLED
+            {"", "", "", "",""}, //DISABLED
+            {"", "\nE", "\nE\nQ", "\nE\nQ"}, //LIMIT_LENGTH
+            {"", "\nE\nE", "\nE", "\nE\nE"}, //LIMIT_DEPTH
+            {"", "\nE", "\nE", "\nE"}}; //LIMIT_BOTH
+
+
+        int index;
+
+        MultilineKind (int index) {
+            this.index = index;
+        }
+
+        boolean isDouble() {
+            return this == DOUBLE || this == DOUBLE_NESTED;
+        }
+
+        boolean isNested() {
+            return this == NESTED || this == DOUBLE_NESTED;
+        }
+
+        String getOutput(OutputKind outKind, ErrorKind errKind, MultilinePolicy policy,
+                IndentKind summaryIndent, IndentKind detailsIndent, IndentKind multiIndent) {
+            String constIndent = (errKind == ErrorKind.DOUBLE) ?
+                summaryIndent.string + detailsIndent.string :
+                summaryIndent.string;
+            constIndent += multiIndent.string;
+
+            String errMsg1 = errKind.getOutput(outKind, summaryIndent, detailsIndent, constIndent);
+            String errMsg2 = errKind.getOutput(outKind, summaryIndent, detailsIndent, constIndent + constIndent);
+
+            errMsg1 = errMsg1.replaceAll("compiler.err", "compiler.misc");
+            errMsg1 = errMsg1.replaceAll("error message", "subdiagnostic");
+            errMsg2 = errMsg2.replaceAll("compiler.err", "compiler.misc");
+            errMsg2 = errMsg2.replaceAll("error message", "subdiagnostic");
+
+            String template = outKind == OutputKind.RAW ?
+                rawTemplates[policy.index][index] :
+                basicTemplates[policy.index][index];
+
+            template = template.replaceAll("E", errMsg1);
+            return template.replaceAll("Q", errMsg2);
+        }
+    }
+
+    enum MultilinePolicy {
+        ENABLED(0, "multilinePolicy", "enabled"),
+        DISABLED(1, "multilinePolicy", "disabled"),
+        LIMIT_LENGTH(2, "multilinePolicy", "limit:1:*"),
+        LIMIT_DEPTH(3, "multilinePolicy", "limit:*:1"),
+        LIMIT_BOTH(4, "multilinePolicy", "limit:1:1");
+
+        String name;
+        String value;
+        int index;
+
+        MultilinePolicy(int index, String name, String value) {
+            this.name = name;
+            this.value = value;
+            this.index = index;
+        }
+
+        void init(Options options) {
+            options.put(name, value);
+        }
+    }
+
+    enum PositionKind {
+        NOPOS(Position.NOPOS, "- ", "error: "),
+        POS(5, "/Test.java:1:6: ", "myfo:/Test.java:1: ");
+
+        int pos;
+        String rawOutput;
+        String nonRawOutput;
+
+        PositionKind(int pos, String rawOutput, String nonRawOutput) {
+            this.pos = pos;
+            this.rawOutput = rawOutput;
+            this.nonRawOutput = nonRawOutput;
+        }
+
+        JCDiagnostic.DiagnosticPosition pos() {
+            return new JCDiagnostic.SimpleDiagnosticPosition(pos);
+        }
+
+        String getOutput(OutputKind outputKind) {
+            return outputKind == OutputKind.RAW ?
+                rawOutput :
+                nonRawOutput;
+        }
+    }
+
+    static class MyFileObject extends SimpleJavaFileObject {
+        private String text;
+        public MyFileObject(String text) {
+            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+            this.text = text;
+        }
+        @Override
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return text;
+        }
+    }
+
+    enum IndentKind {
+        NONE(""),
+        CUSTOM("   ");
+
+        String string;
+
+        IndentKind(String indent) {
+            string = indent;
+        }
+    }
+
+    class MyLog extends Log {
+        MyLog(Context ctx) {
+            super(ctx);
+        }
+
+        @Override
+        protected java.io.PrintWriter getWriterForDiagnosticType(JCDiagnostic.DiagnosticType dt) {
+            return new java.io.PrintWriter(System.out);
+        }
+
+        @Override
+        protected boolean shouldReport(JavaFileObject jfo, int pos) {
+            return true;
+        }
+    }
+
+    int nerrors = 0;
+
+    void exec(OutputKind outputKind, ErrorKind errorKind, MultilineKind multiKind,
+            MultilinePolicy multiPolicy, PositionKind posKind, XDiagsSource xdiagsSource,
+            XDiagsCompact xdiagsCompact, CaretKind caretKind, SourceLineKind sourceLineKind,
+            IndentKind summaryIndent, IndentKind detailsIndent, IndentKind sourceIndent,
+            IndentKind subdiagsIndent) {
+        Context ctx = new Context();
+        Options options = Options.instance(ctx);
+        outputKind.init(options);
+        multiPolicy.init(options);
+        xdiagsSource.init(options);
+        xdiagsCompact.init(options);
+        caretKind.init(options);
+        sourceLineKind.init(options);
+        String indentString = "";
+        indentString = (summaryIndent == IndentKind.CUSTOM) ? "3" : "0";
+        indentString += (detailsIndent == IndentKind.CUSTOM) ? "|3" : "|0";
+        indentString += (sourceIndent == IndentKind.CUSTOM) ? "|3" : "|0";
+        indentString += (subdiagsIndent == IndentKind.CUSTOM) ? "|3" : "|0";
+        options.put("diagsIndentation", indentString);
+        MyLog log = new MyLog(ctx);
+        JavacMessages messages = JavacMessages.instance(ctx);
+        messages.add("tester");
+        JCDiagnostic.Factory diags = JCDiagnostic.Factory.instance(ctx);
+        log.useSource(new MyFileObject("This is a source line"));
+        JCDiagnostic d = diags.error(log.currentSource(),
+            posKind.pos(),
+            errorKind.key(), "Hello!");
+        if (multiKind != MultilineKind.NONE) {
+            JCDiagnostic sub = diags.fragment(errorKind.key(), "Hello!");
+            if (multiKind.isNested())
+                sub = new JCDiagnostic.MultilineDiagnostic(sub, List.of(sub));
+            List<JCDiagnostic> subdiags = multiKind.isDouble() ?
+                List.of(sub, sub) :
+                List.of(sub);
+            d = new JCDiagnostic.MultilineDiagnostic(d, subdiags);
+        }
+        String diag = log.getDiagnosticFormatter().format(d, messages.getCurrentLocale());
+        checkOutput(diag,
+                outputKind,
+                errorKind,
+                multiKind,
+                multiPolicy,
+                posKind,
+                xdiagsSource,
+                xdiagsCompact,
+                caretKind,
+                sourceLineKind,
+                summaryIndent,
+                detailsIndent,
+                sourceIndent,
+                subdiagsIndent);
+    }
+
+    void test() {
+        for (OutputKind outputKind : OutputKind.values()) {
+            for (ErrorKind errKind : ErrorKind.values()) {
+                for (MultilineKind multiKind : MultilineKind.values()) {
+                    for (MultilinePolicy multiPolicy : MultilinePolicy.values()) {
+                        for (PositionKind posKind : PositionKind.values()) {
+                            for (XDiagsSource xdiagsSource : XDiagsSource.values()) {
+                                for (XDiagsCompact xdiagsCompact : XDiagsCompact.values()) {
+                                    for (CaretKind caretKind : CaretKind.values()) {
+                                        for (SourceLineKind sourceLineKind : SourceLineKind.values()) {
+                                            for (IndentKind summaryIndent : IndentKind.values()) {
+                                                for (IndentKind detailsIndent : IndentKind.values()) {
+                                                    for (IndentKind sourceIndent : IndentKind.values()) {
+                                                        for (IndentKind subdiagsIndent : IndentKind.values()) {
+                                                            exec(outputKind,
+                                                                errKind,
+                                                                multiKind,
+                                                                multiPolicy,
+                                                                posKind,
+                                                                xdiagsSource,
+                                                                xdiagsCompact,
+                                                                caretKind,
+                                                                sourceLineKind,
+                                                                summaryIndent,
+                                                                detailsIndent,
+                                                                sourceIndent,
+                                                                subdiagsIndent);
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        if (nerrors != 0)
+            throw new AssertionError(nerrors + " errors found");
+    }
+
+    void printInfo(String msg, OutputKind outputKind, ErrorKind errorKind, MultilineKind multiKind,
+            MultilinePolicy multiPolicy, PositionKind posKind, XDiagsSource xdiagsSource,
+            XDiagsCompact xdiagsCompact, CaretKind caretKind, SourceLineKind sourceLineKind,
+            IndentKind summaryIndent, IndentKind detailsIndent, IndentKind sourceIndent,
+            IndentKind subdiagsIndent, String errorLine) {
+        String sep = "*********************************************************";
+        String desc = "raw=" + outputKind + " pos=" + posKind + " key=" + errorKind.key() +
+                " multiline=" + multiKind +" multiPolicy=" + multiPolicy.value +
+                " diags= " + java.util.Arrays.asList(xdiagsSource.flag, xdiagsCompact.flag) +
+                " caret=" + caretKind + " sourcePosition=" + sourceLineKind +
+                " summaryIndent=" + summaryIndent + " detailsIndent=" + detailsIndent +
+                " sourceIndent=" + sourceIndent + " subdiagsIndent=" + subdiagsIndent;
+        System.out.println(sep);
+        System.out.println(desc);
+        System.out.println(sep);
+        System.out.println(msg);
+        System.out.println("Diagnostic formatting problem - expected diagnostic...\n" + errorLine);
+    }
+
+    void checkOutput(String msg, OutputKind outputKind, ErrorKind errorKind, MultilineKind multiKind,
+            MultilinePolicy multiPolicy, PositionKind posKind, XDiagsSource xdiagsSource,
+            XDiagsCompact xdiagsCompact, CaretKind caretKind, SourceLineKind sourceLineKind,
+            IndentKind summaryIndent, IndentKind detailsIndent, IndentKind sourceIndent,
+            IndentKind subdiagsIndent) {
+        boolean shouldPrintSource = posKind == PositionKind.POS &&
+                xdiagsSource != XDiagsSource.NO_SOURCE &&
+                (xdiagsSource == XDiagsSource.SOURCE ||
+                outputKind == OutputKind.BASIC);
+        String errorLine = posKind.getOutput(outputKind) +
+                errorKind.getOutput(outputKind, summaryIndent, detailsIndent);
+        if (xdiagsCompact != XDiagsCompact.COMPACT)
+            errorLine += multiKind.getOutput(outputKind, errorKind, multiPolicy, summaryIndent, detailsIndent, subdiagsIndent);
+        String[] lines = errorLine.split("\n");
+        if (xdiagsCompact == XDiagsCompact.COMPACT) {
+            errorLine = lines[0];
+            lines = new String[] {errorLine};
+        }
+        if (shouldPrintSource) {
+            if (sourceLineKind.isAfterSummary()) {
+                String sep = "\n";
+                if (lines.length == 1) {
+                    errorLine += "\n";
+                    sep = "";
+                }
+                errorLine = errorLine.replaceFirst("\n",
+                        Matcher.quoteReplacement(xdiagsSource.getOutput(caretKind, sourceIndent, outputKind) + sep));
+            }
+            else
+                errorLine += xdiagsSource.getOutput(caretKind, sourceIndent, outputKind);
+        }
+
+        if (!msg.equals(errorLine)) {
+            printInfo(msg,
+                    outputKind,
+                    errorKind,
+                    multiKind,
+                    multiPolicy,
+                    posKind,
+                    xdiagsSource,
+                    xdiagsCompact,
+                    caretKind,
+                    sourceLineKind,
+                    summaryIndent,
+                    detailsIndent,
+                    sourceIndent,
+                    subdiagsIndent,
+                    errorLine);
+            nerrors++;
+        }
+    }
+
+    public static void main(String... args) throws Exception {
+        new T6769027().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/Diagnostics/6769027/tester.properties	Fri Feb 13 11:57:33 2009 +0000
@@ -0,0 +1,13 @@
+compiler.err.single=\
+    This is a test error message {0}
+
+compiler.err.double=\
+    This is a test error message.\n\
+	This is another line of the above error message {0}
+
+compiler.misc.single=\
+    This is a test subdiagnostic {0}
+
+compiler.misc.double=\
+    This is a test subdiagnostic.\n\
+	This is another line of the above subdiagnostic {0}
--- a/langtools/test/tools/javac/ExtendArray.out	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/test/tools/javac/ExtendArray.out	Fri Feb 13 11:57:33 2009 +0000
@@ -1,6 +1,6 @@
 ExtendArray.java:11: unexpected type
-found   : java.lang.Object[]
-required: class
 public class ExtendArray extends Object[] {}
                                        ^
+  required: class
+  found:    java.lang.Object[]
 1 error
--- a/langtools/test/tools/javac/T5048776b.out	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/test/tools/javac/T5048776b.out	Fri Feb 13 11:57:33 2009 +0000
@@ -1,3 +1,3 @@
-T5048776.java:12:10: compiler.warn.override.varargs.missing: (- compiler.misc.varargs.override: foo(java.lang.Object...), A1a, foo(java.lang.Object[]), A1)
-T5048776.java:20:10: compiler.warn.override.varargs.extra: (- compiler.misc.varargs.override: foo(java.lang.Object[]), A2a, foo(java.lang.Object...), A2)
+T5048776.java:12:10: compiler.warn.override.varargs.missing: (compiler.misc.varargs.override: foo(java.lang.Object...), A1a, foo(java.lang.Object[]), A1)
+T5048776.java:20:10: compiler.warn.override.varargs.extra: (compiler.misc.varargs.override: foo(java.lang.Object[]), A2a, foo(java.lang.Object...), A2)
 2 warnings
--- a/langtools/test/tools/javac/T6214885a.out	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/test/tools/javac/T6214885a.out	Fri Feb 13 11:57:33 2009 +0000
@@ -1,6 +1,6 @@
 T6214885.java:11 cannot find symbol
-symbol  : variable x
-location: class T6214885
         x = 1;
         ^
+  symbol:   variable x
+  location: class T6214885
 1 error
--- a/langtools/test/tools/javac/T6214885b.out	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/test/tools/javac/T6214885b.out	Fri Feb 13 11:57:33 2009 +0000
@@ -1,6 +1,6 @@
 T6214885.java:11:9 cannot find symbol
-symbol  : variable x
-location: class T6214885
         x = 1;
         ^
+  symbol:   variable x
+  location: class T6214885
 1 error
--- a/langtools/test/tools/javac/T6230128.out	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/test/tools/javac/T6230128.out	Fri Feb 13 11:57:33 2009 +0000
@@ -1,2 +1,2 @@
-T6230128.java:11:10: compiler.err.override.weaker.access: (- compiler.misc.cant.override: foo(java.lang.Object...), A1a, foo(java.lang.Object[]), A1), public
+T6230128.java:11:10: compiler.err.override.weaker.access: (compiler.misc.cant.override: foo(java.lang.Object...), A1a, foo(java.lang.Object[]), A1), public
 1 error
--- a/langtools/test/tools/javac/annotations/6365854/test1.out	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/test/tools/javac/annotations/6365854/test1.out	Fri Feb 13 11:57:33 2009 +0000
@@ -1,2 +1,2 @@
-- compiler.warn.annotation.method.not.found.reason: test.annotation.TestAnnotation, test, (- compiler.misc.class.file.not.found: test.annotation.TestAnnotation)
+- compiler.warn.annotation.method.not.found.reason: test.annotation.TestAnnotation, test, (compiler.misc.class.file.not.found: test.annotation.TestAnnotation)
 1 warning
--- a/langtools/test/tools/javac/cast/6557182/T6557182.out	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/test/tools/javac/cast/6557182/T6557182.out	Fri Feb 13 11:57:33 2009 +0000
@@ -1,4 +1,4 @@
-T6557182.java:35:56: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T, java.lang.Comparable<java.lang.Integer>
-T6557182.java:39:56: compiler.warn.prob.found.req: (- compiler.misc.unchecked.cast.to.type), T, java.lang.Comparable<java.lang.Integer>
+T6557182.java:35:56: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T, java.lang.Comparable<java.lang.Integer>
+T6557182.java:39:56: compiler.warn.prob.found.req: (compiler.misc.unchecked.cast.to.type), T, java.lang.Comparable<java.lang.Integer>
 1 error
 1 warning
--- a/langtools/test/tools/javac/cast/6665356/T6665356.out	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/test/tools/javac/cast/6665356/T6665356.out	Fri Feb 13 11:57:33 2009 +0000
@@ -1,8 +1,8 @@
-T6665356.java:54:55: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<? super java.lang.Number>.Inner<java.lang.Long>
-T6665356.java:58:58: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<java.lang.Integer>.Inner<? super java.lang.Number>
-T6665356.java:62:65: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<? super java.lang.Number>.Inner<? super java.lang.Number>
-T6665356.java:66:57: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<? extends java.lang.String>.Inner<java.lang.Long>
-T6665356.java:70:60: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<java.lang.Integer>.Inner<? extends java.lang.String>
-T6665356.java:74:55: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<? super java.lang.String>.Inner<java.lang.Long>
-T6665356.java:78:58: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<java.lang.Integer>.Inner<? super java.lang.String>
+T6665356.java:54:55: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<? super java.lang.Number>.Inner<java.lang.Long>
+T6665356.java:58:58: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<java.lang.Integer>.Inner<? super java.lang.Number>
+T6665356.java:62:65: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<? super java.lang.Number>.Inner<? super java.lang.Number>
+T6665356.java:66:57: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<? extends java.lang.String>.Inner<java.lang.Long>
+T6665356.java:70:60: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<java.lang.Integer>.Inner<? extends java.lang.String>
+T6665356.java:74:55: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<? super java.lang.String>.Inner<java.lang.Long>
+T6665356.java:78:58: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6665356.Outer<java.lang.Integer>.Inner<java.lang.Long>, T6665356.Outer<java.lang.Integer>.Inner<? super java.lang.String>
 7 errors
\ No newline at end of file
--- a/langtools/test/tools/javac/cast/6795580/T6795580.out	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/test/tools/javac/cast/6795580/T6795580.out	Fri Feb 13 11:57:33 2009 +0000
@@ -1,8 +1,8 @@
-T6795580.java:54:57: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<? super java.lang.Number>.Inner<java.lang.Long>[]
-T6795580.java:58:60: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<java.lang.Integer>.Inner<? super java.lang.Number>[]
-T6795580.java:62:67: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<? super java.lang.Number>.Inner<? super java.lang.Number>[]
-T6795580.java:66:59: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<? extends java.lang.String>.Inner<java.lang.Long>[]
-T6795580.java:70:62: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<java.lang.Integer>.Inner<? extends java.lang.String>[]
-T6795580.java:74:57: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<? super java.lang.String>.Inner<java.lang.Long>[]
-T6795580.java:78:60: compiler.err.prob.found.req: (- compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<java.lang.Integer>.Inner<? super java.lang.String>[]
+T6795580.java:54:57: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<? super java.lang.Number>.Inner<java.lang.Long>[]
+T6795580.java:58:60: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<java.lang.Integer>.Inner<? super java.lang.Number>[]
+T6795580.java:62:67: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<? super java.lang.Number>.Inner<? super java.lang.Number>[]
+T6795580.java:66:59: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<? extends java.lang.String>.Inner<java.lang.Long>[]
+T6795580.java:70:62: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<java.lang.Integer>.Inner<? extends java.lang.String>[]
+T6795580.java:74:57: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<? super java.lang.String>.Inner<java.lang.Long>[]
+T6795580.java:78:60: compiler.err.prob.found.req: (compiler.misc.inconvertible.types), T6795580.Outer<java.lang.Integer>.Inner<java.lang.Long>[], T6795580.Outer<java.lang.Integer>.Inner<? super java.lang.String>[]
 7 errors
--- a/langtools/test/tools/javac/generics/6207386/T6207386.out	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/test/tools/javac/generics/6207386/T6207386.out	Fri Feb 13 11:57:33 2009 +0000
@@ -1,2 +1,2 @@
-T6207386.java:13:30: compiler.err.prob.found.req: (- compiler.misc.incompatible.types), X, T6207386.F<? super X>
+T6207386.java:13:30: compiler.err.prob.found.req: (compiler.misc.incompatible.types), X, T6207386.F<? super X>
 1 error
--- a/langtools/test/tools/javac/generics/inference/6315770/T6315770.out	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/test/tools/javac/generics/inference/6315770/T6315770.out	Fri Feb 13 11:57:33 2009 +0000
@@ -1,3 +1,3 @@
-T6315770.java:39:42: compiler.err.undetermined.type.1: <T>T6315770<T>, (- compiler.misc.no.unique.maximal.instance.exists: T, java.lang.String,java.lang.Integer,java.lang.Runnable)
-T6315770.java:40:40: compiler.err.prob.found.req: (- compiler.misc.incompatible.types.1: (- compiler.misc.no.conforming.instance.exists: T, T6315770<T>, T6315770<? super java.lang.String>)), <T>T6315770<T>, T6315770<? super java.lang.String>
+T6315770.java:39:42: compiler.err.undetermined.type.1: <T>T6315770<T>, (compiler.misc.no.unique.maximal.instance.exists: T, java.lang.String,java.lang.Integer,java.lang.Runnable)
+T6315770.java:40:40: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.conforming.instance.exists: T, T6315770<T>, T6315770<? super java.lang.String>)), <T>T6315770<T>, T6315770<? super java.lang.String>
 2 errors
--- a/langtools/test/tools/javac/generics/inference/6718364/T6718364.out	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/test/tools/javac/generics/inference/6718364/T6718364.out	Fri Feb 13 11:57:33 2009 +0000
@@ -1,3 +1,3 @@
-T6718364.java:36:32: compiler.warn.prob.found.req: (- compiler.misc.unchecked.assign), T6718364.X, T6718364.X<java.lang.Integer>
+T6718364.java:36:32: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T6718364.X, T6718364.X<java.lang.Integer>
 T6718364.java:36:10: compiler.warn.unchecked.meth.invocation.applied: kindname.method, m, T6718364.X<T>,T, T6718364.X<T6718364.X<java.lang.Integer>>,T6718364.X, kindname.class, T6718364
 2 warnings
\ No newline at end of file
--- a/langtools/test/tools/javac/generics/typevars/6680106/T6680106.out	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/test/tools/javac/generics/typevars/6680106/T6680106.out	Fri Feb 13 11:57:33 2009 +0000
@@ -1,13 +1,13 @@
-T6680106.java:34:25: compiler.err.type.found.req: T[], (- compiler.misc.type.req.class)
-T6680106.java:35:25: compiler.err.type.found.req: S[], (- compiler.misc.type.req.class)
-T6680106.java:35:40: compiler.err.type.found.req: T[], (- compiler.misc.type.req.class)
-T6680106.java:36:25: compiler.err.type.found.req: S[], (- compiler.misc.type.req.class)
-T6680106.java:36:40: compiler.err.type.found.req: U[], (- compiler.misc.type.req.class)
-T6680106.java:36:55: compiler.err.type.found.req: T[], (- compiler.misc.type.req.class)
-T6680106.java:37:30: compiler.err.type.found.req: T[], (- compiler.misc.type.req.class)
-T6680106.java:38:30: compiler.err.type.found.req: S[], (- compiler.misc.type.req.class)
-T6680106.java:38:50: compiler.err.type.found.req: T[], (- compiler.misc.type.req.class)
-T6680106.java:39:30: compiler.err.type.found.req: S[], (- compiler.misc.type.req.class)
-T6680106.java:39:50: compiler.err.type.found.req: U[], (- compiler.misc.type.req.class)
-T6680106.java:39:70: compiler.err.type.found.req: T[], (- compiler.misc.type.req.class)
+T6680106.java:34:25: compiler.err.type.found.req: T[], (compiler.misc.type.req.class)
+T6680106.java:35:25: compiler.err.type.found.req: S[], (compiler.misc.type.req.class)
+T6680106.java:35:40: compiler.err.type.found.req: T[], (compiler.misc.type.req.class)
+T6680106.java:36:25: compiler.err.type.found.req: S[], (compiler.misc.type.req.class)
+T6680106.java:36:40: compiler.err.type.found.req: U[], (compiler.misc.type.req.class)
+T6680106.java:36:55: compiler.err.type.found.req: T[], (compiler.misc.type.req.class)
+T6680106.java:37:30: compiler.err.type.found.req: T[], (compiler.misc.type.req.class)
+T6680106.java:38:30: compiler.err.type.found.req: S[], (compiler.misc.type.req.class)
+T6680106.java:38:50: compiler.err.type.found.req: T[], (compiler.misc.type.req.class)
+T6680106.java:39:30: compiler.err.type.found.req: S[], (compiler.misc.type.req.class)
+T6680106.java:39:50: compiler.err.type.found.req: U[], (compiler.misc.type.req.class)
+T6680106.java:39:70: compiler.err.type.found.req: T[], (compiler.misc.type.req.class)
 12 errors
\ No newline at end of file
--- a/langtools/test/tools/javac/missingSuperRecovery/MissingSuperRecovery.out	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/test/tools/javac/missingSuperRecovery/MissingSuperRecovery.out	Fri Feb 13 11:57:33 2009 +0000
@@ -1,5 +1,5 @@
 MissingSuperRecovery.java:15: cannot access base
-class file for base not found
 public class MissingSuperRecovery extends impl {
        ^
+  class file for base not found
 1 error
--- a/langtools/test/tools/javac/unicode/UnicodeNewline.out	Fri Feb 06 17:24:04 2009 -0800
+++ b/langtools/test/tools/javac/unicode/UnicodeNewline.out	Fri Feb 13 11:57:33 2009 +0000
@@ -1,6 +1,6 @@
 UnicodeNewline.java:11: cannot find symbol
-symbol  : class xyzzy
-location: class UnicodeNewline
     xyzzy plugh; // error should be HERE
     ^
+  symbol:   class xyzzy
+  location: class UnicodeNewline
 1 error