Merge
authorlana
Thu, 28 Aug 2014 14:53:49 -0700
changeset 26110 6ce251a87137
parent 26086 cfcea23d2d19 (current diff)
parent 26109 0430c63da650 (diff)
child 26111 915a71858aef
Merge
langtools/.hgtags
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/JavacServiceImpl.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/CompilerPool.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/CompilerThread.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/JavacServer.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/JavacService.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/JavacServiceClient.java
langtools/test/tools/javac/lib/ToolBox.java
--- a/langtools/make/build.properties	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/make/build.properties	Thu Aug 28 14:53:49 2014 -0700
@@ -68,7 +68,7 @@
 # set the following to -version to verify the versions of javac being used
 javac.version.opt =
 # in time, there should be no exceptions to -Xlint:all
-javac.lint.opts = -Xlint:all -Werror
+javac.lint.opts = -Xlint:all,-deprecation -Werror
 
 # options for the <javadoc> task for javac
 #javadoc.jls3.url=http://java.sun.com/docs/books/jls/
--- a/langtools/make/intellij/langtools.iml	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/make/intellij/langtools.iml	Thu Aug 28 14:53:49 2014 -0700
@@ -6,10 +6,14 @@
     <content url="file://$MODULE_DIR$">
       <sourceFolder url="file://$MODULE_DIR$/build/bootstrap/gensrc" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/build/genstubs" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/src/share/classes" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/test" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/java.base" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/java.compiler" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/jdk.compiler" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/jdk.dev" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/jdk.javadoc" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
     </content>
-    <orderEntry type="sourceFolder" forTests="false" />    
+    <orderEntry type="sourceFolder" forTests="false" />
     <orderEntry type="inheritedJdk" />
   </component>
 </module>
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java	Thu Aug 28 14:53:49 2014 -0700
@@ -2196,16 +2196,6 @@
             }
 
             @Override
-            public Type visitWildcardType(WildcardType t, Boolean recurse) {
-                final List<Attribute.TypeCompound> annos = t.getAnnotationMirrors();
-                Type erased = erasure(wildUpperBound(t), recurse);
-                if (!annos.isEmpty()) {
-                    erased = erased.annotatedType(annos);
-                }
-                return erased;
-            }
-
-            @Override
             public Type visitClassType(ClassType t, Boolean recurse) {
                 Type erased = t.tsym.erasure(Types.this);
                 List<Attribute.TypeCompound> annos = t.getAnnotationMirrors();
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Aug 28 14:53:49 2014 -0700
@@ -919,14 +919,14 @@
                 // Empty bodies are only allowed for
                 // abstract, native, or interface methods, or for methods
                 // in a retrofit signature class.
-                if (isDefaultMethod || (tree.sym.flags() & (ABSTRACT | NATIVE)) == 0 &&
-                    !relax)
-                    log.error(tree.pos(), "missing.meth.body.or.decl.abstract");
                 if (tree.defaultValue != null) {
                     if ((owner.flags() & ANNOTATION) == 0)
                         log.error(tree.pos(),
                                   "default.allowed.in.intf.annotation.member");
                 }
+                if (isDefaultMethod || (tree.sym.flags() & (ABSTRACT | NATIVE)) == 0 &&
+                    !relax)
+                    log.error(tree.pos(), "missing.meth.body.or.decl.abstract");
             } else if ((tree.sym.flags() & ABSTRACT) != 0 && !isDefaultMethod) {
                 if ((owner.flags() & INTERFACE) != 0) {
                     log.error(tree.body.pos(), "intf.meth.cant.have.body");
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/BuildState.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/BuildState.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -31,15 +31,17 @@
 import java.util.Map;
 import java.util.Set;
 
+import com.sun.tools.javac.util.Assert;
+
 /**
  * The build state class captures the source code and generated artifacts
  * from a build. There are usually two build states, the previous one (prev),
  * loaded from the javac_state file, and the current one (now).
  *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk.  This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
 public class BuildState {
     private Map<String,Module> modules = new HashMap<>();
@@ -75,7 +77,7 @@
      */
     Module findModuleFromPackageName(String pkg) {
         int cp = pkg.indexOf(':');
-        assert(cp != -1);
+        Assert.check(cp != -1);
         String mod = pkg.substring(0, cp);
         return lookupModule(mod);
     }
@@ -94,7 +96,7 @@
             for (Map.Entry<String,Package> j : i.packages().entrySet()) {
                 Package p = packages.get(j.getKey());
                 // Check that no two different packages are stored under same name.
-                assert(p == null || p == j.getValue());
+                Assert.check(p == null || p == j.getValue());
                 if (p == null) {
                     p = j.getValue();
                     packages.put(j.getKey(),j.getValue());
@@ -102,7 +104,7 @@
                 for (Map.Entry<String,Source> k : p.sources().entrySet()) {
                     Source s = sources.get(k.getKey());
                     // Check that no two different sources are stored under same name.
-                    assert(s == null || s == k.getValue());
+                    Assert.check(s == null || s == k.getValue());
                     if (s == null) {
                         s = k.getValue();
                         sources.put(k.getKey(), k.getValue());
@@ -111,7 +113,7 @@
                 for (Map.Entry<String,File> g : p.artifacts().entrySet()) {
                     File f = artifacts.get(g.getKey());
                     // Check that no two artifacts are stored under the same file.
-                    assert(f == null || f == g.getValue());
+                    Assert.check(f == null || f == g.getValue());
                     if (f == null) {
                         f = g.getValue();
                         artifacts.put(g.getKey(), g.getValue());
@@ -134,13 +136,13 @@
             for (Map.Entry<String,Package> j : i.packages().entrySet()) {
                 Package p = packages.get(j.getKey());
                 // Check that no two different packages are stored under same name.
-                assert(p == null || p == j.getValue());
+                Assert.check(p == null || p == j.getValue());
                 p = j.getValue();
                 packages.put(j.getKey(),j.getValue());
                 for (Map.Entry<String,File> g : p.artifacts().entrySet()) {
                     File f = artifacts.get(g.getKey());
                     // Check that no two artifacts are stored under the same file.
-                    assert(f == null || f == g.getValue());
+                    Assert.check(f == null || f == g.getValue());
                     artifacts.put(g.getKey(), g.getValue());
                 }
             }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CleanProperties.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CleanProperties.java	Thu Aug 28 14:53:49 2014 -0700
@@ -36,19 +36,18 @@
 import java.util.Properties;
 
 import com.sun.tools.sjavac.options.Options;
-import com.sun.tools.sjavac.server.JavacService;
+import com.sun.tools.sjavac.server.Sjavac;
 
 /**
  * The clean properties transform should not be necessary.
  * Eventually we will cleanup the property file sources in the OpenJDK instead.
  *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk.  This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
-public class CleanProperties implements Transformer
-{
+public class CleanProperties implements Transformer {
     public void setExtra(String e) {
         // Any extra information is ignored for clean properties.
     }
@@ -57,7 +56,7 @@
         // Any extra information is ignored for clean properties.
     }
 
-    public boolean transform(JavacService javacService,
+    public boolean transform(Sjavac sjavac,
                              Map<String,Set<URI>> pkgSrcs,
                              Set<URI>             visibleSrcs,
                              Map<URI,Set<String>> visibleClasses,
@@ -70,8 +69,7 @@
                              boolean incremental,
                              int numCores,
                              PrintStream out,
-                             PrintStream err)
-    {
+                             PrintStream err) {
         boolean rc = true;
         for (String pkgName : pkgSrcs.keySet()) {
             String pkgNameF = pkgName.replace('.',File.separatorChar);
@@ -87,9 +85,12 @@
         return rc;
     }
 
-    boolean clean(String pkgName, String pkgNameF, File src, File destRoot, int debugLevel,
-                  Map<String,Set<URI>> packageArtifacts)
-    {
+    boolean clean(String pkgName,
+                  String pkgNameF,
+                  File src,
+                  File destRoot,
+                  int debugLevel,
+                  Map<String,Set<URI>> packageArtifacts) {
         // Load the properties file.
         Properties p = new Properties();
         try {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileChunk.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileChunk.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,10 +33,10 @@
  * A compile chunk is a list of sources/packages to be compiled. Possibly a subset of
  * the total number of sources/packages to be compiled for this sjavac invocation.
  *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk.  This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
 public class CompileChunk implements Comparable<CompileChunk> {
     public int numPackages;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java	Thu Aug 28 14:53:49 2014 -0700
@@ -30,13 +30,12 @@
 import java.net.URI;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.Random;
 import java.util.Set;
 import java.util.Map;
 
 import com.sun.tools.sjavac.options.Options;
 import com.sun.tools.sjavac.server.CompilationResult;
-import com.sun.tools.sjavac.server.JavacService;
+import com.sun.tools.sjavac.server.Sjavac;
 import com.sun.tools.sjavac.server.SysInfo;
 
 /**
@@ -67,7 +66,7 @@
         args = a;
     }
 
-    public boolean transform(final JavacService javacService,
+    public boolean transform(final Sjavac sjavac,
                              Map<String,Set<URI>> pkgSrcs,
                              final Set<URI>             visibleSources,
                              final Map<URI,Set<String>> visibleClasses,
@@ -86,18 +85,12 @@
         boolean concurrentCompiles = true;
 
         // Fetch the id.
-        String idOpt = Util.extractStringOption("id", args.getServerConf());
-        if (idOpt == null || idOpt.equals("")) {
-            // No explicit id set. Create a random id so that the requests can be
-            // grouped properly in the server.
-            idOpt = "id"+(((new Random()).nextLong())&Long.MAX_VALUE);
-        }
-        final String id = idOpt;
+        final String id = Util.extractStringOption("id", sjavac.serverSettings());
         // Only keep portfile and sjavac settings..
-        String psServerSettings = Util.cleanSubOptions(Util.set("portfile","sjavac","background","keepalive"), args.getServerConf());
+        String psServerSettings = Util.cleanSubOptions(Util.set("portfile","sjavac","background","keepalive"), sjavac.serverSettings());
 
         // Get maximum heap size from the server!
-        SysInfo sysinfo = javacService.getSysInfo();
+        SysInfo sysinfo = sjavac.getSysInfo();
         if (sysinfo.numCores == -1) {
             Log.error("Could not query server for sysinfo!");
             return false;
@@ -222,7 +215,7 @@
             requests[i] = new Thread() {
                 @Override
                 public void run() {
-                    rn[ii] = javacService.compile("n/a",
+                    rn[ii] = sjavac.compile("n/a",
                                                   id + "-" + ii,
                                                   args.prepJavacArgs(),
                                                   Collections.<File>emptyList(),
@@ -253,6 +246,8 @@
                     requests[ii].run();
                     // If there was an error, then stop early when running single threaded.
                     if (rn[i].returnCode != 0) {
+                        Log.info(rn[i].stdout);
+                        Log.error(rn[i].stderr);
                         return false;
                     }
                 }
@@ -269,6 +264,8 @@
         for (int i=0; i<numCompiles; ++i) {
             if (compileChunks[i].srcs.size() > 0) {
                 if (rn[i].returnCode != 0) {
+                    Log.info(rn[i].stdout);
+                    Log.error(rn[i].stderr);
                     rc = false;
                 }
             }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileProperties.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileProperties.java	Thu Aug 28 14:53:49 2014 -0700
@@ -38,20 +38,19 @@
 import java.util.Map;
 
 import com.sun.tools.sjavac.options.Options;
-import com.sun.tools.sjavac.server.JavacService;
+import com.sun.tools.sjavac.server.Sjavac;
 
 /**
  * Compile properties transform a properties file into a Java source file.
  * Java has built in support for reading properties from either a text file
  * in the source or a compiled java source file.
  *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk.  This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
-public class CompileProperties implements Transformer
-{
+public class CompileProperties implements Transformer {
     // Any extra information passed from the command line, for example if:
     // -tr .proppp=com.sun.tools.javac.smart.CompileProperties,sun.util.resources.LocaleNamesBundle
     // then extra will be "sun.util.resources.LocaleNamesBundle"
@@ -64,7 +63,7 @@
     public void setExtra(Options a) {
     }
 
-    public boolean transform(JavacService javacService,
+    public boolean transform(Sjavac sjavac,
                              Map<String,Set<URI>> pkgSrcs,
                              Set<URI>             visibleSrcs,
                              Map<URI,Set<String>> visibleClasses,
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CopyFile.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CopyFile.java	Thu Aug 28 14:53:49 2014 -0700
@@ -32,16 +32,16 @@
 import java.util.Map;
 
 import com.sun.tools.sjavac.options.Options;
-import com.sun.tools.sjavac.server.JavacService;
+import com.sun.tools.sjavac.server.Sjavac;
 
 /**
  * The copy file transform simply copies a matching file from -src to -d .
  * Such files are typically images, xml documents and other data files.
  *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk.  This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
 public class CopyFile implements Transformer {
 
@@ -51,7 +51,7 @@
     public void setExtra(Options a) {
     }
 
-    public boolean transform(JavacService javacService,
+    public boolean transform(Sjavac sjavac,
                              Map<String,Set<URI>> pkgSrcs,
                              Set<URI> visibleSrcs,
                              Map<URI,Set<String>> visibleClasses,
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/JavacState.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/JavacState.java	Thu Aug 28 14:53:49 2014 -0700
@@ -26,7 +26,6 @@
 package com.sun.tools.sjavac;
 
 import java.io.*;
-import java.nio.file.Path;
 import java.util.Collections;
 import java.util.Date;
 import java.util.Set;
@@ -39,20 +38,18 @@
 import java.util.*;
 
 import com.sun.tools.sjavac.options.Options;
-import com.sun.tools.sjavac.options.SourceLocation;
-import com.sun.tools.sjavac.server.JavacService;
+import com.sun.tools.sjavac.server.Sjavac;
 
 /**
  * The javac state class maintains the previous (prev) and the current (now)
  * build states and everything else that goes into the javac_state file.
  *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk.  This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
-public class JavacState
-{
+public class JavacState {
     // The arguments to the compile. If not identical, then it cannot
     // be an incremental build!
     String theArgs;
@@ -60,7 +57,6 @@
     int numCores;
 
     // The bin_dir/javac_state
-    private String javacStateFilename;
     private File javacState;
 
     // The previous build state is loaded from javac_state
@@ -99,7 +95,7 @@
     private Set<String> recompiledPackages;
 
     // The output directories filled with tasty artifacts.
-    private File binDir, gensrcDir, headerDir;
+    private File binDir, gensrcDir, headerDir, stateDir;
 
     // The current status of the file system.
     private Set<File> binArtifacts;
@@ -128,7 +124,11 @@
     // Where to send stdout and stderr.
     private PrintStream out, err;
 
-    JavacState(Options options, boolean removeJavacState, PrintStream o, PrintStream e) {
+    // Command line options.
+    private Options options;
+
+    JavacState(Options op, boolean removeJavacState, PrintStream o, PrintStream e) {
+        options = op;
         out = o;
         err = e;
         numCores = options.getNumCores();
@@ -136,8 +136,8 @@
         binDir = Util.pathToFile(options.getDestDir());
         gensrcDir = Util.pathToFile(options.getGenSrcDir());
         headerDir = Util.pathToFile(options.getHeaderDir());
-        javacStateFilename = binDir.getPath()+File.separator+"javac_state";
-        javacState = new File(javacStateFilename);
+        stateDir = Util.pathToFile(options.getStateDir());
+        javacState = new File(stateDir, "javac_state");
         if (removeJavacState && javacState.exists()) {
             javacState.delete();
         }
@@ -148,7 +148,7 @@
             // We do not want to risk building a broken incremental build.
             // BUT since the makefiles still copy things straight into the bin_dir et al,
             // we avoid deleting files here, if the option --permit-unidentified-classes was supplied.
-            if (!options.isUnidentifiedArtifactPermitted()) {
+            if (!options.areUnidentifiedArtifactsPermitted()) {
                 deleteContents(binDir);
                 deleteContents(gensrcDir);
                 deleteContents(headerDir);
@@ -268,7 +268,7 @@
      */
     public void save() throws IOException {
         if (!needsSaving) return;
-        try (FileWriter out = new FileWriter(javacStateFilename)) {
+        try (FileWriter out = new FileWriter(javacState)) {
             StringBuilder b = new StringBuilder();
             long millisNow = System.currentTimeMillis();
             Date d = new Date(millisNow);
@@ -311,7 +311,7 @@
         boolean newCommandLine = false;
         boolean syntaxError = false;
 
-        try (BufferedReader in = new BufferedReader(new FileReader(db.javacStateFilename))) {
+        try (BufferedReader in = new BufferedReader(new FileReader(db.javacState))) {
             for (;;) {
                 String l = in.readLine();
                 if (l==null) break;
@@ -512,7 +512,8 @@
         allKnownArtifacts.add(javacState);
 
         for (File f : binArtifacts) {
-            if (!allKnownArtifacts.contains(f)) {
+            if (!allKnownArtifacts.contains(f) &&
+                !options.isUnidentifiedArtifactPermitted(f.getAbsolutePath())) {
                 Log.debug("Removing "+f.getPath()+" since it is unknown to the javac_state.");
                 f.delete();
             }
@@ -605,13 +606,16 @@
     /**
      * Recursively delete a directory and all its contents.
      */
-    private static void deleteContents(File dir) {
+    private void deleteContents(File dir) {
         if (dir != null && dir.exists()) {
             for (File f : dir.listFiles()) {
                 if (f.isDirectory()) {
                     deleteContents(f);
                 }
-                f.delete();
+                if (!options.isUnidentifiedArtifactPermitted(f.getAbsolutePath())) {
+                    Log.debug("Removing "+f.getAbsolutePath());
+                    f.delete();
+                }
             }
         }
     }
@@ -648,7 +652,7 @@
     /**
      * Compile all the java sources. Return true, if it needs to be called again!
      */
-    public boolean performJavaCompilations(JavacService javacService,
+    public boolean performJavaCompilations(Sjavac sjavac,
                                            Options args,
                                            Set<String> recentlyCompiled,
                                            boolean[] rcValue) {
@@ -656,7 +660,7 @@
         suffixRules.put(".java", compileJavaPackages);
         compileJavaPackages.setExtra(args);
 
-        rcValue[0] = perform(javacService, binDir, suffixRules);
+        rcValue[0] = perform(sjavac, binDir, suffixRules);
         recentlyCompiled.addAll(taintedPackages());
         clearTaintedPackages();
         boolean again = !packagesWithChangedPublicApis.isEmpty();
@@ -686,10 +690,9 @@
      * For all packages, find all sources belonging to the package, group the sources
      * based on their transformers and apply the transformers on each source code group.
      */
-    private boolean perform(JavacService javacService,
+    private boolean perform(Sjavac sjavac,
                             File outputDir,
-                            Map<String,Transformer> suffixRules)
-    {
+                            Map<String,Transformer> suffixRules) {
         boolean rc = true;
         // Group sources based on transforms. A source file can only belong to a single transform.
         Map<Transformer,Map<String,Set<URI>>> groupedSources = new HashMap<>();
@@ -713,7 +716,7 @@
             Map<String,String> packagePublicApis =
                     Collections.synchronizedMap(new HashMap<String, String>());
 
-            boolean  r = t.transform(javacService,
+            boolean  r = t.transform(sjavac,
                                      srcs,
                                      visibleSrcs,
                                      visibleClasses,
@@ -791,9 +794,7 @@
      * Used to detect bugs where the makefile and sjavac have different opinions on which files
      * should be compiled.
      */
-    public void compareWithMakefileList(File makefileSourceList)
-            throws ProblemException
-    {
+    public void compareWithMakefileList(File makefileSourceList) throws ProblemException {
         // If we are building on win32 using for example cygwin the paths in the makefile source list
         // might be /cygdrive/c/.... which does not match c:\....
         // We need to adjust our calculated sources to be identical, if necessary.
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Log.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Log.java	Thu Aug 28 14:53:49 2014 -0700
@@ -31,10 +31,10 @@
  * Utility class only for sjavac logging.
  * The log level can be set using for example --log=DEBUG on the sjavac command line.
  *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk.  This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
 public class Log {
     private static PrintStream out, err;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Main.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Main.java	Thu Aug 28 14:53:49 2014 -0700
@@ -31,19 +31,21 @@
 import java.nio.file.Path;
 import java.nio.file.Files;
 
+import com.sun.tools.sjavac.client.SjavacClient;
+import com.sun.tools.sjavac.comp.SjavacImpl;
+import com.sun.tools.sjavac.comp.PooledSjavac;
 import com.sun.tools.sjavac.options.Options;
 import com.sun.tools.sjavac.options.SourceLocation;
-import com.sun.tools.sjavac.server.JavacService;
-import com.sun.tools.sjavac.server.JavacServer;
-import com.sun.tools.sjavac.server.JavacServiceClient;
+import com.sun.tools.sjavac.server.Sjavac;
+import com.sun.tools.sjavac.server.SjavacServer;
 
 /**
  * The main class of the smart javac wrapper tool.
  *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk.  This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
 public class Main {
 
@@ -163,13 +165,19 @@
                 return;
             }
             // Spawn a background server.
-            int rc = JavacServer.startServer(args[0], System.err);
-            System.exit(rc);
+            try {
+                SjavacServer server = new SjavacServer(args[0], System.err);
+                int rc = server.startServer();
+                System.exit(rc);
+            } catch (IOException ioex) {
+                Log.error("IOException caught: " + ioex);
+                System.exit(-1);
+            }
         }
         Main main = new Main();
         int rc = main.go(args, System.out, System.err);
         // Remove the portfile, but only if this background=false was used.
-        JavacServer.cleanup(args);
+        SjavacServer.cleanup(args);
         System.exit(rc);
     }
 
@@ -205,6 +213,9 @@
         if (!createIfMissing(options.getDestDir()))
             return -1;
 
+        if (!createIfMissing(options.getStateDir()))
+            return -1;
+
         Path gensrc = options.getGenSrcDir();
         if (gensrc != null && !createIfMissing(gensrc))
             return -1;
@@ -302,7 +313,7 @@
         // For examples, files that have been manually copied into these dirs.
         // Artifacts with bad timestamps (ie the on disk timestamp does not match the timestamp
         // in javac_state) have already been removed when the javac_state was loaded.
-        if (!options.isUnidentifiedArtifactPermitted()) {
+        if (!options.areUnidentifiedArtifactsPermitted()) {
             javac_state.removeUnidentifiedArtifacts();
         }
         // Go through all sources and taint all packages that miss artifacts.
@@ -338,15 +349,22 @@
             // Collect the name of all compiled packages.
             Set<String> recently_compiled = new HashSet<>();
             boolean[] rc = new boolean[1];
+            Sjavac sjavac;
+            boolean background = Util.extractBooleanOption("background", options.getServerConf(), true);
             do {
                 // Clean out artifacts in tainted packages.
                 javac_state.deleteClassArtifactsInTaintedPackages();
-                // Create a JavacService to delegate the actual compilation to.
-                // Currently sjavac always connects to a server through a socket
-                // regardless if sjavac runs as a background service or not.
-                // This will most likely change in the future.
-                JavacService javacService = new JavacServiceClient(options.getServerConf());
-                again = javac_state.performJavaCompilations(javacService, options, recently_compiled, rc);
+                // Create an sjavac implementation to be used for compilation
+                if (background) {
+                    sjavac = new SjavacClient(options);
+                } else {
+                    int poolsize = Util.extractIntOption("poolsize", options.getServerConf());
+                    if (poolsize <= 0)
+                        poolsize = Runtime.getRuntime().availableProcessors();
+                    sjavac = new PooledSjavac(new SjavacImpl(), poolsize);
+                }
+
+                again = javac_state.performJavaCompilations(sjavac, options, recently_compiled, rc);
                 if (!rc[0]) break;
             } while (again);
             // Only update the state if the compile went well.
@@ -357,6 +375,8 @@
                 // Remove artifacts that were generated during the last compile, but not this one.
                 javac_state.removeSuperfluousArtifacts(recently_compiled);
             }
+            if (!background)
+                sjavac.shutdown();
             return rc[0] ? 0 : -1;
         } catch (ProblemException e) {
             Log.error(e.getMessage());
@@ -375,8 +395,6 @@
             err = "Please specify output directory.";
         } else if (options.isJavaFilesAmongJavacArgs()) {
             err = "Sjavac does not handle explicit compilation of single .java files.";
-        } else if (options.isAtFilePresent()) {
-            err = "Sjavac does not handle @-files.";
         } else if (options.getServerConf() == null) {
             err = "No server configuration provided.";
         } else if (!options.getImplicitPolicy().equals("none")) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Module.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Module.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -36,10 +36,10 @@
  * The module is the root of a set of packages/sources/artifacts.
  * At the moment there is only one module in use, the empty/no-name/default module.
  *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk.  This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
 public class Module implements Comparable<Module> {
     private String name;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Package.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Package.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -35,6 +35,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import com.sun.tools.javac.util.Assert;
 
 /**
  * The Package class maintains meta information about a package.
@@ -54,10 +55,10 @@
  * the visible recompilation of the dependent packages indicates how much circular
  * dependencies your code has.
  *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk.  This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
 public class Package implements Comparable<Package> {
     // The module this package belongs to. (There is a legacy module with an empty string name,
@@ -83,9 +84,9 @@
 
     public Package(Module m, String n) {
         int c = n.indexOf(":");
-        assert(c != -1);
+        Assert.check(c != -1);
         String mn = n.substring(0,c);
-        assert(m.name().equals(m.name()));
+        Assert.check(m.name().equals(m.name()));
         name = n;
         dirname = n.replace('.', File.separatorChar);
         if (m.name().length() > 0) {
@@ -256,7 +257,7 @@
     }
 
     public void setArtifacts(Set<URI> as) {
-        assert(!artifacts.isEmpty());
+        Assert.check(!artifacts.isEmpty());
         artifacts = new HashMap<>();
         addArtifacts(as);
     }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/ProblemException.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/ProblemException.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -28,10 +28,10 @@
 /**
  * Used to signal serious problems when running sjavac.
  *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk.  This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
 public class ProblemException extends Exception {
     static final long serialVersionUID = -3387516993124229949L;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Source.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Source.java	Thu Aug 28 14:53:49 2014 -0700
@@ -37,10 +37,10 @@
  * The class also knows how to find source files (scanRoot) given include/exclude
  * patterns and a root.
  *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk.  This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
 public class Source implements Comparable<Source> {
     // The package the source belongs to.
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Transformer.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Transformer.java	Thu Aug 28 14:53:49 2014 -0700
@@ -31,7 +31,7 @@
 import java.util.Map;
 
 import com.sun.tools.sjavac.options.Options;
-import com.sun.tools.sjavac.server.JavacService;
+import com.sun.tools.sjavac.server.Sjavac;
 
 /**
  * The transform interface is used to transform content inside a package, from one form to another.
@@ -39,13 +39,12 @@
  * but can also be an unpredictable number of generated source files (eg idl2java)
  * or a single predictable output file (eg when copying,cleaning or compiling a properties file).
  *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk.  This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
-public interface Transformer
-{
+public interface Transformer {
     /**
      * The transform method takes a set of package names, mapped to their source files and to the
      * pubapis of the packages.
@@ -83,7 +82,7 @@
      * If num_cores is set to a non-zero value. The transform should attempt to use no more than these
      * number of threads for heavy work.
      */
-    boolean transform(JavacService javacService,
+    boolean transform(Sjavac sjavac,
                       Map<String,Set<URI>> pkgSrcs,
                       Set<URI>             visibleSources,
                       Map<URI,Set<String>> visibleClasses,
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Util.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Util.java	Thu Aug 28 14:53:49 2014 -0700
@@ -26,8 +26,6 @@
 package com.sun.tools.sjavac;
 
 import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
 import java.nio.file.Path;
 import java.util.Arrays;
 import java.util.HashSet;
@@ -37,10 +35,10 @@
 /**
  * Utilities.
  *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk.  This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
 public class Util {
 
@@ -64,7 +62,8 @@
 
     public static String justPackageName(String pkgName) {
         int c = pkgName.indexOf(":");
-        assert(c != -1);
+        if (c == -1)
+            throw new IllegalArgumentException("Expected ':' in package name (" + pkgName + ")");
         return pkgName.substring(c+1);
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/SjavacClient.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac.client;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.URI;
+import java.util.List;
+import java.util.Set;
+
+import com.sun.tools.sjavac.Log;
+import com.sun.tools.sjavac.ProblemException;
+import com.sun.tools.sjavac.Util;
+import com.sun.tools.sjavac.server.CompilationResult;
+import com.sun.tools.sjavac.server.PortFile;
+import com.sun.tools.sjavac.server.Sjavac;
+import com.sun.tools.sjavac.server.SjavacServer;
+import com.sun.tools.sjavac.server.SysInfo;
+import com.sun.tools.sjavac.options.Options;
+
+/**
+ * Sjavac implementation that delegates requests to a SjavacServer.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class SjavacClient implements Sjavac {
+
+    // The id can perhaps be used in the future by the javac server to reuse the
+    // JavaCompiler instance for several compiles using the same id.
+    private final String id;
+    private final String portfileName;
+    private final String logfile;
+    private final String stdouterrfile;
+    private final boolean background;
+
+    // Default keepalive for server is 120 seconds.
+    // I.e. it will accept 120 seconds of inactivity before quitting.
+    private final int keepalive;
+    private final int poolsize;
+
+    // The sjavac option specifies how the server part of sjavac is spawned.
+    // If you have the experimental sjavac in your path, you are done. If not, you have
+    // to point to a com.sun.tools.sjavac.Main that supports --startserver
+    // for example by setting: sjavac=java%20-jar%20...javac.jar%com.sun.tools.sjavac.Main
+    private final String sjavacForkCmd;
+
+    // Wait 2 seconds for response, before giving up on javac server.
+    static int CONNECTION_TIMEOUT = 2000;
+    static int MAX_CONNECT_ATTEMPTS = 3;
+    static int WAIT_BETWEEN_CONNECT_ATTEMPTS = 2000;
+
+    // Store the server conf settings here.
+    private final String settings;
+
+    public SjavacClient(Options options) {
+        String tmpServerConf = options.getServerConf();
+        String serverConf = (tmpServerConf!=null)? tmpServerConf : "";
+        String tmpId = Util.extractStringOption("id", serverConf);
+        id = (tmpId!=null) ? tmpId : "id"+(((new java.util.Random()).nextLong())&Long.MAX_VALUE);
+        String p = Util.extractStringOption("portfile", serverConf);
+        portfileName = (p!=null) ? p : options.getStateDir().toFile().getAbsolutePath()+File.separatorChar+"javac_server";
+        logfile = Util.extractStringOption("logfile", serverConf, portfileName + ".javaclog");
+        stdouterrfile = Util.extractStringOption("stdouterrfile", serverConf, portfileName + ".stdouterr");
+        background = Util.extractBooleanOption("background", serverConf, true);
+        sjavacForkCmd = Util.extractStringOption("sjavac", serverConf, "sjavac");
+        int poolsize = Util.extractIntOption("poolsize", serverConf);
+        keepalive = Util.extractIntOption("keepalive", serverConf, 120);
+
+        this.poolsize = poolsize > 0 ? poolsize : Runtime.getRuntime().availableProcessors();
+        settings = (serverConf.equals("")) ? "id="+id+",portfile="+portfileName : serverConf;
+    }
+
+    /**
+     * Hand out the server settings.
+     * @return The server settings, possibly a default value.
+     */
+    public String serverSettings() {
+        return settings;
+    }
+
+    /**
+     * Make a request to the server only to get the maximum possible heap size to use for compilations.
+     *
+     * @param port_file The port file used to synchronize creation of this server.
+     * @param id The identify of the compilation.
+     * @param out Standard out information.
+     * @param err Standard err information.
+     * @return The maximum heap size in bytes.
+     */
+    @Override
+    public SysInfo getSysInfo() {
+        try (Socket socket = tryConnect()) {
+            // The ObjectInputStream constructor will block until the
+            // corresponding ObjectOutputStream has written and flushed the
+            // header, so it is important that the ObjectOutputStreams on server
+            // and client are opened before the ObjectInputStreams.
+            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
+            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
+            oos.writeObject(id);
+            oos.writeObject(SjavacServer.CMD_SYS_INFO);
+            oos.flush();
+            return (SysInfo) ois.readObject();
+        } catch (IOException | ClassNotFoundException ex) {
+            Log.error("[CLIENT] Exception caught: " + ex);
+            StringWriter sw = new StringWriter();
+            ex.printStackTrace(new PrintWriter(sw));
+        }
+        return null;
+    }
+
+    @Override
+    public CompilationResult compile(String protocolId,
+                                     String invocationId,
+                                     String[] args,
+                                     List<File> explicitSources,
+                                     Set<URI> sourcesToCompile,
+                                     Set<URI> visibleSources) {
+        CompilationResult result;
+        try (Socket socket = tryConnect()) {
+            // The ObjectInputStream constructor will block until the
+            // corresponding ObjectOutputStream has written and flushed the
+            // header, so it is important that the ObjectOutputStreams on server
+            // and client are opened before the ObjectInputStreams.
+            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
+            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
+            oos.writeObject(id);
+            oos.writeObject(SjavacServer.CMD_COMPILE);
+            oos.writeObject(protocolId);
+            oos.writeObject(invocationId);
+            oos.writeObject(args);
+            oos.writeObject(explicitSources);
+            oos.writeObject(sourcesToCompile);
+            oos.writeObject(visibleSources);
+            oos.flush();
+            result = (CompilationResult) ois.readObject();
+        } catch (IOException | ClassNotFoundException ex) {
+            Log.error("Exception caught: " + ex);
+            result = new CompilationResult(CompilationResult.ERROR_FATAL);
+            result.stderr = ex.getMessage();
+        }
+        return result;
+    }
+
+    private Socket tryConnect() throws IOException {
+
+        PortFile portFile;
+        try {
+            // This should be taken care of at a higher level (JDK-8048451)
+            portFile = SjavacServer.getPortFile(portfileName);
+        } catch (FileNotFoundException e) {
+            // Reached for instance if directory of port file does not exist
+            Log.error("Port file inaccessable: " + e);
+            throw new RuntimeException(e);
+        }
+        for (int i = 0; i < MAX_CONNECT_ATTEMPTS; i++) {
+            Log.info(String.format("Trying to connect (attempt %d of %d)",
+                                   i+1, MAX_CONNECT_ATTEMPTS));
+            try {
+                if (!makeSureServerIsRunning(portFile))
+                    continue;
+                Socket socket = new Socket();
+                InetAddress localhost = InetAddress.getByName(null);
+                socket.connect(new InetSocketAddress(localhost, portFile.getPort()),
+                               CONNECTION_TIMEOUT);
+                return socket;
+            } catch (ProblemException | IOException ex) {
+                Log.error("Caught exception during tryConnect: " + ex);
+            }
+
+            try {
+                Thread.sleep(WAIT_BETWEEN_CONNECT_ATTEMPTS);
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+            }
+        }
+        throw new IOException("Could not connect to server");
+    }
+
+    private boolean makeSureServerIsRunning(PortFile portFile)
+            throws IOException, ProblemException, FileNotFoundException {
+
+        synchronized (portFile) {
+            portFile.lock();
+            portFile.getValues();
+            portFile.unlock();
+        }
+
+        if (!portFile.containsPortInfo()) {
+            String forkCmd = SjavacServer.fork(sjavacForkCmd,
+                                               portFile.getFilename(),
+                                               logfile,
+                                               poolsize,
+                                               keepalive,
+                                               System.err,
+                                               stdouterrfile,
+                                               background);
+            if (!portFile.waitForValidValues()) {
+                // This can be simplified once JDK-8048457 has been addressed
+                // since we won't have an SjavacClient if background = false
+                if (background) {
+                    // There seems be some problem with spawning the external
+                    // process (for instance no fork command provided and no
+                    // sjavac on path)
+                    StringWriter sw = new StringWriter();
+                    SjavacClient.printFailedAttempt(forkCmd,
+                                                    stdouterrfile,
+                                                    new PrintWriter(sw));
+                    Log.error(sw.toString());
+                }
+            }
+        }
+        return portFile.containsPortInfo();
+    }
+
+
+    public static void printFailedAttempt(String cmd, String f, PrintWriter err) {
+        err.println("---- Failed to start javac server with this command -----");
+        err.println(cmd);
+        try {
+            BufferedReader in = new BufferedReader(new FileReader(f));
+            err.println("---- stdout/stderr output from attempt to start javac server -----");
+            for (;;) {
+                String l = in.readLine();
+                if (l == null) {
+                    break;
+                }
+                err.println(l);
+            }
+            err.println("------------------------------------------------------------------");
+        } catch (Exception e) {
+            err.println("The stdout/stderr output in file " + f + " does not exist and the server did not start.");
+        }
+    }
+
+    @Override
+    public void shutdown() {
+        // Nothing to clean up
+    }
+}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/AttrWithDeps.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/AttrWithDeps.java	Thu Aug 28 14:53:49 2014 -0700
@@ -30,10 +30,10 @@
 
 /** Subclass to Attr that overrides reportDepedence.
  *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk.  This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
 public class AttrWithDeps extends Attr {
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/Dependencies.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/Dependencies.java	Thu Aug 28 14:53:49 2014 -0700
@@ -34,6 +34,7 @@
 import java.util.Set;
 
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.util.Assert;
 import com.sun.tools.javac.util.Context;
 import com.sun.tools.javac.util.Log;
 import com.sun.tools.javac.util.Name;
@@ -41,10 +42,10 @@
 /** Utility class containing dependency information between packages
  *  and the pubapi for a package.
  *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk.  This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
 public class Dependencies {
     protected static final Context.Key<Dependencies> dependenciesKey = new Context.Key<>();
@@ -154,7 +155,7 @@
         Name n = ((ClassSymbol)e).fullname;
         Name p = ((ClassSymbol)e).packge().fullname;
         StringBuffer sb = publicApiPerClass.get(n);
-        assert(sb == null);
+        Assert.check(sb == null);
         sb = new StringBuffer();
         PubapiVisitor v = new PubapiVisitor(sb);
         v.visit(e);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/JavaCompilerWithDeps.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/JavaCompilerWithDeps.java	Thu Aug 28 14:53:49 2014 -0700
@@ -32,29 +32,29 @@
 
 /** Subclass to Resolve that overrides collect.
  *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk.  This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
 public class JavaCompilerWithDeps extends JavaCompiler {
 
     /** The dependency database
      */
     protected Dependencies deps;
-    protected JavacServiceImpl javacService;
+    protected SjavacErrorHandler errorHandler;
 
-    public JavaCompilerWithDeps(Context context, JavacServiceImpl jsi) {
+    public JavaCompilerWithDeps(Context context, SjavacErrorHandler eh) {
         super(context);
         deps = Dependencies.instance(context);
-        javacService = jsi;
+        errorHandler = eh;
         needRootClasses = true;
     }
 
-    public static void preRegister(Context context, final JavacServiceImpl t) {
+    public static void preRegister(Context context, final SjavacErrorHandler eh) {
         context.put(compilerKey, new Context.Factory<JavaCompiler>() {
             public JavaCompiler make(Context c) {
-                JavaCompiler instance = new JavaCompilerWithDeps(c, t);
+                JavaCompiler instance = new JavaCompilerWithDeps(c, eh);
                 c.put(JavaCompiler.class, instance);
                 return instance;
             }
@@ -97,7 +97,7 @@
 
             // Now check if the truncated uri ends with the path. (It does not == failure!)
             if (path.length() > 0 && !path.equals("/unnamed package/") && !pp.endsWith(path)) {
-                javacService.logError("Error: The source file "+sym.sourcefile.getName()+
+                errorHandler.logError("Error: The source file "+sym.sourcefile.getName()+
                                         " is located in the wrong package directory, because it contains the class "+
                                         sym.getQualifiedName());
             }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/JavacServiceImpl.java	Thu Aug 21 14:16:28 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,146 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.tools.sjavac.comp;
-
-import java.io.File;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.net.URI;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-
-import javax.tools.JavaCompiler.CompilationTask;
-import javax.tools.JavaFileObject;
-import javax.tools.StandardJavaFileManager;
-
-import com.sun.tools.javac.api.JavacTaskImpl;
-import com.sun.tools.javac.api.JavacTool;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.ListBuffer;
-import com.sun.tools.sjavac.Util;
-import com.sun.tools.sjavac.server.CompilationResult;
-import com.sun.tools.sjavac.server.JavacServer;
-import com.sun.tools.sjavac.server.JavacService;
-import com.sun.tools.sjavac.server.SysInfo;
-
-public class JavacServiceImpl implements JavacService {
-
-    JavacServer javacServer;
-    private ThreadLocal<Boolean> forcedExit;
-
-    public JavacServiceImpl(JavacServer javacServer) {
-        this.javacServer = javacServer;
-
-    }
-
-    public void logError(String msg) {
-//        stderr.println(msg);
-        forcedExit.set(true);
-    }
-
-    @Override
-    public SysInfo getSysInfo() {
-        return new SysInfo(Runtime.getRuntime().availableProcessors(),
-                           Runtime.getRuntime().maxMemory());
-    }
-
-    @Override
-    public CompilationResult compile(String protocolId,
-                                     String invocationId,
-                                     String[] args,
-                                     List<File> explicitSources,
-                                     Set<URI> sourcesToCompile,
-                                     Set<URI> visibleSources) {
-
-        JavacTool compiler = JavacTool.create();
-        StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
-        SmartFileManager smartFileManager = new SmartFileManager(fileManager);
-        Context context = new Context();
-        ResolveWithDeps.preRegister(context);
-        AttrWithDeps.preRegister(context);
-        JavaCompilerWithDeps.preRegister(context, this);
-
-        // Now setup the actual compilation....
-        CompilationResult compilationResult = new CompilationResult(0);
-
-        // First deal with explicit source files on cmdline and in at file.
-        ListBuffer<JavaFileObject> compilationUnits = new ListBuffer<>();
-        for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(explicitSources)) {
-            compilationUnits.append(i);
-        }
-        // Now deal with sources supplied as source_to_compile.
-        ListBuffer<File> sourcesToCompileFiles = new ListBuffer<>();
-        for (URI u : sourcesToCompile) {
-            sourcesToCompileFiles.append(new File(u));
-        }
-        for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(sourcesToCompileFiles)) {
-            compilationUnits.append(i);
-        }
-        // Log the options to be used.
-        StringBuilder options = new StringBuilder();
-        for (String s : args) {
-            options.append(">").append(s).append("< ");
-        }
-        javacServer.log(protocolId+" <"+invocationId+"> options "+options.toString());
-
-        forcedExit.set(false);
-        // Create a new logger.
-        StringWriter stdoutLog = new StringWriter();
-        StringWriter stderrLog = new StringWriter();
-        PrintWriter stdout = new PrintWriter(stdoutLog);
-        PrintWriter stderr = new PrintWriter(stderrLog);
-        com.sun.tools.javac.main.Main.Result rc = com.sun.tools.javac.main.Main.Result.OK;
-        try {
-            if (compilationUnits.size() > 0) {
-                smartFileManager.setVisibleSources(visibleSources);
-                smartFileManager.cleanArtifacts();
-                smartFileManager.setLog(stdout);
-
-
-                // Do the compilation!
-                CompilationTask task = compiler.getTask(stderr, smartFileManager, null, Arrays.asList(args), null, compilationUnits, context);
-                rc = ((JavacTaskImpl) task).doCall();
-                smartFileManager.flush();
-            }
-        } catch (Exception e) {
-            stderr.println(e.getMessage());
-            forcedExit.set(true);
-        }
-
-        compilationResult.packageArtifacts = smartFileManager.getPackageArtifacts();
-
-        Dependencies deps = Dependencies.instance(context);
-        compilationResult.packageDependencies = deps.getDependencies();
-        compilationResult.packagePubapis = deps.getPubapis();
-
-        compilationResult.stdout = stdoutLog.toString();
-        compilationResult.stderr = stderrLog.toString();
-        compilationResult.returnCode = rc.exitCode == 0 && forcedExit.get() ? -1 : rc.exitCode;
-
-        return compilationResult;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/PooledSjavac.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.comp;
+
+import java.io.File;
+import java.net.URI;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import com.sun.tools.sjavac.Log;
+import com.sun.tools.sjavac.server.CompilationResult;
+import com.sun.tools.sjavac.server.Sjavac;
+import com.sun.tools.sjavac.server.SysInfo;
+
+/**
+ * An sjavac implementation that limits the number of concurrent calls by
+ * wrapping invocations in Callables and delegating them to a FixedThreadPool.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class PooledSjavac implements Sjavac {
+
+    final Sjavac delegate;
+    final ExecutorService pool;
+
+    public PooledSjavac(Sjavac delegate, int poolsize) {
+        Objects.requireNonNull(delegate);
+        this.delegate = delegate;
+        pool = Executors.newFixedThreadPool(poolsize, new ThreadFactory() {
+            AtomicInteger count = new AtomicInteger();
+            @Override
+            public Thread newThread(Runnable runnable) {
+                String cls = PooledSjavac.class.getSimpleName();
+                int num = count.incrementAndGet();
+                Thread t = new Thread(runnable, cls + "-" + num);
+                t.setDaemon(true);
+                return t;
+            }
+        });
+    }
+
+    @Override
+    public SysInfo getSysInfo() {
+        try {
+            return pool.submit(new Callable<SysInfo>() {
+                @Override
+                public SysInfo call() throws Exception {
+                    return delegate.getSysInfo();
+                }
+            }).get();
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("Error during getSysInfo", e);
+        }
+    }
+
+    @Override
+    public CompilationResult compile(final String protocolId,
+                                     final String invocationId,
+                                     final String[] args,
+                                     final List<File> explicitSources,
+                                     final Set<URI> sourcesToCompile,
+                                     final Set<URI> visibleSources) {
+        try {
+            return pool.submit(new Callable<CompilationResult>() {
+                @Override
+                public CompilationResult call() throws Exception {
+                    return delegate.compile(protocolId,
+                                            invocationId,
+                                            args,
+                                            explicitSources,
+                                            sourcesToCompile,
+                                            visibleSources);
+                }
+            }).get();
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("Error during compile", e);
+        }
+    }
+
+    @Override
+    public void shutdown() {
+        pool.shutdown(); // Disable new tasks from being submitted
+        try {
+            // Wait a while for existing tasks to terminate
+            if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
+                pool.shutdownNow(); // Cancel currently executing tasks
+                // Wait a while for tasks to respond to being cancelled
+                if (!pool.awaitTermination(60, TimeUnit.SECONDS))
+                    Log.error("ThreadPool did not terminate");
+            }
+            // Grace period for thread termination
+            Thread.sleep(1000);
+        } catch (InterruptedException ie) {
+          // (Re-)Cancel if current thread also interrupted
+          pool.shutdownNow();
+          // Preserve interrupt status
+          Thread.currentThread().interrupt();
+        }
+
+        delegate.shutdown();
+    }
+
+    @Override
+    public String serverSettings() {
+        return delegate.serverSettings();
+    }
+}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/PubapiVisitor.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/PubapiVisitor.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, 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
@@ -37,10 +37,10 @@
 /** Utility class that constructs a textual representation
  * of the public api of a class.
  *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk.  This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
 public class PubapiVisitor extends ElementScanner9<Void, Void> {
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/ResolveWithDeps.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/ResolveWithDeps.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -30,10 +30,10 @@
 
 /** Subclass to Resolve that overrides collect.
  *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk.  This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
 public class ResolveWithDeps extends Resolve {
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SjavacErrorHandler.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac.comp;
+
+/**
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public interface SjavacErrorHandler {
+    void logError(String msg);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SjavacImpl.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.comp;
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.tools.JavaCompiler.CompilationTask;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+
+import com.sun.tools.javac.api.JavacTaskImpl;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.Options;
+import com.sun.tools.sjavac.server.CompilationResult;
+import com.sun.tools.sjavac.server.Sjavac;
+import com.sun.tools.sjavac.server.SysInfo;
+
+/**
+ * The sjavac implementation that interacts with javac and performs the actual
+ * compilation.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class SjavacImpl implements Sjavac {
+
+    @Override
+    public SysInfo getSysInfo() {
+        return new SysInfo(Runtime.getRuntime().availableProcessors(),
+                           Runtime.getRuntime().maxMemory());
+    }
+
+    @Override
+    public CompilationResult compile(String protocolId,
+                                     String invocationId,
+                                     String[] args,
+                                     List<File> explicitSources,
+                                     Set<URI> sourcesToCompile,
+                                     Set<URI> visibleSources) {
+        final AtomicBoolean forcedExit = new AtomicBoolean();
+
+        JavacTool compiler = JavacTool.create();
+        StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
+        SmartFileManager smartFileManager = new SmartFileManager(fileManager);
+        Context context = new Context();
+        ResolveWithDeps.preRegister(context);
+        AttrWithDeps.preRegister(context);
+        JavaCompilerWithDeps.preRegister(context, new SjavacErrorHandler() {
+            @Override
+            public void logError(String msg) {
+                forcedExit.set(true);
+            }
+        });
+
+        // Now setup the actual compilation....
+        CompilationResult compilationResult = new CompilationResult(0);
+
+        // First deal with explicit source files on cmdline and in at file.
+        ListBuffer<JavaFileObject> compilationUnits = new ListBuffer<>();
+        for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(explicitSources)) {
+            compilationUnits.append(i);
+        }
+        // Now deal with sources supplied as source_to_compile.
+        ListBuffer<File> sourcesToCompileFiles = new ListBuffer<>();
+        for (URI u : sourcesToCompile) {
+            sourcesToCompileFiles.append(new File(u));
+        }
+        for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(sourcesToCompileFiles)) {
+            compilationUnits.append(i);
+        }
+        forcedExit.set(false);
+        // Create a new logger.
+        StringWriter stdoutLog = new StringWriter();
+        StringWriter stderrLog = new StringWriter();
+        PrintWriter stdout = new PrintWriter(stdoutLog);
+        PrintWriter stderr = new PrintWriter(stderrLog);
+        com.sun.tools.javac.main.Main.Result rc = com.sun.tools.javac.main.Main.Result.OK;
+        try {
+            if (compilationUnits.size() > 0) {
+                smartFileManager.setVisibleSources(visibleSources);
+                smartFileManager.cleanArtifacts();
+                smartFileManager.setLog(stdout);
+
+                // Do the compilation!
+                CompilationTask task = compiler.getTask(stderr,
+                                                        smartFileManager,
+                                                        null,
+                                                        Arrays.asList(args),
+                                                        null,
+                                                        compilationUnits,
+                                                        context);
+                smartFileManager.setSymbolFileEnabled(!Options.instance(context).isSet("ignore.symbol.file"));
+                rc = ((JavacTaskImpl) task).doCall();
+                smartFileManager.flush();
+            }
+        } catch (Exception e) {
+            stderrLog.append(e.getMessage());
+            forcedExit.set(true);
+        }
+
+        compilationResult.packageArtifacts = smartFileManager.getPackageArtifacts();
+
+        Dependencies deps = Dependencies.instance(context);
+        compilationResult.packageDependencies = deps.getDependencies();
+        compilationResult.packagePubapis = deps.getPubapis();
+
+        compilationResult.stdout = stdoutLog.toString();
+        compilationResult.stderr = stderrLog.toString();
+
+        compilationResult.returnCode = rc.exitCode == 0 && forcedExit.get() ? -1 : rc.exitCode;
+
+        return compilationResult;
+    }
+
+    @Override
+    public void shutdown() {
+        // Nothing to clean up
+        // ... maybe we should wait for any current request to finish?
+    }
+
+
+    @Override
+    public String serverSettings() {
+        return "";
+    }
+
+}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SmartFileManager.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SmartFileManager.java	Thu Aug 28 14:53:49 2014 -0700
@@ -37,7 +37,6 @@
 import javax.tools.JavaFileObject.Kind;
 
 import com.sun.tools.javac.file.JavacFileManager;
-import com.sun.tools.javac.util.BaseFileManager;
 import com.sun.tools.javac.util.ListBuffer;
 
 /**
@@ -50,10 +49,10 @@
  * Can also blind out the filemanager from seeing certain files in the file system.
  * Necessary to prevent javac from seeing some sources where the source path points.
  *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk.  This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
 public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager> {
 
@@ -97,9 +96,7 @@
     public Iterable<JavaFileObject> list(Location location,
                                          String packageName,
                                          Set<Kind> kinds,
-                                         boolean recurse)
-        throws IOException
-    {
+                                         boolean recurse) throws IOException {
         // Acquire the list of files.
         Iterable<JavaFileObject> files = super.list(location, packageName, kinds, recurse);
         if (visibleSources.isEmpty()) {
@@ -112,8 +109,7 @@
             String t = uri.toString();
             if (t.startsWith("jar:")
                 || t.endsWith(".class")
-                || visibleSources.contains(uri))
-            {
+                || visibleSources.contains(uri)) {
                 filteredFiles.add(f);
             }
         }
@@ -128,9 +124,7 @@
     @Override
     public JavaFileObject getJavaFileForInput(Location location,
                                               String className,
-                                              Kind kind)
-        throws IOException
-    {
+                                              Kind kind) throws IOException {
         JavaFileObject file = super.getJavaFileForInput(location, className, kind);
         if (file == null || visibleSources.isEmpty()) {
             return file;
@@ -146,9 +140,7 @@
     public JavaFileObject getJavaFileForOutput(Location location,
                                                String className,
                                                Kind kind,
-                                               FileObject sibling)
-        throws IOException
-    {
+                                               FileObject sibling) throws IOException {
         JavaFileObject file = super.getJavaFileForOutput(location, className, kind, sibling);
         if (file == null) return file;
         int dp = className.lastIndexOf('.');
@@ -165,9 +157,7 @@
     @Override
     public FileObject getFileForInput(Location location,
                                       String packageName,
-                                      String relativeName)
-        throws IOException
-    {
+                                      String relativeName) throws IOException {
         FileObject file =  super.getFileForInput(location, packageName, relativeName);
         if (file == null || visibleSources.isEmpty()) {
             return file;
@@ -183,9 +173,7 @@
     public FileObject getFileForOutput(Location location,
                                        String packageName,
                                        String relativeName,
-                                       FileObject sibling)
-        throws IOException
-    {
+                                       FileObject sibling) throws IOException {
         FileObject file = super.getFileForOutput(location, packageName, relativeName, sibling);
         if (file == null) return file;
         if (location.equals(StandardLocation.NATIVE_HEADER_OUTPUT) &&
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SmartFileObject.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SmartFileObject.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -36,10 +36,10 @@
  * and compare the new content with the old content on disk. Only if they differ,
  * will the file be updated.
  *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk.  This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
 public class SmartFileObject implements JavaFileObject {
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SmartWriter.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SmartWriter.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -34,9 +34,9 @@
  * If not, the file is not touched.
  *
  *  <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk.  This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
 public class SmartWriter extends Writer {
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/ArgumentIterator.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/ArgumentIterator.java	Thu Aug 28 14:53:49 2014 -0700
@@ -27,6 +27,12 @@
 
 import java.util.Iterator;
 
+/**
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
 public class ArgumentIterator implements Iterator<String> {
 
     /** The underlying argument iterator */
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Option.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Option.java	Thu Aug 28 14:53:49 2014 -0700
@@ -47,6 +47,11 @@
  * This enum represents all options from (1) and (2). Note that instances of
  * this enum only entail static information about the option. For storage of
  * option values, refer to com.sun.tools.sjavac.options.Options.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
 public enum Option {
 
@@ -231,7 +236,14 @@
             helper.logLevel("info");
         }
     },
-    PERMIT_UNIDENTIFIED_ARTIFACTS("--permit-unidentified-artifacts", "Keep unidentified artifacts in destination directory") {
+    PERMIT_ARTIFACT("--permit-artifact=", "Allow this artifact in destination directory") {
+        @Override
+        protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+            String a = iter.current().substring(arg.length());
+            helper.permitArtifact(Paths.get(a).toFile().getAbsolutePath());
+        }
+    },
+    PERMIT_UNIDENTIFIED_ARTIFACTS("--permit-unidentified-artifacts", "Allow unidentified artifacts in destination directory") {
         @Override
         protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
             helper.permitUnidentifiedArtifacts();
@@ -274,8 +286,16 @@
             if (dir != null)
                 helper.headerDir(dir);
         }
+    },
+    STATE_DIR("--state-dir=", "Directory used to store sjavac state and log files.") {
+        @Override
+        protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+            String p = iter.current().substring(arg.length());
+            helper.stateDir(Paths.get(p));
+        }
     };
 
+
     public final String arg;
 
     final String description;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/OptionHelper.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/OptionHelper.java	Thu Aug 28 14:53:49 2014 -0700
@@ -25,17 +25,23 @@
 
 package com.sun.tools.sjavac.options;
 
-import java.nio.file.Files;
+import java.io.IOException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Arrays;
 import java.util.List;
 
+import com.sun.tools.javac.main.CommandLine;
 import com.sun.tools.sjavac.Transformer;
 
 /**
  * This class is used to decode sjavac options.
  * See com.sun.tools.sjavac.options.Options for example usage.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
 public abstract class OptionHelper {
 
@@ -78,6 +84,9 @@
     /** Record path for reference source list */
     public abstract void compareFoundSources(Path referenceList);
 
+    /** Record a single permitted artifact */
+    public abstract void permitArtifact(String f);
+
     /** Record the fact that unidentified artifacts are permitted */
     public abstract void permitUnidentifiedArtifacts();
 
@@ -102,6 +111,9 @@
     /** Sets the directory for generated headers */
     public abstract void headerDir(Path dir);
 
+    /** Sets the directory for state and log files generated by sjavac */
+    public abstract void stateDir(Path dir);
+
     /** Sets the implicit policy */
     public abstract void implicit(String policy);
 
@@ -112,7 +124,11 @@
      * @param args the arguments to traverse.
      */
     void traverse(String[] args) {
-
+        try {
+            args = CommandLine.parse(args); // Detect @file and load it as a command line.
+        } catch (java.io.IOException e) {
+            throw new IllegalArgumentException("Problem reading @"+e.getMessage());
+        }
         ArgumentIterator argIter = new ArgumentIterator(Arrays.asList(args));
 
         nextArg:
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.java	Thu Aug 28 14:53:49 2014 -0700
@@ -32,16 +32,23 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
+import java.util.HashSet;
 
 import com.sun.tools.sjavac.Transformer;
 
 /**
  * Instances of this class represent values for sjavac command line options.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
 public class Options {
 
     // Output directories
-    private Path destDir, genSrcDir, headerDir;
+    private Path destDir, genSrcDir, headerDir, stateDir;
 
     // Input directories
     private List<SourceLocation> sources = new ArrayList<>();
@@ -51,7 +58,8 @@
 
     private String logLevel = "info";
 
-    private boolean permitUnidentifiedArtifact = false;
+    private Set<String> permitted_artifacts = new HashSet<>();
+    private boolean permitUnidentifiedArtifacts = false;
     private boolean permitSourcesInDefaultPackage = false;
 
     private Path sourceReferenceList;
@@ -86,6 +94,11 @@
         return headerDir;
     }
 
+    /** Get the path for the state directory, defaults to destDir. */
+    public Path getStateDir() {
+        return stateDir != null ? stateDir : destDir;
+    }
+
     /** Get all source locations for files to be compiled */
     public List<SourceLocation> getSources() {
         return sources;
@@ -114,10 +127,15 @@
         return logLevel;
     }
 
+    /** Returns true iff the artifact is permitted in the output dir. */
+    public boolean isUnidentifiedArtifactPermitted(String f) {
+        return permitted_artifacts.contains(f);
+    }
+
     /** Returns true iff artifacts in the output directories should be kept,
      * even if they would not be generated in a clean build. */
-    public boolean isUnidentifiedArtifactPermitted() {
-        return permitUnidentifiedArtifact;
+    public boolean areUnidentifiedArtifactsPermitted() {
+        return permitUnidentifiedArtifacts;
     }
 
     /** Returns true iff sources in the default package should be permitted. */
@@ -176,14 +194,6 @@
         return false;
     }
 
-    /** Returns true iff an @-file is among the javac arguments */
-    public boolean isAtFilePresent() {
-        for (String javacArg : javacArgs)
-            if (javacArg.startsWith("@"))
-                return true;
-        return false;
-    }
-
     /**
      * Returns a string representation of the options that affect the result of
      * the compilation. (Used for saving the state of the options used in a
@@ -239,6 +249,9 @@
         if (destDir != null)
             args.addArg(Option.D, destDir.normalize());
 
+        if (stateDir != null)
+            args.addArg(Option.STATE_DIR, stateDir.normalize());
+
         // Source roots
         args.addSourceLocations(Option.SRC, sources);
         args.addSourceLocations(Option.SOURCEPATH, sourceSearchPaths);
@@ -249,7 +262,11 @@
         if (permitSourcesInDefaultPackage)
             args.addArg(Option.PERMIT_SOURCES_WITHOUT_PACKAGE);
 
-        if (permitUnidentifiedArtifact)
+        for (String f : permitted_artifacts) {
+            args.addArg(Option.PERMIT_ARTIFACT, f);
+        }
+
+        if (permitUnidentifiedArtifacts)
             args.addArg(Option.PERMIT_UNIDENTIFIED_ARTIFACTS);
 
         // Translation rules
@@ -327,6 +344,7 @@
 
         boolean headerProvided = false;
         boolean genSrcProvided = false;
+        boolean stateProvided = false;
 
         @Override
         public void reportError(String msg) {
@@ -399,8 +417,13 @@
         }
 
         @Override
+        public void permitArtifact(String f) {
+            permitted_artifacts.add(f);
+        }
+
+        @Override
         public void permitUnidentifiedArtifacts() {
-            permitUnidentifiedArtifact = true;
+            permitUnidentifiedArtifacts = true;
         }
 
         @Override
@@ -465,6 +488,16 @@
             headerDir = dir.toAbsolutePath();
         }
 
+        @Override
+        public void stateDir(Path dir) {
+            if (stateProvided) {
+                reportError("State directory already specified.");
+                return;
+            }
+            stateProvided = true;
+            stateDir = dir.toAbsolutePath();
+        }
+
         private List<SourceLocation> createSourceLocations(List<Path> paths) {
             List<SourceLocation> result = new ArrayList<>();
             for (Path path : paths) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/SourceLocation.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/SourceLocation.java	Thu Aug 28 14:53:49 2014 -0700
@@ -37,6 +37,11 @@
 /**
  * Represents a directory to be used for input to sjavac. (For instance a
  * sourcepath or classpath.)
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
 public class SourceLocation {
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/CompilationResult.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/CompilationResult.java	Thu Aug 28 14:53:49 2014 -0700
@@ -25,28 +25,35 @@
 
 package com.sun.tools.sjavac.server;
 
+import java.io.Serializable;
 import java.net.URI;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
 
-public class CompilationResult {
+/**
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class CompilationResult implements Serializable {
+
+    static final long serialVersionUID = 46739181113L;
 
     // Return code constants
-    public final static int ERROR_BUT_TRY_AGAIN = -4712;
     public final static int ERROR_FATAL = -1;
 
     public int returnCode;
     public Map<String, Set<URI>> packageArtifacts = new HashMap<>();
     public Map<String, Set<String>> packageDependencies = new HashMap<>();
     public Map<String, String> packagePubapis = new HashMap<>();
-    public SysInfo sysinfo;
-    public String stdout;
-    public String stderr;
+    public String stdout = "";
+    public String stderr = "";
 
     public CompilationResult(int returnCode) {
         this.returnCode = returnCode;
-        this.sysinfo = new SysInfo(-1, -1);
     }
 
     public void setReturnCode(int returnCode) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/CompilerPool.java	Thu Aug 21 14:16:28 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,165 +0,0 @@
-/*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.tools.sjavac.server;
-
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Semaphore;
-import java.util.Stack;
-import java.util.concurrent.Future;
-
-import com.sun.tools.sjavac.comp.JavacServiceImpl;
-
-/** The compiler pool maintains compiler threads.
- *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk.  This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
- */
-public class CompilerPool {
-    // The javac server that created this pool.
-    private JavacServer javacServer;
-    // A semaphore protecting the poolsize number of threads.
-    private Semaphore available;
-    // The stack of compiler threads.
-    private Stack<CompilerThread> compilers = new Stack<>();
-    // And the executor server to spawn threads.
-    private final ExecutorService executorPool;
-    // How many requests are active right now?
-    private int concurrentRequests = 0;
-    // When was the last request finished?
-    private long lastRequestFinished = 0;
-    // The total number of requests to this pool.
-    private int numRequests = 0;
-    // Protect access to the three above values.
-    private static final Object conc = new Object();
-
-    /**
-     * Return the javac server that this pool belongs to.
-     */
-    public JavacServer getJavacServer() {
-        return javacServer;
-    }
-
-    /**
-     * Return how many threads are running at this very moment.
-     */
-    public int numActiveRequests()
-    {
-        synchronized (conc) {
-            return concurrentRequests;
-        }
-    }
-
-    /**
-     * Return when the last request was finished.
-     * I.e. the pool has been idle since.
-     */
-    public long lastRequestFinished()
-    {
-        synchronized (conc) {
-            return lastRequestFinished;
-        }
-    }
-
-    /**
-     * Up the number of active requests.
-     */
-    public int startRequest() {
-        int n;
-        synchronized (conc) {
-            concurrentRequests++;
-            numRequests++;
-            n = numRequests;
-        }
-        return n;
-    }
-
-    /**
-     * Down the number of active requests. Return the current time.
-     */
-    public long stopRequest() {
-        synchronized (conc) {
-            concurrentRequests--;
-            lastRequestFinished = System.currentTimeMillis();
-        }
-        return lastRequestFinished;
-    }
-
-    /**
-     * Create a new compiler pool.
-     */
-    CompilerPool(int poolsize, JavacServer server) {
-        available = new Semaphore(poolsize, true);
-        javacServer = server;
-        executorPool = Executors.newFixedThreadPool(poolsize);
-        lastRequestFinished = System.currentTimeMillis();
-    }
-
-    /**
-     * Execute a compiler thread.
-     */
-    public void execute(CompilerThread ct) {
-        executorPool.execute(ct);
-    }
-
-    /**
-     * Execute a minor task, for example generating bytecodes and writing them to disk,
-     * that belong to a major compiler thread task.
-     */
-    public Future<?> executeSubtask(CompilerThread t, Runnable r) {
-        return executorPool.submit(r);
-    }
-
-    /**
-     * Shutdown the pool.
-     */
-    public void shutdown() {
-        executorPool.shutdown();
-    }
-
-    /**
-     * Acquire a compiler thread from the pool, or block until a thread is available.
-     * If the pools is empty, create a new thread, but never more than is "available".
-     */
-    public CompilerThread grabCompilerThread() throws InterruptedException {
-        available.acquire();
-        if (compilers.empty()) {
-            return new CompilerThread(this, new JavacServiceImpl(javacServer));
-        }
-        return compilers.pop();
-    }
-
-    /**
-     * Return the specified compiler thread to the pool.
-     */
-    public void returnCompilerThread(CompilerThread h) {
-        compilers.push(h);
-        available.release();
-    }
-}
-
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/CompilerThread.java	Thu Aug 21 14:16:28 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,412 +0,0 @@
-/*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.tools.sjavac.server;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.net.Socket;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Future;
-
-import javax.tools.JavaCompiler.CompilationTask;
-import javax.tools.JavaFileObject;
-import javax.tools.StandardJavaFileManager;
-
-import com.sun.tools.javac.api.JavacTaskImpl;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.ListBuffer;
-import com.sun.tools.javac.util.Options;
-import com.sun.tools.javac.util.StringUtils;
-import com.sun.tools.sjavac.comp.AttrWithDeps;
-import com.sun.tools.sjavac.comp.Dependencies;
-import com.sun.tools.sjavac.comp.JavaCompilerWithDeps;
-import com.sun.tools.sjavac.comp.JavacServiceImpl;
-import com.sun.tools.sjavac.comp.ResolveWithDeps;
-import com.sun.tools.sjavac.comp.SmartFileManager;
-
-/**
- * The compiler thread maintains a JavaCompiler instance and
- * can receive a request from the client, perform the compilation
- * requested and report back the results.
- *
- *  * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk.  This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
- */
-public class CompilerThread implements Runnable {
-    private JavacServer javacServer;
-    private CompilerPool compilerPool;
-    private JavacServiceImpl javacServiceImpl;
-    private List<Future<?>> subTasks;
-
-    // Communicating over this socket.
-    private Socket socket;
-
-    // The necessary classes to do a compilation.
-    private com.sun.tools.javac.api.JavacTool compiler;
-    private StandardJavaFileManager fileManager;
-    private SmartFileManager smartFileManager;
-    private Context context;
-
-    // If true, then this thread is serving a request.
-    private boolean inUse = false;
-
-    CompilerThread(CompilerPool cp, JavacServiceImpl javacServiceImpl) {
-        compilerPool = cp;
-        javacServer = cp.getJavacServer();
-        this.javacServiceImpl = javacServiceImpl;
-    }
-
-    /**
-     * Execute a minor task, for example generating bytecodes and writing them to disk,
-     * that belong to a major compiler thread task.
-     */
-    public synchronized void executeSubtask(Runnable r) {
-        subTasks.add(compilerPool.executeSubtask(this, r));
-    }
-
-    /**
-     * Count the number of active sub tasks.
-     */
-    public synchronized int numActiveSubTasks() {
-        int c = 0;
-        for (Future<?> f : subTasks) {
-            if (!f.isDone() && !f.isCancelled()) {
-                c++;
-            }
-        }
-        return c;
-    }
-
-    /**
-     * Use this socket for the upcoming request.
-     */
-    public void setSocket(Socket s) {
-        socket = s;
-    }
-
-    /**
-     * Prepare the compiler thread for use. It is not yet started.
-     * It will be started by the executor service.
-     */
-    public synchronized void use() {
-        assert(!inUse);
-        inUse = true;
-        compiler = com.sun.tools.javac.api.JavacTool.create();
-        fileManager = compiler.getStandardFileManager(null, null, null);
-        smartFileManager = new SmartFileManager(fileManager);
-        context = new Context();
-        ResolveWithDeps.preRegister(context);
-        AttrWithDeps.preRegister(context);
-        JavaCompilerWithDeps.preRegister(context, javacServiceImpl);
-        subTasks = new ArrayList<>();
-    }
-
-    /**
-     * Prepare the compiler thread for idleness.
-     */
-    public synchronized void unuse() {
-        assert(inUse);
-        inUse = false;
-        compiler = null;
-        fileManager = null;
-        smartFileManager = null;
-        context = null;
-        subTasks = null;
-    }
-
-    /**
-     * Expect this key on the next line read from the reader.
-     */
-    private static boolean expect(BufferedReader in, String key) throws IOException {
-        String s = in.readLine();
-        if (s != null && s.equals(key)) {
-            return true;
-        }
-        return false;
-    }
-
-    // The request identifier, for example GENERATE_NEWBYTECODE
-    String id = "";
-
-    public String currentRequestId() {
-        return id;
-    }
-
-    PrintWriter stdout;
-    PrintWriter stderr;
-    int forcedExitCode = 0;
-
-    public void logError(String msg) {
-        stderr.println(msg);
-        forcedExitCode = -1;
-    }
-
-    /**
-     * Invoked by the executor service.
-     */
-    public void run() {
-        // Unique nr that identifies this request.
-        int thisRequest = compilerPool.startRequest();
-        long start = System.currentTimeMillis();
-        int numClasses = 0;
-        StringBuilder compiledPkgs = new StringBuilder();
-        use();
-
-        PrintWriter out = null;
-        try {
-            javacServer.log("<"+thisRequest+"> Connect from "+socket.getRemoteSocketAddress()+" activethreads="+compilerPool.numActiveRequests());
-            BufferedReader in = new BufferedReader(new InputStreamReader(
-                                                       socket.getInputStream()));
-            out = new PrintWriter(new OutputStreamWriter(
-                                                  socket.getOutputStream()));
-            if (!expect(in, JavacServer.PROTOCOL_COOKIE_VERSION)) {
-                javacServer.log("<"+thisRequest+"> Bad protocol from ip "+socket.getRemoteSocketAddress());
-                return;
-            }
-
-            String cookie = in.readLine();
-            if (cookie == null || !cookie.equals(""+javacServer.getCookie())) {
-                javacServer.log("<"+thisRequest+"> Bad cookie from ip "+socket.getRemoteSocketAddress());
-                return;
-            }
-            if (!expect(in, JavacServer.PROTOCOL_CWD)) {
-                return;
-            }
-            String cwd = in.readLine();
-            if (cwd == null)
-                return;
-            if (!expect(in, JavacServer.PROTOCOL_ID)) {
-                return;
-            }
-            id = in.readLine();
-            if (id == null)
-                return;
-            if (!expect(in, JavacServer.PROTOCOL_ARGS)) {
-                return;
-            }
-            ArrayList<String> the_options = new ArrayList<>();
-            ArrayList<File> the_classes = new ArrayList<>();
-            Iterable<File> path = Arrays.<File> asList(new File(cwd));
-
-            for (;;) {
-                String l = in.readLine();
-                if (l == null)
-                    return;
-                if (l.equals(JavacServer.PROTOCOL_SOURCES_TO_COMPILE))
-                    break;
-                if (l.startsWith("--server:"))
-                    continue;
-                if (!l.startsWith("-") && l.endsWith(".java")) {
-                    the_classes.add(new File(l));
-                    numClasses++;
-                } else {
-                    the_options.add(l);
-                }
-                continue;
-            }
-
-            // Load sources to compile
-            Set<URI> sourcesToCompile = new HashSet<>();
-            for (;;) {
-                String l = in.readLine();
-                if (l == null)
-                    return;
-                if (l.equals(JavacServer.PROTOCOL_VISIBLE_SOURCES))
-                    break;
-                try {
-                    sourcesToCompile.add(new URI(l));
-                    numClasses++;
-                } catch (URISyntaxException e) {
-                    return;
-                }
-            }
-            // Load visible sources
-            Set<URI> visibleSources = new HashSet<>();
-            boolean fix_drive_letter_case =
-                StringUtils.toLowerCase(System.getProperty("os.name")).startsWith("windows");
-            for (;;) {
-                String l = in.readLine();
-                if (l == null)
-                    return;
-                if (l.equals(JavacServer.PROTOCOL_END))
-                    break;
-                try {
-                    URI u = new URI(l);
-                    if (fix_drive_letter_case) {
-                        // Make sure the driver letter is lower case.
-                        String s = u.toString();
-                        if (s.startsWith("file:/") &&
-                            Character.isUpperCase(s.charAt(6))) {
-                            u = new URI("file:/"+Character.toLowerCase(s.charAt(6))+s.substring(7));
-                        }
-                    }
-                    visibleSources.add(u);
-                } catch (URISyntaxException e) {
-                    return;
-                }
-            }
-
-            // A completed request has been received.
-
-            // Now setup the actual compilation....
-            // First deal with explicit source files on cmdline and in at file.
-            ListBuffer<JavaFileObject> compilationUnits = new ListBuffer<>();
-            for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(the_classes)) {
-                compilationUnits.append(i);
-            }
-            // Now deal with sources supplied as source_to_compile.
-            ListBuffer<File> sourcesToCompileFiles = new ListBuffer<>();
-            for (URI u : sourcesToCompile) {
-                sourcesToCompileFiles.append(new File(u));
-            }
-            for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(sourcesToCompileFiles)) {
-                compilationUnits.append(i);
-            }
-            // Log the options to be used.
-            StringBuilder options = new StringBuilder();
-            for (String s : the_options) {
-                options.append(">").append(s).append("< ");
-            }
-            javacServer.log(id+" <"+thisRequest+"> options "+options.toString());
-
-            forcedExitCode = 0;
-            // Create a new logger.
-            StringWriter stdoutLog = new StringWriter();
-            StringWriter stderrLog = new StringWriter();
-            stdout = new PrintWriter(stdoutLog);
-            stderr = new PrintWriter(stderrLog);
-            com.sun.tools.javac.main.Main.Result rc = com.sun.tools.javac.main.Main.Result.OK;
-            try {
-                if (compilationUnits.size() > 0) {
-                    smartFileManager.setVisibleSources(visibleSources);
-                    smartFileManager.cleanArtifacts();
-                    smartFileManager.setLog(stdout);
-
-                    // Do the compilation!
-                    CompilationTask task = compiler.getTask(stderr, smartFileManager, null, the_options, null, compilationUnits, context);
-                    smartFileManager.setSymbolFileEnabled(!Options.instance(context).isSet("ignore.symbol.file"));
-                    rc = ((JavacTaskImpl) task).doCall();
-
-                    while (numActiveSubTasks()>0) {
-                        try { Thread.sleep(1000); } catch (InterruptedException e) { }
-                    }
-
-                    smartFileManager.flush();
-                }
-            } catch (Exception e) {
-                stderr.println(e.getMessage());
-                forcedExitCode = -1;
-            }
-
-            // Send the response..
-            out.println(JavacServer.PROTOCOL_STDOUT);
-            out.print(stdoutLog);
-            out.println(JavacServer.PROTOCOL_STDERR);
-            out.print(stderrLog);
-            // The compilation is complete! And errors will have already been printed on out!
-            out.println(JavacServer.PROTOCOL_PACKAGE_ARTIFACTS);
-            Map<String,Set<URI>> pa = smartFileManager.getPackageArtifacts();
-            for (String aPkgName : pa.keySet()) {
-                out.println("+"+aPkgName);
-                Set<URI> as = pa.get(aPkgName);
-                for (URI a : as) {
-                    out.println(" "+a.toString());
-                }
-            }
-            Dependencies deps = Dependencies.instance(context);
-            out.println(JavacServer.PROTOCOL_PACKAGE_DEPENDENCIES);
-            Map<String,Set<String>> pd = deps.getDependencies();
-            for (String aPkgName : pd.keySet()) {
-                out.println("+"+aPkgName);
-                Set<String> ds = pd.get(aPkgName);
-                    // Everything depends on java.lang
-                    if (!ds.contains(":java.lang")) ds.add(":java.lang");
-                for (String d : ds) {
-                    out.println(" "+d);
-                }
-            }
-            out.println(JavacServer.PROTOCOL_PACKAGE_PUBLIC_APIS);
-            Map<String,String> pp = deps.getPubapis();
-            for (String aPkgName : pp.keySet()) {
-                out.println("+"+aPkgName);
-                String ps = pp.get(aPkgName);
-                // getPubapis added a space to each line!
-                out.println(ps);
-                compiledPkgs.append(aPkgName+" ");
-            }
-            out.println(JavacServer.PROTOCOL_SYSINFO);
-            out.println("num_cores=" + Runtime.getRuntime().availableProcessors());
-            out.println("max_memory=" + Runtime.getRuntime().maxMemory());
-            out.println(JavacServer.PROTOCOL_RETURN_CODE);
-
-            // Errors from sjavac that affect compilation status!
-            int rcv = rc.exitCode;
-            if (rcv == 0 && forcedExitCode != 0) {
-                rcv = forcedExitCode;
-            }
-            out.println("" + rcv);
-            out.println(JavacServer.PROTOCOL_END);
-            out.flush();
-        } catch (IOException e) {
-            e.printStackTrace();
-        } finally {
-            try {
-                if (out != null) out.close();
-                if (!socket.isClosed()) {
-                    socket.close();
-                }
-                socket = null;
-            } catch (Exception e) {
-                javacServer.log("ERROR "+e);
-                e.printStackTrace();
-            }
-            compilerPool.stopRequest();
-            long duration = System.currentTimeMillis()-start;
-            javacServer.addBuildTime(duration);
-            float classpersec = ((float)numClasses)*(((float)1000.0)/((float)duration));
-            javacServer.log(id+" <"+thisRequest+"> "+compiledPkgs+" duration " + duration+ " ms    num_classes="+numClasses+
-                             "     classpersec="+classpersec+" subtasks="+subTasks.size());
-            javacServer.flushLog();
-            unuse();
-            compilerPool.returnCompilerThread(this);
-        }
-    }
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/IdleResetSjavac.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.server;
+
+import java.io.File;
+import java.net.URI;
+import java.util.List;
+import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * An sjavac implementation that keeps track of idleness and shuts down the
+ * given Terminable upon idleness timeout.
+ *
+ * An idleness timeout kicks in {@code idleTimeout} milliseconds after the last
+ * request is completed.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class IdleResetSjavac implements Sjavac {
+
+    private final Sjavac delegate;
+    private final AtomicInteger outstandingCalls = new AtomicInteger();
+    private final Terminable toShutdown;
+    private final Timer idlenessTimer = new Timer();
+    private final long idleTimeout;
+
+    // Class invariant: idlenessTimerTask != null <-> idlenessTimerTask is scheduled
+    private TimerTask idlenessTimerTask;
+
+    public IdleResetSjavac(Sjavac delegate,
+                            Terminable toShutdown,
+                            long idleTimeout) {
+        this.delegate = delegate;
+        this.toShutdown = toShutdown;
+        this.idleTimeout = idleTimeout;
+        scheduleTimeout();
+    }
+
+    @Override
+    public SysInfo getSysInfo() {
+        startCall();
+        try {
+            return delegate.getSysInfo();
+        } finally {
+            endCall();
+        }
+    }
+
+    @Override
+    public CompilationResult compile(String protocolId,
+                                     String invocationId,
+                                     String[] args,
+                                     List<File> explicitSources,
+                                     Set<URI> sourcesToCompile,
+                                     Set<URI> visibleSources) {
+        startCall();
+        try {
+            return delegate.compile(protocolId,
+                                    invocationId,
+                                    args,
+                                    explicitSources,
+                                    sourcesToCompile,
+                                    visibleSources);
+        } finally {
+            endCall();
+        }
+    }
+
+    private void startCall() {
+        // Was there no outstanding calls before this call?
+        if (outstandingCalls.incrementAndGet() == 1) {
+            // Then the timer task must have been scheduled
+            if (idlenessTimerTask == null)
+                throw new IllegalStateException("Idle timeout already cancelled");
+            // Cancel timeout task
+            idlenessTimerTask.cancel();
+            idlenessTimerTask = null;
+        }
+    }
+
+    private void endCall() {
+        if (outstandingCalls.decrementAndGet() == 0) {
+            // No more outstanding calls. Schedule timeout.
+            scheduleTimeout();
+        }
+    }
+
+    private void scheduleTimeout() {
+        if (idlenessTimerTask != null)
+            throw new IllegalStateException("Idle timeout already scheduled");
+        idlenessTimerTask = new TimerTask() {
+            public void run() {
+                toShutdown.shutdown("Server has been idle for " + (idleTimeout / 1000) + " seconds.");
+            }
+        };
+        idlenessTimer.schedule(idlenessTimerTask, idleTimeout);
+    }
+
+    @Override
+    public void shutdown() {
+        idlenessTimer.cancel();
+        delegate.shutdown();
+    }
+
+    @Override
+    public String serverSettings() {
+        return delegate.serverSettings();
+    }
+}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/JavacServer.java	Thu Aug 21 14:16:28 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,382 +0,0 @@
-/*
- * Copyright (c) 2011-2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.sun.tools.sjavac.server;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.FileNotFoundException;
-import java.util.HashMap;
-import java.util.Map;
-
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.Random;
-
-import com.sun.tools.sjavac.Util;
-import com.sun.tools.sjavac.ProblemException;
-import java.io.*;
-
-/**
- * The JavacServer class contains methods both to setup a server that responds to requests and methods to connect to this server.
- *
- * <p><b>This is NOT part of any supported API. If you write code that depends on this, you do so at your own risk. This code and its internal interfaces are
- * subject to change or deletion without notice.</b></p>
- */
-public class JavacServer {
-    // Responding to this tcp/ip port on localhost.
-
-    private final ServerSocket serverSocket;
-    // The secret cookie shared between server and client through the port file.
-    private final long myCookie;
-    // When the server was started.
-    private long serverStart;
-    // Accumulated build time for all requests, not counting idle time.
-    private long totalBuildTime;
-    // The javac server specific log file.
-    PrintWriter theLog;
-    // The compiler pool that maintains the compiler threads.
-    CompilerPool compilerPool;
-    // For the client, all port files fetched, one per started javac server.
-    // Though usually only one javac server is started by a client.
-    private static Map<String, PortFile> allPortFiles;
-    private static Map<String, Long> maxServerMemory;
-    final static String PROTOCOL_COOKIE_VERSION = "----THE-COOKIE-V2----";
-    final static String PROTOCOL_CWD = "----THE-CWD----";
-    final static String PROTOCOL_ID = "----THE-ID----";
-    final static String PROTOCOL_ARGS = "----THE-ARGS----";
-    final static String PROTOCOL_SOURCES_TO_COMPILE = "----THE-SOURCES-TO-COMPILE----";
-    final static String PROTOCOL_VISIBLE_SOURCES = "----THE-VISIBLE-SOURCES----";
-    final static String PROTOCOL_END = "----THE-END----";
-    final static String PROTOCOL_STDOUT = "----THE-STDOUT----";
-    final static String PROTOCOL_STDERR = "----THE-STDERR----";
-    final static String PROTOCOL_PACKAGE_ARTIFACTS = "----THE-PACKAGE_ARTIFACTS----";
-    final static String PROTOCOL_PACKAGE_DEPENDENCIES = "----THE-PACKAGE_DEPENDENCIES----";
-    final static String PROTOCOL_PACKAGE_PUBLIC_APIS = "----THE-PACKAGE-PUBLIC-APIS----";
-    final static String PROTOCOL_SYSINFO = "----THE-SYSINFO----";
-    final static String PROTOCOL_RETURN_CODE = "----THE-RETURN-CODE----";
-    // Check if the portfile is gone, every 5 seconds.
-    static int CHECK_PORTFILE_INTERVAL = 5;
-    // Wait 2 seconds for response, before giving up on javac server.
-    static int CONNECTION_TIMEOUT = 2;
-    static int WAIT_BETWEEN_CONNECT_ATTEMPTS = 1;
-    static int MAX_NUM_CONNECT_ATTEMPTS = 3;
-
-    /**
-     * Acquire the port file. Synchronized since several threads inside an smart javac wrapper client acquires the same port file at the same time.
-     */
-    public static synchronized PortFile getPortFile(String filename) throws FileNotFoundException {
-        if (allPortFiles == null) {
-            allPortFiles = new HashMap<>();
-        }
-        PortFile pf = allPortFiles.get(filename);
-
-        // Port file known. Does it still exist?
-        if (pf != null) {
-            try {
-                if (!pf.exists())
-                    pf = null;
-            } catch (IOException ioex) {
-                ioex.printStackTrace();
-            }
-        }
-
-        if (pf == null) {
-            pf = new PortFile(filename);
-            allPortFiles.put(filename, pf);
-        }
-        return pf;
-    }
-
-    /**
-     * Get the cookie used for this server.
-     */
-    long getCookie() {
-        return myCookie;
-    }
-
-    /**
-     * Get the port used for this server.
-     */
-    int getPort() {
-        return serverSocket.getLocalPort();
-    }
-
-    /**
-     * Sum up the total build time for this javac server.
-     */
-    public void addBuildTime(long inc) {
-        totalBuildTime += inc;
-    }
-
-    /**
-     * Log this message.
-     */
-    public void log(String msg) {
-        if (theLog != null) {
-            theLog.println(msg);
-        } else {
-            System.err.println(msg);
-        }
-    }
-
-    /**
-     * Make sure the log is flushed.
-     */
-    public void flushLog() {
-        if (theLog != null) {
-            theLog.flush();
-        }
-    }
-
-    /**
-     * Start a server using a settings string. Typically: "--startserver:portfile=/tmp/myserver,poolsize=3" and the string "portfile=/tmp/myserver,poolsize=3"
-     * is sent as the settings parameter. Returns 0 on success, -1 on failure.
-     */
-    public static int startServer(String settings, PrintStream err) {
-        try {
-            String portfile = Util.extractStringOption("portfile", settings);
-            // The log file collects more javac server specific log information.
-            String logfile = Util.extractStringOption("logfile", settings);
-            // The stdouterr file collects all the System.out and System.err writes to disk.
-            String stdouterrfile = Util.extractStringOption("stdouterrfile", settings);
-            // We could perhaps use System.setOut and setErr here.
-            // But for the moment we rely on the client to spawn a shell where stdout
-            // and stderr are redirected already.
-            // The pool size is a limit the number of concurrent compiler threads used.
-            // The server might use less than these to avoid memory problems.
-            int defaultPoolSize = Runtime.getRuntime().availableProcessors();
-            int poolsize = Util.extractIntOption("poolsize", settings, defaultPoolSize);
-
-            // How many seconds of inactivity will the server accept before quitting?
-            int keepalive = Util.extractIntOption("keepalive", settings, 120);
-
-            // The port file is locked and the server port and cookie is written into it.
-            PortFile portFile = getPortFile(portfile);
-            JavacServer s;
-
-            synchronized (portFile) {
-                portFile.lock();
-                portFile.getValues();
-                if (portFile.containsPortInfo()) {
-                    err.println("Javac server not started because portfile exists!");
-                    portFile.unlock();
-                    return -1;
-                }
-                s = new JavacServer(poolsize, logfile);
-                portFile.setValues(s.getPort(), s.getCookie());
-                portFile.unlock();
-            }
-
-            // Run the server. Will delete the port file when shutting down.
-            // It will shut down automatically when no new requests have come in
-            // during the last 125 seconds.
-            s.run(portFile, err, keepalive);
-            // The run loop for the server has exited.
-            return 0;
-        } catch (Exception e) {
-            e.printStackTrace(err);
-            return -1;
-        }
-    }
-
-    /**
-     * Spawn the server instance.
-     */
-
-    private JavacServer(int poolSize, String logfile) throws IOException {
-        serverStart = System.currentTimeMillis();
-        // Create a server socket on a random port that is bound to the localhost/127.0.0.1 interface.
-        // I.e only local processes can connect to this port.
-        serverSocket = new ServerSocket(0, 128, InetAddress.getByName(null));
-        compilerPool = new CompilerPool(poolSize, this);
-        Random rnd = new Random();
-        myCookie = rnd.nextLong();
-        theLog = new PrintWriter(logfile);
-        log("Javac server started. port=" + getPort() + " date=" + (new java.util.Date()) + " with poolsize=" + poolSize);
-        flushLog();
-    }
-
-    /**
-     * Fork a background process. Returns the command line used that can be printed if something failed.
-     */
-    public static String fork(String sjavac, String portfile, String logfile, int poolsize, int keepalive,
-            final PrintStream err, String stdouterrfile, boolean background)
-            throws IOException, ProblemException {
-        if (stdouterrfile != null && stdouterrfile.trim().equals("")) {
-            stdouterrfile = null;
-        }
-        final String startserver = "--startserver:portfile=" + portfile + ",logfile=" + logfile + ",stdouterrfile=" + stdouterrfile + ",poolsize=" + poolsize + ",keepalive="+ keepalive;
-
-        if (background) {
-            sjavac += "%20" + startserver;
-            sjavac = sjavac.replaceAll("%20", " ");
-            sjavac = sjavac.replaceAll("%2C", ",");
-            // If the java/sh/cmd launcher fails the failure will be captured by stdouterr because of the redirection here.
-            String[] cmd = {"/bin/sh", "-c", sjavac + " >> " + stdouterrfile + " 2>&1"};
-            if (!(new File("/bin/sh")).canExecute()) {
-                ArrayList<String> wincmd = new ArrayList<>();
-                wincmd.add("cmd");
-                wincmd.add("/c");
-                wincmd.add("start");
-                wincmd.add("cmd");
-                wincmd.add("/c");
-                wincmd.add(sjavac + " >> " + stdouterrfile + " 2>&1");
-                cmd = wincmd.toArray(new String[wincmd.size()]);
-            }
-            Process pp = null;
-            try {
-                pp = Runtime.getRuntime().exec(cmd);
-            } catch (Exception e) {
-                e.printStackTrace(err);
-                e.printStackTrace(new PrintWriter(stdouterrfile));
-            }
-            StringBuilder rs = new StringBuilder();
-            for (String s : cmd) {
-                rs.append(s + " ");
-            }
-            return rs.toString();
-        }
-
-        // Do not spawn a background server, instead run it within the same JVM.
-        Thread t = new Thread() {
-            @Override
-            public void run() {
-                try {
-                    JavacServer.startServer(startserver, err);
-                } catch (Throwable t) {
-                    t.printStackTrace(err);
-                }
-            }
-        };
-        t.start();
-        return "";
-    }
-
-    /**
-     * Run the server thread until it exits. Either because of inactivity or because the port file has been deleted by someone else, or overtaken by some other
-     * javac server.
-     */
-    private void run(PortFile portFile, PrintStream err, int keepalive) {
-        boolean fileDeleted = false;
-        long timeSinceLastCompile;
-        try {
-            // Every 5 second (check_portfile_interval) we test if the portfile has disappeared => quit
-            // Or if the last request was finished more than 125 seconds ago => quit
-            // 125 = seconds_of_inactivity_before_shutdown+check_portfile_interval
-            serverSocket.setSoTimeout(CHECK_PORTFILE_INTERVAL*1000);
-            for (;;) {
-                try {
-                    Socket s = serverSocket.accept();
-                    CompilerThread ct = compilerPool.grabCompilerThread();
-                    ct.setSocket(s);
-                    compilerPool.execute(ct);
-                    flushLog();
-                } catch (java.net.SocketTimeoutException e) {
-                    if (compilerPool.numActiveRequests() > 0) {
-                        // Never quit while there are active requests!
-                        continue;
-                    }
-                    // If this is the timeout after the portfile
-                    // has been deleted by us. Then we truly stop.
-                    if (fileDeleted) {
-                        log("Quitting because of "+(keepalive+CHECK_PORTFILE_INTERVAL)+" seconds of inactivity!");
-                        break;
-                    }
-                    // Check if the portfile is still there.
-                    if (!portFile.exists()) {
-                        // Time to quit because the portfile was deleted by another
-                        // process, probably by the makefile that is done building.
-                        log("Quitting because portfile was deleted!");
-                        flushLog();
-                        break;
-                    }
-                    // Check if portfile.stop is still there.
-                    if (portFile.markedForStop()) {
-                        // Time to quit because another process touched the file
-                        // server.port.stop to signal that the server should stop.
-                        // This is necessary on some operating systems that lock
-                        // the port file hard!
-                        log("Quitting because a portfile.stop file was found!");
-                        portFile.delete();
-                        flushLog();
-                        break;
-                    }
-                    // Does the portfile still point to me?
-                    if (!portFile.stillMyValues()) {
-                        // Time to quit because another build has started.
-                        log("Quitting because portfile is now owned by another javac server!");
-                        flushLog();
-                        break;
-                    }
-
-                    // Check how long since the last request finished.
-                    long diff = System.currentTimeMillis() - compilerPool.lastRequestFinished();
-                    if (diff < keepalive * 1000) {
-                        // Do not quit if we have waited less than 120 seconds.
-                        continue;
-                    }
-                    // Ok, time to quit because of inactivity. Perhaps the build
-                    // was killed and the portfile not cleaned up properly.
-                    portFile.delete();
-                    fileDeleted = true;
-                    log("" + keepalive + " seconds of inactivity quitting in "
-                        + CHECK_PORTFILE_INTERVAL + " seconds!");
-                    flushLog();
-                    // Now we have a second 5 second grace
-                    // period where javac remote requests
-                    // that have loaded the data from the
-                    // recently deleted portfile can connect
-                    // and complete their requests.
-                }
-            }
-        } catch (Exception e) {
-            e.printStackTrace(err);
-            e.printStackTrace(theLog);
-            flushLog();
-        } finally {
-            compilerPool.shutdown();
-        }
-        long realTime = System.currentTimeMillis() - serverStart;
-        log("Shutting down.");
-        log("Total wall clock time " + realTime + "ms build time " + totalBuildTime + "ms");
-        flushLog();
-    }
-
-    public static void cleanup(String... args) {
-        String settings = Util.findServerSettings(args);
-        if (settings == null) return;
-        String portfile = Util.extractStringOption("portfile", settings);
-        String background = Util.extractStringOption("background", settings);
-        if (background != null && background.equals("false")) {
-            // If the server runs within this jvm, then delete the portfile,
-            // since this jvm is about to exit soon.
-            File f = new File(portfile);
-            f.delete();
-        }
-    }
-}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/JavacService.java	Thu Aug 21 14:16:28 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.tools.sjavac.server;
-
-import java.io.File;
-import java.net.URI;
-import java.util.List;
-import java.util.Set;
-
-public interface JavacService {
-
-    SysInfo getSysInfo();
-
-    CompilationResult compile(String protocolId,
-                              String invocationId,
-                              String[] args,
-                              List<File> explicitSources,
-                              Set<URI> sourcesToCompile,
-                              Set<URI> visibleSources);
-}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/JavacServiceClient.java	Thu Aug 21 14:16:28 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,433 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.tools.sjavac.server;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.net.URI;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import com.sun.tools.sjavac.Util;
-
-import static com.sun.tools.sjavac.server.CompilationResult.ERROR_BUT_TRY_AGAIN;
-import static com.sun.tools.sjavac.server.CompilationResult.ERROR_FATAL;
-
-public class JavacServiceClient implements JavacService {
-
-
-    // The id can perhaps be used in the future by the javac server to reuse the
-    // JavaCompiler instance for several compiles using the same id.
-    private final String id;
-    private final String portfile;
-    private final String logfile;
-    private final String stdouterrfile;
-    private final boolean background;
-
-    // Default keepalive for server is 120 seconds.
-    // I.e. it will accept 120 seconds of inactivity before quitting.
-    private final int keepalive;
-    private final int poolsize;
-
-    // The sjavac option specifies how the server part of sjavac is spawned.
-    // If you have the experimental sjavac in your path, you are done. If not, you have
-    // to point to a com.sun.tools.sjavac.Main that supports --startserver
-    // for example by setting: sjavac=java%20-jar%20...javac.jar%com.sun.tools.sjavac.Main
-    private final String sjavac;
-
-    public JavacServiceClient(String settings) {
-        id = Util.extractStringOption("id", settings);
-        portfile = Util.extractStringOption("portfile", settings);
-        logfile = Util.extractStringOption("logfile", settings, portfile + ".javaclog");
-        stdouterrfile = Util.extractStringOption("stdouterrfile", settings, portfile + ".stdouterr");
-        background = Util.extractBooleanOption("background", settings, true);
-        sjavac = Util.extractStringOption("sjavac", settings, "sjavac");
-        int poolsize = Util.extractIntOption("poolsize", settings);
-        keepalive = Util.extractIntOption("keepalive", settings, 120);
-
-        this.poolsize = poolsize > 0 ? poolsize : Runtime.getRuntime().availableProcessors();
-    }
-
-
-    /**
-     * Make a request to the server only to get the maximum possible heap size to use for compilations.
-     *
-     * @param port_file The port file used to synchronize creation of this server.
-     * @param id The identify of the compilation.
-     * @param out Standard out information.
-     * @param err Standard err information.
-     * @return The maximum heap size in bytes.
-     */
-    @Override
-    public SysInfo getSysInfo() {
-        try {
-            CompilationResult cr = useServer(new String[0],
-                                             Collections.<URI>emptySet(),
-                                             Collections.<URI>emptySet(),
-                                             Collections.<URI, Set<String>>emptyMap());
-            return cr.sysinfo;
-        } catch (Exception e) {
-            return new SysInfo(-1, -1);
-        }
-    }
-
-    @Override
-    public CompilationResult compile(String protocolId,
-                                     String invocationId,
-                                     String[] args,
-                                     List<File> explicitSources,
-                                     Set<URI> sourcesToCompile,
-                                     Set<URI> visibleSources) {
-        // Delegate to useServer, which delegates to compileHelper
-        return useServer(args, sourcesToCompile, visibleSources, null);
-    }
-
-    /**
-     * Connect and compile using the javac server settings and the args. When using more advanced features, the sources_to_compile and visible_sources are
-     * supplied to the server and meta data is returned in package_artifacts, package_dependencies and package_pubapis.
-     */
-    public CompilationResult compileHelper(String id,
-                                           String[] args,
-                                           Set<URI> sourcesToCompile,
-                                           Set<URI> visibleSources) {
-
-        CompilationResult rc = new CompilationResult(-3);
-
-        try {
-            PortFile portFile = JavacServer.getPortFile(this.portfile);
-
-            int port = portFile.containsPortInfo() ? portFile.getPort() : 0;
-            if (port == 0) {
-                return new CompilationResult(ERROR_BUT_TRY_AGAIN);
-            }
-            long cookie = portFile.getCookie();
-            // Acquire the localhost/127.0.0.1 address.
-            InetAddress addr = InetAddress.getByName(null);
-            SocketAddress sockaddr = new InetSocketAddress(addr, port);
-            Socket sock = new Socket();
-            int timeoutMs = JavacServer.CONNECTION_TIMEOUT * 1000;
-            try {
-                sock.connect(sockaddr, timeoutMs);
-            } catch (java.net.ConnectException e) {
-                rc.setReturnCode(ERROR_BUT_TRY_AGAIN);
-                rc.stderr = "Could not connect to javac server found in portfile: " + portFile.getFilename() + " " + e;
-                return rc;
-            }
-            if (!sock.isConnected()) {
-                rc.setReturnCode(ERROR_BUT_TRY_AGAIN);
-                rc.stderr = "Could not connect to javac server found in portfile: " + portFile.getFilename();
-                return rc;
-            }
-
-            //
-            // Send arguments
-            //
-            BufferedReader in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
-            PrintWriter sockout = new PrintWriter(sock.getOutputStream());
-
-            sockout.println(JavacServer.PROTOCOL_COOKIE_VERSION);
-            sockout.println("" + cookie);
-            sockout.println(JavacServer.PROTOCOL_CWD);
-            sockout.println(System.getProperty("user.dir"));
-            sockout.println(JavacServer.PROTOCOL_ID);
-            sockout.println(id);
-            sockout.println(JavacServer.PROTOCOL_ARGS);
-            for (String s : args) {
-                StringBuffer buf = new StringBuffer();
-                String[] paths = s.split(File.pathSeparator);
-                int c = 0;
-                for (String path : paths) {
-                    File f = new File(path);
-                    if (f.isFile() || f.isDirectory()) {
-                        buf.append(f.getAbsolutePath());
-                        c++;
-                        if (c < paths.length) {
-                            buf.append(File.pathSeparator);
-                        }
-                    } else {
-                        buf = new StringBuffer(s);
-                        break;
-                    }
-                }
-                sockout.println(buf.toString());
-            }
-            sockout.println(JavacServer.PROTOCOL_SOURCES_TO_COMPILE);
-            for (URI uri : sourcesToCompile) {
-                sockout.println(uri.toString());
-            }
-            sockout.println(JavacServer.PROTOCOL_VISIBLE_SOURCES);
-            for (URI uri : visibleSources) {
-                sockout.println(uri.toString());
-            }
-            sockout.println(JavacServer.PROTOCOL_END);
-            sockout.flush();
-
-            //
-            // Receive result
-            //
-            StringBuffer stdout = new StringBuffer();
-            StringBuffer stderr = new StringBuffer();
-
-            if (!JavacServiceClient.expect(in, JavacServer.PROTOCOL_STDOUT)) {
-                return new CompilationResult(ERROR_FATAL);
-            }
-            // Load stdout
-            for (;;) {
-                String l = in.readLine();
-                if (l == null) {
-                    return new CompilationResult(ERROR_FATAL);
-                }
-                if (l.equals(JavacServer.PROTOCOL_STDERR)) {
-                    break;
-                }
-                stdout.append(l);
-                stdout.append('\n');
-            }
-            // Load stderr
-            for (;;) {
-                String l = in.readLine();
-                if (l == null) {
-                    return new CompilationResult(ERROR_FATAL);
-                }
-                if (l.equals(JavacServer.PROTOCOL_PACKAGE_ARTIFACTS)) {
-                    break;
-                }
-                stderr.append(l);
-                stderr.append('\n');
-            }
-            // Load the package artifacts
-            Set<URI> lastUriSet = null;
-            for (;;) {
-                String l = in.readLine();
-                if (l == null) {
-                    return new CompilationResult(ERROR_FATAL);
-                }
-                if (l.equals(JavacServer.PROTOCOL_PACKAGE_DEPENDENCIES)) {
-                    break;
-                }
-                if (l.length() > 1 && l.charAt(0) == '+') {
-                    String pkg = l.substring(1);
-                    lastUriSet = new HashSet<>();
-                    rc.packageArtifacts.put(pkg, lastUriSet);
-                } else if (l.length() > 1 && lastUriSet != null) {
-                    lastUriSet.add(new URI(l.substring(1)));
-                }
-            }
-            // Load package dependencies
-            Set<String> lastPackageSet = null;
-            for (;;) {
-                String l = in.readLine();
-                if (l == null) {
-                    return new CompilationResult(ERROR_FATAL);
-                }
-                if (l.equals(JavacServer.PROTOCOL_PACKAGE_PUBLIC_APIS)) {
-                    break;
-                }
-                if (l.length() > 1 && l.charAt(0) == '+') {
-                    String pkg = l.substring(1);
-                    lastPackageSet = new HashSet<>();
-                    rc.packageDependencies.put(pkg, lastPackageSet);
-                } else if (l.length() > 1 && lastPackageSet != null) {
-                    lastPackageSet.add(l.substring(1));
-                }
-            }
-            // Load package pubapis
-            Map<String, StringBuffer> tmp = new HashMap<>();
-            StringBuffer lastPublicApi = null;
-            for (;;) {
-                String l = in.readLine();
-                if (l == null) {
-                    return new CompilationResult(ERROR_FATAL);
-                }
-                if (l.equals(JavacServer.PROTOCOL_SYSINFO)) {
-                    break;
-                }
-                if (l.length() > 1 && l.charAt(0) == '+') {
-                    String pkg = l.substring(1);
-                    lastPublicApi = new StringBuffer();
-                    tmp.put(pkg, lastPublicApi);
-                } else if (l.length() > 1 && lastPublicApi != null) {
-                    lastPublicApi.append(l.substring(1));
-                    lastPublicApi.append("\n");
-                }
-            }
-            for (String p : tmp.keySet()) {
-                //assert (packagePublicApis.get(p) == null);
-                String api = tmp.get(p).toString();
-                rc.packagePubapis.put(p, api);
-            }
-            // Now reading the max memory possible.
-            for (;;) {
-                String l = in.readLine();
-                if (l == null) {
-                    return new CompilationResult(ERROR_FATAL);
-                }
-                if (l.equals(JavacServer.PROTOCOL_RETURN_CODE)) {
-                    break;
-                }
-                if (l.startsWith("num_cores=")) {
-                    rc.sysinfo.numCores = Integer.parseInt(l.substring(10));
-                }
-                if (l.startsWith("max_memory=")) {
-                    rc.sysinfo.maxMemory = Long.parseLong(l.substring(11));
-                }
-            }
-            String l = in.readLine();
-            if (l == null) {
-                rc.setReturnCode(ERROR_FATAL);
-                rc.stderr = "No return value from the server!";
-                return rc;
-            }
-            rc.setReturnCode(Integer.parseInt(l));
-            rc.stdout = stdout.toString();
-            rc.stderr = stderr.toString();
-        } catch (Exception e) {
-            StringWriter sw = new StringWriter();
-            e.printStackTrace(new PrintWriter(sw));
-            rc.stderr = sw.toString();
-        }
-        return rc;
-    }
-
-    /**
-     * Dispatch a compilation request to a javac server.
-     *
-     * @param args are the command line args to javac and is allowed to contain source files, @file and other command line options to javac.
-     *
-     * The generated classes, h files and other artifacts from the javac invocation are stored by the javac server to disk.
-     *
-     * @param sources_to_compile The sources to compile.
-     *
-     * @param visibleSources If visible sources has a non zero size, then visible_sources are the only files in the file system that the javac server can see!
-     * (Sources to compile are always visible.) The visible sources are those supplied by the (filtered) -sourcepath
-     *
-     * @param visibleClasses If visible classes for a specific root/jar has a non zero size, then visible_classes are the only class files that the javac server
-     * can see, in that root/jar. It maps from a classpath root or a jar file to the set of visible classes for that root/jar.
-     *
-     * The server return meta data about the build in the following parameters.
-     * @param package_artifacts, map from package name to set of created artifacts for that package.
-     * @param package_dependencies, map from package name to set of packages that it depends upon.
-     * @param package_pubapis, map from package name to unique string identifying its pub api.
-     */
-    public CompilationResult useServer(String[] args,
-                                       Set<URI> sourcesToCompile,
-                                       Set<URI> visibleSources,
-                                       Map<URI, Set<String>> visibleClasses) {
-        try {
-            if (portfile == null) {
-                CompilationResult cr = new CompilationResult(CompilationResult.ERROR_FATAL);
-                cr.stderr = "No portfile was specified!";
-                return cr;
-            }
-
-            int attempts = 0;
-            CompilationResult rc;
-            do {
-                PortFile port_file = JavacServer.getPortFile(portfile);
-                synchronized (port_file) {
-                    port_file.lock();
-                    port_file.getValues();
-                    port_file.unlock();
-                }
-                if (!port_file.containsPortInfo()) {
-                    String cmd = JavacServer.fork(sjavac, port_file.getFilename(), logfile, poolsize, keepalive, System.err, stdouterrfile, background);
-
-                    if (background && !port_file.waitForValidValues()) {
-                        // Ouch the server did not start! Lets print its stdouterrfile and the command used.
-                        StringWriter sw = new StringWriter();
-                        JavacServiceClient.printFailedAttempt(cmd, stdouterrfile, new PrintWriter(sw));
-                        // And give up.
-                        CompilationResult cr = new CompilationResult(ERROR_FATAL);
-                        cr.stderr = sw.toString();
-                        return cr;
-                    }
-                }
-                rc = compileHelper(id, args, sourcesToCompile, visibleSources);
-                // Try again until we manage to connect. Any error after that
-                // will cause the compilation to fail.
-                if (rc.returnCode == CompilationResult.ERROR_BUT_TRY_AGAIN) {
-                    // We could not connect to the server. Try again.
-                    attempts++;
-                    try {
-                        Thread.sleep(JavacServer.WAIT_BETWEEN_CONNECT_ATTEMPTS * 1000);
-                    } catch (InterruptedException e) {
-                    }
-                }
-            } while (rc.returnCode == ERROR_BUT_TRY_AGAIN && attempts < JavacServer.MAX_NUM_CONNECT_ATTEMPTS);
-            return rc;
-        } catch (Exception e) {
-            StringWriter sw = new StringWriter();
-            e.printStackTrace(new PrintWriter(sw));
-            CompilationResult cr = new CompilationResult(ERROR_FATAL);
-            cr.stderr = sw.toString();
-            return cr;
-        }
-    }
-
-    public static void printFailedAttempt(String cmd, String f, PrintWriter err) {
-        err.println("---- Failed to start javac server with this command -----");
-        err.println(cmd);
-        try {
-            BufferedReader in = new BufferedReader(new FileReader(f));
-            err.println("---- stdout/stderr output from attempt to start javac server -----");
-            for (;;) {
-                String l = in.readLine();
-                if (l == null) {
-                    break;
-                }
-                err.println(l);
-            }
-            err.println("------------------------------------------------------------------");
-        } catch (Exception e) {
-            err.println("The stdout/stderr output in file " + f + " does not exist and the server did not start.");
-        }
-    }
-
-    /**
-     * Expect this key on the next line read from the reader.
-     */
-    public static boolean expect(BufferedReader in, String key) throws IOException {
-        String s = in.readLine();
-        if (s != null && s.equals(key)) {
-            return true;
-        }
-        return false;
-    }
-}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/PortFile.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/PortFile.java	Thu Aug 28 14:53:49 2014 -0700
@@ -33,6 +33,7 @@
 import java.nio.channels.FileChannel;
 import java.nio.channels.FileLock;
 import java.nio.channels.FileLockInterruptionException;
+import com.sun.tools.javac.util.Assert;
 import com.sun.tools.sjavac.Log;
 
 /**
@@ -41,12 +42,12 @@
  * primitives to avoid race conditions when several javac clients are started at the same. Note that file
  * system locking is not always supported on a all operating systems and/or file systems.
  *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk.  This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
  */
-class PortFile {
+public class PortFile {
 
     // Port file format:
     // byte ordering: high byte first = big endian
@@ -72,8 +73,7 @@
      * Create a new portfile.
      * @param filename is the path to the file.
      */
-    public PortFile(String fn) throws FileNotFoundException
-    {
+    public PortFile(String fn) throws FileNotFoundException {
         filename = fn;
         file = new File(filename);
         stopFile = new File(filename+".stop");
@@ -88,7 +88,7 @@
     /**
      * Lock the port file.
      */
-    void lock() throws IOException {
+    public void lock() throws IOException {
         lock = channel.lock();
     }
 
@@ -115,7 +115,7 @@
                     containsPortInfo = false;
                 }
             }
-        } catch (Exception e) {
+        } catch (IOException e) {
             containsPortInfo = false;
         }
     }
@@ -131,7 +131,7 @@
      * If so, then we can acquire the tcp/ip port on localhost.
      */
     public int getPort() {
-        assert(containsPortInfo);
+        Assert.check(containsPortInfo);
         return serverPort;
     }
 
@@ -139,7 +139,7 @@
      * If so, then we can acquire the server cookie.
      */
     public long getCookie() {
-        assert(containsPortInfo);
+        Assert.check(containsPortInfo);
         return serverCookie;
     }
 
@@ -147,7 +147,7 @@
      * Store the values into the locked port file.
      */
     public void setValues(int port, long cookie) throws IOException {
-        assert(lock != null);
+        Assert.check(lock != null);
         rwfile.seek(0);
         // Write the magic nr that identifes a port file.
         rwfile.writeInt(magicNr);
@@ -192,7 +192,7 @@
      * Unlock the port file.
      */
     public void unlock() throws IOException {
-        assert(lock != null);
+        Assert.check(lock != null);
         lock.release();
         lock = null;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/PortFileMonitor.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.server;
+
+import java.io.IOException;
+import java.util.Timer;
+import java.util.TimerTask;
+
+/**
+ * Monitors the presence of a port file and shuts down the given SjavacServer
+ * whenever the port file is deleted or invalidated.
+ *
+ * TODO: JDK-8046882
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class PortFileMonitor {
+
+    // Check if the portfile is gone, every 5 seconds.
+    private final static int CHECK_PORTFILE_INTERVAL = 5000;
+
+    final private Timer timer = new Timer();
+    final private PortFile portFile;
+    final private SjavacServer server;
+
+    public PortFileMonitor(PortFile portFile,
+                           SjavacServer server) {
+        this.portFile = portFile;
+        this.server = server;
+    }
+
+    public void start() {
+        TimerTask shutdownCheck = new TimerTask() {
+            public void run() {
+                try {
+                    if (!portFile.exists()) {
+                        // Time to quit because the portfile was deleted by another
+                        // process, probably by the makefile that is done building.
+                        server.shutdown("Quitting because portfile was deleted!");
+                    } else if (portFile.markedForStop()) {
+                        // Time to quit because another process touched the file
+                        // server.port.stop to signal that the server should stop.
+                        // This is necessary on some operating systems that lock
+                        // the port file hard!
+                        server.shutdown("Quitting because a portfile.stop file was found!");
+                    } else if (!portFile.stillMyValues()) {
+                        // Time to quit because another build has started.
+                        server.shutdown("Quitting because portfile is now owned by another javac server!");
+                    }
+                } catch (IOException e) {
+                    e.printStackTrace(server.theLog);
+                    server.flushLog();
+                }
+            }
+        };
+
+        timer.schedule(shutdownCheck, 0, CHECK_PORTFILE_INTERVAL);
+    }
+
+    public void shutdown() {
+        timer.cancel();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/RequestHandler.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.server;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.Socket;
+import java.net.URI;
+import java.util.List;
+import java.util.Set;
+
+import com.sun.tools.sjavac.Log;
+
+/**
+ * A RequestHandler handles requests performed over a socket. Specifically it
+ *  - Reads the command string specifying which method is to be invoked
+ *  - Reads the appropriate arguments
+ *  - Delegates the actual invocation to the given sjavac implementation
+ *  - Writes the result back to the socket output stream
+ *
+ * None of the work performed by this class is really bound by the CPU. It
+ * should be completely fine to have a large number of RequestHandlers active.
+ * To limit the number of concurrent compilations, use PooledSjavac.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class RequestHandler implements Runnable {
+
+    private final Socket socket;
+    private final Sjavac sjavac;
+
+    public RequestHandler(Socket socket, Sjavac sjavac) {
+        this.socket = socket;
+        this.sjavac = sjavac;
+    }
+
+    @Override
+    public void run() {
+        try (ObjectOutputStream oout = new ObjectOutputStream(socket.getOutputStream());
+             ObjectInputStream oin = new ObjectInputStream(socket.getInputStream())) {
+            String id = (String) oin.readObject();
+            String cmd = (String) oin.readObject();
+            Log.info("Handling request, id: " + id + " cmd: " + cmd);
+            switch (cmd) {
+            case SjavacServer.CMD_SYS_INFO: handleSysInfoRequest(oin, oout); break;
+            case SjavacServer.CMD_COMPILE:  handleCompileRequest(oin, oout); break;
+            default: Log.error("Unknown command: " + cmd);
+            }
+        } catch (Exception ex) {
+            // Not much to be done at this point. The client side request
+            // code will most likely throw an IOException and the
+            // compilation will fail.
+            StringWriter sw = new StringWriter();
+            ex.printStackTrace(new PrintWriter(sw));
+            Log.error(sw.toString());
+        }
+    }
+
+    private void handleSysInfoRequest(ObjectInputStream oin,
+                                      ObjectOutputStream oout) throws IOException {
+        oout.writeObject(sjavac.getSysInfo());
+        oout.flush();
+    }
+
+    @SuppressWarnings("unchecked")
+    private void handleCompileRequest(ObjectInputStream oin,
+                                      ObjectOutputStream oout) throws IOException {
+        try {
+            // Read request arguments
+            String protocolId = (String) oin.readObject();
+            String invocationId = (String) oin.readObject();
+            String[] args = (String[]) oin.readObject();
+            List<File> explicitSources = (List<File>) oin.readObject();
+            Set<URI> sourcesToCompile = (Set<URI>) oin.readObject();
+            Set<URI> visibleSources = (Set<URI>) oin.readObject();
+
+            // Perform compilation
+            CompilationResult cr = sjavac.compile(protocolId,
+                                                  invocationId,
+                                                  args,
+                                                  explicitSources,
+                                                  sourcesToCompile,
+                                                  visibleSources);
+            // Write request response
+            oout.writeObject(cr);
+            oout.flush();
+        } catch (ClassNotFoundException cnfe) {
+            throw new IOException(cnfe);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/Sjavac.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.server;
+
+import java.io.File;
+import java.net.URI;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Interface of the SjavacImpl, the sjavac client and all wrappers such as
+ * PooledSjavac etc.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public interface Sjavac {
+
+    SysInfo getSysInfo();
+
+    CompilationResult compile(String protocolId,
+                              String invocationId,
+                              String[] args,
+                              List<File> explicitSources,
+                              Set<URI> sourcesToCompile,
+                              Set<URI> visibleSources);
+
+    void shutdown();
+    String serverSettings();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/SjavacServer.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,349 @@
+/*
+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.server;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import com.sun.tools.sjavac.ProblemException;
+import com.sun.tools.sjavac.Util;
+import com.sun.tools.sjavac.comp.SjavacImpl;
+import com.sun.tools.sjavac.comp.PooledSjavac;
+
+/**
+ * The JavacServer class contains methods both to setup a server that responds to requests and methods to connect to this server.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class SjavacServer implements Terminable {
+
+    // Used in protocol to indicate which method to invoke
+    public final static String CMD_COMPILE = "compile";
+    public final static String CMD_SYS_INFO = "sys-info";
+
+    final private String portfilename;
+    final private String logfile;
+    final private String stdouterrfile;
+    final private int poolsize;
+    final private int keepalive;
+    final private PrintStream err;
+
+    // The secret cookie shared between server and client through the port file.
+    // Used to prevent clients from believing that they are communicating with
+    // an old server when a new server has started and reused the same port as
+    // an old server.
+    private final long myCookie;
+
+    // Accumulated build time, not counting idle time, used for logging purposes
+    private long totalBuildTime;
+
+    // The javac server specific log file.
+    PrintWriter theLog;
+
+    // The sjavac implementation to delegate requests to
+    Sjavac sjavac;
+
+    private ServerSocket serverSocket;
+
+    private PortFile portFile;
+    private PortFileMonitor portFileMonitor;
+
+    // Set to false break accept loop
+    final AtomicBoolean keepAcceptingRequests = new AtomicBoolean();
+
+    // For the client, all port files fetched, one per started javac server.
+    // Though usually only one javac server is started by a client.
+    private static Map<String, PortFile> allPortFiles;
+    private static Map<String, Long> maxServerMemory;
+
+    public SjavacServer(String settings, PrintStream err) throws FileNotFoundException {
+        // Extract options. TODO: Change to proper constructor args
+        portfilename = Util.extractStringOption("portfile", settings);
+        logfile = Util.extractStringOption("logfile", settings);
+        stdouterrfile = Util.extractStringOption("stdouterrfile", settings);
+        keepalive = Util.extractIntOption("keepalive", settings, 120);
+        poolsize = Util.extractIntOption("poolsize", settings,
+                                         Runtime.getRuntime().availableProcessors());
+        this.err = err;
+
+        myCookie = new Random().nextLong();
+        theLog = new PrintWriter(logfile);
+    }
+
+
+    /**
+     * Acquire the port file. Synchronized since several threads inside an smart javac wrapper client acquires the same port file at the same time.
+     */
+    public static synchronized PortFile getPortFile(String filename) throws FileNotFoundException {
+        if (allPortFiles == null) {
+            allPortFiles = new HashMap<>();
+        }
+        PortFile pf = allPortFiles.get(filename);
+
+        // Port file known. Does it still exist?
+        if (pf != null) {
+            try {
+                if (!pf.exists())
+                    pf = null;
+            } catch (IOException ioex) {
+                ioex.printStackTrace();
+            }
+        }
+
+        if (pf == null) {
+            pf = new PortFile(filename);
+            allPortFiles.put(filename, pf);
+        }
+        return pf;
+    }
+
+    /**
+     * Get the cookie used for this server.
+     */
+    long getCookie() {
+        return myCookie;
+    }
+
+    /**
+     * Get the port used for this server.
+     */
+    int getPort() {
+        return serverSocket.getLocalPort();
+    }
+
+    /**
+     * Sum up the total build time for this javac server.
+     */
+    public void addBuildTime(long inc) {
+        totalBuildTime += inc;
+    }
+
+    /**
+     * Log this message.
+     */
+    public void log(String msg) {
+        if (theLog != null) {
+            theLog.println(msg);
+        } else {
+            System.err.println(msg);
+        }
+    }
+
+    /**
+     * Make sure the log is flushed.
+     */
+    public void flushLog() {
+        if (theLog != null) {
+            theLog.flush();
+        }
+    }
+
+    /**
+     * Start a server using a settings string. Typically: "--startserver:portfile=/tmp/myserver,poolsize=3" and the string "portfile=/tmp/myserver,poolsize=3"
+     * is sent as the settings parameter. Returns 0 on success, -1 on failure.
+     */
+    public int startServer() throws IOException {
+        long serverStart = System.currentTimeMillis();
+
+        // The port file is locked and the server port and cookie is written into it.
+        portFile = getPortFile(portfilename);
+
+        synchronized (portFile) {
+            portFile.lock();
+            portFile.getValues();
+            if (portFile.containsPortInfo()) {
+                err.println("Javac server not started because portfile exists!");
+                portFile.unlock();
+                return -1;
+            }
+
+            //           .-----------.   .--------.   .------.
+            // socket -->| IdleReset |-->| Pooled |-->| Impl |--> javac
+            //           '-----------'   '--------'   '------'
+            sjavac = new SjavacImpl();
+            sjavac = new PooledSjavac(sjavac, poolsize);
+            sjavac = new IdleResetSjavac(sjavac,
+                                         this,
+                                         keepalive * 1000);
+
+            serverSocket = new ServerSocket();
+            InetAddress localhost = InetAddress.getByName(null);
+            serverSocket.bind(new InetSocketAddress(localhost, 0));
+
+            // At this point the server accepts connections, so it is  now safe
+            // to publish the port / cookie information
+            portFile.setValues(getPort(), getCookie());
+            portFile.unlock();
+        }
+
+        portFileMonitor = new PortFileMonitor(portFile, this);
+        portFileMonitor.start();
+
+        log("Sjavac server started. Accepting connections...");
+        log("    port: " + getPort());
+        log("    time: " + new java.util.Date());
+        log("    poolsize: " + poolsize);
+        flushLog();
+
+        keepAcceptingRequests.set(true);
+        do {
+            try {
+                Socket socket = serverSocket.accept();
+                new Thread(new RequestHandler(socket, sjavac)).start();
+            } catch (SocketException se) {
+                // Caused by serverSocket.close() and indicates shutdown
+            }
+        } while (keepAcceptingRequests.get());
+
+        log("Shutting down.");
+
+        // No more connections accepted. If any client managed to connect after
+        // the accept() was interrupted but before the server socket is closed
+        // here, any attempt to read or write to the socket will result in an
+        // IOException on the client side.
+
+        long realTime = System.currentTimeMillis() - serverStart;
+        log("Total wall clock time " + realTime + "ms build time " + totalBuildTime + "ms");
+        flushLog();
+
+        // Shut down
+        sjavac.shutdown();
+
+        return 0;
+    }
+
+    /**
+     * Fork a background process. Returns the command line used that can be printed if something failed.
+     */
+    public static String fork(String sjavac, String portfile, String logfile, int poolsize, int keepalive,
+            final PrintStream err, String stdouterrfile, boolean background)
+            throws IOException, ProblemException {
+        if (stdouterrfile != null && stdouterrfile.trim().equals("")) {
+            stdouterrfile = null;
+        }
+        final String startserver = "--startserver:portfile=" + portfile + ",logfile=" + logfile + ",stdouterrfile=" + stdouterrfile + ",poolsize=" + poolsize + ",keepalive="+ keepalive;
+
+        if (background) {
+            sjavac += "%20" + startserver;
+            sjavac = sjavac.replaceAll("%20", " ");
+            sjavac = sjavac.replaceAll("%2C", ",");
+            // If the java/sh/cmd launcher fails the failure will be captured by stdouterr because of the redirection here.
+            String[] cmd = {"/bin/sh", "-c", sjavac + " >> " + stdouterrfile + " 2>&1"};
+            if (!(new File("/bin/sh")).canExecute()) {
+                ArrayList<String> wincmd = new ArrayList<>();
+                wincmd.add("cmd");
+                wincmd.add("/c");
+                wincmd.add("start");
+                wincmd.add("cmd");
+                wincmd.add("/c");
+                wincmd.add(sjavac + " >> " + stdouterrfile + " 2>&1");
+                cmd = wincmd.toArray(new String[wincmd.size()]);
+            }
+            Process pp = null;
+            try {
+                pp = Runtime.getRuntime().exec(cmd);
+            } catch (Exception e) {
+                e.printStackTrace(err);
+                e.printStackTrace(new PrintWriter(stdouterrfile));
+            }
+            StringBuilder rs = new StringBuilder();
+            for (String s : cmd) {
+                rs.append(s + " ");
+            }
+            return rs.toString();
+        }
+
+        // Do not spawn a background server, instead run it within the same JVM.
+        Thread t = new Thread() {
+            @Override
+            public void run() {
+                try {
+                    SjavacServer server = new SjavacServer(startserver, err);
+                    server.startServer();
+                } catch (Throwable t) {
+                    t.printStackTrace(err);
+                }
+            }
+        };
+        t.setDaemon(true);
+        t.start();
+        return "";
+    }
+
+    @Override
+    public void shutdown(String quitMsg) {
+        if (!keepAcceptingRequests.compareAndSet(false, true)) {
+            // Already stopped, no need to shut down again
+            return;
+        }
+
+        log("Quitting: " + quitMsg);
+        flushLog();
+
+        portFileMonitor.shutdown(); // No longer any need to monitor port file
+
+        // Unpublish port before shutting down socket to minimize the number of
+        // failed connection attempts
+        try {
+            portFile.delete();
+        } catch (IOException e) {
+            e.printStackTrace(theLog);
+        }
+        try {
+            serverSocket.close();
+        } catch (IOException e) {
+            e.printStackTrace(theLog);
+        }
+    }
+
+    public static void cleanup(String... args) {
+        String settings = Util.findServerSettings(args);
+        if (settings == null) return;
+        String portfile = Util.extractStringOption("portfile", settings);
+        String background = Util.extractStringOption("background", settings);
+        if (background != null && background.equals("false")) {
+            // If the server runs within this jvm, then delete the portfile,
+            // since this jvm is about to exit soon.
+            File f = new File(portfile);
+            f.delete();
+        }
+    }
+}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/SysInfo.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/SysInfo.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -34,7 +34,18 @@
  */
 package com.sun.tools.sjavac.server;
 
-public class SysInfo {
+import java.io.Serializable;
+
+/**
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class SysInfo implements Serializable {
+
+    static final long serialVersionUID = -3096346807579L;
+
     public int numCores;
     public long maxMemory;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/Terminable.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.server;
+
+/**
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public interface Terminable {
+    void shutdown(String quitMsg);
+}
--- a/langtools/test/com/sun/javadoc/lib/JavadocTester.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/com/sun/javadoc/lib/JavadocTester.java	Thu Aug 28 14:53:49 2014 -0700
@@ -38,6 +38,7 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.nio.file.Files;
+import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.EnumMap;
 import java.util.HashMap;
@@ -290,6 +291,7 @@
                 break;
             }
         }
+        out.println("args: " + Arrays.toString(args));
 //        log.setOutDir(outputDir);
 
         outputDirectoryCheck.check(outputDir);
--- a/langtools/test/tools/apt/Basics/CheckAptIsRemovedTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/apt/Basics/CheckAptIsRemovedTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -25,7 +25,7 @@
  * @test
  * @bug 4908512 5024825 4957203 4993280 4996963 6174696 6177059 7041249
  * @summary Make sure apt is removed and doesn't come back
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main CheckAptIsRemovedTest
  */
@@ -34,7 +34,7 @@
 import java.nio.file.Path;
 import java.nio.file.Paths;
 
-//original test: test/tools/apt/Basics/apt.sh
+// Original test: test/tools/apt/Basics/apt.sh
 public class CheckAptIsRemovedTest {
     //I think this class can be let with the imports only and that should be enough for as test's purpose
     private static final String NullAPFSrc =
@@ -77,20 +77,18 @@
         Path aptLin = Paths.get(testJDK, "bin", "apt");
         Path aptWin = Paths.get(testJDK, "bin", "apt.exe");
 
-//        if [ -f "${TESTJAVA}/bin/apt" -o -f "${TESTJAVA}/bin/apt.exe" ];then
         if (Files.exists(aptLin) || Files.exists(aptWin)) {
             throw new AssertionError("apt executable should not exist");
         }
 
-//        JAVAC="${TESTJAVA}/bin/javac ${TESTTOOLVMOPTS} -source 1.5 -sourcepath ${TESTSRC} -classpath ${TESTJAVA}/lib/tools.jar -d . "
-//        $JAVAC ${TESTSRC}/NullAPF.java
         Path classpath = Paths.get(testJDK, "lib", "tools.jar");
-        ToolBox.JavaToolArgs javacArgs =
-                new ToolBox.JavaToolArgs(ToolBox.Expect.FAIL)
-                .setOptions("-sourcepath", ".",
-                    "-classpath", classpath.toString())
-                .setSources(NullAPFSrc);
-        ToolBox.javac(javacArgs);
+        ToolBox tb = new ToolBox();
+        tb.new JavacTask()
+                .classpath(classpath.toString()) // TODO: add overload
+                .sourcepath(".")
+                .sources(NullAPFSrc)
+                .run(ToolBox.Expect.FAIL)
+                .writeAll();
     }
 
 }
--- a/langtools/test/tools/javac/4846262/CheckEBCDICLocaleTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/4846262/CheckEBCDICLocaleTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,15 +25,17 @@
  * @test
  * @bug 4846262
  * @summary check that javac operates correctly in EBCDIC locale
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main CheckEBCDICLocaleTest
  */
 
 import java.io.File;
 import java.nio.file.Files;
+import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Arrays;
+import java.util.List;
 
 public class CheckEBCDICLocaleTest {
 
@@ -58,39 +60,32 @@
     }
 
     public void test() throws Exception {
-        String native2asciiBinary = Paths.get(
-                System.getProperty("test.jdk"),"bin", "native2ascii").toString();
-
-        ToolBox.createJavaFileFromSource(TestSrc);
-        Files.createDirectory(Paths.get("output"));
+        ToolBox tb = new ToolBox();
+        Path native2asciiBinary = tb.getJDKTool("native2ascii");
 
-        ToolBox.AnyToolArgs nativeCmdParams =
-                new ToolBox.AnyToolArgs()
-                .appendArgs(native2asciiBinary)
-                .appendArgs(ToolBox.testToolVMOpts)
-                .appendArgs("-reverse", "-encoding", "IBM1047", "Test.java",
-                "output/Test.java");
-        ToolBox.executeCommand(nativeCmdParams);
+        tb.writeFile("Test.java", TestSrc);
+        tb.createDirectories("output");
+
+        tb.new ExecTask(native2asciiBinary)
+                .args("-reverse", "-encoding", "IBM1047", "Test.java", "output/Test.java")
+                .run();
 
-        ToolBox.AnyToolArgs javacParams =
-                new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL)
-                .appendArgs(ToolBox.javacBinary)
-                .appendArgs(ToolBox.testToolVMOpts)
-                .appendArgs("-J-Duser.language=en",
-                "-J-Duser.region=US", "-J-Dfile.encoding=IBM1047",
-                "output/Test.java")
-                .setErrOutput(new File("Test.tmp"));
-        ToolBox.executeCommand(javacParams);
+        tb.new JavacTask(ToolBox.Mode.EXEC)
+                .redirect(ToolBox.OutputKind.STDERR, "Test.tmp")
+                .options("-J-Duser.language=en",
+                        "-J-Duser.region=US",
+                        "-J-Dfile.encoding=IBM1047")
+                .files("output/Test.java")
+                .run(ToolBox.Expect.FAIL);
 
-        nativeCmdParams = new ToolBox.AnyToolArgs()
-                .appendArgs(native2asciiBinary)
-                .appendArgs(ToolBox.testToolVMOpts)
-                .appendArgs("-encoding", "IBM1047", "Test.tmp", "Test.out");
-        ToolBox.executeCommand(nativeCmdParams);
+        tb.new ExecTask(native2asciiBinary)
+                .args("-encoding", "IBM1047", "Test.tmp", "Test.out")
+                .run();
 
-        String goldenFile = String.format(TestOutTemplate, File.separator);
-        ToolBox.compareLines(Paths.get("Test.out"),
-                Arrays.asList(goldenFile.split("\n")), null, true);
+        List<String> expectLines = Arrays.asList(
+                String.format(TestOutTemplate, File.separator).split("\n"));
+        List<String> actualLines = Files.readAllLines(Paths.get("Test.out"));
+        tb.checkEqual(expectLines, actualLines);
     }
 
 }
--- a/langtools/test/tools/javac/6302184/HiddenOptionsShouldUseGivenEncodingTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/6302184/HiddenOptionsShouldUseGivenEncodingTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -26,7 +26,7 @@
  * @bug 6302184 6350124 6357979
  * @summary javac hidden options that generate source should use the given
  * encoding, if available
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run compile -encoding iso-8859-1 -XD-printsource T6302184.java
  * @run main HiddenOptionsShouldUseGivenEncodingTest
@@ -34,16 +34,19 @@
 
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.List;
 
-//original test: test/tools/javac/6302184/T6302184.sh
+// Original test: test/tools/javac/6302184/T6302184.sh
 public class HiddenOptionsShouldUseGivenEncodingTest {
 
     public static void main(String[] args) throws Exception {
-//"${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d ${TC} -cp ${TC} -encoding iso-8859-1 -XD-printsource ${TS}${FS}T6302184.java 2>&1
-//diff ${DIFFOPTS} -c ${TC}${FS}T6302184.java ${TS}${FS}T6302184.out
-        Path path1 = Paths.get(System.getProperty("test.classes"), "T6302184.java");
-        Path path2 = Paths.get(System.getProperty("test.src"), "T6302184.out");
-        ToolBox.compareLines(path1, path2, "iso-8859-1");
+        ToolBox tb = new ToolBox();
+        String encoding = "iso-8859-1";
+        Path path1 = Paths.get(ToolBox.testClasses, "T6302184.java");
+        List<String> file1 = tb.readAllLines(path1, encoding);
+        Path path2 = Paths.get(ToolBox.testSrc, "T6302184.out");
+        List<String> file2 = tb.readAllLines(path2, encoding);
+        tb.checkEqual(file1, file2);
     }
 
 }
--- a/langtools/test/tools/javac/AnonymousSubclassTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/AnonymousSubclassTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -25,19 +25,18 @@
  * @test
  * @bug 8023945
  * @summary javac wrongly allows a subclass of an anonymous class
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main AnonymousSubclassTest
  */
 
-import java.util.ArrayList;
-import java.io.IOException;
-
 public class AnonymousSubclassTest {
     public static void main(String... args) throws Exception {
         new AnonymousSubclassTest().run();
     }
 
+    ToolBox tb = new ToolBox();
+
     // To trigger the error we want, first we need to compile
     // a class with an anonymous inner class: Foo$1.
     final String foo =
@@ -65,20 +64,21 @@
         "}";
 
     void compOk(String code) throws Exception {
-        ToolBox.javac(new ToolBox.JavaToolArgs().setSources(code));
+        tb.new JavacTask()
+                .sources(code)
+                .run();
     }
 
     void compFail(String code) throws Exception {
-        ArrayList<String> errors = new ArrayList<>();
-        ToolBox.JavaToolArgs args = new ToolBox.JavaToolArgs();
-        args.setSources(code)
-            .appendArgs("-cp", ".", "-XDrawDiagnostics")
-            .set(ToolBox.Expect.FAIL)
-            .setErrOutput(errors);
-        ToolBox.javac(args);
+        String errs = tb.new JavacTask()
+                .sources(code)
+                .classpath(".")
+                .options("-XDrawDiagnostics")
+                .run(ToolBox.Expect.FAIL)
+                .writeAll()
+                .getOutput(ToolBox.OutputKind.DIRECT);
 
-        if (!errors.get(0).contains("cant.inherit.from.anon")) {
-            System.out.println(errors.get(0));
+        if (!errs.contains("cant.inherit.from.anon")) {
             throw new Exception("test failed");
         }
     }
--- a/langtools/test/tools/javac/ClassPathTest/ClassPathTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/ClassPathTest/ClassPathTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,19 +25,14 @@
  * @test
  * @bug 4241229 4785453
  * @summary Test -classpath option and classpath defaults.
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main ClassPathTest
  */
 
 import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
 
-//original test: test/tools/javac/ClassPathTest/ClassPathTest.sh
+// Original test: test/tools/javac/ClassPathTest/ClassPathTest.sh
 public class ClassPathTest {
 
     private static final String ClassPathTest1Src =
@@ -70,12 +65,12 @@
         "package pkg;\n" +
         "public class ClassPathTestAux3 {}";
 
-    ProcessBuilder pb = null;
-
     public static void main(String[] args) throws Exception {
         new ClassPathTest().test();
     }
 
+    ToolBox tb = new ToolBox();
+
     public void test() throws Exception {
         createOutputDirAndSourceFiles();
         checkCompileCommands();
@@ -83,14 +78,16 @@
 
     void createOutputDirAndSourceFiles() throws Exception {
         //dirs and files creation
-        ToolBox.createJavaFileFromSource(ClassPathTest1Src);
-        ToolBox.createJavaFileFromSource(ClassPathTest2Src);
-        ToolBox.createJavaFileFromSource(ClassPathTest3Src);
-        ToolBox.createJavaFileFromSource(Paths.get("foo"),
+        tb.writeJavaFiles(Paths.get("."),
+                ClassPathTest1Src,
+                ClassPathTest2Src,
+                ClassPathTest3Src);
+        tb.writeJavaFiles(Paths.get("foo"),
                 fooPkgClassPathTestAux1Src);
-        ToolBox.createJavaFileFromSource(Paths.get("bar"),
+        tb.writeJavaFiles(Paths.get("bar"),
                 barPkgClassPathTestAux2Src);
-        ToolBox.createJavaFileFromSource(pkgClassPathTestAux3Src);
+        tb.writeJavaFiles(Paths.get("."),
+                pkgClassPathTestAux3Src);
     }
 
     void checkCompileCommands() throws Exception {
@@ -99,80 +96,55 @@
 //        automatically but this is not happening when called using ProcessBuilder
 
 //        testJavac success ClassPathTest3.java
-        List<String> mainArgs = new ArrayList<>();
-        mainArgs.add(ToolBox.javacBinary.toString());
-        if (ToolBox.testToolVMOpts != null) {
-            mainArgs.addAll(ToolBox.testToolVMOpts);
-        }
-
-        List<String> commonArgs = new ArrayList<>();
-        commonArgs.addAll(mainArgs);
-        commonArgs.addAll(Arrays.asList("-cp", "."));
-
-        ToolBox.AnyToolArgs successParams = new ToolBox.AnyToolArgs()
-                .appendArgs(commonArgs)
-                .appendArgs("ClassPathTest3.java");
-        ToolBox.executeCommand(successParams);
+        tb.new JavacTask(ToolBox.Mode.EXEC)
+                .classpath(".")
+                .files("ClassPathTest3.java")
+                .run();
 
 //        testJavac failure ClassPathTest1.java
-        ToolBox.AnyToolArgs failParams =
-                new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL)
-                .appendArgs(commonArgs)
-                .appendArgs("ClassPathTest1.java");
-        ToolBox.executeCommand(failParams);
-
-//        This is done inside the executeCommand method
-//        CLASSPATH=bar; export CLASSPATH
-
-        Map<String, String> extVars = new TreeMap<>();
-        extVars.put("CLASSPATH", "bar");
+        tb.new JavacTask(ToolBox.Mode.EXEC)
+                .classpath(".")
+                .files("ClassPathTest1.java")
+                .run(ToolBox.Expect.FAIL);
 
 //        testJavac success ClassPathTest2.java
-        successParams = new ToolBox.AnyToolArgs()
-                .appendArgs(mainArgs)
-                .appendArgs("ClassPathTest2.java")
-                .set(extVars);
-        ToolBox.executeCommand(successParams);
+        tb.new JavacTask(ToolBox.Mode.EXEC)
+                .envVar("CLASSPATH", "bar")
+                .files("ClassPathTest2.java")
+                .run();
 
 //        testJavac failure ClassPathTest1.java
-        failParams = new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL)
-                .appendArgs(mainArgs)
-                .appendArgs("ClassPathTest1.java")
-                .set(extVars);
-        ToolBox.executeCommand(failParams);
+        tb.new JavacTask(ToolBox.Mode.EXEC)
+                .envVar("CLASSPATH", "bar")
+                .files("ClassPathTest1.java")
+                .run(ToolBox.Expect.FAIL);
 
 //        testJavac failure ClassPathTest3.java
-        failParams = new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL)
-                .appendArgs(mainArgs)
-                .appendArgs("ClassPathTest3.java")
-                .set(extVars);
-        ToolBox.executeCommand(failParams);
+        tb.new JavacTask(ToolBox.Mode.EXEC)
+                .envVar("CLASSPATH", "bar")
+                .files("ClassPathTest3.java")
+                .run(ToolBox.Expect.FAIL);
 
 //        testJavac success -classpath foo ClassPathTest1.java
-
-        commonArgs.clear();
-        commonArgs.addAll(mainArgs);
-        commonArgs.addAll(Arrays.asList("-cp", "foo"));
-
-        successParams = new ToolBox.AnyToolArgs()
-                .appendArgs(commonArgs)
-                .appendArgs("ClassPathTest1.java")
-                .set(extVars);
-        ToolBox.executeCommand(successParams);
+        tb.new JavacTask(ToolBox.Mode.EXEC)
+                .envVar("CLASSPATH", "bar")
+                .classpath("foo")
+                .files("ClassPathTest1.java")
+                .run();
 
 //        testJavac failure -classpath foo ClassPathTest2.java
-        failParams = new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL)
-                .appendArgs(commonArgs)
-                .appendArgs("ClassPathTest2.java")
-                .set(extVars);
-        ToolBox.executeCommand(failParams);
+        tb.new JavacTask(ToolBox.Mode.EXEC)
+                .envVar("CLASSPATH", "bar")
+                .classpath("foo")
+                .files("ClassPathTest2.java")
+                .run(ToolBox.Expect.FAIL);
 
 //        testJavac failure -classpath foo ClassPathTest3.java
-        failParams = new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL)
-                .appendArgs(commonArgs)
-                .appendArgs("ClassPathTest3.java")
-                .set(extVars);
-        ToolBox.executeCommand(failParams);
+        tb.new JavacTask(ToolBox.Mode.EXEC)
+                .envVar("CLASSPATH", "bar")
+                .classpath("foo")
+                .files("ClassPathTest3.java")
+                .run(ToolBox.Expect.FAIL);
     }
 
 }
--- a/langtools/test/tools/javac/ConstFoldTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/ConstFoldTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -25,7 +25,7 @@
  * @test
  * @bug 8025505
  * @summary Constant folding deficiency
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main ConstFoldTest
  */
@@ -45,23 +45,23 @@
             int x;
             if (1 != 2)       x=1; else x=0;
             if (1 == 2)       x=1; else x=0;
-            if ("" != null) x=1; else x=0;
-            if ("" == null) x=1; else x=0;
+            if ("" != null)   x=1; else x=0;
+            if ("" == null)   x=1; else x=0;
             if (null == null) x=1; else x=0;
             if (null != null) x=1; else x=0;
 
             x = 1 != 2        ? 1 : 0;
             x = 1 == 2        ? 1 : 0;
-            x = "" != null  ? 1 : 0;
-            x = "" == null  ? 1 : 0;
+            x = "" != null    ? 1 : 0;
+            x = "" == null    ? 1 : 0;
             x = null == null  ? 1 : 0;
             x = null != null  ? 1 : 0;
 
             boolean b;
             b = 1 != 2         && true;
             b = 1 == 2         || true;
-            b = ("" != null) && true;
-            b = ("" == null) || true;
+            b = ("" != null)   && true;
+            b = ("" == null)   || true;
             b = (null == null) && true;
             b = (null != null) || true;
         }
@@ -72,11 +72,17 @@
     final String regex = "\\sif(?:null|nonnull|eq|ne){1}\\s";
 
     void run() throws Exception {
+        ToolBox tb = new ToolBox();
+
         URL url = ConstFoldTest.class.getResource("ConstFoldTest$CFTest.class");
-        String result = ToolBox.javap(new ToolBox.JavaToolArgs().setAllArgs("-c", url.getFile()));
-        System.out.println(result);
+        List<String> result = tb.new JavapTask()
+                .options("-c")
+                .classes(url.getFile())
+                .run()
+                .write(ToolBox.OutputKind.DIRECT)
+                .getOutputLines(ToolBox.OutputKind.DIRECT);
 
-        List<String> bad_codes = ToolBox.grep(regex, result, "\n");
+        List<String> bad_codes = tb.grep(regex, result);
         if (!bad_codes.isEmpty()) {
             for (String code : bad_codes)
                 System.out.println("Bad OpCode Found: " + code);
--- a/langtools/test/tools/javac/ExtDirs/ExtDirTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/ExtDirs/ExtDirTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,18 +25,14 @@
  * @test
  * @bug 4204897 4256097 4785453 4863609
  * @summary Test that '.jar' files in -extdirs are found.
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main ExtDirTest
  */
 
 import java.io.File;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.Arrays;
-import java.util.List;
 
-//original test: test/tools/javac/ExtDirs/ExtDirs.sh
+// Original test: test/tools/javac/ExtDirs/ExtDirs.sh
 public class ExtDirTest {
 
     private static final String ExtDirTestClass1Src =
@@ -100,72 +96,73 @@
         "SHA-Digest: ILJOhwHg5US+yuw1Sc1d+Avu628=\n" +
         "MD5-Digest: j8wnz8wneEcuJ/gjXBBQNA==\n";
 
-    List<String> ouputDirParam = Arrays.asList("-d", ".");
-
     public static void main(String args[]) throws Exception {
         new ExtDirTest().run();
     }
 
+    private final ToolBox tb = new ToolBox();
+
     void run() throws Exception {
         createJars();
         compileWithExtDirs();
     }
 
     void createJars() throws Exception {
-        sun.tools.jar.Main jarGenerator =
-                new sun.tools.jar.Main(System.out, System.err, "jar");
+        tb.new JavacTask()
+                .outdir(".")
+                .sources(ExtDirTestClass1Src)
+                .run();
 
-        ToolBox.JavaToolArgs javacParams =
-                new ToolBox.JavaToolArgs()
-                .setOptions(ouputDirParam)
-                .setSources(ExtDirTestClass1Src);
-        ToolBox.javac(javacParams);
+        tb.new JarTask("pkg1.jar")
+                .manifest(jar1Manifest)
+                .files("pkg1/ExtDirTestClass1.class")
+                .run();
 
-        ToolBox.writeFile(Paths.get("pkg1", "MANIFEST.MF"), jar1Manifest);
-        jarGenerator.run(new String[] {"cfm", "pkg1.jar", "pkg1/MANIFEST.MF",
-            "pkg1/ExtDirTestClass1.class"});
-
-        javacParams.setSources(ExtDirTestClass2Src);
-        ToolBox.javac(javacParams);
+        tb.new JavacTask()
+                .outdir(".")
+                .sources(ExtDirTestClass2Src)
+                .run();
 
-        ToolBox.writeFile(Paths.get("pkg2", "MANIFEST.MF"), jar2Manifest);
-        jarGenerator.run(new String[] {"cfm", "pkg2.jar", "pkg2/MANIFEST.MF",
-            "pkg2/ExtDirTestClass2.class"});
-
-        ToolBox.copyFile(Paths.get("ext1", "pkg1.jar"), Paths.get("pkg1.jar"));
-        ToolBox.copyFile(Paths.get("ext2", "pkg2.jar"), Paths.get("pkg2.jar"));
-        ToolBox.copyFile(Paths.get("ext3", "pkg1.jar"), Paths.get("pkg1.jar"));
-        ToolBox.copyFile(Paths.get("ext3", "pkg2.jar"), Paths.get("pkg2.jar"));
+        tb.new JarTask("pkg2.jar")
+                .manifest(jar2Manifest)
+                .files("pkg2/ExtDirTestClass2.class")
+                .run();
 
-        Files.delete(Paths.get("pkg1.jar"));
-        Files.delete(Paths.get("pkg2.jar"));
+        tb.createDirectories("ext1", "ext2", "ext3");
+        tb.copyFile("pkg1.jar", "ext1");
+        tb.copyFile("pkg2.jar", "ext2");
+        tb.copyFile("pkg1.jar", "ext3");
+        tb.copyFile("pkg2.jar", "ext3");
 
-        Files.delete(Paths.get("pkg1", "ExtDirTestClass1.class"));
-        Files.delete(Paths.get("pkg1", "MANIFEST.MF"));
-        Files.delete(Paths.get("pkg1"));
-        Files.delete(Paths.get("pkg2", "ExtDirTestClass2.class"));
-        Files.delete(Paths.get("pkg2", "MANIFEST.MF"));
-        Files.delete(Paths.get("pkg2"));
+        tb.deleteFiles(
+                "pkg1.jar",
+                "pkg2.jar",
+                "pkg1/ExtDirTestClass1.class",
+                "pkg1",
+                "pkg2/ExtDirTestClass2.class",
+                "pkg2"
+        );
     }
 
     void compileWithExtDirs() throws Exception {
-
-//javac -extdirs ext1 ExtDirTest_1.java
-        ToolBox.JavaToolArgs params =
-                new ToolBox.JavaToolArgs()
-                .setOptions("-d", ".", "-extdirs", "ext1")
-                .setSources(ExtDirTest_1Src);
-        ToolBox.javac(params);
+        tb.new JavacTask()
+                .outdir(".")
+                .options("-extdirs", "ext1")
+                .sources(ExtDirTest_1Src)
+                .run()
+                .writeAll();
 
-//javac -extdirs ext1:ext2 ExtDirTest_2.java
-        params.setOptions("-d", ".", "-extdirs", "ext1" + File.pathSeparator + "ext2")
-                .setSources(ExtDirTest_2Src);
-        ToolBox.javac(params);
+        tb.new JavacTask()
+                .outdir(".")
+                .options("-extdirs", "ext1" + File.pathSeparator + "ext2")
+                .sources(ExtDirTest_2Src)
+                .run();
 
-//javac -extdirs ext3 ExtDirTest_3.java
-        params.setOptions("-d", ".", "-extdirs", "ext3")
-                .setSources(ExtDirTest_3Src);
-        ToolBox.javac(params);
+        tb.new JavacTask()
+                .outdir(".")
+                .options("-extdirs", "ext3")
+                .sources(ExtDirTest_3Src)
+                .run();
     }
 
 }
--- a/langtools/test/tools/javac/IncorrectInheritance/IncorrectInheritanceTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/IncorrectInheritance/IncorrectInheritanceTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -25,7 +25,7 @@
  * @test
  * @bug 8034924
  * @summary Incorrect inheritance of inaccessible static method
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main IncorrectInheritanceTest
  */
@@ -59,10 +59,11 @@
     }
 
     public void test() throws Exception {
-        ToolBox.JavaToolArgs javacParams =
-                new ToolBox.JavaToolArgs()
-                .setSources(ASrc, BSrc, CSrc);
-        ToolBox.javac(javacParams);
+        ToolBox tb = new ToolBox();
+
+        tb.new JavacTask()
+                .sources(ASrc, BSrc, CSrc)
+                .run();
     }
 
 }
--- a/langtools/test/tools/javac/MissingInclude/MissingIncludeTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/MissingInclude/MissingIncludeTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -26,25 +26,26 @@
  * @bug 4509051 4785453
  * @summary javac <AT>sourcefiles should catch Exception, when sourcefiles
  * doesn't exist.
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main MissingIncludeTest
  */
 
-//original test: test/tools/javac/MissingInclude.sh
+// Original test: test/tools/javac/MissingInclude.sh
 public class MissingIncludeTest {
 
-    private static final String MissingIncludeSrc =
-        "class MissingInclude {}";
+    private static final String MissingIncludeFile = "MissingInclude.java";
+    private static final String MissingIncludeSrc = "class MissingInclude {}";
 
     public static void main(String[] args) throws Exception {
-        ToolBox.createJavaFileFromSource(MissingIncludeSrc);
+        ToolBox tb = new ToolBox();
+
+        tb.writeFile(MissingIncludeFile, MissingIncludeSrc);
 
-//        "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} @/nonexistent_file MissingInclude.java 2> ${TMP1}
-        ToolBox.JavaToolArgs params =
-                new ToolBox.JavaToolArgs(ToolBox.Expect.FAIL)
-                .setAllArgs("@/nonexistent_file", "MissingInclude.java");
-        ToolBox.javac(params);
+        tb.new JavacTask(ToolBox.Mode.CMDLINE)
+                .options("@/nonexistent_file")
+                .files(MissingIncludeFile)
+                .run(ToolBox.Expect.FAIL);
     }
 
 }
--- a/langtools/test/tools/javac/Paths/AbsolutePathTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/Paths/AbsolutePathTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -23,36 +23,49 @@
 
 /*
  * @test
+ * @ignore 8055500 [javac] fix for 8030046 is incorrect
  * @bug 8030046
  * @summary javac incorrectly handles absolute paths in manifest classpath
  * @author govereau
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main AbsolutePathTest
  */
 
 import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 
 public class AbsolutePathTest {
     public static void main(String... cmdline) throws Exception {
+        ToolBox tb = new ToolBox();
+
         // compile test.Test
-        ToolBox.JavaToolArgs args = new ToolBox.JavaToolArgs();
-        args.appendArgs("-d", "."); // this is needed to get the classfiles in test
-        ToolBox.javac(args.setSources("package test; public class Test{}"));
+        tb.new JavacTask()
+                .outdir(".") // this is needed to get the classfiles in test
+                .sources("package test; public class Test{}")
+                .run();
 
         // build test.jar containing test.Test
         // we need the jars in a directory different from the working
-        // directory to trigger the bug. I will reuse test/
-        ToolBox.jar("cf", "test/test.jar", "test/Test.class");
+        // directory to trigger the bug.
+        Files.createDirectory(Paths.get("jars"));
+        tb.new JarTask("jars/test.jar")
+                .files("test/Test.class")
+                .run();
 
-        // build second jar in test directory using
+        // build second jar in jars directory using
         // an absolute path reference to the first jar
-        String path = new File("test/test.jar").getAbsolutePath();
-        ToolBox.mkManifestWithClassPath(null, path);
-        ToolBox.jar("cfm", "test/test2.jar", "MANIFEST.MF");
+        tb.new JarTask("jars/test2.jar")
+                .classpath(new File("jars/test.jar").getAbsolutePath())
+                .run();
 
         // this should not fail
-        args.appendArgs("-cp", ".");
-        ToolBox.javac(args.setSources("import test.Test; class Test2 {}"));
+        tb.new JavacTask()
+                .outdir(".")
+                .classpath("jars/test2.jar")
+                .sources("import test.Test; class Test2 {}")
+                .run()
+                .writeAll();
     }
 }
--- a/langtools/test/tools/javac/ProtectedInnerClass/ProtectedInnerClassesTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/ProtectedInnerClass/ProtectedInnerClassesTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,13 +25,13 @@
  * @test
  * @bug 4087314 4800342 4307565
  * @summary Verify allowed access to protected class from another package
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main ProtectedInnerClassesTest
  */
 
-//original tests: test/tools/javac/ProtectedInnerClass/ProtectedInnerClass.sh
-//and test/tools/javac/ProtectedInnerClass/ProtectedInnerClass_2.java
+// Original tests: test/tools/javac/ProtectedInnerClass/ProtectedInnerClass.sh
+// and test/tools/javac/ProtectedInnerClass/ProtectedInnerClass_2.java
 public class ProtectedInnerClassesTest {
 
     private static final String protectedInnerClass1Src =
@@ -74,45 +74,36 @@
         new ProtectedInnerClassesTest().run();
     }
 
+    ToolBox tb = new ToolBox();
+
     void run() throws Exception {
         compileAndExecute();
         compileOnly();
     }
 
     void compileAndExecute() throws Exception {
-//"${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d "${TESTCLASSES}" "${TESTSRC}${FS}p1${FS}ProtectedInnerClass1.java" "${TESTSRC}${FS}p2${FS}ProtectedInnerClass2.java"
-        ToolBox.JavaToolArgs javacParams =
-                new ToolBox.JavaToolArgs()
-                .setOptions("-d", ".")
-                .setSources(protectedInnerClass1Src, protectedInnerClass2Src);
-
-        ToolBox.javac(javacParams);
+        tb.new JavacTask()
+                .outdir(".")
+                .sources(protectedInnerClass1Src, protectedInnerClass2Src)
+                .run();
 
-//"${TESTJAVA}${FS}bin${FS}java" ${TESTVMOPTS} -classpath "${CLASSPATH}${PS}${TESTCLASSES}" p2.ProtectedInnerClass2
-        ToolBox.AnyToolArgs javaParams =
-                new ToolBox.AnyToolArgs()
-                .appendArgs(ToolBox.javaBinary)
-                .appendArgs(ToolBox.testVMOpts)
-                .appendArgs("-classpath", System.getProperty("user.dir"),
-                    "p2.ProtectedInnerClass2");
-        ToolBox.executeCommand(javaParams);
+        tb.new JavaTask()
+                .classpath(System.getProperty("user.dir"))
+                .className("p2.ProtectedInnerClass2")
+                .run();
     }
 
 //from test/tools/javac/ProtectedInnerClass/ProtectedInnerClass_2.java
     void compileOnly() throws Exception {
-//@run compile p1/ProtectedInnerClass1.java
-        ToolBox.JavaToolArgs javacParams =
-                new ToolBox.JavaToolArgs()
-                .appendArgs("-d", ".")
-                .setSources(protectedInnerClass1Src);
+        tb.new JavacTask()
+                .outdir(".")
+                .sources(protectedInnerClass1Src)
+                .run();
 
-        ToolBox.javac(javacParams);
-
-//@run compile/fail p2/ProtectedInnerClass3.java
-        javacParams = new ToolBox.JavaToolArgs(ToolBox.Expect.FAIL)
-                .appendArgs("-d", ".")
-                .setSources(protectedInnerClass3Src);
-        ToolBox.javac(javacParams);
+        tb.new JavacTask()
+                .outdir(".")
+                .sources(protectedInnerClass3Src)
+                .run(ToolBox.Expect.FAIL);
     }
 
 }
--- a/langtools/test/tools/javac/T5090006/AssertionFailureTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/T5090006/AssertionFailureTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
  * @test
  * @bug 5090006
  * @summary javac fails with assertion error
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main AssertionFailureTest
  */
@@ -33,7 +33,7 @@
 import java.io.File;
 import java.nio.file.Paths;
 
-//original test: test/tools/javac/T5090006/compiler.sh
+// Original test: test/tools/javac/T5090006/compiler.sh
 public class AssertionFailureTest {
 
     private static final String testSrc =
@@ -54,16 +54,14 @@
         "}";
 
     public static void main(String args[]) throws Exception {
-        String classpath = Paths.get(System.getProperty("test.src"), "broken.jar")
-                .toString();
-        classpath = new StringBuilder(classpath)
-                .append(File.pathSeparator).append(".").toString();
-//        "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -verbose -d "${TESTCLASSES}" -cp "${TESTSRC}${FS}broken.jar" "${TESTSRC}${FS}$1"
-        ToolBox.JavaToolArgs params =
-                new ToolBox.JavaToolArgs()
-                .setOptions("-cp", classpath)
-                .setSources(testSrc);
-        ToolBox.javac(params);
+        ToolBox tb = new ToolBox();
+        String classpath = Paths.get(tb.testSrc, "broken.jar")
+                + File.pathSeparator
+                + ".";
+        tb.new JavacTask()
+                .classpath(classpath)
+                .sources(testSrc)
+                .run();
     }
 
 }
--- a/langtools/test/tools/javac/T6970173/DebugPointerAtBadPositionTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/T6970173/DebugPointerAtBadPositionTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
  * @test
  * @bug 6970173
  * @summary Debug pointer at bad position
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main DebugPointerAtBadPositionTest
  */
@@ -75,9 +75,10 @@
     }
 
     void compileTestClass() throws Exception {
-        ToolBox.JavaToolArgs javacSuccessArgs =
-                new ToolBox.JavaToolArgs().setSources(testSource);
-        ToolBox.javac(javacSuccessArgs);
+        ToolBox tb = new ToolBox();
+        tb.new JavacTask()
+                .sources(testSource)
+                .run();
     }
 
     void checkClassFile(final File cfile, String methodToFind) throws Exception {
--- a/langtools/test/tools/javac/T7008643/InlinedFinallyConfuseDebuggersTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/T7008643/InlinedFinallyConfuseDebuggersTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
  * @test
  * @bug 7008643
  * @summary inlined finally clauses confuse debuggers
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main InlinedFinallyConfuseDebuggersTest
  */
@@ -73,6 +73,8 @@
         new InlinedFinallyConfuseDebuggersTest().run();
     }
 
+    ToolBox tb = new ToolBox();
+
     void run() throws Exception {
         compileTestClass();
         checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
@@ -80,9 +82,9 @@
     }
 
     void compileTestClass() throws Exception {
-        ToolBox.JavaToolArgs javacSuccessArgs =
-                new ToolBox.JavaToolArgs().setSources(testSource);
-        ToolBox.javac(javacSuccessArgs);
+        tb.new JavacTask()
+                .sources(testSource)
+                .run();
     }
 
     void checkClassFile(final File cfile, String methodToFind) throws Exception {
--- a/langtools/test/tools/javac/T8009640/CheckRejectProfileBCPOptionsIfUsedTogetherTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/T8009640/CheckRejectProfileBCPOptionsIfUsedTogetherTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -27,14 +27,13 @@
  * @test
  * @bug 8009640
  * @summary -profile <compact> does not work when -bootclasspath specified
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main CheckRejectProfileBCPOptionsIfUsedTogetherTest
  */
 
 import com.sun.tools.javac.util.Assert;
-import java.util.ArrayList;
-import java.util.List;
+import java.nio.file.Paths;
 
 public class CheckRejectProfileBCPOptionsIfUsedTogetherTest {
 
@@ -44,21 +43,16 @@
         "}";
 
     public static void main(String args[]) throws Exception {
-        List<String> errOutput = new ArrayList<>();
-        String testJDK = ToolBox.jdkUnderTest;
-        ToolBox.createJavaFileFromSource(TestSrc);
+        ToolBox tb = new ToolBox();
 
-        ToolBox.AnyToolArgs javacParams =
-                new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL)
-                .appendArgs(ToolBox.javacBinary)
-                .appendArgs(ToolBox.testToolVMOpts)
-                .appendArgs("-profile", "compact1", "-bootclasspath",
-                testJDK + "/jre/lib/rt.jar", "Test.java")
-                .setErrOutput(errOutput);
+        ToolBox.Result result = tb.new JavacTask(ToolBox.Mode.CMDLINE)
+                .options("-profile", "compact1",
+                        "-bootclasspath", Paths.get(ToolBox.testJDK, "jre/lib/rt.jar").toString())
+                .sources(TestSrc)
+                .run(ToolBox.Expect.FAIL);
 
-        ToolBox.executeCommand(javacParams);
-
-        Assert.check(errOutput.get(0).startsWith(
+        String out = result.getOutput(ToolBox.OutputKind.DIRECT);
+        Assert.check(out.startsWith(
                 "javac: profile and bootclasspath options cannot be used together"),
                 "Incorrect javac error output");
     }
--- a/langtools/test/tools/javac/T8010659/CompilerCrashWhenMixingBinariesAndSourcesTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/T8010659/CompilerCrashWhenMixingBinariesAndSourcesTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -27,7 +27,7 @@
  * @test
  * @bug 8010659
  * @summary Javac Crashes while building OpenJFX
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main CompilerCrashWhenMixingBinariesAndSourcesTest
  */
@@ -48,19 +48,18 @@
             "        Object m(int i) {return null;}\n" +
             "}";
 
-    public static void main (String[] args) throws Exception{
-        ToolBox.JavaToolArgs javacParams = new ToolBox.JavaToolArgs()
-                .setSources(ASource, BSource, CSource, DSource);
-        ToolBox.javac(javacParams);
+    public static void main(String[] args) throws Exception {
+        ToolBox tb = new ToolBox();
+
+        tb.new JavacTask()
+                .sources(ASource, BSource, CSource, DSource)
+                .run();
 
-        ToolBox.rm("A.class");
-        ToolBox.rm("A$1.class");
-        ToolBox.rm("C.class");
-        ToolBox.rm("D.class");
+        tb.deleteFiles("A.class", "A$1.class", "C.class", "D.class");
 
-        javacParams = new ToolBox.JavaToolArgs()
-                .setOptions("-cp", ".")
-                .setSources(ASource, CSource, DSource);
-        ToolBox.javac(javacParams);
+        tb.new JavacTask()
+                .classpath(".")
+                .sources(ASource, CSource, DSource)
+                .run();
     }
 }
--- a/langtools/test/tools/javac/T8013394/CompileErrorWithIteratorTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/T8013394/CompileErrorWithIteratorTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -27,7 +27,7 @@
  * @test
  * @bug 8013394
  * @summary compile of iterator use fails with error "defined in an inaccessible class or interface"
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main CompileErrorWithIteratorTest
  */
@@ -71,15 +71,16 @@
         new CompileErrorWithIteratorTest().run();
     }
 
+    ToolBox tb = new ToolBox();
+
     void run() throws Exception {
         compile();
     }
 
     void compile() throws Exception {
-        ToolBox.JavaToolArgs javacParams =
-                new ToolBox.JavaToolArgs()
-                .setSources(TestCollectionSrc, TestSrc);
-        ToolBox.javac(javacParams);
+        tb.new JavacTask()
+                .sources(TestCollectionSrc, TestSrc)
+                .run();
     }
 
 }
--- a/langtools/test/tools/javac/T8019486/WrongLNTForLambdaTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/T8019486/WrongLNTForLambdaTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -27,7 +27,7 @@
  * @test
  * @bug 8019486 8026861 8027142
  * @summary javac, generates erroneous LVT for a test case with lambda code
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main WrongLNTForLambdaTest
  */
@@ -125,6 +125,8 @@
         new WrongLNTForLambdaTest().run();
     }
 
+    ToolBox tb = new ToolBox();
+
     void run() throws Exception {
         compileTestClass();
         checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
@@ -146,9 +148,9 @@
     }
 
     void compileTestClass() throws Exception {
-        ToolBox.JavaToolArgs javacSuccessArgs =
-                new ToolBox.JavaToolArgs().setSources(testSource);
-        ToolBox.javac(javacSuccessArgs);
+        tb.new JavacTask()
+                .sources(testSource)
+                .run();
     }
 
     void checkClassFile(final File cfile, String methodToFind, int[][] expectedLNT) throws Exception {
--- a/langtools/test/tools/javac/T8022162/IncorrectSignatureDeterminationForInnerClassesTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/T8022162/IncorrectSignatureDeterminationForInnerClassesTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,14 +25,11 @@
  * @test
  * @bug 8022162
  * @summary Incorrect signature determination for certain inner class generics
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main IncorrectSignatureDeterminationForInnerClassesTest
  */
 
-import java.nio.file.Files;
-import java.nio.file.Paths;
-
 public class IncorrectSignatureDeterminationForInnerClassesTest {
 
     private static final String DSrc =
@@ -69,21 +66,20 @@
     }
 
     void compile() throws Exception {
-        Files.createDirectory(Paths.get("classes"));
+        ToolBox tb = new ToolBox();
+        tb.createDirectories("classes");
 
-        ToolBox.JavaToolArgs javacParams =
-                new ToolBox.JavaToolArgs()
-                .appendArgs("-d", "classes")
-                .setSources(DSrc);
-
-        ToolBox.javac(javacParams);
+        tb.new JavacTask()
+                .outdir("classes")
+                .sources(DSrc)
+                .run();
 
         // compile class H against the class files for classes D and Q
-        javacParams =
-                new ToolBox.JavaToolArgs()
-                .appendArgs("-d", "classes", "-cp", "classes")
-                .setSources(HSrc);
-        ToolBox.javac(javacParams);
+        tb.new JavacTask()
+                .outdir("classes")
+                .classpath("classes")
+                .sources(HSrc)
+                .run();
     }
 
 }
--- a/langtools/test/tools/javac/T8024039/NoDeadCodeGenerationOnTrySmtTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/T8024039/NoDeadCodeGenerationOnTrySmtTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -27,7 +27,7 @@
  * @test
  * @bug 8024039
  * @summary javac, previous solution for JDK-8022186 was incorrect
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main NoDeadCodeGenerationOnTrySmtTest
  */
@@ -76,6 +76,8 @@
 
     static final String[] methodsToLookFor = {"m1", "m2"};
 
+    ToolBox tb = new ToolBox();
+
     public static void main(String[] args) throws Exception {
         new NoDeadCodeGenerationOnTrySmtTest().run();
     }
@@ -87,9 +89,9 @@
     }
 
     void compileTestClass() throws Exception {
-        ToolBox.JavaToolArgs javacSuccessArgs =
-                new ToolBox.JavaToolArgs().setSources(testSource);
-        ToolBox.javac(javacSuccessArgs);
+        tb.new JavacTask()
+                .sources(testSource)
+                .run();
     }
 
     void checkClassFile(final File cfile, String[] methodsToFind) throws Exception {
--- a/langtools/test/tools/javac/T8024437/ExceptionInferenceFromClassFileTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/T8024437/ExceptionInferenceFromClassFileTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -27,7 +27,7 @@
  * @test
  * @bug 8024437
  * @summary Inferring the exception thrown by a lambda: sometimes fails to compile
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main ExceptionInferenceFromClassFileTest
  */
@@ -56,19 +56,19 @@
             "}";
 
     public static void main(String[] args) throws Exception {
-        Files.createDirectory(Paths.get("out"));
+        ToolBox tb = new ToolBox();
+        tb.createDirectories("out");
 
-        ToolBox.JavaToolArgs compileABParams =
-                new ToolBox.JavaToolArgs()
-                .setOptions("-d", "out")
-                .setSources(ABSrc);
-        ToolBox.javac(compileABParams);
+        tb.new JavacTask()
+                .outdir("out")
+                .sources(ABSrc)
+                .run();
 
-        ToolBox.JavaToolArgs compileCParams =
-                new ToolBox.JavaToolArgs()
-                .setOptions("-d", "out", "-cp", "out")
-                .setSources(CSrc);
-        ToolBox.javac(compileCParams);
+        tb.new JavacTask()
+                .outdir("out")
+                .classpath("out")
+                .sources(CSrc)
+                .run();
     }
 
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/InvalidPackageAnno.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,11 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8054964
+ * @summary Invalid package annotations
+ * @author sogoel
+ *
+ * @compile/fail/ref=InvalidPackageAnno.out -XDrawDiagnostics  bar/package-info.java
+ */
+
+package bar;
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/InvalidPackageAnno.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+package-info.java:24:1: compiler.err.annotation.type.not.applicable
+1 error
--- a/langtools/test/tools/javac/annotations/neg/NoAnnotationMethods.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/NoAnnotationMethods.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,32 +1,9 @@
 /*
- * Copyright (c) 2006, 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
+ * @test    /nodynamiccopyright/
  * @bug     6393539
  * @summary no compile-time error for clone, etc. in annotation type
  * @author  Peter von der Ah\u00e9
- * @compile/fail NoAnnotationMethods.java
+ * @compile/fail/ref=NoAnnotationMethods.out -XDrawDiagnostics  NoAnnotationMethods.java
  */
 
 public @interface NoAnnotationMethods {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/NoAnnotationMethods.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+NoAnnotationMethods.java:10:9: compiler.err.intf.annotation.member.clash: annotationType(), java.lang.annotation.Annotation
+1 error
--- a/langtools/test/tools/javac/annotations/neg/NoClone.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/NoClone.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,32 +1,9 @@
 /*
- * Copyright (c) 2006, 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
+ * @test    /nodynamiccopyright/
  * @bug     6393539
  * @summary no compile-time error for clone, etc. in annotation type
  * @author  Peter von der Ah\u00e9
- * @compile/fail NoClone.java
+ * @compile/fail/ref=NoClone.out -XDrawDiagnostics  NoClone.java
  */
 
 public @interface NoClone {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/NoClone.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,3 @@
+NoClone.java:10:5: compiler.err.invalid.annotation.member.type
+NoClone.java:10:12: compiler.err.intf.annotation.member.clash: clone(), java.lang.Object
+2 errors
--- a/langtools/test/tools/javac/annotations/neg/NoObjectMethods.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/NoObjectMethods.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,32 +1,9 @@
 /*
- * Copyright (c) 2006, 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
+ * @test    /nodynamiccopyright/
  * @bug     6393539
  * @summary no compile-time error for clone, etc. in annotation type
  * @author  Peter von der Ah\u00e9
- * @compile/fail NoObjectMethods.java
+ * @compile/fail/ref=NoObjectMethods.out -XDrawDiagnostics  NoObjectMethods.java
  */
 
 public @interface NoObjectMethods {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/NoObjectMethods.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+NoObjectMethods.java:10:9: compiler.err.intf.annotation.member.clash: clone(), java.lang.Object
+1 error
--- a/langtools/test/tools/javac/annotations/neg/ObjectMembers.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/ObjectMembers.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2003, 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
+ * @test /nodynamiccopyright/
  * @bug 4901264
  * @summary JSR175 (2): don't allow annotating members from Object
  * @author gafter
  *
- * @compile/fail ObjectMembers.java
+ * @compile/fail/ref=ObjectMembers.out -XDrawDiagnostics  ObjectMembers.java
  */
 
 @ObjectMembers(hashCode = 23)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/ObjectMembers.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+ObjectMembers.java:10:16: compiler.err.no.annotation.member: hashCode, ObjectMembers
+1 error
--- a/langtools/test/tools/javac/annotations/neg/OverrideNo.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/OverrideNo.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2003, 2004, 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
+ * @test /nodynamiccopyright/
  * @bug 4901275 4989669
  * @summary JSR175 (7): implement <at>Overrides
  * @author gafter
  *
- * @compile/fail OverrideNo.java
+ * @compile/fail/ref=OverrideNo.out -XDrawDiagnostics  OverrideNo.java
  */
 
 package overrideNo;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/OverrideNo.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+OverrideNo.java:16:5: compiler.err.method.does.not.override.superclass
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Package.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Package.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2003, 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
+ * @test /nodynamiccopyright/
  * @bug 4901290
  * @summary Package annotations
  * @author gafter
  *
- * @compile/fail Package.java
+ * @compile/fail/ref=Package.out -XDrawDiagnostics  Package.java
  */
 
 @java.lang.annotation.Documented
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Package.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Package.java:10:1: compiler.err.pkg.annotations.sb.in.package-info.java
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Recovery.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Recovery.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2004, 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
+ * @test /nodynamiccopyright/
  * @bug 4993451
  * @summary compiler crash with malformed annotations
  * @author gafter
  *
- * @compile/fail Recovery.java
+ * @compile/fail/ref=Recovery.out -XDrawDiagnostics  Recovery.java
  */
 
 import java.lang.annotation.*;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Recovery.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Recovery.java:12:2: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.annotation.RetentionPolicy, java.lang.annotation.Annotation)
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Recovery1.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Recovery1.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2004, 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
+ * @test /nodynamiccopyright/
  * @bug 4963450
  * @summary Assertion error is thrown when an annotation class cannot be found.
  * @author gafter
  *
- * @compile/fail Recovery1.java
+ * @compile/fail/ref=Recovery1.out -XDrawDiagnostics  Recovery1.java
  */
 
 package recovery1;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Recovery1.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,4 @@
+Recovery1.java:14:5: compiler.err.cant.resolve.location: kindname.class, Marker, , , (compiler.misc.location: kindname.annotation, recovery1.MyAnnotation, null)
+Recovery1.java:14:30: compiler.err.cant.resolve.location: kindname.class, Marker, , , (compiler.misc.location: kindname.annotation, recovery1.MyAnnotation, null)
+Recovery1.java:18:43: compiler.err.cant.resolve.location.args: kindname.method, markerToo, , , (compiler.misc.location: kindname.annotation, recovery1.MyAnnotation, null)
+3 errors
--- a/langtools/test/tools/javac/annotations/neg/Scope.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Scope.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2004, 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
+ * @test /nodynamiccopyright/
  * @bug 4901280
  * @summary name lookup scope for annotations
  * @author gafter
  *
- * @compile/fail Scope.java
+ * @compile/fail/ref=Scope.out -XDrawDiagnostics  Scope.java
  */
 
 package annotation.scope;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Scope.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Scope.java:12:4: compiler.err.cant.resolve: kindname.variable, red, , 
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Syntax1.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Syntax1.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2004, 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
+ * @test /nodynamiccopyright/
  * @bug 4974524
  * @summary compiler crash with ill-formed annotation
  * @author gafter
  *
- * @compile/fail Syntax1.java
+ * @compile/fail/ref=Syntax1.out -XDrawDiagnostics  Syntax1.java
  */
 
 package syntax1;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Syntax1.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,4 @@
+Syntax1.java:17:20: compiler.err.annotation.value.must.be.name.value
+Syntax1.java:17:40: compiler.err.annotation.value.must.be.name.value
+Syntax1.java:17:1: compiler.err.annotation.missing.default.value: java.lang.annotation.Target, value
+3 errors
--- a/langtools/test/tools/javac/annotations/neg/WrongTarget.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/WrongTarget.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,35 +1,14 @@
 /*
- * Copyright (c) 2003, 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
+ * @test /nodynamiccopyright/
  * @bug 4901271
  * @summary java.lang.annotation.Target
  * @author gafter
  *
- * @compile/fail WrongTarget.java
+ * @compile/fail/ref=WrongTarget.out -XDrawDiagnostics  WrongTarget.java
  */
 
+import static java.lang.annotation.ElementType.*;
+
 @java.lang.annotation.Target({FIELD})
 @interface foo {
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/WrongTarget.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+WrongTarget.java:16:1: compiler.err.annotation.type.not.applicable
+1 error
--- a/langtools/test/tools/javac/annotations/neg/WrongTarget2.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/WrongTarget2.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2004, 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
+ * @test /nodynamiccopyright/
  * @bug 4973504
  * @summary Compiler allows Inherited meta-attribute on local variable declaration.
  * @author gafter
  *
- * @compile/fail WrongTarget2.java
+ * @compile/fail/ref=WrongTarget2.out -XDrawDiagnostics  WrongTarget2.java
  */
 
 import java.lang.annotation.Inherited;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/WrongTarget2.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+WrongTarget2.java:12:6: compiler.err.annotation.type.not.applicable
+1 error
--- a/langtools/test/tools/javac/annotations/neg/WrongValue.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/WrongValue.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2004, 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
+ * @test /nodynamiccopyright/
  * @bug 4951298
  * @summary compiler: crashes when attributes with same elements are used in place of other
  * @author gafter
  *
- * @compile/fail WrongValue.java
+ * @compile/fail/ref=WrongValue.out -XDrawDiagnostics  WrongValue.java
  */
 
 @interface TestM2 {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/WrongValue.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+WrongValue.java:25:5: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: TestM3, TestM2)
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z1.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z1.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2003, 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
+ * @test /nodynamiccopyright/
  * @bug 4865660
  * @summary implement "metadata" (attribute interfaces and program annotations)
  * @author gafter
  *
- * @compile/fail Z1.java
+ * @compile/fail/ref=Z1.out -XDrawDiagnostics  Z1.java
  */
 
 enum Color { red, green, blue }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z1.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z1.java:16:10: compiler.err.cant.resolve: kindname.variable, teal, , 
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z10.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z10.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,37 +1,12 @@
 /*
- * Copyright (c) 2003, 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
+ * @test /nodynamiccopyright/
  * @bug 4865660
  * @summary implement "metadata" (attribute interfaces and program annotations)
  * @author gafter
  *
- * @compile/fail Z10.java
+ * @compile/fail/ref=Z10.out -XDrawDiagnostics  Z10.java
  */
 
-enum Color { red, green, blue }
-
 @interface An {
     int[][] a();
  }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z10.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z10.java:11:8: compiler.err.invalid.annotation.member.type
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z11.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z11.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,37 +1,12 @@
 /*
- * Copyright (c) 2003, 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
+ * @test /nodynamiccopyright/
  * @bug 4865660
  * @summary implement "metadata" (attribute interfaces and program annotations)
  * @author gafter
  *
- * @compile/fail Z11.java
+ * @compile/fail/ref=Z11.out -XDrawDiagnostics  Z11.java
  */
 
-enum Color { red, green, blue }
-
 class X {}
 
 @interface An {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z11.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z11.java:13:5: compiler.err.invalid.annotation.member.type
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z12.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z12.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,37 +1,12 @@
 /*
- * Copyright (c) 2003, 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
+ * @test /nodynamiccopyright/
  * @bug 4865660
  * @summary implement "metadata" (attribute interfaces and program annotations)
  * @author gafter
  *
- * @compile/fail Z12.java
+ * @compile/fail/ref=Z12.out -XDrawDiagnostics  Z12.java
  */
 
-enum Color { red, green, blue }
-
 @interface An {
     void a();
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z12.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z12.java:11:5: compiler.err.invalid.annotation.member.type
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z13.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z13.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2003, 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
+ * @test /nodynamiccopyright/
  * @bug 4865660
  * @summary implement "metadata" (attribute interfaces and program annotations)
  * @author gafter
  *
- * @compile/fail Z13.java
+ * @compile/fail/ref=Z13.out -XDrawDiagnostics  Z13.java
  */
 
 @interface An {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z13.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z13.java:11:20: compiler.err.throws.not.allowed.in.intf.annotation
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z14.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z14.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2003, 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
+ * @test /nodynamiccopyright/
  * @bug 4865660
  * @summary implement "metadata" (attribute interfaces and program annotations)
  * @author gafter
  *
- * @compile/fail Z14.java
+ * @compile/fail/ref=Z14.out -XDrawDiagnostics  Z14.java
  */
 
 @interface An<T> {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z14.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z14.java:10:15: compiler.err.intf.annotation.cant.have.type.params
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z15.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z15.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2003, 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
+ * @test /nodynamiccopyright/
  * @bug 4865660
  * @summary implement "metadata" (attribute interfaces and program annotations)
  * @author gafter
  *
- * @compile/fail Z15.java
+ * @compile/fail/ref=Z15.out -XDrawDiagnostics  Z15.java
  */
 
 @interface An {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z15.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z15.java:11:36: compiler.err.attribute.value.must.be.constant
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z16.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z16.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2003, 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
+ * @test /nodynamiccopyright/
  * @bug 4865660
  * @summary implement "metadata" (attribute interfaces and program annotations)
  * @author gafter
  *
- * @compile/fail Z16.java
+ * @compile/fail/ref=Z16.out -XDrawDiagnostics  Z16.java
  */
 
 enum Color { red, green, blue }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z16.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z16.java:13:27: compiler.err.cant.resolve.location: kindname.variable, redx, , , (compiler.misc.location: kindname.annotation, Colored, null)
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z2.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z2.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,37 +1,14 @@
 /*
- * Copyright (c) 2003, 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
+ * @test /nodynamiccopyright/
  * @bug 4865660
  * @summary implement "metadata" (attribute interfaces and program annotations)
  * @author gafter
  *
- * @compile/fail Z2.java
+ * @compile/fail/ref=Z2.out -XDrawDiagnostics  Z2.java
  */
 
 enum Color { red, green, blue }
 
 interface Colored {
-    Color value() default red;
+    Color value() default Color.red;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z2.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z2.java:13:11: compiler.err.default.allowed.in.intf.annotation.member
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z3.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z3.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,37 +1,14 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 4865660
+ * @test /nodynamiccopyright/
+ * @bug 4865660 8054556
  * @summary implement "metadata" (attribute interfaces and program annotations)
  * @author gafter
  *
- * @compile/fail Z3.java
+ * @compile/fail/ref=Z3.out -XDrawDiagnostics  Z3.java
  */
 
 enum Color { red, green, blue }
 
 class Colored {
-    Color value() default red;
+    Color value() default Color.red;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z3.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z3.java:13:11: compiler.err.default.allowed.in.intf.annotation.member
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z4.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z4.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,37 +1,14 @@
 /*
- * Copyright (c) 2003, 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
+ * @test /nodynamiccopyright/
  * @bug 4865660
  * @summary implement "metadata" (attribute interfaces and program annotations)
  * @author gafter
  *
- * @compile/fail Z4.java
+ * @compile/fail/ref=Z4.out -XDrawDiagnostics  Z4.java
  */
 
 enum Color { red, green, blue }
 
 @interface Colored {
-    Color value() default teal;
+    Color value() default Color.teal;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z4.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z4.java:13:32: compiler.err.cant.resolve.location: kindname.variable, teal, , , (compiler.misc.location: kindname.class, Color, null)
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z5.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z5.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2003, 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
+ * @test /nodynamiccopyright/
  * @bug 4865660
  * @summary implement "metadata" (attribute interfaces and program annotations)
  * @author gafter
  *
- * @compile/fail Z5.java
+ * @compile/fail/ref=Z5.out -XDrawDiagnostics  Z5.java
  */
 
 interface Foo {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z5.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z5.java:12:28: compiler.err.cant.extend.intf.annotation
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z8.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z8.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2003, 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
+ * @test /nodynamiccopyright/
  * @bug 4865660
  * @summary implement "metadata" (attribute interfaces and program annotations)
  * @author gafter
  *
- * @compile/fail Z8.java
+ * @compile/fail/ref=Z8.out -XDrawDiagnostics  Z8.java
  */
 
 @interface An {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z8.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z8.java:11:15: compiler.err.intf.annotation.members.cant.have.params
+1 error
--- a/langtools/test/tools/javac/annotations/neg/Z9.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/neg/Z9.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2003, 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
+ * @test /nodynamiccopyright/
  * @bug 4865660
  * @summary implement "metadata" (attribute interfaces and program annotations)
  * @author gafter
  *
- * @compile/fail Z9.java
+ * @compile/fail/ref=Z9.out -XDrawDiagnostics  Z9.java
  */
 
 @interface An {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/Z9.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+Z9.java:11:6: compiler.err.intf.annotation.members.cant.have.type.params
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/bar/package-info.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2014, 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.
+ */
+
+@java.lang.annotation.Documented
+package bar;
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingAndContainerPresent.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingAndContainerPresent.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,30 +1,7 @@
 /*
- * Copyright (c) 2012, 2013, 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
+ * @test /nodynamiccopyright/
  * @summary Smoke test for repeating annotations
- * @compile/fail RepeatingAndContainerPresent.java
+ * @compile/fail/ref=RepeatingAndContainerPresent.out -XDrawDiagnostics  RepeatingAndContainerPresent.java
  * @bug 7151010
  */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingAndContainerPresent.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+RepeatingAndContainerPresent.java:20:1: compiler.err.invalid.repeatable.annotation.repeated.and.container.present: Foos
+1 error
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongRepeatable.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongRepeatable.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,30 +1,7 @@
 /*
- * Copyright (c) 2012, 2013, 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
+ * @test /nodynamiccopyright/
  * @summary Smoke test for repeating annotations
- * @compile/fail UseWrongRepeatable.java
+ * @compile/fail/ref=UseWrongRepeatable.out -XDrawDiagnostics  UseWrongRepeatable.java
  * @bug 7151010
  */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongRepeatable.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,4 @@
+UseWrongRepeatable.java:17:1: compiler.err.invalid.repeatable.annotation.value.return: java.lang.annotation.Target, java.lang.annotation.ElementType[], UseWrongRepeatable[]
+UseWrongRepeatable.java:17:21: compiler.err.invalid.repeatable.annotation.value.return: java.lang.annotation.Target, java.lang.annotation.ElementType[], UseWrongRepeatable[]
+UseWrongRepeatable.java:14:1: compiler.err.invalid.repeatable.annotation.value.return: java.lang.annotation.Target, java.lang.annotation.ElementType[], UseWrongRepeatable[]
+3 errors
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/VoidGenericMethod.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/VoidGenericMethod.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,35 +1,12 @@
 /*
- * Copyright (c) 2008, 2013, 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 /nodynamiccopyright/
+ * @bug 6843077 8006775
+ * @summary test type annotation on void generic methods
+ * @author Mahmood Ali
+ * @compile/fail/ref=VoidGenericMethod.out -XDrawDiagnostics  VoidGenericMethod.java
  */
 
 import java.lang.annotation.*;
-
-/*
- * @test
- * @bug 6843077 8006775
- * @summary test type annotation on void generic methods
- * @author Mahmood Ali
- * @compile/fail VoidGenericMethod.java
- */
 class VoidGenericMethod {
   public @A <T> void method() { }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/VoidGenericMethod.out	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,2 @@
+VoidGenericMethod.java:11:10: compiler.err.annotation.type.not.applicable
+1 error
--- a/langtools/test/tools/javac/api/ToolProvider/HelloWorldTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/api/ToolProvider/HelloWorldTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,21 +25,19 @@
  * @test
  * @bug 6604599
  * @summary ToolProvider should be less compiler-specific
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main HelloWorldTest
  */
 
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.List;
 
 // verify that running a simple program, such as this one, does not trigger
 // the loading of ToolProvider or any com.sun.tools.javac class
 public class HelloWorldTest {
     public static void main(String... args) throws Exception {
         if (args.length > 0) {
-            System.err.println(Arrays.asList(args));
+            System.err.println(Arrays.toString(args));
             return;
         }
 
@@ -47,27 +45,26 @@
     }
 
     void run() throws Exception {
+        ToolBox tb = new ToolBox();
+
         String classpath = System.getProperty("java.class.path");
 
-        List<String> output = new ArrayList<>();
-        ToolBox.AnyToolArgs javaParams =
-                new ToolBox.AnyToolArgs()
-                        .appendArgs(ToolBox.javaBinary)
-                        .appendArgs(ToolBox.testVMOpts)
-                        .appendArgs(ToolBox.testJavaOpts)
-                        .appendArgs("-verbose:class",
-                                "-classpath", classpath,
-                                HelloWorldTest.class.getName(),
-                                "Hello", "World")
-                        .setErrOutput(output)
-                        .setStdOutput(output);
+        ToolBox.Result tr = tb.new JavaTask()
+                .vmOptions("-verbose:class")
+                .classpath(classpath)
+                .className(HelloWorldTest.class.getName())
+                .classArgs("Hello", "World")
+                .run();
 
-       ToolBox.executeCommand(javaParams);
-
-        for (String line : output) {
-            System.err.println(line);
-            if (line.contains("javax.tools.ToolProvider") || line.contains("com.sun.tools.javac."))
-                error(">>> " + line);
+        if (tr.getOutput(ToolBox.OutputKind.STDOUT).contains("java.lang.Object")) {
+            for (String line : tr.getOutputLines(ToolBox.OutputKind.STDOUT)) {
+                System.err.println(line);
+                if (line.contains("javax.tools.ToolProvider") || line.contains("com.sun.tools.javac."))
+                    error(">>> " + line);
+            }
+        } else {
+            tr.writeAll();
+            error("verbose output not as expected");
         }
 
         if (errors > 0)
--- a/langtools/test/tools/javac/api/ToolProvider/ToolProviderTest1.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/api/ToolProvider/ToolProviderTest1.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,12 +25,11 @@
  * @test
  * @bug 6604599
  * @summary ToolProvider should be less compiler-specific
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main ToolProviderTest1
  */
 
-import java.util.ArrayList;
 import java.util.List;
 
 // verify that running accessing ToolProvider by itself does not
@@ -46,24 +45,18 @@
     }
 
     void run() throws Exception {
+        ToolBox tb = new ToolBox();
         String classpath = System.getProperty("java.class.path");
 
-        List<String> output = new ArrayList<>();
-        ToolBox.AnyToolArgs javaParams =
-                new ToolBox.AnyToolArgs()
-                        .appendArgs(ToolBox.javaBinary)
-                        .appendArgs(ToolBox.testVMOpts)
-                        .appendArgs(ToolBox.testJavaOpts)
-                        .appendArgs("-verbose:class",
-                                "-classpath", classpath,
-                                ToolProviderTest1.class.getName(),
-                                "javax.tools.ToolProvider")
-                        .setErrOutput(output)
-                        .setStdOutput(output);
+        List<String> lines = tb.new JavaTask()
+                .vmOptions("-verbose:class")
+                .classpath(classpath)
+                .className(getClass().getName())
+                .classArgs("javax.tools.ToolProvider")
+                .run()
+                .getOutputLines(ToolBox.OutputKind.STDOUT);
 
-        ToolBox.executeCommand(javaParams);
-
-        for (String line : output) {
+        for (String line : lines) {
             System.err.println(line);
             if (line.contains("com.sun.tools.javac."))
                 error(">>> " + line);
--- a/langtools/test/tools/javac/api/ToolProvider/ToolProviderTest2.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/api/ToolProvider/ToolProviderTest2.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,13 +25,12 @@
  * @test
  * @bug 6604599
  * @summary ToolProvider should be less compiler-specific
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main ToolProviderTest2
  */
 
 import javax.tools.ToolProvider;
-import java.util.ArrayList;
 import java.util.List;
 
 // control for ToolProviderTest1 -- verify that using ToolProvider to
@@ -47,25 +46,19 @@
     }
 
     void run() throws Exception {
+        ToolBox tb = new ToolBox();
         String classpath = System.getProperty("java.class.path");
 
-        List<String> output = new ArrayList<>();
-        ToolBox.AnyToolArgs javaParams =
-                new ToolBox.AnyToolArgs()
-                        .appendArgs(ToolBox.javaBinary)
-                        .appendArgs(ToolBox.testVMOpts)
-                        .appendArgs(ToolBox.testJavaOpts)
-                        .appendArgs( "-verbose:class",
-                                "-classpath", classpath,
-                                ToolProviderTest2.class.getName(),
-                                "javax.tools.ToolProvider")
-                        .setErrOutput(output)
-                        .setStdOutput(output);
-
-        ToolBox.executeCommand(javaParams);
+        List<String> lines = tb.new JavaTask()
+                .vmOptions("-verbose:class")
+                .classpath(classpath)
+                .className(getClass().getName())
+                .classArgs("javax.tools.ToolProvider")
+                .run()
+                .getOutputLines(ToolBox.OutputKind.STDOUT);
 
         boolean found = false;
-        for (String line : output) {
+        for (String line : lines) {
             System.err.println(line);
             if (line.contains("com.sun.tools.javac."))
                 found = true;
--- a/langtools/test/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTableTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTableTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -25,8 +25,8 @@
  * @test
  * @summary local variable table attribute test.
  * @bug 8040097
- * @library /tools/javac/lib ../lib
- * @build LocalVariableTestBase TestBase InMemoryFileManager ToolBox
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build ToolBox LocalVariableTestBase TestBase InMemoryFileManager
  * @compile -g LocalVariableTableTest.java
  * @run main LocalVariableTableTest
  */
--- a/langtools/test/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTypeTableTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTypeTableTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -25,8 +25,8 @@
  * @test
  * @summary local variable type table attribute test.
  * @bug 8040097
- * @library /tools/javac/lib ../lib
- * @build LocalVariableTestBase TestBase InMemoryFileManager ToolBox
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build ToolBox LocalVariableTestBase TestBase InMemoryFileManager
  * @compile -g LocalVariableTypeTableTest.java
  * @run main LocalVariableTypeTableTest
  */
--- a/langtools/test/tools/javac/classfiles/attributes/SourceFile/AnonymousClassTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/SourceFile/AnonymousClassTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -25,8 +25,8 @@
  * @test
  * @summary sourcefile attribute test for anonymous class.
  * @bug 8040129
- * @library /tools/javac/lib ../lib
- * @build SourceFileTestBase TestBase InMemoryFileManager ToolBox
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build ToolBox SourceFileTestBase TestBase InMemoryFileManager
  * @run main AnonymousClassTest
  */
 
--- a/langtools/test/tools/javac/classfiles/attributes/SourceFile/InnerClassTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/SourceFile/InnerClassTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -25,8 +25,8 @@
  * @test
  * @summary sourcefile attribute test for inner class.
  * @bug 8040129
- * @library /tools/javac/lib ../lib
- * @build SourceFileTestBase TestBase InMemoryFileManager ToolBox
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build ToolBox SourceFileTestBase TestBase InMemoryFileManager
  * @run main InnerClassTest
  */
 
--- a/langtools/test/tools/javac/classfiles/attributes/SourceFile/LocalClassTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/SourceFile/LocalClassTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -25,8 +25,8 @@
  * @test
  * @summary sourcefile attribute test for local class.
  * @bug 8040129
- * @library /tools/javac/lib ../lib
- * @build SourceFileTestBase TestBase InMemoryFileManager ToolBox
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build ToolBox SourceFileTestBase TestBase InMemoryFileManager
  * @run main LocalClassTest
  */
 
--- a/langtools/test/tools/javac/classfiles/attributes/SourceFile/MixTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/SourceFile/MixTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -25,8 +25,8 @@
  * @test
  * @summary sourcefile attribute test for complex structure of nested classes and other types.
  * @bug 8040129
- * @library /tools/javac/lib ../lib
- * @build SourceFileTestBase TestBase InMemoryFileManager ToolBox
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build ToolBox SourceFileTestBase TestBase InMemoryFileManager
  * @run main MixTest
  */
 
--- a/langtools/test/tools/javac/classfiles/attributes/SourceFile/NoSourceFileAttribute.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/SourceFile/NoSourceFileAttribute.java	Thu Aug 28 14:53:49 2014 -0700
@@ -25,8 +25,8 @@
  * @test
  * @summary sourcefile attribute test for file compiled without debug information.
  * @bug 8040129
- * @library /tools/javac/lib ../lib
- * @build SourceFileTestBase TestBase InMemoryFileManager ToolBox
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build ToolBox SourceFileTestBase TestBase InMemoryFileManager
  * @compile -g:none NoSourceFileAttribute.java
  * @run main NoSourceFileAttribute
  */
--- a/langtools/test/tools/javac/classfiles/attributes/SourceFile/SyntheticClassTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/SourceFile/SyntheticClassTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -25,8 +25,8 @@
  * @test
  * @summary sourcefile attribute test for synthetic class.
  * @bug 8040129
- * @library /tools/javac/lib ../lib
- * @build SourceFileTestBase TestBase InMemoryFileManager ToolBox
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build ToolBox SourceFileTestBase TestBase InMemoryFileManager
  * @run main SyntheticClassTest
  */
 
--- a/langtools/test/tools/javac/classfiles/attributes/SourceFile/TopLevelClassesOneFileTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/SourceFile/TopLevelClassesOneFileTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -25,8 +25,8 @@
  * @test
  * @summary sourcefile attribute test for two type in one file.
  * @bug 8040129
- * @library /tools/javac/lib ../lib
- * @build SourceFileTestBase TestBase InMemoryFileManager ToolBox
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build ToolBox SourceFileTestBase TestBase InMemoryFileManager
  * @run main TopLevelClassesOneFileTest
  */
 
--- a/langtools/test/tools/javac/classfiles/attributes/deprecated/DeprecatedPackageTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/deprecated/DeprecatedPackageTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -25,8 +25,8 @@
  * @test
  * @bug 8042261
  * @summary Checking that deprecated attribute does not apply to classes of deprecated package.
- * @library /tools/javac/lib ../lib
- * @build DeprecatedPackageTest TestBase TestResult InMemoryFileManager ToolBox
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build  ToolBox TestBase TestResult InMemoryFileManager
  * @run main DeprecatedPackageTest
  */
 
--- a/langtools/test/tools/javac/classfiles/attributes/deprecated/DeprecatedTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/deprecated/DeprecatedTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -26,8 +26,8 @@
  * @bug 8042261
  * @summary Checking what attribute is generated by annotation Deprecated
  *          or javadoc deprecated for field, method, class(inner/local), interface.
- * @library /tools/javac/lib ../lib
- * @build DeprecatedTest TestBase TestResult InMemoryFileManager ToolBox
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build ToolBox TestBase TestResult InMemoryFileManager
  * @run main DeprecatedTest
  */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerAnnotationsInInnerAnnotationTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner annotations in inner annotation.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerAnnotationsInInnerAnnotationTest
+ */
+
+public class InnerAnnotationsInInnerAnnotationTest extends InnerClassesInInnerClassTestBase {
+
+    public static void main(String[] args) throws TestFailedException {
+        InnerClassesTestBase test = new InnerAnnotationsInInnerAnnotationTest();
+        test.test("InnerClassesSrc$Inner", "Inner", "1");
+    }
+
+    @Override
+    public void setProperties() {
+        setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+        setInnerAccessModifiers(Modifier.EMPTY, Modifier.PUBLIC);
+        setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+        setOuterClassType(ClassType.ANNOTATION);
+        setInnerClassType(ClassType.ANNOTATION);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerAnnotationsInInnerClassTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner annotations in inner class.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerAnnotationsInInnerClassTest
+ */
+
+public class InnerAnnotationsInInnerClassTest extends InnerClassesInInnerClassTestBase {
+
+    public static void main(String[] args) throws TestFailedException {
+        InnerClassesTestBase test = new InnerAnnotationsInInnerClassTest();
+        test.test("InnerClassesSrc$Inner", "Inner", "1");
+    }
+
+    @Override
+    public void setProperties() {
+        setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+        setForbiddenWithoutStaticInOuterMods(true);
+        setOuterClassType(ClassType.CLASS);
+        setInnerClassType(ClassType.ANNOTATION);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerAnnotationsInInnerEnumTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner annotations in inner enum.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerAnnotationsInInnerEnumTest
+ */
+
+public class InnerAnnotationsInInnerEnumTest extends InnerClassesInInnerClassTestBase {
+
+    public static void main(String[] args) throws TestFailedException {
+        InnerClassesTestBase test = new InnerAnnotationsInInnerEnumTest();
+        test.test("InnerClassesSrc$Inner", "Inner", "1");
+    }
+
+    @Override
+    public void setProperties() {
+        setOuterOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
+        setInnerOtherModifiers(Modifier.EMPTY, Modifier.STATIC, Modifier.ABSTRACT);
+        setOuterClassType(ClassType.ENUM);
+        setInnerClassType(ClassType.ANNOTATION);
+        setPrefix("Inner {;");
+        setSuffix("}");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerAnnotationsInInnerInterfaceTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner annotations in inner interface.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerAnnotationsInInnerInterfaceTest
+ */
+
+public class InnerAnnotationsInInnerInterfaceTest extends InnerClassesInInnerClassTestBase {
+
+    public static void main(String[] args) throws TestFailedException {
+        InnerClassesTestBase test = new InnerAnnotationsInInnerInterfaceTest();
+        test.test("InnerClassesSrc$Inner", "Inner", "1");
+    }
+
+    @Override
+    public void setProperties() {
+        setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+        setInnerAccessModifiers(Modifier.EMPTY, Modifier.PUBLIC);
+        setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+        setOuterClassType(ClassType.INTERFACE);
+        setInnerClassType(ClassType.ANNOTATION);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesHierarchyTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,433 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Test that inner classes have in its inner classes attribute enclosing classes and its immediate members.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build TestResult TestBase InMemoryFileManager ToolBox
+ * @run main InnerClassesHierarchyTest
+ */
+
+import com.sun.tools.classfile.*;
+import com.sun.tools.classfile.InnerClasses_attribute.Info;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class InnerClassesHierarchyTest extends TestResult {
+
+    private final Map<String, Set<String>> innerClasses;
+    private final String outerClassName;
+
+    public InnerClassesHierarchyTest() throws IOException, ConstantPoolException {
+        innerClasses = new HashMap<>();
+        outerClassName = InnerClassesHierarchyTest.class.getSimpleName();
+        File classDir = getClassDir();
+        FilenameFilter filter =
+                (dir, name) -> name.matches(outerClassName + ".*\\.class");
+        for (File file : Arrays.asList(classDir.listFiles(filter))) {
+            ClassFile classFile = readClassFile(file);
+            String className = classFile.getName();
+            for (ConstantPool.CPInfo info : classFile.constant_pool.entries()) {
+                if (info instanceof ConstantPool.CONSTANT_Class_info) {
+                    ConstantPool.CONSTANT_Class_info classInfo =
+                            (ConstantPool.CONSTANT_Class_info) info;
+                    String cpClassName = classInfo.getBaseName();
+                    if (isInnerClass(cpClassName)) {
+                        get(className).add(cpClassName);
+                    }
+                }
+            }
+        }
+    }
+
+    private boolean isInnerClass(String cpClassName) {
+        return cpClassName.contains("$");
+    }
+
+    private Set<String> get(String className) {
+        if (!innerClasses.containsKey(className)) {
+            innerClasses.put(className, new HashSet<>());
+        }
+        return innerClasses.get(className);
+    }
+
+    public static void main(String[] args) throws IOException, ConstantPoolException, TestFailedException {
+        new InnerClassesHierarchyTest().test();
+    }
+
+    private void test() throws TestFailedException {
+        addTestCase("Source file is InnerClassesHierarchyTest.java");
+        try {
+            Queue<String> queue = new LinkedList<>();
+            Set<String> visitedClasses = new HashSet<>();
+            queue.add(outerClassName);
+            while (!queue.isEmpty()) {
+                String currentClassName = queue.poll();
+                if (!currentClassName.startsWith(outerClassName)) {
+                    continue;
+                }
+                ClassFile cf = readClassFile(currentClassName);
+                InnerClasses_attribute attr = (InnerClasses_attribute)
+                        cf.getAttribute(Attribute.InnerClasses);
+                assertNotNull(attr, "Class should not contain "
+                        + "inner classes attribute : " + currentClassName);
+                assertTrue(innerClasses.containsKey(currentClassName),
+                        "map contains class name : " + currentClassName);
+                Set<String> setClasses = innerClasses.get(currentClassName);
+                if (setClasses == null) {
+                    continue;
+                }
+                assertEquals(attr.number_of_classes,
+                        setClasses.size(),
+                        "Check number of inner classes : " + setClasses);
+                for (Info info : attr.classes) {
+                    String innerClassName = info
+                            .getInnerClassInfo(cf.constant_pool).getBaseName();
+                    assertTrue(setClasses.contains(innerClassName),
+                            currentClassName + " contains inner class : "
+                                    + innerClassName);
+                    if (visitedClasses.add(innerClassName)) {
+                        queue.add(innerClassName);
+                    }
+                }
+            }
+            Set<String> allClasses = innerClasses.entrySet().stream()
+                    .flatMap(entry -> entry.getValue().stream())
+                    .collect(Collectors.toSet());
+
+            Set<String> a_b = removeAll(visitedClasses, allClasses);
+            Set<String> b_a = removeAll(allClasses, visitedClasses);
+            assertEquals(visitedClasses, allClasses,
+                    "All classes are found\n"
+                    + "visited - all classes : " + a_b
+                    + "\nall classes - visited : " + b_a);
+        } catch (Exception e) {
+            addFailure(e);
+        } finally {
+            checkStatus();
+        }
+    }
+
+    private Set<String> removeAll(Set<String> set1, Set<String> set2) {
+        Set<String> set = new HashSet<>(set1);
+        set.removeAll(set2);
+        return set;
+    }
+
+    public static class A1 {
+
+        public class B1 {
+        }
+
+        public enum B2 {
+        }
+
+        public interface B3 {
+        }
+
+        public @interface B4 {
+        }
+
+        public void f() {
+            new B1() {
+            };
+            new B3() {
+            };
+            new B4() {
+                @Override
+                public Class<? extends Annotation> annotationType() {
+                    return null;
+                }
+            };
+            class B5 {
+            }
+        }
+
+        Runnable r = () -> {
+            new B1() {
+            };
+            new B3() {
+            };
+            new B4() {
+                @Override
+                public Class<? extends Annotation> annotationType() {
+                    return null;
+                }
+            };
+            class B5 {
+            }
+        };
+    }
+
+    public enum A2 {;
+
+        public class B1 {
+        }
+
+        public enum B2 {
+        }
+
+        public interface B3 {
+        }
+
+        public @interface B4 {
+        }
+
+        public void a2() {
+            new B1() {
+            };
+            new B3() {
+            };
+            new B4() {
+                @Override
+                public Class<? extends Annotation> annotationType() {
+                    return null;
+                }
+            };
+            class B5 {
+            }
+        }
+
+        Runnable r = () -> {
+            new B1() {
+            };
+            new B3() {
+            };
+            new B4() {
+                @Override
+                public Class<? extends Annotation> annotationType() {
+                    return null;
+                }
+            };
+            class B5 {
+            }
+        };
+    }
+
+    public interface A3 {
+
+        public class B1 {
+        }
+
+        public enum B2 {
+        }
+
+        public interface B3 {
+        }
+
+        public @interface B4 {
+        }
+
+        default void a1() {
+            new B1() {
+            };
+            new B3() {
+            };
+            new B4() {
+                @Override
+                public Class<? extends Annotation> annotationType() {
+                    return null;
+                }
+            };
+            class B5 {
+            }
+        }
+
+        static void a2() {
+            new B1() {
+            };
+            new B3() {
+            };
+            new B4() {
+                @Override
+                public Class<? extends Annotation> annotationType() {
+                    return null;
+                }
+            };
+            class B5 {
+            }
+        }
+    }
+
+    public @interface A4 {
+
+        public class B1 {
+        }
+
+        public enum B2 {
+        }
+
+        public interface B3 {
+        }
+
+        public @interface B4 {
+        }
+    }
+
+    {
+        new A1() {
+            class B1 {
+            }
+
+            public void a2() {
+                new B1() {
+                };
+                class B5 {
+                }
+            }
+        };
+        new A3() {
+            class B1 {
+            }
+
+            public void a3() {
+                new B1() {
+                };
+                class B5 {
+                }
+            }
+        };
+        new A4() {
+            @Override
+            public Class<? extends Annotation> annotationType() {
+                return null;
+            }
+
+            class B1 {
+            }
+
+            public void a4() {
+                new B1() {
+                };
+                class B5 {
+                }
+            }
+        };
+        Runnable r = () -> {
+            new A1() {
+            };
+            new A3() {
+            };
+            new A4() {
+                @Override
+                public Class<? extends Annotation> annotationType() {
+                    return null;
+                }
+            };
+            class B5 {
+            }
+        };
+    }
+
+    static {
+        new A1() {
+            class B1 {
+            }
+
+            public void a2() {
+                new B1() {
+                };
+                class B5 {
+                }
+            }
+        };
+        new A3() {
+            class B1 {
+            }
+
+            public void a3() {
+                new B1() {
+                };
+                class B5 {
+                }
+            }
+        };
+        new A4() {
+            @Override
+            public Class<? extends Annotation> annotationType() {
+                return null;
+            }
+
+            class B1 {
+            }
+
+            public void a4() {
+                new B1() {
+                };
+                class B5 {
+                }
+            }
+        };
+        Runnable r = () -> {
+            new A1() {
+            };
+            new A3() {
+            };
+            new A4() {
+                @Override
+                public Class<? extends Annotation> annotationType() {
+                    return null;
+                }
+            };
+            class B5 {
+            }
+        };
+    }
+
+    public void a5() {
+        class A5 {
+
+            class B1 {
+            }
+
+            public void a5() {
+                new B1() {
+                };
+
+                class B5 {
+                }
+            }
+        }
+        Runnable r = () -> {
+            new A1() {
+            };
+            new A3() {
+            };
+            new A4() {
+                @Override
+                public Class<? extends Annotation> annotationType() {
+                    return null;
+                }
+            };
+            class B5 {
+            }
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesInAnonymousClassTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner classes in anonymous class.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesTestBase TestResult TestBase InMemoryFileManager ToolBox
+ * @run main InnerClassesInAnonymousClassTest
+ */
+
+import java.util.*;
+
+public class InnerClassesInAnonymousClassTest extends InnerClassesTestBase {
+
+    private ClassType currentClassType;
+
+    public static void main(String[] args) throws TestFailedException {
+        InnerClassesTestBase test = new InnerClassesInAnonymousClassTest();
+        test.test("InnerClassesSrc$1", "Anonymous", "1");
+    }
+
+    @Override
+    public void setProperties() {
+        setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+        setInnerAccessModifiers(Modifier.EMPTY);
+        setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.FINAL);
+        setOuterClassType(ClassType.OTHER);
+        setInnerClassType(ClassType.CLASS);
+        setSuffix("};}");
+    }
+
+    @Override
+    public List<TestCase> generateTestCases() {
+        currentClassType = ClassType.CLASS;
+        setPrefix("class Anonymous {} {new Anonymous() {");
+        List<TestCase> sources = super.generateTestCases();
+
+        currentClassType = ClassType.INTERFACE;
+        setPrefix("interface Anonymous {} {new Anonymous() {");
+        sources.addAll(super.generateTestCases());
+
+        currentClassType = ClassType.ANNOTATION;
+        setPrefix("@interface Anonymous {} {new Anonymous() {@Override public "
+                + "Class<? extends java.lang.annotation.Annotation> "
+                + "annotationType() {return null;}");
+        sources.addAll(super.generateTestCases());
+        return sources;
+    }
+
+    @Override
+    public void getAdditionalFlags(Map<String, Set<String>> class2Flags, ClassType type, Modifier... flags) {
+        super.getAdditionalFlags(class2Flags, type, flags);
+        class2Flags.put("Anonymous", getFlags(currentClassType, Arrays.asList(flags)));
+        class2Flags.put("1", new HashSet<>());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerAnnotationTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner classes in inner annotation.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestResult TestBase InMemoryFileManager ToolBox
+ * @run main InnerClassesInInnerAnnotationTest
+ */
+
+public class InnerClassesInInnerAnnotationTest extends InnerClassesInInnerClassTestBase {
+
+    public static void main(String[] args) throws TestFailedException {
+        InnerClassesTestBase test = new InnerClassesInInnerAnnotationTest();
+        test.test("InnerClassesSrc$Inner", "Inner", "1");
+    }
+
+    @Override
+    public void setProperties() {
+        setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+        setInnerAccessModifiers(Modifier.EMPTY, Modifier.PUBLIC);
+        setOuterClassType(ClassType.ANNOTATION);
+        setInnerClassType(ClassType.CLASS);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerClassTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8034854 8042251
+ * @summary Testing InnerClasses_attribute of inner classes in inner class.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestResult TestBase InMemoryFileManager ToolBox
+ * @run main InnerClassesInInnerClassTest
+ */
+
+import java.util.List;
+
+public class InnerClassesInInnerClassTest extends InnerClassesInInnerClassTestBase {
+
+    public static void main(String[] args) throws TestFailedException {
+        InnerClassesTestBase test = new InnerClassesInInnerClassTest();
+        test.test("InnerClassesSrc$Inner", "Inner", "1");
+    }
+
+    @Override
+    public void setProperties() {
+        setHasSyntheticClass(true);
+        setOuterClassType(ClassType.CLASS);
+        setInnerClassType(ClassType.CLASS);
+    }
+
+    @Override
+    public List<TestCase> generateTestCases() {
+        setForbiddenWithoutStaticInOuterMods(true);
+        List<TestCase> sources = super.generateTestCases();
+
+        setForbiddenWithoutStaticInOuterMods(false);
+        setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.FINAL);
+        setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.FINAL);
+        sources.addAll(super.generateTestCases());
+
+        return sources;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerClassTestBase.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ * Base class for tests that check inner classes in inner class.
+ *
+ * @author Andrei Eremeev
+ */
+public abstract class InnerClassesInInnerClassTestBase extends InnerClassesTestBase {
+
+    public InnerClassesInInnerClassTestBase() {
+        setPrefix("Inner {");
+        setSuffix("}");
+    }
+
+    @Override
+    public void getAdditionalFlags(
+            Map<String, Set<String>> class2Flags, ClassType type, Modifier...flags) {
+        super.getAdditionalFlags(class2Flags, type, flags);
+        class2Flags.put("Inner", getFlags(type, Arrays.asList(flags)));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerEnumTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8034854 8042251
+ * @summary Testing InnerClasses_attribute of inner classes in inner enum.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestResult TestBase InMemoryFileManager ToolBox
+ * @run main InnerClassesInInnerEnumTest
+ */
+
+public class InnerClassesInInnerEnumTest extends InnerClassesInInnerClassTestBase {
+
+    public static void main(String[] args) throws TestFailedException {
+        InnerClassesTestBase test = new InnerClassesInInnerEnumTest();
+        test.test("InnerClassesSrc$Inner", "Inner", "1");
+    }
+
+    @Override
+    public void setProperties() {
+        setOuterOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
+        setOuterClassType(ClassType.ENUM);
+        setInnerClassType(ClassType.CLASS);
+        setHasSyntheticClass(true);
+        setPrefix("Inner {;");
+        setSuffix("}");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerInterfaceTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner classes in inner interface.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestResult TestBase InMemoryFileManager ToolBox
+ * @run main InnerClassesInInnerInterfaceTest
+ */
+
+public class InnerClassesInInnerInterfaceTest extends InnerClassesInInnerClassTestBase {
+
+    public static void main(String[] args) throws TestFailedException {
+        InnerClassesTestBase test = new InnerClassesInInnerInterfaceTest();
+        test.test("InnerClassesSrc$Inner", "Inner", "1");
+    }
+
+    @Override
+    public void setProperties() {
+        setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT);
+        setInnerAccessModifiers(Modifier.EMPTY, Modifier.PUBLIC);
+        setOuterClassType(ClassType.INTERFACE);
+        setInnerClassType(ClassType.CLASS);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesInLocalClassTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner classes in local class.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesTestBase TestResult TestBase InMemoryFileManager ToolBox
+ * @run main InnerClassesInLocalClassTest
+ */
+
+import java.util.*;
+
+public class InnerClassesInLocalClassTest extends InnerClassesTestBase {
+
+    private final static Modifier[] LOCAL_CLASS_MODIFIERS =
+            new Modifier[]{Modifier.EMPTY, Modifier.ABSTRACT, Modifier.FINAL};
+    private final static String CLASS_TEMPLATE =
+            "public %CLASS% OuterClass {\n" +
+            "%SOURCE%\n" +
+            "}";
+
+    private final List<Data> innerClassesData;
+
+    public InnerClassesInLocalClassTest() {
+        innerClassesData = new ArrayList<>();
+        for (Modifier outerModifier : LOCAL_CLASS_MODIFIERS) {
+            StringBuilder sb = new StringBuilder();
+            sb.append(outerModifier.getString()).append(' ');
+            sb.append("class Local {");
+            Map<String, Set<String>> class2Flags = new HashMap<>();
+            for (int i = 0; i < LOCAL_CLASS_MODIFIERS.length; ++i) {
+                Modifier innerModifier = LOCAL_CLASS_MODIFIERS[i];
+                sb.append(innerModifier.getString()).append(' ')
+                        .append("class").append(' ')
+                        .append('A').append(i).append("{}\n");
+                class2Flags.put("A" + i, getFlags(innerModifier));
+            }
+            sb.append("};");
+            class2Flags.put("1Local", getFlags(outerModifier));
+            innerClassesData.add(new Data(sb.toString(), class2Flags));
+        }
+    }
+
+    public static void main(String[] args) throws TestFailedException {
+        InnerClassesTestBase test = new InnerClassesInLocalClassTest();
+        test.test("OuterClass$1Local", "1Local");
+    }
+
+    @Override
+    public void setProperties() {
+    }
+
+    @Override
+    public List<TestCase> generateTestCases() {
+        List<TestCase> testCases = new ArrayList<>();
+        testCases.addAll(localClassInClassMethod());
+        testCases.addAll(localClassInInterfaceMethod());
+        return testCases;
+    }
+
+    private List<TestCase> localClassInClassMethod() {
+        List<TestCase> list = new ArrayList<>();
+        String template = CLASS_TEMPLATE.replace("%CLASS%", "class");
+        list.addAll(lambda(template));
+        list.addAll(constructor(template));
+        list.addAll(method(template,
+                new Modifier[]{Modifier.EMPTY, Modifier.PRIVATE, Modifier.PROTECTED, Modifier.PUBLIC},
+                new Modifier[]{Modifier.EMPTY, Modifier.FINAL, Modifier.STATIC}));
+        list.addAll(staticAndInstanceInitializer(template));
+        return list;
+    }
+
+    private List<TestCase> localClassInInterfaceMethod() {
+        String template = CLASS_TEMPLATE.replace("%CLASS%", "interface");
+        return method(template,
+                new Modifier[]{Modifier.EMPTY, Modifier.PUBLIC},
+                new Modifier[]{Modifier.DEFAULT, Modifier.STATIC});
+    }
+
+    private List<TestCase> generate(String template, String prefix, String suffix) {
+        List<TestCase> list = new ArrayList<>();
+        for (Data data : innerClassesData) {
+            list.add(new TestCase(template.replace("%SOURCE%",
+                    prefix + data.sources + suffix),
+                    data.class2Flags));
+        }
+        return list;
+    }
+
+    private List<TestCase> lambda(String template) {
+        return generate(template, "Runnable run = () -> {", "};");
+    }
+
+    private List<TestCase> constructor(String template) {
+        List<TestCase> list = new ArrayList<>();
+        for (Modifier modifier :
+                new Modifier[]{Modifier.EMPTY, Modifier.PRIVATE, Modifier.PROTECTED, Modifier.PUBLIC}) {
+            list.addAll(generate(template, modifier.getString() + " OuterClass() {", "}"));
+        }
+        return list;
+    }
+
+    private List<TestCase> method(String template, Modifier[] mods, Modifier[] otherMods) {
+        List<TestCase> list = new ArrayList<>();
+        for (Modifier modifier : mods) {
+            for (Modifier otherMod : otherMods) {
+                list.addAll(generate(template,
+                        String.format("%s %s void method() {",
+                                modifier.getString(),
+                                otherMod.getString()),
+                        "}"));
+            }
+        }
+        return list;
+    }
+
+    private List<TestCase> staticAndInstanceInitializer(String template) {
+        List<TestCase> list = new ArrayList<>();
+        for (Modifier modifier : new Modifier[]{Modifier.EMPTY, Modifier.STATIC}) {
+            list.addAll(generate(template, modifier.getString() + "{", "}"));
+        }
+        return list;
+    }
+
+    private Set<String> getFlags(Modifier modifier) {
+        HashSet<String> set = new HashSet<>();
+        if (modifier != Modifier.EMPTY) {
+            set.add("ACC_" + modifier.getString().toUpperCase());
+        }
+        return set;
+    }
+
+    /**
+     * Class represents part of sources which is inserted in other code.
+     */
+    private static class Data {
+        public final String sources;
+        public final Map<String, Set<String>> class2Flags;
+
+        public Data(String sources, Map<String, Set<String>> class2Flags) {
+            this.sources = sources;
+            this.class2Flags = class2Flags;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesIndexTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Test that outer_class_info_index of local and anonymous class is zero.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerClassesIndexTest
+ */
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.InnerClasses_attribute;
+import com.sun.tools.classfile.InnerClasses_attribute.Info;
+
+public class InnerClassesIndexTest extends TestResult {
+
+    public static void main(String[] args) throws TestFailedException {
+        new InnerClassesIndexTest().test();
+    }
+
+    private boolean isExcluded(String className) {
+        return !className.startsWith(InnerClassesIndexTest.class.getName())
+                || "InnerClassesIndexTest$Inner".equals(className);
+    }
+
+    private Set<String> getInnerClasses() {
+        FilenameFilter filter = (dir, name) -> name.matches("InnerClassesIndexTest\\$.*\\.class");
+        return Stream.of(getClassDir().listFiles(filter))
+                .map(File::getName)
+                .map(s -> s.replace(".class", ""))
+                .collect(Collectors.toSet());
+    }
+
+    public void test() throws TestFailedException {
+        try {
+            addTestCase("Source is InnerClassesIndexTest.java");
+            ClassFile classFile = readClassFile(InnerClassesIndexTest.class);
+            InnerClasses_attribute attr = (InnerClasses_attribute)
+                    classFile.getAttribute(Attribute.InnerClasses);
+
+            Set<String> foundClasses = new HashSet<>();
+            for (Info info : attr.classes) {
+                String innerName = classFile.constant_pool.
+                        getClassInfo(info.inner_class_info_index).getBaseName();
+                echo("Testing class : " + innerName);
+                if (isExcluded(innerName)) {
+                    echo("Ignored : " + innerName);
+                    continue;
+                }
+                foundClasses.add(innerName);
+                assertEquals(info.outer_class_info_index, 0,
+                        "outer_class_info_index of " + innerName);
+                if (innerName.matches("\\$\\d+")) {
+                    assertEquals(info.inner_name_index, 0,
+                            "inner_name_index of anonymous class");
+                }
+            }
+            Set<String> expectedClasses = getInnerClasses();
+            expectedClasses.remove("InnerClassesIndexTest$Inner");
+            assertEquals(foundClasses, expectedClasses, "All classes are found");
+        } catch (Exception e) {
+            addFailure(e);
+        } finally {
+            checkStatus();
+        }
+    }
+
+    static class Inner {
+    }
+
+    Inner inner1 = new Inner() {
+    };
+
+    static Inner inner2 = new Inner() {
+    };
+
+    Runnable r = () -> {
+        class Local {
+        }
+        new Local() {
+        };
+    };
+
+    public void local() {
+        class Local {
+        }
+        new Local() {
+        };
+    }
+
+    public InnerClassesIndexTest() {
+        class Local {
+        }
+        new Local() {
+        };
+    }
+
+    {
+        class Local {
+        }
+        new Local() {
+        };
+    }
+
+    static {
+        class Local {
+        }
+        new Local() {
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ * @test
+ * @bug 8034854 8042251
+ * @summary Testing inner classes attributes.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerClassesTest
+ */
+
+import java.util.List;
+
+public class InnerClassesTest extends InnerClassesTestBase {
+
+    public static void main(String[] args) throws TestFailedException {
+        new InnerClassesTest().test("InnerClassesSrc");
+    }
+
+    private List<TestCase> generateClasses() {
+        setInnerClassType(ClassType.CLASS);
+        setHasSyntheticClass(true);
+        return super.generateTestCases();
+    }
+
+    private List<TestCase> generateEnums() {
+        setInnerOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
+        setInnerClassType(ClassType.ENUM);
+        setHasSyntheticClass(false);
+        return super.generateTestCases();
+    }
+
+    private List<TestCase> generateInterfaces() {
+        setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+        setInnerClassType(ClassType.INTERFACE);
+        return super.generateTestCases();
+    }
+
+    private List<TestCase> generateAnnotations() {
+        setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+        setInnerClassType(ClassType.ANNOTATION);
+        return super.generateTestCases();
+    }
+
+    @Override
+    public void setProperties() {
+        setOuterAccessModifiers(Modifier.EMPTY);
+        setOuterOtherModifiers(Modifier.EMPTY);
+        setOuterClassType(ClassType.OTHER);
+    }
+
+    @Override
+    public List<TestCase> generateTestCases() {
+        List<TestCase> sources = generateClasses();
+        sources.addAll(generateEnums());
+        sources.addAll(generateInterfaces());
+        sources.addAll(generateAnnotations());
+        return sources;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerClassesTestBase.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,446 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.InnerClasses_attribute;
+import com.sun.tools.classfile.InnerClasses_attribute.Info;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Base class for tests of inner classes attribute.
+ * The scenario of tests:
+ *   1. set possible values of class modifiers.
+ *   2. according to set class modifiers, a test generates sources
+ * and golden data with {@code generateTestCases}.
+ *   3. a test loops through all test cases and checks InnerClasses
+ * attribute with {@code test}.
+ *
+ * Example, possible flags for outer class are {@code Modifier.PRIVATE and Modifier.PUBLIC},
+ * possible flags for inner class are {@code Modifier.EMPTY}.
+ * At the second step the test generates two test cases:
+ *   1. public class A {
+ *        public class B {
+ *          class C {}
+ *        }
+ *      }
+ *   2. public class A {
+ *        private class B {
+ *          class C {}
+ *        }
+ *      }
+ */
+public abstract class InnerClassesTestBase extends TestResult {
+
+    private Modifier[] outerAccessModifiers = {Modifier.EMPTY, Modifier.PRIVATE, Modifier.PROTECTED, Modifier.PUBLIC};
+    private Modifier[] outerOtherModifiers = {Modifier.EMPTY, Modifier.STATIC, Modifier.FINAL, Modifier.ABSTRACT};
+    private Modifier[] innerAccessModifiers = outerAccessModifiers;
+    private Modifier[] innerOtherModifiers = outerOtherModifiers;
+    private boolean isForbiddenWithoutStaticInOuterMods = false;
+
+    private ClassType outerClassType;
+    private ClassType innerClassType;
+    private boolean hasSyntheticClass;
+    private String prefix = "";
+    private String suffix = "";
+
+    /**
+     * Sets properties.
+     *
+     * Returns generated list of test cases. Method is called in {@code test()}.
+     */
+    public abstract void setProperties();
+
+    /**
+     * Runs the test.
+     *
+     * @param classToTest expected name of outer class
+     * @param skipClasses classes that names should not be checked
+     */
+    public void test(String classToTest, String...skipClasses) throws TestFailedException {
+        try {
+            for (TestCase test : generateTestCases()) {
+                addTestCase(test.getSource());
+                test(classToTest, test, skipClasses);
+            }
+        } catch (Exception e) {
+            addFailure(e);
+        } finally {
+            checkStatus();
+        }
+    }
+
+    /**
+     * If {@code flag} is {@code true} an outer class can not have static modifier.
+     *
+     * @param flag if {@code true} the outer class can not have static modifier
+     */
+    public void setForbiddenWithoutStaticInOuterMods(boolean flag) {
+        isForbiddenWithoutStaticInOuterMods = flag;
+    }
+
+    /**
+     * Sets the possible access flags of an outer class.
+     *
+     * @param mods the possible access flags of an outer class
+     */
+    public void setOuterAccessModifiers(Modifier...mods) {
+        outerAccessModifiers = mods;
+    }
+
+    /**
+     * Sets the possible flags of an outer class.
+     *
+     * @param mods the possible flags of an outer class
+     */
+    public void setOuterOtherModifiers(Modifier...mods) {
+        outerOtherModifiers = mods;
+    }
+
+    /**
+     * Sets the possible access flags of an inner class.
+     *
+     * @param mods the possible access flags of an inner class
+     */
+    public void setInnerAccessModifiers(Modifier...mods) {
+        innerAccessModifiers = mods;
+    }
+
+    /**
+     * Sets the possible flags of an inner class.
+     *
+     * @param mods the possible flags of an inner class
+     */
+    public void setInnerOtherModifiers(Modifier...mods) {
+        innerOtherModifiers = mods;
+    }
+
+    /**
+     * Sets the suffix for the generated source.
+     *
+     * @param suffix a suffix
+     */
+    public void setSuffix(String suffix) {
+        this.suffix = suffix;
+    }
+
+    /**
+     * Sets the prefix for the generated source.
+     *
+     * @param prefix a prefix
+     */
+    public void setPrefix(String prefix) {
+        this.prefix = prefix;
+    }
+
+    /**
+     * If {@code true} synthetic class is generated.
+     *
+     * @param hasSyntheticClass if {@code true} synthetic class is generated
+     */
+    public void setHasSyntheticClass(boolean hasSyntheticClass) {
+        this.hasSyntheticClass = hasSyntheticClass;
+    }
+
+    /**
+     * Sets the inner class type.
+     *
+     * @param innerClassType the inner class type
+     */
+    public void setInnerClassType(ClassType innerClassType) {
+        this.innerClassType = innerClassType;
+    }
+
+    /**
+     * Sets the outer class type.
+     *
+     * @param outerClassType the outer class type
+     */
+    public void setOuterClassType(ClassType outerClassType) {
+        this.outerClassType = outerClassType;
+    }
+
+    private void test(String classToTest, TestCase test, String...skipClasses) {
+        printf("Testing :\n%s\n", test.getSource());
+        try {
+            Map<String, Set<String>> class2Flags = test.getFlags();
+            ClassFile cf = readClassFile(compile(test.getSource())
+                    .getClasses().get(classToTest));
+            InnerClasses_attribute innerClasses = (InnerClasses_attribute)
+                    cf.getAttribute(Attribute.InnerClasses);
+            int count = 0;
+            for (Attribute a : cf.attributes.attrs) {
+                if (a instanceof InnerClasses_attribute) {
+                    ++count;
+                }
+            }
+            assertEquals(1, count, "Number of inner classes attribute");
+            if (innerClasses == null) {
+                return;
+            }
+            assertEquals(cf.constant_pool.
+                    getUTF8Info(innerClasses.attribute_name_index).value, "InnerClasses",
+                    "innerClasses.attribute_name_index");
+            // Inner Classes attribute consists of length (2 bytes)
+            // and 8 bytes for each inner class's entry.
+            assertEquals(innerClasses.attribute_length,
+                    2 + 8 * class2Flags.size(), "innerClasses.attribute_length");
+            assertEquals(innerClasses.number_of_classes,
+                    class2Flags.size(), "innerClasses.number_of_classes");
+            Set<String> visitedClasses = new HashSet<>();
+            for (Info e : innerClasses.classes) {
+                String baseName = cf.constant_pool.getClassInfo(
+                        e.inner_class_info_index).getBaseName();
+                if (cf.major_version >= 51 && e.inner_name_index == 0) {
+                    assertEquals(e.outer_class_info_index, 0,
+                        "outer_class_info_index "
+                                + "in case of inner_name_index is zero : "
+                                + baseName);
+                }
+                String className = baseName.replaceFirst(".*\\$", "");
+                assertTrue(class2Flags.containsKey(className),
+                        className);
+                assertTrue(visitedClasses.add(className),
+                        "there are no duplicates in attribute : " + className);
+                assertEquals(e.inner_class_access_flags.getInnerClassFlags(),
+                        class2Flags.get(className),
+                        "inner_class_access_flags " + className);
+                if (!Arrays.asList(skipClasses).contains(className)) {
+                        assertEquals(
+                            cf.constant_pool.getClassInfo(e.inner_class_info_index).getBaseName(),
+                            classToTest + "$" + className,
+                            "inner_class_info_index of " + className);
+                    if (e.outer_class_info_index > 0) {
+                        assertEquals(
+                                cf.constant_pool.getClassInfo(e.outer_class_info_index).getName(),
+                                classToTest,
+                                "outer_class_info_index of " + className);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            addFailure(e);
+        }
+    }
+
+    /**
+     * Methods generates list of test cases. Method generates all possible combinations
+     * of acceptable flags for nested inner classes.
+     *
+     * @return generated list of test cases
+     */
+    protected List<TestCase> generateTestCases() {
+        setProperties();
+        List<TestCase> list = new ArrayList<>();
+
+        List<List<Modifier>> outerMods = getAllCombinations(outerAccessModifiers, outerOtherModifiers);
+        List<List<Modifier>> innerMods = getAllCombinations(innerAccessModifiers, innerOtherModifiers);
+
+        for (List<Modifier> outerMod : outerMods) {
+            if (isForbiddenWithoutStaticInOuterMods && !outerMod.contains(Modifier.STATIC)) {
+                continue;
+            }
+            StringBuilder sb = new StringBuilder();
+            sb.append("public class InnerClassesSrc {")
+                    .append(toString(outerMod)).append(' ')
+                    .append(outerClassType).append(' ')
+                    .append(prefix).append(' ').append('\n');
+            int count = 0;
+            Map<String, Set<String>> class2Flags = new HashMap<>();
+            List<String> syntheticClasses = new ArrayList<>();
+            for (List<Modifier> innerMod : innerMods) {
+                ++count;
+                String privateConstructor = "";
+                if (hasSyntheticClass && !innerMod.contains(Modifier.ABSTRACT)) {
+                    privateConstructor = "private A" + count + "() {}";
+                    syntheticClasses.add("new A" + count + "();");
+                }
+                sb.append(toString(innerMod)).append(' ');
+                sb.append(String.format("%s A%d {%s}\n", innerClassType, count, privateConstructor));
+                Set<String> flags = getFlags(innerClassType, innerMod);
+                class2Flags.put("A" + count, flags);
+            }
+            if (hasSyntheticClass) {
+                // Source to generate synthetic classes
+                sb.append(syntheticClasses.stream().collect(Collectors.joining(" ", "{", "}")));
+                class2Flags.put("1", new HashSet<>(Arrays.asList("ACC_STATIC", "ACC_SYNTHETIC")));
+            }
+            sb.append(suffix).append("\n}");
+            getAdditionalFlags(class2Flags, outerClassType, outerMod.toArray(new Modifier[outerMod.size()]));
+            list.add(new TestCase(sb.toString(), class2Flags));
+        }
+        return list;
+    }
+
+    /**
+     * Methods returns flags which must have type.
+     *
+     * @param type class, interface, enum or annotation
+     * @param mods modifiers
+     * @return set of access flags
+     */
+    protected Set<String> getFlags(ClassType type, List<Modifier> mods) {
+        Set<String> flags = mods.stream()
+                .map(Modifier::getString)
+                .filter(str -> !str.isEmpty())
+                .map(str -> "ACC_" + str.toUpperCase())
+                .collect(Collectors.toSet());
+        type.addSpecificFlags(flags);
+        return flags;
+    }
+
+    private List<List<Modifier>> getAllCombinations(Modifier[] accessModifiers, Modifier[] otherModifiers) {
+        List<List<Modifier>> list = new ArrayList<>();
+        for (Modifier access : accessModifiers) {
+            for (int i = 0; i < otherModifiers.length; ++i) {
+                Modifier mod1 = otherModifiers[i];
+                for (int j = i + 1; j < otherModifiers.length; ++j) {
+                    Modifier mod2 = otherModifiers[j];
+                    if (isForbidden(mod1, mod2)) {
+                        continue;
+                    }
+                    list.add(Arrays.asList(access, mod1, mod2));
+                }
+                if (mod1 == Modifier.EMPTY) {
+                    list.add(Arrays.asList(access));
+                }
+            }
+        }
+        return list;
+    }
+
+    private boolean isForbidden(Modifier mod1, Modifier mod2) {
+        return mod1 == Modifier.FINAL && mod2 == Modifier.ABSTRACT
+                || mod1 == Modifier.ABSTRACT && mod2 == Modifier.FINAL;
+    }
+
+    private String toString(List<Modifier> mods) {
+        return mods.stream()
+                .map(Modifier::getString)
+                .filter(s -> !s.isEmpty())
+                .collect(Collectors.joining(" "));
+    }
+
+    /**
+     * Method is called in generateTestCases().
+     * If you need to add additional access flags, you should override this method.
+     *
+     *
+     * @param class2Flags map with flags
+     * @param type class, interface, enum or @annotation
+     * @param mods modifiers
+     */
+    public void getAdditionalFlags(Map<String, Set<String>> class2Flags, ClassType type, Modifier...mods) {
+        class2Flags.values().forEach(type::addFlags);
+    }
+
+    public enum ClassType {
+        CLASS("class") {
+            @Override
+            public void addSpecificFlags(Set<String> flags) {
+            }
+        },
+        INTERFACE("interface") {
+            @Override
+            public void addFlags(Set<String> flags) {
+                flags.add("ACC_STATIC");
+                flags.add("ACC_PUBLIC");
+            }
+
+            @Override
+            public void addSpecificFlags(Set<String> flags) {
+                flags.add("ACC_INTERFACE");
+                flags.add("ACC_ABSTRACT");
+                flags.add("ACC_STATIC");
+            }
+        },
+        ANNOTATION("@interface") {
+            @Override
+            public void addFlags(Set<String> flags) {
+                flags.add("ACC_STATIC");
+                flags.add("ACC_PUBLIC");
+            }
+
+            @Override
+            public void addSpecificFlags(Set<String> flags) {
+                flags.add("ACC_INTERFACE");
+                flags.add("ACC_ABSTRACT");
+                flags.add("ACC_STATIC");
+                flags.add("ACC_ANNOTATION");
+            }
+        },
+        ENUM("enum") {
+            @Override
+            public void addSpecificFlags(Set<String> flags) {
+                flags.add("ACC_ENUM");
+                flags.add("ACC_FINAL");
+                flags.add("ACC_STATIC");
+            }
+        },
+        OTHER("") {
+            @Override
+            public void addSpecificFlags(Set<String> flags) {
+            }
+        };
+
+        private final String classType;
+
+        private ClassType(String clazz) {
+            this.classType = clazz;
+        }
+
+        public abstract void addSpecificFlags(Set<String> flags);
+
+        public String toString() {
+            return classType;
+        }
+
+        public void addFlags(Set<String> set) {
+        }
+    }
+
+    public enum Modifier {
+        PUBLIC("public"), PRIVATE("private"),
+        PROTECTED("protected"), DEFAULT("default"),
+        FINAL("final"), ABSTRACT("abstract"),
+        STATIC("static"), EMPTY("");
+
+        private final String str;
+
+        private Modifier(String str) {
+            this.str = str;
+        }
+
+        public String getString() {
+            return str;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerEnumInInnerAnnotationTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner enums in inner annotation.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerEnumInInnerAnnotationTest
+ */
+
+public class InnerEnumInInnerAnnotationTest extends InnerClassesInInnerClassTestBase {
+
+    public static void main(String[] args) throws TestFailedException {
+        InnerClassesTestBase test = new InnerEnumInInnerAnnotationTest();
+        test.test("InnerClassesSrc$Inner", "Inner", "1");
+    }
+
+    @Override
+    public void setProperties() {
+        setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+        setInnerAccessModifiers(Modifier.EMPTY, Modifier.PUBLIC);
+        setInnerOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
+        setOuterClassType(ClassType.ANNOTATION);
+        setInnerClassType(ClassType.ENUM);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerEnumInInnerEnumTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner enums in inner enum.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerEnumInInnerEnumTest
+ */
+
+public class InnerEnumInInnerEnumTest extends InnerClassesInInnerClassTestBase {
+
+    public static void main(String[] args) throws TestFailedException {
+        InnerClassesTestBase test = new InnerEnumInInnerEnumTest();
+        test.test("InnerClassesSrc$Inner", "Inner", "1");
+    }
+
+    @Override
+    public void setProperties() {
+        setOuterOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
+        setInnerOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
+        setOuterClassType(ClassType.ENUM);
+        setInnerClassType(ClassType.ENUM);
+        setPrefix("Inner {;");
+        setSuffix("}");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerEnumInInnerInterfaceTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner enums in inner interface.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerEnumInInnerInterfaceTest
+ */
+
+public class InnerEnumInInnerInterfaceTest extends InnerClassesInInnerClassTestBase {
+
+    public static void main(String[] args) throws TestFailedException {
+        InnerClassesTestBase test = new InnerEnumInInnerInterfaceTest();
+        test.test("InnerClassesSrc$Inner", "Inner", "1");
+    }
+
+    @Override
+    public void setProperties() {
+        setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+        setInnerAccessModifiers(Modifier.EMPTY, Modifier.PUBLIC);
+        setInnerOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
+        setOuterClassType(ClassType.INTERFACE);
+        setInnerClassType(ClassType.ENUM);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerEnumsInInnerClassTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner enums in inner class.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerEnumsInInnerClassTest
+ */
+
+public class InnerEnumsInInnerClassTest extends InnerClassesInInnerClassTestBase {
+
+    public static void main(String[] args) throws TestFailedException {
+        InnerClassesTestBase test = new InnerEnumsInInnerClassTest();
+        test.test("InnerClassesSrc$Inner", "Inner", "1");
+    }
+
+    @Override
+    public void setProperties() {
+        setForbiddenWithoutStaticInOuterMods(true);
+        setInnerOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
+        setOuterClassType(ClassType.CLASS);
+        setInnerClassType(ClassType.ENUM);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerInterfacesInInnerAnnotationTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner interfaces in inner annotation.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerInterfacesInInnerAnnotationTest
+ */
+
+public class InnerInterfacesInInnerAnnotationTest extends InnerClassesInInnerClassTestBase {
+
+    public static void main(String[] args) throws TestFailedException {
+        InnerClassesTestBase test = new InnerInterfacesInInnerAnnotationTest();
+        test.test("InnerClassesSrc$Inner", "Inner", "1");
+    }
+
+    @Override
+    public void setProperties() {
+        setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+        setInnerAccessModifiers(Modifier.EMPTY, Modifier.PUBLIC);
+        setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+        setOuterClassType(ClassType.ANNOTATION);
+        setInnerClassType(ClassType.INTERFACE);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerInterfacesInInnerClassTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, 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
+ * @summary Testing InnerClasses_attribute of inner interfaces in inner class.
+ * @author aeremeev
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerInterfacesInInnerClassTest
+ */
+
+public class InnerInterfacesInInnerClassTest extends InnerClassesInInnerClassTestBase {
+
+    public static void main(String[] args) throws TestFailedException {
+        InnerClassesTestBase test = new InnerInterfacesInInnerClassTest();
+        test.test("InnerClassesSrc$Inner", "Inner", "1");
+    }
+
+    @Override
+    public void setProperties() {
+        setForbiddenWithoutStaticInOuterMods(true);
+        setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+        setOuterClassType(ClassType.CLASS);
+        setInnerClassType(ClassType.INTERFACE);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerInterfacesInInnerEnumTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner interfaces in inner enum.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerInterfacesInInnerEnumTest
+ */
+
+public class InnerInterfacesInInnerEnumTest extends InnerClassesInInnerClassTestBase {
+
+    public static void main(String[] args) throws TestFailedException {
+        InnerClassesTestBase test = new InnerInterfacesInInnerEnumTest();
+        test.test("InnerClassesSrc$Inner", "Inner", "1");
+    }
+
+    @Override
+    public void setProperties() {
+        setOuterOtherModifiers(Modifier.EMPTY, Modifier.STATIC);
+        setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+        setOuterClassType(ClassType.ENUM);
+        setInnerClassType(ClassType.INTERFACE);
+        setPrefix("Inner {;");
+        setSuffix("}");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/InnerInterfacesInInnerInterfaceTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Testing InnerClasses_attribute of inner interfaces in inner interface.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build InnerClassesInInnerClassTestBase InnerClassesTestBase TestBase TestResult InMemoryFileManager ToolBox
+ * @run main InnerInterfacesInInnerInterfaceTest
+ */
+
+import java.util.List;
+
+public class InnerInterfacesInInnerInterfaceTest extends InnerClassesInInnerClassTestBase {
+
+    public static void main(String[] args) throws TestFailedException {
+        InnerClassesTestBase test = new InnerInterfacesInInnerInterfaceTest();
+        test.test("InnerClassesSrc$Inner", "Inner", "1");
+    }
+
+    @Override
+    public void setProperties() {
+        setOuterOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+        setInnerAccessModifiers(Modifier.EMPTY, Modifier.PUBLIC);
+        setInnerOtherModifiers(Modifier.EMPTY, Modifier.ABSTRACT, Modifier.STATIC);
+        setOuterClassType(ClassType.INTERFACE);
+        setInnerClassType(ClassType.INTERFACE);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/NoInnerClassesTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042251
+ * @summary Test that there are no inner classes attributes in case of there are no inner classes.
+ * @library /tools/lib /tools/javac/lib ../lib
+ * @build TestBase InMemoryFileManager ToolBox
+ * @run main NoInnerClassesTest
+ */
+
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPoolException;
+
+import java.io.IOException;
+
+public class NoInnerClassesTest extends TestBase {
+
+    public static void main(String[] args) throws IOException, ConstantPoolException {
+        new NoInnerClassesTest().test();
+    }
+
+    public void test() throws IOException, ConstantPoolException {
+        ClassFile classFile = readClassFile("NoInnerClassesTest");
+        assertNull(classFile.getAttribute(Attribute.InnerClasses), "Found inner class attribute");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/README.txt	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,92 @@
+The description of the tests for the InnerClasses attribute.
+
+InnerClassesTestBase is the base class for tests of inner classes attribute.
+Each tests extends the base class.
+The scenario of tests:
+    1. set possible values of class modifiers, outer/inner class types.
+    2. according to set class modifiers, a test generates sources
+       and golden data with generateTestCases.
+    3. a test loops through all test cases and checks InnerClasses attribute in method test().
+
+Example, possible flags for outer class are Modifier.PRIVATE and Modifier.PUBLIC,
+possible flags for inner class are Modifier.EMPTY, outer class type is CLASS
+and inner class type is CLASS.
+At the second step the test generates two test cases:
+  1. public class A {
+       public class B {
+         class C {}
+        }
+     }
+  2. public class A {
+       private class B {
+         class C {}
+       }
+     }
+
+The list of tests.
+
+Test: test if there is not inner class, the InnerClasses attribute
+is not generated (NoInnerClasses.java).
+
+Test: inner classes in anonymous class (InnerClassesInAnonymousClassTest.java).
+Possible access flags of the inner class: abstract and final.
+
+Test: inner classes in local class (InnerClassesInLocalClassTest.java).
+Locations of local class: static and instance initializer, constructor, method, lambda,
+default and static methods of interface.
+
+Test: test the outer_class_info_index and inner_name_index of
+local and anonymous classes (InnerClassesIndexTest.java).
+
+List of test cases for Inner*InInner*Test:
+    * InnerClassesInInnerClassTest
+        outer flags: all possible flags
+        inner flags: all possible flags
+    * InnerClassesInInnerEnumTest
+        outer flags: all access flags, abstract
+        inner flags: all possible flags
+    * InnerClassesInInnerAnnotationTest
+        outer flags: all access flags, abstract
+        inner flags: all flags, except private and protected
+    * InnerClassesInInnerInterfaceTest
+        outer flags: all access flags, abstract
+        inner flags: all flags, except private and protected
+
+    * InnerEnumsInInnerClassTest
+        outer flags: all possible flags
+        inner flags: all possible flags
+    * InnerEnumsInInnerEnumTest
+        outer flags: all possible flags
+        inner flags: all possible flags
+    * InnerEnumsInInnerAnnotationTest
+        outer flags: all access flags, abstract, static
+        inner flags: public, static
+    * InnerEnumsInInnerInterfaceTest
+        outer flags: all access flags, abstract, static
+        inner flags: public, static
+
+    * InnerAnnotationInInnerClassTest
+        outer flags: all possible flags, except static
+        inner flags: all access flags, abstract and static
+    * InnerAnnotationInInnerEnumTest
+        outer flags: all access flags, static
+        inner flags: all access flags, abstract and static
+    * InnerAnnotationInInnerAnnotation
+        outer flags: all access flags, static and abstract
+        inner flags: public, abstract, static
+    * InnerAnnotationInInnerInterface
+        outer flags: all access flags, static and abstract
+        inner flags: public, abstract, static
+
+    * InnerInterfaceInInnerClassTest
+        outer flags: all possible flags, except static
+        inner flags: all access flags, abstract and static
+    * InnerInterfaceInInnerEnumTest
+        outer flags: all access flags, static
+        inner flags: all access flags, abstract and static
+    * InnerInterfaceInInnerAnnotation
+        outer flags: all access flags, static and abstract
+        inner flags: public, abstract, static
+    * InnerInterfaceInInnerInterface
+        outer flags: all access flags, static and abstract
+        inner flags: public, abstract, static
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/innerclasses/TestCase.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Class represents test cases. This class contains source code and
+ * access flags for each inner class in source code.
+ */
+public class TestCase {
+
+    private final String sourceCode;
+    private final Map<String, Set<String>> class2Flags;
+
+    public TestCase(String sourceCode, Map<String, Set<String>> class2Flags) {
+        this.sourceCode = sourceCode;
+        this.class2Flags = class2Flags;
+    }
+
+    /**
+     * Returns source code.
+     *
+     * @return source code
+     */
+    public String getSource() {
+        return sourceCode;
+    }
+
+    /**
+     * Returns map with entries (ClassName, set of access flags for the ClassName).
+     *
+     * @return map with entries (ClassName, set of access flags for the ClassName)
+     */
+    public Map<String, Set<String>> getFlags() {
+        return class2Flags;
+    }
+}
--- a/langtools/test/tools/javac/classfiles/attributes/lib/TestBase.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/lib/TestBase.java	Thu Aug 28 14:53:49 2014 -0700
@@ -22,22 +22,23 @@
  */
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
 import java.util.function.Function;
-import java.util.stream.Stream;
+import java.util.stream.Collectors;
+
 import javax.tools.DiagnosticCollector;
 import javax.tools.JavaCompiler;
 import javax.tools.JavaFileObject;
 import javax.tools.ToolProvider;
 
-import static java.lang.String.format;
-import static java.lang.System.lineSeparator;
-import static java.util.Arrays.asList;
-import static java.util.Collections.emptyList;
-import static java.util.stream.Collectors.joining;
-import static java.util.stream.Collectors.toList;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPoolException;
 
 /**
  * Base class for class file attribute tests.
@@ -46,7 +47,7 @@
  */
 public class TestBase {
 
-    public static final String LINE_SEPARATOR = lineSeparator();
+    public static final String LINE_SEPARATOR = System.lineSeparator();
 
     private <S> InMemoryFileManager compile(
             List<String> options,
@@ -57,7 +58,7 @@
         JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
         List<? extends JavaFileObject> src = sources.stream()
                 .map(src2JavaFileObject)
-                .collect(toList());
+                .collect(Collectors.toList());
 
         DiagnosticCollector<? super JavaFileObject> dc = new DiagnosticCollector<>();
         try (InMemoryFileManager fileManager
@@ -67,7 +68,7 @@
             if (!success) {
                 String errorMessage = dc.getDiagnostics().stream()
                         .map(Object::toString)
-                        .collect(joining("\n"));
+                        .collect(Collectors.joining("\n"));
                 throw new CompilationException("Compilation Error\n\n" + errorMessage);
             }
             return fileManager;
@@ -82,7 +83,7 @@
      */
     public InMemoryFileManager compile(String... sources)
             throws IOException, CompilationException {
-        return compile(emptyList(), sources);
+        return compile(Collections.emptyList(), sources);
     }
 
     /**
@@ -94,7 +95,7 @@
      */
     public InMemoryFileManager compile(List<String> options, String... sources)
             throws IOException, CompilationException {
-        return compile(options, ToolBox.JavaSource::new, asList(sources));
+        return compile(options, ToolBox.JavaSource::new, Arrays.asList(sources));
     }
 
     /**
@@ -105,7 +106,7 @@
      */
     public InMemoryFileManager compile(String[]... sources) throws IOException,
             CompilationException {
-        return compile(emptyList(), sources);
+        return compile(Collections.emptyList(), sources);
     }
 
     /**
@@ -117,12 +118,73 @@
      */
     public InMemoryFileManager compile(List<String> options, String[]... sources)
             throws IOException, CompilationException {
-        return compile(options, src -> new ToolBox.JavaSource(src[0], src[1]), asList(sources));
+        return compile(options, src -> new ToolBox.JavaSource(src[0], src[1]), Arrays.asList(sources));
+    }
+
+    /**
+     * Returns class file that is read from {@code is}.
+     *
+     * @param is an input stream
+     * @return class file that is read from {@code is}
+     * @throws IOException if I/O error occurs
+     * @throws ConstantPoolException if constant pool error occurs
+     */
+    public ClassFile readClassFile(InputStream is) throws IOException, ConstantPoolException {
+        return ClassFile.read(is);
+    }
+
+    /**
+     * Returns class file that is read from {@code fileObject}.
+     *
+     * @param fileObject a file object
+     * @return class file that is read from {@code fileObject}
+     * @throws IOException if I/O error occurs
+     * @throws ConstantPoolException if constant pool error occurs
+     */
+    public ClassFile readClassFile(JavaFileObject fileObject) throws IOException, ConstantPoolException {
+        return readClassFile(fileObject.openInputStream());
+    }
+
+    /**
+     * Returns class file that corresponds to {@code clazz}.
+     *
+     * @param clazz a class
+     * @return class file that is read from {@code clazz}
+     * @throws IOException if I/O error occurs
+     * @throws ConstantPoolException if constant pool error occurs
+     */
+    public ClassFile readClassFile(Class<?> clazz) throws IOException, ConstantPoolException {
+        return readClassFile(getClassFile(clazz));
+    }
+
+    /**
+     * Returns class file that corresponds to {@code className}.
+     *
+     * @param className a class name
+     * @return class file that is read from {@code className}
+     * @throws IOException if I/O error occurs
+     * @throws ConstantPoolException if constant pool error occurs
+     */
+    public ClassFile readClassFile(String className) throws IOException, ConstantPoolException {
+        return readClassFile(getClassFile(className + ".class"));
+    }
+
+    /**
+     * Returns class file that is read from {@code file}.
+     *
+     * @param file a file
+     * @return class file that is read from {@code file}
+     * @throws IOException if I/O error occurs
+     * @throws ConstantPoolException if constant pool error occurs
+     */
+    public ClassFile readClassFile(File file) throws IOException, ConstantPoolException {
+        return readClassFile(new FileInputStream(file));
     }
 
     public void assertEquals(Object actual, Object expected, String message) {
         if (!Objects.equals(actual, expected))
-            throw new AssertionFailedException(format("%s%nGot: %s, Expected: %s", message, actual, expected));
+            throw new AssertionFailedException(String.format("%s%nGot: %s, Expected: %s",
+                    message, actual, expected));
     }
 
     public void assertNull(Object actual, String message) {
@@ -169,22 +231,18 @@
      * @param message string to print.
      */
     public void echo(String message) {
-        System.err.println(message.replace("\n", LINE_SEPARATOR));
+        printf(message + "\n");
     }
 
     /**
-     * Substitutes args in template and prints result to standard error. New lines are converted to system dependent NL.
+     * Substitutes args in template and prints result to standard error.
+     * New lines are converted to system dependent NL.
      *
      * @param template template in standard String.format(...) format.
      * @param args arguments to substitute in template.
      */
     public void printf(String template, Object... args) {
-        System.err.printf(template, Stream.of(args)
-                .map(Objects::toString)
-                .map(m -> m.replace("\n", LINE_SEPARATOR))
-                .collect(toList())
-                .toArray());
-
+        System.err.printf(String.format(template, args).replace("\n", LINE_SEPARATOR));
     }
 
     public static class CompilationException extends Exception {
--- a/langtools/test/tools/javac/classfiles/attributes/lib/TestResult.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/lib/TestResult.java	Thu Aug 28 14:53:49 2014 -0700
@@ -23,13 +23,15 @@
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
+import java.util.*;
+import java.util.stream.Stream;
 
 import static java.lang.String.format;
 import static java.util.stream.Collectors.joining;
 
+/**
+ * This class accumulates test results. Test results can be checked with method @{code checkStatus}.
+ */
 public class TestResult extends TestBase {
 
     private final List<Info> testCases;
@@ -39,15 +41,18 @@
         testCases.add(new Info("Global test info"));
     }
 
-    public void addTestCase(String src) {
-        testCases.add(new Info(src));
+    /**
+     * Adds new test case info.
+     *
+     * @param info the information about test case
+     */
+    public void addTestCase(String info) {
+        testCases.add(new Info(info));
     }
 
-    public String errorMessage() {
+    private String errorMessage() {
         return testCases.stream().filter(Info::isFailed)
-                .map(tc -> format("Failure in test case:\n%s\n%s", tc.info(),
-                        (tc.asserts.size() > 0 ? tc.getAssertMessage() + "\n" : "")
-                                + tc.getErrorMessage()))
+                .map(tc -> format("Failure in test case:\n%s\n%s", tc.info(), tc.getMessage()))
                 .collect(joining("\n"));
     }
 
@@ -76,8 +81,14 @@
         getLastTestCase().assertEquals(actual, true, message);
     }
 
+    public void assertContains(Set<?> found, Set<?> expected, String message) {
+        Set<?> copy = new HashSet<>(expected);
+        copy.removeAll(found);
+        assertTrue(found.containsAll(expected), message + " : " + copy);
+    }
+
     public void addFailure(Throwable th) {
-        getLastTestCase().addFailure(th);
+        testCases.get(testCases.size() - 1).addFailure(th);
     }
 
     private Info getLastTestCase() {
@@ -87,6 +98,13 @@
         return testCases.get(testCases.size() - 1);
     }
 
+    /**
+     * Throws {@code TestFailedException} if one of the asserts are failed
+     * or an exception occurs. Prints error message of failed test cases.
+     *
+     * @throws TestFailedException if one of the asserts are failed
+     *                             or an exception occurs
+     */
     public void checkStatus() throws TestFailedException {
         if (testCases.stream().anyMatch(Info::isFailed)) {
             echo(errorMessage());
@@ -120,7 +138,13 @@
         }
 
         public void addFailure(String message) {
-            asserts.add(message);
+            String stackTrace = Stream.of(Thread.currentThread().getStackTrace())
+                    // just to get stack trace without TestResult and Thread
+                    .filter(e -> !"TestResult.java".equals(e.getFileName()) &&
+                            !"java.lang.Thread".equals(e.getClassName()))
+                    .map(e -> "\tat " + e)
+                    .collect(joining("\n"));
+            asserts.add(format("%s\n%s", message, stackTrace));
             printf("[ASSERT] : %s\n", message);
         }
 
@@ -138,6 +162,10 @@
             }
         }
 
+        public String getMessage() {
+            return (asserts.size() > 0 ? getAssertMessage() + "\n" : "") + getErrorMessage();
+        }
+
         public String getAssertMessage() {
             return asserts.stream()
                     .map(failure -> "[ASSERT] : " + failure)
@@ -146,8 +174,7 @@
 
         public String getErrorMessage() {
             return errors.stream()
-                    .map(throwable ->
-                            format("[ERROR] : %s", getStackTrace(throwable)))
+                    .map(throwable -> format("[ERROR] : %s", getStackTrace(throwable)))
                     .collect(joining("\n"));
         }
 
--- a/langtools/test/tools/javac/defaultMethodsVisibility/DefaultMethodsNotVisibleForSourceLessThan8Test.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/defaultMethodsVisibility/DefaultMethodsNotVisibleForSourceLessThan8Test.java	Thu Aug 28 14:53:49 2014 -0700
@@ -26,7 +26,7 @@
  * @bug 8029240 8030855
  * @summary Default methods not always visible under -source 7
  * Default methods should be visible under source previous to 8
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main DefaultMethodsNotVisibleForSourceLessThan8Test
  */
@@ -111,6 +111,7 @@
 
     String outDir;
     String source;
+    ToolBox tb = new ToolBox();
 
     void run(String source) throws Exception {
         this.source = source;
@@ -127,50 +128,53 @@
         /* as an extra check let's make sure that interface 'I' can't be compiled
          * with source < 8
          */
-        ToolBox.JavaToolArgs javacArgs =
-                new ToolBox.JavaToolArgs(ToolBox.Expect.FAIL)
-                .setOptions("-d", outDir, "-source", source)
-                .setSources(ISrc);
-        ToolBox.javac(javacArgs);
+        tb.new JavacTask()
+                .outdir(outDir)
+                .options("-source", source)
+                .sources(ISrc)
+                .run(ToolBox.Expect.FAIL);
 
         //but it should compile with source >= 8
-        javacArgs =
-                new ToolBox.JavaToolArgs()
-                .setOptions("-d", outDir)
-                .setSources(ISrc);
-        ToolBox.javac(javacArgs);
+        tb.new JavacTask()
+                .outdir(outDir)
+                .sources(ISrc)
+                .run();
 
-        javacArgs =
-                new ToolBox.JavaToolArgs()
-                .setOptions("-cp", outDir, "-d", outDir, "-source", source)
-                .setSources(JSrc, ASrc, BSrc);
-        ToolBox.javac(javacArgs);
+        tb.new JavacTask()
+                .outdir(outDir)
+                .classpath(outDir)
+                .options("-source", source)
+                .sources(JSrc, ASrc, BSrc)
+                .run();
     }
 
     void testLegacyImplementations() throws Exception {
         //compile C1-4
-        ToolBox.JavaToolArgs javacArgs =
-                new ToolBox.JavaToolArgs()
-                .setOptions("-cp", outDir, "-d", outDir, "-source", source)
-                .setSources(C1Src, C2Src, C3Src, C4Src);
-        ToolBox.javac(javacArgs);
+        tb.new JavacTask()
+                .outdir(outDir)
+                .classpath(outDir)
+                .options("-source", source)
+                .sources(C1Src, C2Src, C3Src, C4Src)
+                .run();
     }
 
     void testLegacyInvocations() throws Exception {
         //compile LegacyInvocation
-        ToolBox.JavaToolArgs javacArgs =
-                new ToolBox.JavaToolArgs()
-                .setOptions("-cp", outDir, "-d", outDir, "-source", source)
-                .setSources(LegacyInvocationSrc);
-        ToolBox.javac(javacArgs);
+        tb.new JavacTask()
+                .outdir(outDir)
+                .classpath(outDir)
+                .options("-source", source)
+                .sources(LegacyInvocationSrc)
+                .run();
     }
 
     void testSuperInvocations() throws Exception {
         //compile SubA, SubB
-        ToolBox.JavaToolArgs javacArgs =
-                new ToolBox.JavaToolArgs()
-                .setOptions("-cp", outDir, "-d", outDir, "-source", source)
-                .setSources(SubASrc, SubBSrc);
-        ToolBox.javac(javacArgs);
+        tb.new JavacTask()
+                .outdir(outDir)
+                .classpath(outDir)
+                .options("-source", source)
+                .sources(SubASrc, SubBSrc)
+                .run();
     }
 }
--- a/langtools/test/tools/javac/fatalErrors/NoJavaLangTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/fatalErrors/NoJavaLangTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,15 +25,12 @@
  * @test
  * @bug 4263768 4785453
  * @summary Verify that the compiler does not crash when java.lang is not
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main NoJavaLangTest
  */
 
-import java.util.ArrayList;
-import java.util.List;
-
-//original test: test/tools/javac/fatalErrors/NoJavaLang.sh
+// Original test: test/tools/javac/fatalErrors/NoJavaLang.sh
 public class NoJavaLangTest {
 
     private static final String noJavaLangSrc =
@@ -49,26 +46,20 @@
         "Fatal Error: Unable to find package java.lang in classpath or bootclasspath";
 
     public static void main(String[] args) throws Exception {
-//        "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} NoJavaLang.java 2> "${TMP1}"
-        ToolBox.JavaToolArgs javacSuccessArgs =
-                new ToolBox.JavaToolArgs().setSources(noJavaLangSrc);
-        ToolBox.javac(javacSuccessArgs);
+        ToolBox tb = new ToolBox();
+
+        tb.new JavacTask()
+                .sources(noJavaLangSrc)
+                .run();
 
-//        "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -bootclasspath . NoJavaLang.java 2> "${TMP1}"
-        List<String> output = new ArrayList<>();
-        ToolBox.JavaToolArgs javacFailArgs =
-                new ToolBox.JavaToolArgs(ToolBox.Expect.FAIL)
-                .setOptions("-bootclasspath", ".")
-                .setSources(noJavaLangSrc)
-                .setErrOutput(output);
+        String out = tb.new JavacTask()
+                .options("-bootclasspath", ".")
+                .sources(noJavaLangSrc)
+                .run(ToolBox.Expect.FAIL, 3)
+                .writeAll()
+                .getOutput(ToolBox.OutputKind.DIRECT);
 
-        int cr = ToolBox.javac(javacFailArgs);
-        if (cr != 3) {
-            throw new AssertionError("Compiler exit result should be 3");
-        }
-
-//        diff ${DIFFOPTS} -c "${TESTSRC}${FS}NoJavaLang.out" "${TMP1}"
-        if (!(output.size() == 1 && output.get(0).equals(compilerErrorMessage))) {
+        if (!out.trim().equals(compilerErrorMessage)) {
             throw new AssertionError("javac generated error output is not correct");
         }
     }
--- a/langtools/test/tools/javac/innerClassFile/InnerClassFileTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/innerClassFile/InnerClassFileTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,14 +25,15 @@
  * @test
  * @bug 4491755 4785453
  * @summary Prob w/static inner class with same name as a regular class
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main InnerClassFileTest
  */
 
+import java.nio.file.Path;
 import java.nio.file.Paths;
 
-//original test: test/tools/javac/innerClassFile/Driver.sh
+// Original test: test/tools/javac/innerClassFile/Driver.sh
 public class InnerClassFileTest {
 
     private static final String BSrc =
@@ -90,38 +91,37 @@
         new InnerClassFileTest().run();
     }
 
+    private final ToolBox tb = new ToolBox();
+
     void run() throws Exception {
         createFiles();
         compileFiles();
     }
 
     void createFiles() throws Exception {
-//        mkdir src
-//        cp -r ${TESTSRC}${FS}* src
-        ToolBox.createJavaFileFromSource(Paths.get("src"), BSrc);
-        ToolBox.createJavaFileFromSource(Paths.get("src"), CSrc);
-        ToolBox.createJavaFileFromSource(Paths.get("src"), MainSrc);
-        ToolBox.createJavaFileFromSource(Paths.get("src"), R1Src);
-        ToolBox.createJavaFileFromSource(Paths.get("src"), R2Src);
-        ToolBox.createJavaFileFromSource(Paths.get("src"), R3Src);
+        Path srcDir = Paths.get("src");
+        tb.writeJavaFiles(srcDir, BSrc, CSrc, MainSrc, R1Src, R2Src, R3Src);
     }
 
     void compileFiles() throws Exception {
-//        "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d . -classpath .
-//              -sourcepath src src/x/B.java src/x/C.java src/y/Main.java
-        ToolBox.JavaToolArgs args =
-                new ToolBox.JavaToolArgs()
-                .setAllArgs("-d", ".", "-cp" , ".", "-sourcepath", "src",
-                "src/x/B.java", "src/x/C.java", "src/y/Main.java");
-        ToolBox.javac(args);
+        tb.new JavacTask()
+                .outdir(".")
+                .classpath(".")
+                .sourcepath("src")
+                .files("src/x/B.java", "src/x/C.java", "src/y/Main.java")
+                .run()
+                .writeAll();
 
-//        rm y/R3.class
-        ToolBox.rm(Paths.get("y", "R3.class"));
+        tb.deleteFiles("y/R3.class");
 
-//        "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d . -classpath .
-//                -sourcepath src src/y/Main.java
-        args.setAllArgs("-d", ".", "-cp", ".", "-sourcepath", "src", "src/y/Main.java");
-        ToolBox.javac(args);
+        tb.new JavacTask()
+                .outdir(".")
+                .classpath(".")
+                .sourcepath("src")
+                .files("src/y/Main.java")
+                .run()
+                .writeAll();
+
     }
 
 }
--- a/langtools/test/tools/javac/javazip/JavaZipTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/javazip/JavaZipTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,15 +25,16 @@
  * @test
  * @bug 4098712 6304984 6388453
  * @summary check that source files inside zip files on the class path are ignored
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main JavaZipTest
  */
 
-import java.io.File;
+import java.nio.file.Files;
 import java.nio.file.Paths;
+import java.util.Arrays;
 
-//original test: test/tools/javac/javazip/Test.sh
+// Original test: test/tools/javac/javazip/Test.sh
 public class JavaZipTest {
 
     private static final String ASrc =
@@ -62,7 +63,7 @@
         {"-d", "output", "-cp", "good.jar", "A.java"},
     };
 
-    private static final String[][] unSuccessfulCompilationArgs = {
+    private static final String[][] unsuccessfulCompilationArgs = {
         {"-d", "output", "A.java", "bad/B.java"},
         {"-d", "output", "-cp", "bad", "A.java"},
         {"-d", "output", "-sourcepath", "bad", "A.java"},
@@ -74,53 +75,57 @@
         new JavaZipTest().test();
     }
 
+    private final ToolBox tb = new ToolBox();
+
     public void test() throws Exception {
         createOutputDirAndSourceFiles();
         createZipsAndJars();
         check(ToolBox.Expect.SUCCESS, successfulCompilationArgs);
-        check(ToolBox.Expect.FAIL, unSuccessfulCompilationArgs);
+        check(ToolBox.Expect.FAIL, unsuccessfulCompilationArgs);
     }
 
     void createOutputDirAndSourceFiles() throws Exception {
         //create output dir
-        new File("output").mkdir();
+        Files.createDirectory(Paths.get("output"));
 
         //source file creation
-        ToolBox.createJavaFileFromSource(Paths.get("good"), BGoodSrc);
-        ToolBox.createJavaFileFromSource(Paths.get("bad"), BBadSrc);
-        ToolBox.createJavaFileFromSource(ASrc);
+        tb.writeJavaFiles(Paths.get("good"), BGoodSrc);
+        tb.writeJavaFiles(Paths.get("bad"), BBadSrc);
+        tb.writeJavaFiles(ToolBox.currDir, ASrc);
     }
 
     void createZipsAndJars() throws Exception {
         //jar and zip creation
-//        check ok   "${TESTJAVA}${FS}bin${FS}jar" cf "${SCR}${FS}good.jar" -C "${TESTSRC}${FS}good" B.java
-//        check ok   "${TESTJAVA}${FS}bin${FS}jar" cf "${SCR}${FS}good.zip" -C "${TESTSRC}${FS}good" B.java
-//        check ok   "${TESTJAVA}${FS}bin${FS}jar" cf "${SCR}${FS}bad.jar"  -C "${TESTSRC}${FS}bad" B.java
-//        check ok   "${TESTJAVA}${FS}bin${FS}jar" cf "${SCR}${FS}bad.zip"  -C "${TESTSRC}${FS}bad" B.java
         for (String[] args: jarArgs) {
-            ToolBox.jar(args);
+            tb.new JarTask().run(args).writeAll();
         }
     }
 
-    void check(ToolBox.Expect whatToExpect, String[][] theArgs) throws Exception {
-//        check ok   "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d ${TC} "${TESTSRC}${FS}A.java" "${TESTSRC}${FS}good${FS}B.java"
-//        check ok   "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d ${TC} -classpath "${TESTSRC}${FS}good"   "${TESTSRC}${FS}A.java"
-//        check ok   "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d ${TC} -sourcepath "${TESTSRC}${FS}good"  "${TESTSRC}${FS}A.java"
-//        check ok   "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d ${TC} -classpath "${SCR}${FS}good.zip"   "${TESTSRC}${FS}A.java"
-//        check ok   "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d ${TC} -classpath "${SCR}${FS}good.jar"   "${TESTSRC}${FS}A.java"
+    void check(ToolBox.Expect expectedStatus, String[][] theArgs) throws Exception {
 
-//        check err  "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d ${TC} "${TESTSRC}${FS}A.java" "${TESTSRC}${FS}bad${FS}B.java"
-//        check err  "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d ${TC} -classpath "${TESTSRC}${FS}bad"    "${TESTSRC}${FS}A.java"
-//        check err  "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d ${TC} -sourcepath "${TESTSRC}${FS}bad"   "${TESTSRC}${FS}A.java"
-//        check err  "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d ${TC} -sourcepath "${SCR}${FS}bad.zip"   "${TESTSRC}${FS}A.java"
-//        check err  "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d ${TC} -sourcepath "${SCR}${FS}bad.jar"   "${TESTSRC}${FS}A.java"
-        ToolBox.JavaToolArgs args =
-                new ToolBox.JavaToolArgs(whatToExpect);
 
         for (String[] allArgs: theArgs) {
-            args.setAllArgs(allArgs);
-            ToolBox.javac(args);
+            tb.new JavacTask()
+                    .options(opts(allArgs))
+                    .files(files(allArgs))
+                    .run(expectedStatus)
+                    .writeAll();
+
         }
     }
 
+    private String[] opts(String... allArgs) {
+        int i = allArgs.length;
+        while (allArgs[i - 1].endsWith(".java"))
+            i--;
+        return Arrays.copyOfRange(allArgs, 0, i);
+    }
+
+    private String[] files(String... allArgs) {
+        int i = allArgs.length;
+        while (allArgs[i - 1].endsWith(".java"))
+            i--;
+        return Arrays.copyOfRange(allArgs, i, allArgs.length);
+    }
+
 }
--- a/langtools/test/tools/javac/lambda/lambdaNaming/TestSerializedLambdaNameStability.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/lambda/lambdaNaming/TestSerializedLambdaNameStability.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
  * @test
  * @bug 8023668
  * @summary Desugar serializable lambda bodies using more robust naming scheme
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main TestSerializedLambdaNameStability
  */
@@ -125,6 +125,7 @@
         static final String compiledDir = System.getProperty("user.dir");
         static final String sourceBaseDir = System.getProperty("test.src");
 
+        final ToolBox tb = new ToolBox();
         final String context;
 
         public TestClassLoader(String context) {
@@ -154,10 +155,10 @@
             else
                 throw new Exception("Did not expect to load " + name);
             Path srcFile = Paths.get(sourceBaseDir, context, srcName + ".java");
-            String testSource = new String(Files.readAllBytes(srcFile));
-            ToolBox.JavaToolArgs javacSuccessArgs =
-                    new ToolBox.JavaToolArgs().setSources(testSource);
-            ToolBox.javac(javacSuccessArgs);
+            tb.new JavacTask()
+                    .outdir(compiledDir)
+                    .files(srcFile)
+                    .run();
             Path cfFile = Paths.get(compiledDir, name + ".class");
             byte[] bytes = Files.readAllBytes(cfFile);
             return bytes;
--- a/langtools/test/tools/javac/lib/ToolBox.java	Thu Aug 21 14:16:28 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1080 +0,0 @@
-/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileWriter;
-import java.io.FilterOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.net.URI;
-import java.nio.charset.Charset;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.StandardOpenOption;
-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.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.tools.FileObject;
-import javax.tools.ForwardingJavaFileManager;
-import javax.tools.JavaCompiler;
-import javax.tools.JavaFileManager;
-import javax.tools.JavaFileManager.Location;
-import javax.tools.JavaFileObject;
-import javax.tools.JavaFileObject.Kind;
-import javax.tools.SimpleJavaFileObject;
-import javax.tools.StandardJavaFileManager;
-import javax.tools.ToolProvider;
-
-import com.sun.source.util.JavacTask;
-import com.sun.tools.javac.api.JavacTaskImpl;
-
-import sun.tools.jar.Main;
-
-import static java.nio.file.StandardCopyOption.*;
-
-/**
- * Toolbox for jtreg tests.
- */
-
-public class ToolBox {
-
-    public static final String lineSeparator = System.getProperty("line.separator");
-    public static final String jdkUnderTest = System.getProperty("test.jdk");
-    public static final Path javaBinary = Paths.get(jdkUnderTest, "bin", "java");
-    public static final Path javacBinary = Paths.get(jdkUnderTest, "bin", "javac");
-
-    public static final List<String> testVMOpts = readOptions("test.vm.opts");
-    public static final List<String> testToolVMOpts = readOptions("test.tool.vm.opts");
-    public static final List<String> testJavaOpts = readOptions("test.java.opts");
-
-    private static final Charset defaultCharset = Charset.defaultCharset();
-
-    static final JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
-
-    private static List<String> readOptions(String property) {
-        String options = System.getProperty(property, "");
-        return options.length() > 0 ? Arrays.asList(options.split("\\s+")) : Collections.<String>emptyList();
-    }
-
-    /**
-     * The expected result of command-like method execution.
-     */
-    public enum Expect {SUCCESS, FAIL}
-
-    enum AcceptedParams {
-        EXPECT,
-        SOURCES,
-        OPTIONS,
-        STD_OUTPUT,
-        ERR_OUTPUT,
-        EXTRA_ENV,
-    }
-
-    enum OutputKind {STD, ERR}
-
-    /**
-     * Helper class to abstract the processing of command's output.
-     */
-    static abstract class WriterHelper {
-        OutputKind kind;
-        public abstract void pipeOutput(ProcessBuilder pb);
-        public abstract void readFromStream(Process p) throws IOException;
-        public abstract void addAll(Collection<? extends String> c) throws IOException;
-    }
-
-    /**
-     * Helper class for redirecting command's output to a file.
-     */
-    static class FileWriterHelper extends WriterHelper {
-        File file;
-
-        FileWriterHelper(File file, OutputKind kind) {
-            this.file = file;
-            this.kind = kind;
-        }
-
-        @Override
-        public void pipeOutput(ProcessBuilder pb) {
-            if (file != null) {
-                switch (kind) {
-                    case STD:
-                        pb.redirectInput(file);
-                        break;
-                    case ERR:
-                        pb.redirectError(file);
-                        break;
-                }
-            }
-        }
-
-        @Override
-        public void readFromStream(Process p) throws IOException {}
-
-        @Override
-        public void addAll(Collection<? extends String> c) throws IOException {
-            if (file.exists())
-                Files.write(file.toPath(), c, defaultCharset,
-                        StandardOpenOption.WRITE, StandardOpenOption.APPEND);
-            else
-                Files.write(file.toPath(), c, defaultCharset);
-        }
-    }
-
-    /**
-     * Helper class for redirecting command's output to a String list.
-     */
-    static class ListWriterHelper extends WriterHelper {
-        List<String> list;
-
-        public ListWriterHelper(List<String> list, OutputKind kind) {
-            this.kind = kind;
-            this.list = list;
-        }
-
-        @Override
-        public void pipeOutput(ProcessBuilder pb) {}
-
-        @Override
-        public void readFromStream(Process p) throws IOException {
-            BufferedReader br = null;
-            switch (kind) {
-                case STD:
-                    br = new BufferedReader(new InputStreamReader(p.getInputStream()));
-                    break;
-                case ERR:
-                    br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
-                    break;
-            }
-            String line;
-            while ((line = br.readLine()) != null) {
-                list.add(line);
-            }
-        }
-
-        public void addAll(Collection<? extends String> c) {
-            list.addAll(c);
-        }
-    }
-
-    /**
-     * Simple factory class for creating a WriterHelper instance.
-     */
-    static class WriterHelperFactory {
-        static WriterHelper make(File file, OutputKind kind) {
-            return new FileWriterHelper(file, kind);
-        }
-
-        static WriterHelper make(List<String> list, OutputKind kind) {
-            return new ListWriterHelper(list, kind);
-        }
-    }
-
-    /**
-     * A generic class for holding command's arguments.
-     */
-    public static abstract class GenericArgs <T extends GenericArgs> {
-        protected static List<Set<AcceptedParams>> minAcceptedParams;
-
-        protected Set<AcceptedParams> currentParams =
-                EnumSet.<AcceptedParams>noneOf(AcceptedParams.class);
-
-        protected Expect whatToExpect;
-        protected WriterHelper stdOutput;
-        protected WriterHelper errOutput;
-        protected List<String> args = new ArrayList<>();
-        protected String[] argsArr;
-
-        protected GenericArgs() {
-            set(Expect.SUCCESS);
-        }
-
-        public T set(Expect whatToExpt) {
-            currentParams.add(AcceptedParams.EXPECT);
-            this.whatToExpect = whatToExpt;
-            return (T)this;
-        }
-
-        public T setStdOutput(List<String> stdOutput) {
-            currentParams.add(AcceptedParams.STD_OUTPUT);
-            this.stdOutput = WriterHelperFactory.make(stdOutput, OutputKind.STD);
-            return (T)this;
-        }
-
-        public T setStdOutput(File output) {
-            currentParams.add(AcceptedParams.STD_OUTPUT);
-            this.stdOutput = WriterHelperFactory.make(output, OutputKind.STD);
-            return (T)this;
-        }
-
-        public T setErrOutput(List<String> errOutput) {
-            currentParams.add(AcceptedParams.ERR_OUTPUT);
-            this.errOutput = WriterHelperFactory.make(errOutput, OutputKind.ERR);
-            return (T)this;
-        }
-
-        public T setErrOutput(File errOutput) {
-            currentParams.add(AcceptedParams.ERR_OUTPUT);
-            this.errOutput = WriterHelperFactory.make(errOutput, OutputKind.ERR);
-            return (T)this;
-        }
-
-        public T setAllArgs(String... args) {
-            currentParams.add(AcceptedParams.OPTIONS);
-            this.argsArr = args;
-            return (T) this;
-        }
-
-
-        public T appendArgs(String... args) {
-            appendArgs(Arrays.asList(args));
-            return (T)this;
-        }
-
-        public T appendArgs(Path... args) {
-            if (args != null) {
-                List<String> list = new ArrayList<>();
-                for (int i = 0; i < args.length; i++) {
-                    if (args[i] != null) {
-                        list.add(args[i].toString());
-                    }
-                }
-                appendArgs(list);
-            }
-            return (T)this;
-        }
-
-        public T appendArgs(List<String> args) {
-            if (args != null && args.size() > 0) {
-                currentParams.add(AcceptedParams.OPTIONS);
-                for (int i = 0; i < args.size(); i++) {
-                    if (args.get(i) != null) {
-                        this.args.add(args.get(i));
-                    }
-                }
-            }
-            return (T)this;
-        }
-
-        public T setOptions(List<String> options) {
-            currentParams.add(AcceptedParams.OPTIONS);
-            this.args = options;
-            return (T)this;
-        }
-
-        public T setOptions(String... options) {
-            currentParams.add(AcceptedParams.OPTIONS);
-            this.args = Arrays.asList(options);
-            return (T)this;
-        }
-
-        public boolean hasMinParams() {
-            for (Set<AcceptedParams> minSet : minAcceptedParams) {
-                if (currentParams.containsAll(minSet)) {
-                    return true;
-                }
-            }
-            return false;
-        }
-    }
-
-    /**
-     * A more specific class for holding javac-like command's arguments.
-     */
-    public static class JavaToolArgs extends GenericArgs<JavaToolArgs> {
-
-        static {
-            minAcceptedParams = new ArrayList<>();
-            minAcceptedParams.add(EnumSet.<AcceptedParams>of(
-                    AcceptedParams.EXPECT, AcceptedParams.OPTIONS));
-            minAcceptedParams.add(EnumSet.<AcceptedParams>of(
-                    AcceptedParams.EXPECT, AcceptedParams.SOURCES));
-        }
-
-        protected List<? extends JavaFileObject> sources;
-
-        public JavaToolArgs() {
-            super();
-        }
-
-        public JavaToolArgs(Expect whatToExpt) {
-            super.set(whatToExpt);
-        }
-
-        public JavaToolArgs setSources(List<? extends JavaFileObject> sources) {
-            currentParams.add(AcceptedParams.SOURCES);
-            this.sources = sources;
-            return this;
-        }
-
-        public JavaToolArgs setSources(JavaSource... sources) {
-            return setSources(Arrays.asList(sources));
-        }
-
-        public JavaToolArgs setSources(String... sources) {
-            List<JavaSource> javaSrcs = new ArrayList<>();
-            for (String source : sources) {
-                javaSrcs.add(new JavaSource(source));
-            }
-            return setSources(javaSrcs);
-        }
-    }
-
-    /**
-     * A more specific class for holding any command's arguments.
-     */
-    public static class AnyToolArgs extends GenericArgs<AnyToolArgs> {
-
-        static {
-            minAcceptedParams = new ArrayList<>();
-            minAcceptedParams.add(EnumSet.<AcceptedParams>of(
-                    AcceptedParams.EXPECT, AcceptedParams.OPTIONS));
-        }
-
-        Map<String, String> extraEnv;
-
-        public AnyToolArgs() {
-            super();
-        }
-
-        public AnyToolArgs(Expect whatToExpt) {
-            set(whatToExpt);
-        }
-
-        public AnyToolArgs set(Map<String, String> extraEnv) {
-            currentParams.add(AcceptedParams.EXTRA_ENV);
-            this.extraEnv = extraEnv;
-            return this;
-        }
-    }
-
-    /**
-     * Custom exception for bad command execution.
-     */
-    public static class CommandExecutionException extends Exception {
-        CommandExecutionException(List<String> command, Expect whatToExpt) {
-            super(createMessage(command, whatToExpt));
-        }
-
-        CommandExecutionException(Expect whatToExpt, String... command) {
-            this(Arrays.asList(command), whatToExpt);
-        }
-
-        private static String createMessage(List<String> command, Expect whatToExpt) {
-            StringBuilder sb = new StringBuilder().append("Command : ");
-            sb.append(command.toString()).append(lineSeparator);
-            switch (whatToExpt) {
-                case SUCCESS:
-                    sb.append("    has unexpectedly failed");
-                    break;
-                case FAIL:
-                    sb.append("    has been unexpectedly successful");
-                    break;
-            }
-            return sb.toString();
-        }
-    }
-
-    /**
-     * Custom exception for not equal resources.
-     */
-    public static class ResourcesNotEqualException extends Exception {
-        public ResourcesNotEqualException(List<String> res1, List<String> res2) {
-            super(createMessage(res1, res2));
-        }
-
-        public ResourcesNotEqualException(String line1, String line2) {
-            super(createMessage(line1, line2));
-        }
-
-        public ResourcesNotEqualException(Path path1, Path path2) {
-            super(createMessage(path1, path2));
-        }
-
-        private static String createMessage(Path path1, Path path2) {
-            return new StringBuilder()
-                    .append("The resources provided for comparison in paths \n")
-                    .append(path1.toString()).append(" and \n")
-                    .append(path2.toString()).append("are different").toString();
-        }
-
-        private static String createMessage(String line1, String line2) {
-            return new StringBuilder()
-                    .append("The resources provided for comparison are different at lines: \n")
-                    .append(line1).append(" and \n")
-                    .append(line2).toString();
-        }
-
-        private static String createMessage(List<String> res1, List<String> res2) {
-            return new StringBuilder()
-                    .append("The resources provided for comparison are different: \n")
-                    .append("Resource 1 is: ").append(res1).append("\n and \n")
-                    .append("Resource 2 is: ").append(res2).append("\n").toString();
-        }
-    }
-
-    /**
-     * A javac compiler caller method.
-     */
-    public static int javac(JavaToolArgs params)
-            throws CommandExecutionException, IOException {
-        if (params.hasMinParams()) {
-            if (params.argsArr != null) {
-                return genericJavaCMD(JavaCMD.JAVAC, params);
-            } else {
-                return genericJavaCMD(JavaCMD.JAVAC_API, params);
-            }
-        }
-        throw new AssertionError("javac command has been invoked with less parameters than needed");
-    }
-
-    /**
-     * Run javac and return the resulting classfiles.
-     */
-    public static Map<String, byte[]> compile(JavaToolArgs params)
-            throws CommandExecutionException, IOException {
-        if (params.hasMinParams()) {
-            if (params.argsArr != null) {
-                throw new AssertionError("setAllArgs is not supported for compile");
-            }
-
-            StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
-            MemoryFileManager mfm = new MemoryFileManager(fm);
-            StringWriter sw = null;
-            boolean rc;
-
-            try (PrintWriter pw = (params.errOutput == null) ?
-                    null : new PrintWriter(sw = new StringWriter())) {
-                JavacTask ct = (JavacTask)comp.getTask(pw, mfm, null,
-                        params.args, null, params.sources);
-                rc = ct.call();
-            }
-
-            String out = (sw == null) ? null : sw.toString();
-
-            if (params.errOutput != null && (out != null) && !out.isEmpty()) {
-                params.errOutput.addAll(splitLines(out, lineSeparator));
-            }
-
-            if ( ( rc && params.whatToExpect == Expect.SUCCESS) ||
-                 (!rc && params.whatToExpect == Expect.FAIL) ) {
-                return mfm.classes;
-            }
-
-            throw new CommandExecutionException(JavaCMD.JAVAC_API.getExceptionMsgContent(params),
-                    params.whatToExpect);
-        }
-        throw new AssertionError("compile command has been invoked with less parameters than needed");
-    }
-
-    /**
-     * A javap calling method.
-     */
-    public static String javap(JavaToolArgs params)
-            throws CommandExecutionException, IOException {
-        if (params.hasMinParams()) {
-            List<String> list = new ArrayList<>();
-            params.setErrOutput(list);
-            genericJavaCMD(JavaCMD.JAVAP, params);
-            return listToString(list);
-        }
-        throw new AssertionError("javap command has been invoked with less parameters than needed");
-    }
-
-    /**
-     * A javah calling method.
-     */
-    public static int javah(JavaToolArgs params)
-            throws CommandExecutionException, IOException {
-        if (params.hasMinParams()) {
-            return genericJavaCMD(JavaCMD.JAVAH, params);
-        }
-        throw new AssertionError("javah command has been invoked with less parameters than needed");
-    }
-
-    /**
-     * A enum class for langtools commands.
-     */
-    enum JavaCMD {
-        JAVAC {
-            @Override
-            int run(JavaToolArgs params, PrintWriter pw) {
-                return com.sun.tools.javac.Main.compile(params.argsArr, pw);
-            }
-        },
-        JAVAC_API {
-            @Override
-            int run(JavaToolArgs params, PrintWriter pw) {
-                JavacTask ct = (JavacTask)comp.getTask(pw, null, null,
-                        params.args, null, params.sources);
-                return ((JavacTaskImpl)ct).doCall().exitCode;
-            }
-
-            @Override
-            String getName() {
-                return "javac";
-            }
-
-            @Override
-            List<String> getExceptionMsgContent(JavaToolArgs params) {
-                List<String> result = super.getExceptionMsgContent(params);
-                for (JavaFileObject source : params.sources) {
-                    if (source instanceof JavaSource) {
-                        result.add(((JavaSource)source).name);
-                    }
-                }
-                return result;
-            }
-        },
-        JAVAH {
-            @Override
-            int run(JavaToolArgs params, PrintWriter pw) {
-                return com.sun.tools.javah.Main.run(params.argsArr, pw);
-            }
-        },
-        JAVAP {
-            @Override
-            int run(JavaToolArgs params, PrintWriter pw) {
-                return com.sun.tools.javap.Main.run(params.argsArr, pw);
-            }
-        };
-
-        abstract int run(JavaToolArgs params, PrintWriter pw);
-
-        String getName() {
-            return this.name().toLowerCase();
-        }
-
-        List<String> getExceptionMsgContent(JavaToolArgs params) {
-            List<String> result = new ArrayList<>();
-            result.add(getName());
-            result.addAll(params.argsArr != null ?
-                    Arrays.asList(params.argsArr) :
-                    params.args);
-            return result;
-        }
-    }
-
-    /**
-     * A helper method for executing langtools commands.
-     */
-    private static int genericJavaCMD(
-            JavaCMD cmd,
-            JavaToolArgs params)
-            throws CommandExecutionException, IOException {
-        int rc = 0;
-        StringWriter sw = null;
-        try (PrintWriter pw = (params.errOutput == null) ?
-                null : new PrintWriter(sw = new StringWriter())) {
-            rc = cmd.run(params, pw);
-        }
-        String out = (sw == null) ? null : sw.toString();
-
-        if (params.errOutput != null && (out != null) && !out.isEmpty()) {
-            params.errOutput.addAll(splitLines(out, lineSeparator));
-        }
-
-        if ( (rc == 0 && params.whatToExpect == Expect.SUCCESS) ||
-             (rc != 0 && params.whatToExpect == Expect.FAIL) ) {
-            return rc;
-        }
-
-        throw new CommandExecutionException(cmd.getExceptionMsgContent(params),
-                params.whatToExpect);
-    }
-
-    /**
-     * A jar calling method.
-     */
-    public static boolean jar(String... params) throws CommandExecutionException {
-        Main jarGenerator = new Main(System.out, System.err, "jar");
-        boolean result = jarGenerator.run(params);
-        if (!result) {
-            List<String> command = new ArrayList<>();
-            command.add("jar");
-            command.addAll(Arrays.asList(params));
-            throw new CommandExecutionException(command, Expect.SUCCESS);
-        }
-        return result;
-    }
-
-    /**
-     * A general command calling method.
-     */
-    public static int executeCommand(AnyToolArgs params)
-            throws CommandExecutionException, IOException, InterruptedException {
-        if (params.hasMinParams()) {
-            List<String> cmd = (params.args != null) ?
-                    params.args :
-                    Arrays.asList(params.argsArr);
-            return executeCommand(cmd, params.extraEnv, params.stdOutput,
-                    params.errOutput, params.whatToExpect);
-        }
-        throw new AssertionError("command has been invoked with less parameters than needed");
-    }
-
-    /**
-     * A helper method for calling a general command.
-     */
-    private static int executeCommand(
-            List<String> command,
-            Map<String, String> extraEnv,
-            WriterHelper stdOutput,
-            WriterHelper errOutput,
-            Expect whatToExpt)
-            throws IOException, InterruptedException, CommandExecutionException {
-        ProcessBuilder pb = new ProcessBuilder(command);
-
-        if (stdOutput != null) stdOutput.pipeOutput(pb);
-        if (errOutput != null) errOutput.pipeOutput(pb);
-
-        if (extraEnv != null) {
-            pb.environment().putAll(extraEnv);
-        }
-
-        Process p = pb.start();
-
-        if (stdOutput != null) stdOutput.readFromStream(p);
-        if (errOutput != null) errOutput.readFromStream(p);
-
-        int result = p.waitFor();
-        if ( (result == 0 && whatToExpt == Expect.SUCCESS) ||
-             (result != 0 && whatToExpt == Expect.FAIL) ) {
-            return result;
-        }
-
-        throw new CommandExecutionException(command, whatToExpt);
-    }
-
-    /**
-     * This set of methods can be used instead of diff when the only needed
-     * result is the equality or inequality of the two given resources.
-     *
-     * A resource can be a file or a String list.
-     */
-    public static void compareLines(Path aPath, Path otherPath, String encoding)
-            throws FileNotFoundException, IOException, ResourcesNotEqualException {
-        compareLines(aPath, otherPath, encoding, false);
-    }
-
-    public static void compareLines(
-            Path aPath, Path otherPath, String encoding, boolean trim)
-            throws FileNotFoundException, IOException, ResourcesNotEqualException {
-        Charset charset = encoding != null ?
-                Charset.forName(encoding) :
-                defaultCharset;
-        List<String> list1 = Files.readAllLines(aPath, charset);
-        List<String> list2 = Files.readAllLines(otherPath, charset);
-        compareLines(list1, list2, trim);
-    }
-
-    public static void compareLines(Path path, List<String> strings, String encoding)
-            throws FileNotFoundException, IOException, ResourcesNotEqualException {
-        compareLines(path, strings, encoding, false);
-    }
-
-    public static void compareLines(Path path, List<String> strings,
-            String encoding, boolean trim)
-            throws FileNotFoundException, IOException, ResourcesNotEqualException {
-        Charset charset = encoding != null ?
-                Charset.forName(encoding) :
-                defaultCharset;
-        List<String> list = Files.readAllLines(path, charset);
-        compareLines(list, strings, trim);
-    }
-
-    public static void compareLines(List<String> list1, List<String> list2)
-            throws ResourcesNotEqualException {
-        compareLines(list1, list2, false);
-    }
-
-    public static void compareLines(List<String> list1,
-            List<String> list2, boolean trim) throws ResourcesNotEqualException {
-        if ((list1 == list2) || (list1 == null && list2 == null)) return;
-        if (list1.size() != list2.size())
-            throw new ResourcesNotEqualException(list1, list2);
-        int i = 0;
-        int j = 0;
-        while (i < list1.size() &&
-               j < list2.size() &&
-               equals(list1.get(i), list2.get(j), trim)) {
-            i++; j++;
-        }
-        if (!(i == list1.size() && j == list2.size()))
-            throw new ResourcesNotEqualException(list1, list2);
-    }
-
-    private static boolean equals(String s1, String s2, boolean trim) {
-        return (trim ? s1.trim().equals(s2.trim()) : s1.equals(s2));
-    }
-
-    /**
-     * A set of simple grep-like methods, looks for regExpr in text.
-     * The content of text is split using the new line character as a pattern
-     * and later the regExpr is seek in every split line. If a match is found,
-     * the whole line is added to the result.
-     */
-    public static List<String> grep(String regExpr, String text, String sep) {
-        return grep(regExpr, splitLines(text, sep));
-    }
-
-    public static List<String> grep(String regExpr, List<String> text) {
-        List<String> result = new ArrayList<>();
-        Pattern pattern = Pattern.compile(regExpr);
-        for (String s : text) {
-            if (pattern.matcher(s).find()) {
-                result.add(s);
-            }
-        }
-        return result;
-    }
-
-    public static List<String> grep(String regExpr, File f)
-            throws IOException {
-        List<String> lines = Files.readAllLines(f.toPath(), defaultCharset);
-        return grep(regExpr, lines);
-    }
-
-    /**
-     * A touch-like method.
-     */
-    public static boolean touch(String fileName) {
-        File file = new File(fileName);
-        return touch(file);
-    }
-
-    public static boolean touch(File file) {
-        if (file.exists()) {
-            file.setLastModified(System.currentTimeMillis());
-            return true;
-        }
-        return false;
-    }
-
-    public static void createJavaFile(File outFile) throws IOException {
-        createJavaFile(outFile, null);
-    }
-
-    /**
-     * A method for creating a valid but very simple java file.
-     */
-    public static void createJavaFile(File outFile, File superClass)
-            throws IOException {
-        String srcStr = "public class " + getSimpleName(outFile) + " ";
-        if (superClass != null) {
-            srcStr = srcStr.concat("extends " + getSimpleName(superClass) + " ");
-        }
-        srcStr = srcStr.concat("{}");
-        try (PrintWriter ps = new PrintWriter(new FileWriter(outFile))) {
-            ps.println(srcStr);
-        }
-    }
-
-    /**
-     * Creates a java file name given its source.
-     * The file is created in the working directory, creating a directory
-     * tree if there is a package declaration.
-     */
-    public static void createJavaFileFromSource(String source) throws IOException {
-        createJavaFileFromSource(null, source);
-    }
-
-    /**
-     * Creates a java file name given its source.
-     * The file is created in the working directory, creating a directory
-     * tree if there is a package declaration or the argument initialPath
-     * has a valid path.
-     *
-     * e.i. if initialPath is foo/ and the source is:
-     * package bar;
-     *
-     * public class bazz {}
-     *
-     * this method will create the file foo/bar/bazz.java in the working
-     * directory.
-     */
-    public static void createJavaFileFromSource(Path initialPath,
-            String source) throws IOException {
-        String fileName = getJavaFileNameFromSource(source);
-        String dirTree = getDirTreeFromSource(source);
-        Path path = (dirTree != null) ?
-                Paths.get(dirTree, fileName) :
-                Paths.get(fileName);
-        path = (initialPath != null) ?
-                initialPath.resolve(path):
-                path;
-        writeFile(path, source);
-    }
-
-    static Pattern publicClassPattern =
-            Pattern.compile("public\\s+(?:class|enum|interface){1}\\s+(\\w+)");
-    static Pattern packageClassPattern =
-            Pattern.compile("(?:class|enum|interface){1}\\s+(\\w+)");
-
-    /**
-     * Extracts the java file name from the class declaration.
-     * This method is intended for simple files and uses regular expressions,
-     * so comments matching the pattern can make the method fail.
-     */
-    static String getJavaFileNameFromSource(String source) {
-        String className = null;
-        Matcher matcher = publicClassPattern.matcher(source);
-        if (matcher.find()) {
-            className = matcher.group(1) + ".java";
-        } else {
-            matcher = packageClassPattern.matcher(source);
-            if (matcher.find()) {
-                className = matcher.group(1) + ".java";
-            } else {
-                throw new AssertionError("Could not extract the java class " +
-                        "name from the provided source");
-            }
-        }
-        return className;
-    }
-
-    static Pattern packagePattern =
-            Pattern.compile("package\\s+(((?:\\w+\\.)*)(?:\\w+))");
-
-    /**
-     * Extracts the path from the package declaration if present.
-     * This method is intended for simple files and uses regular expressions,
-     * so comments matching the pattern can make the method fail.
-     */
-    private static String getDirTreeFromSource(String source) {
-        Matcher matcher = packagePattern.matcher(source);
-        return matcher.find() ?
-            matcher.group(1).replace(".", File.separator) :
-            null;
-    }
-
-    /**
-     * A method for creating a jar's manifest file with supplied data.
-     */
-    public static void mkManifestWithClassPath(String mainClass,
-            String... classes) throws IOException {
-        List <String> lines = new ArrayList<>();
-
-        StringBuilder sb = new StringBuilder("Class-Path: ".length() +
-                classes[0].length()).append("Class-Path: ").append(classes[0]);
-        for (int i = 1; i < classes.length; i++) {
-            sb.append(" ").append(classes[i]);
-        }
-        lines.add(sb.toString());
-        if (mainClass != null) {
-            lines.add(new StringBuilder("Main-Class: ".length() +
-                      mainClass.length())
-                      .append("Main-Class: ")
-                      .append(mainClass).toString());
-        }
-        Files.write(Paths.get("MANIFEST.MF"), lines,
-                    StandardOpenOption.CREATE, StandardOpenOption.WRITE,
-                    StandardOpenOption.TRUNCATE_EXISTING);
-    }
-
-    /**
-     * A utility method to obtain the file name.
-     */
-    static String getSimpleName(File inFile) {
-        return inFile.toPath().getFileName().toString();
-    }
-
-    /**
-     * A method to write to a file, the directory tree is created if needed.
-     */
-    public static File writeFile(Path path, String body) throws IOException {
-        File result;
-        if (path.getParent() != null) {
-            Files.createDirectories(path.getParent());
-        }
-        try (FileWriter out = new FileWriter(result = path.toAbsolutePath().toFile())) {
-            out.write(body);
-        }
-        return result;
-    }
-
-    public static File writeFile(String path, String body) throws IOException {
-        return writeFile(Paths.get(path), body);
-    }
-
-    /**
-     * A rm-like method, the file is deleted only if it exists.
-     */
-    public static void rm(Path path) throws Exception {
-        Files.deleteIfExists(path);
-    }
-
-    public static void rm(String filename) throws Exception {
-        rm(Paths.get(filename));
-    }
-
-    public static void rm(File f) throws Exception {
-        rm(f.toPath());
-    }
-
-    /**
-     * Copy source file to destination file.
-     */
-    public static void copyFile(File destfile, File srcfile)
-        throws IOException {
-        copyFile(destfile.toPath(), srcfile.toPath());
-    }
-
-    public static void copyFile(Path destPath, Path srcPath)
-        throws IOException {
-        Files.createDirectories(destPath);
-        Files.copy(srcPath, destPath, REPLACE_EXISTING);
-    }
-
-    /**
-     * Splits a String using the System's line separator character as splitting point.
-     */
-    public static List<String> splitLines(String lines, String sep) {
-        return Arrays.asList(lines.split(sep));
-    }
-
-    /**
-     * Converts a String list into one String by appending the System's line separator
-     * character after each component.
-     */
-    private static String listToString(List<String> lines) {
-        StringBuilder sb = new StringBuilder();
-        for (String s : lines) {
-            sb.append(s).append(lineSeparator);
-        }
-        return sb.toString();
-    }
-
-    /**
-     * Returns true if the OS is a Windows version.
-     */
-    public static boolean isWindows() {
-        String osName = System.getProperty("os.name");
-        return osName.toUpperCase().startsWith("WINDOWS");
-    }
-
-    /**
-     * Class representing an in-memory java source file. It is able to extract
-     * the file name from simple source codes using regular expressions.
-     */
-    public static class JavaSource extends SimpleJavaFileObject {
-        String source;
-        String name;
-
-        public JavaSource(String className, String source) {
-            super(URI.create(className),
-                    JavaFileObject.Kind.SOURCE);
-            this.name = className;
-            this.source = source;
-        }
-
-        public JavaSource(String source) {
-            super(URI.create(getJavaFileNameFromSource(source)),
-                    JavaFileObject.Kind.SOURCE);
-            this.name = getJavaFileNameFromSource(source);
-            this.source = source;
-        }
-
-        @Override
-        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
-            return source;
-        }
-    }
-
-    /**
-     * A file manager for compiling strings to byte arrays.
-     * This file manager delegates to another file manager
-     * to lookup classes on boot class path.
-     */
-    public static final class MemoryFileManager extends ForwardingJavaFileManager {
-        /**
-         * Maps binary class names to class files stored as byte arrays.
-         */
-        private final Map<String, byte[]> classes;
-
-        /**
-         * Construct a memory file manager which delegates to the specified
-         * file manager for unknown sources.
-         * @param fileManager a file manager used to look up class files on class path, etc.
-         */
-        public MemoryFileManager(JavaFileManager fileManager) {
-            super(fileManager);
-            classes = new HashMap<>();
-        }
-
-        @java.lang.Override
-        public JavaFileObject getJavaFileForOutput(Location location,
-                                                   String name,
-                                                   Kind kind,
-                                                   FileObject sibling)
-            throws UnsupportedOperationException
-        {
-            return new JavaClassInArray(name);
-        }
-
-        /**
-         * A file object representing a Java class file stored in a byte array.
-         */
-        private class JavaClassInArray extends SimpleJavaFileObject {
-
-            private final String name;
-
-            /**
-             * Constructs a JavaClassInArray object.
-             * @param name binary name of the class to be stored in this file object
-             */
-            JavaClassInArray(String name) {
-                super(URI.create("mfm:///" + name.replace('.','/') + Kind.CLASS.extension),
-                      Kind.CLASS);
-                this.name = name;
-            }
-
-            public OutputStream openOutputStream() {
-                return new FilterOutputStream(new ByteArrayOutputStream()) {
-                    public void close() throws IOException {
-                        out.close();
-                        ByteArrayOutputStream bos = (ByteArrayOutputStream)out;
-                        classes.put(name, bos.toByteArray());
-                    }
-                };
-            }
-        }
-
-    }
-
-}
--- a/langtools/test/tools/javac/links/LinksTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/links/LinksTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
  * @test
  * @bug 4266026
  * @summary javac no longer follows symlinks
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main LinksTest
  */
@@ -33,7 +33,7 @@
 import java.nio.file.Files;
 import java.nio.file.Paths;
 
-//original test: test/tools/javac/links/links.sh
+// Original test: test/tools/javac/links/links.sh
 public class LinksTest {
 
     private static final String BSrc =
@@ -44,20 +44,18 @@
     private static final String TSrc =
         "class T extends a.B {}";
 
-    public static void main(String args[])
-            throws Exception {
-//      mkdir tmp
-//      cp ${TESTSRC}/b/B.java tmp
-        ToolBox.writeFile(Paths.get("tmp", "B.java"), BSrc);
+    public static void main(String... args) throws Exception {
+        ToolBox tb = new ToolBox();
+        tb.writeFile("tmp/B.java", BSrc);
 
         try {
-//        ln -s `pwd`/tmp "${TESTCLASSES}/a"
             Files.createSymbolicLink(Paths.get("a"), Paths.get("tmp"));
-            ////"${TESTJAVA}/bin/javac" ${TESTTOOLVMOPTS} -sourcepath "${TESTCLASSES}" -d "${TESTCLASSES}/classes" "${TESTSRC}/T.java" 2>&1
-            ToolBox.JavaToolArgs javacArgs =
-                    new ToolBox.JavaToolArgs()
-                    .setOptions("-sourcepath", ".", "-d", ".").setSources(TSrc);
-            ToolBox.javac(javacArgs);
+
+            tb.new JavacTask()
+                    .sourcepath(".")
+                    .outdir(".")
+                    .sources(TSrc)
+                    .run();
         } catch (UnsupportedOperationException e) {
             System.err.println("Symbolic links not supported on this system. The test can't finish");
         }
--- a/langtools/test/tools/javac/newlines/NewLineTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/newlines/NewLineTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
  * @test
  * @bug 4110560 4785453
  * @summary portability : javac.properties
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main NewLineTest
  */
@@ -39,18 +39,13 @@
 public class NewLineTest {
 
     public static void main(String args[]) throws Exception {
-//        "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -J-Dline.separator='@' > ${TMP1} 2>&1
+        ToolBox tb = new ToolBox();
         File javacErrOutput = new File("output.txt");
-        ToolBox.AnyToolArgs cmdArgs =
-                new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL)
-                .appendArgs(ToolBox.javacBinary)
-                .appendArgs(ToolBox.testToolVMOpts)
-                .appendArgs("-J-Dline.separator='@'")
-                .setErrOutput(javacErrOutput);
-        ToolBox.executeCommand(cmdArgs);
+        tb.new JavacTask(ToolBox.Mode.EXEC)
+                .redirect(ToolBox.OutputKind.STDERR, javacErrOutput.getPath())
+                .options("-J-Dline.separator='@'")
+                .run(ToolBox.Expect.FAIL);
 
-//        result=`cat ${TMP1} | wc -l`
-//        if [ "$result" -eq 0 ] passed
         List<String> lines = Files.readAllLines(javacErrOutput.toPath(),
                 Charset.defaultCharset());
         if (lines.size() != 1) {
--- a/langtools/test/tools/javac/processing/rounds/CompleteOnClosed.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/processing/rounds/CompleteOnClosed.java	Thu Aug 28 14:53:49 2014 -0700
@@ -26,8 +26,8 @@
  * @bug 8038455
  * @summary Ensure that formatting diagnostics with an already closed JavaCompiler won't crash
  *          the compiler.
- * @library /tools/javac/lib
- * @build CompleteOnClosed ToolBox JavacTestingAbstractProcessor
+ * @library /tools/lib /tools/javac/lib
+ * @build ToolBox JavacTestingAbstractProcessor
  * @run main CompleteOnClosed
  */
 
--- a/langtools/test/tools/javac/processing/rounds/OverwriteBetweenCompilations.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/processing/rounds/OverwriteBetweenCompilations.java	Thu Aug 28 14:53:49 2014 -0700
@@ -26,7 +26,7 @@
  * @bug 8038455
  * @summary Verify that annotation processor can overwrite source and class files it generated
  *          during previous compilations, and that the Symbols are updated appropriatelly.
- * @library /tools/javac/lib/
+ * @library /tools/lib /tools/javac/lib/
  * @clean *
  * @build OverwriteBetweenCompilations ToolBox JavacTestingAbstractProcessor
  * @compile/ref=OverwriteBetweenCompilations_1.out -processor OverwriteBetweenCompilations -Apass=1 -parameters -XDrawDiagnostics OverwriteBetweenCompilationsSource.java
@@ -49,6 +49,7 @@
 @SupportedOptions("pass")
 public class OverwriteBetweenCompilations extends JavacTestingAbstractProcessor {
     int round = 1;
+    @Override
     public boolean process(Set<? extends TypeElement> annotations,
                            RoundEnvironment roundEnv) {
         Log log = Log.instance(((JavacProcessingEnvironment) processingEnv).getContext());
@@ -85,11 +86,17 @@
             try (OutputStream out = filer.createClassFile("GeneratedClass").openOutputStream()) {
                 String code = pass != 2 ? GENERATED_INIT : GENERATED_UPDATE;
                 code = code.replace("NAME", "GeneratedClass");
-                ToolBox.JavaToolArgs args =
-                        new ToolBox.JavaToolArgs().appendArgs("-parameters").setSources(code);
-                Map<String, byte[]> codeMap = ToolBox.compile(args);
-                out.write(codeMap.get("GeneratedClass"));
-            } catch (IOException | ToolBox.CommandExecutionException e) {
+
+                ToolBox tb = new ToolBox();
+                ToolBox.MemoryFileManager mfm = new ToolBox.MemoryFileManager();
+                tb.new JavacTask()
+                        .fileManager(mfm)
+                        .options("-parameters")
+                        .sources(code)
+                        .run();
+
+                out.write(mfm.getFileBytes(StandardLocation.CLASS_OUTPUT, "GeneratedClass"));
+            } catch (IOException e) {
                 processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.toString());
             }
         }
--- a/langtools/test/tools/javac/stackmap/StackMapTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javac/stackmap/StackMapTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
  * @test
  * @bug 4955930
  * @summary The "method0" StackMap attribute should have two entries instead of three
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run compile StackMapTest.java
  * @run main StackMapTest
@@ -34,7 +34,7 @@
 import java.nio.file.Path;
 import java.nio.file.Paths;
 
-//original test: test/tools/javac/stackmap/T4955930.sh
+// Original test: test/tools/javac/stackmap/T4955930.sh
 public class StackMapTest {
 
     class Test {
@@ -48,16 +48,15 @@
     }
 
     public static void main(String args[]) throws Exception {
-//    "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} T4955930.java
+        ToolBox tb = new ToolBox();
+        Path pathToClass = Paths.get(ToolBox.testClasses, "StackMapTest$Test.class");
+        String javapOut = tb.new JavapTask()
+                .options("-v")
+                .classes(pathToClass.toString())
+                .run()
+                .getOutput(ToolBox.OutputKind.DIRECT);
 
-//    "${TESTJAVA}${FS}bin${FS}javap" ${TESTTOOLVMOPTS} -verbose T4955930 > ${TMP1}
-        Path pathToClass = Paths.get(System.getProperty("test.classes"),
-                "StackMapTest$Test.class");
-        ToolBox.JavaToolArgs javapArgs =
-                new ToolBox.JavaToolArgs().setAllArgs("-v", pathToClass.toString());
-
-//        grep "StackMapTable: number_of_entries = 2" ${TMP1}
-        if (!ToolBox.javap(javapArgs).contains("StackMapTable: number_of_entries = 2"))
+        if (!javapOut.contains("StackMapTable: number_of_entries = 2"))
             throw new AssertionError("The number of entries of the stack map "
                     + "table should be equal to 2");
     }
--- a/langtools/test/tools/javah/6257087/T6257087.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javah/6257087/T6257087.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,12 +25,12 @@
  * @test
  * @bug 6257087
  * @summary javah doesn't produce proper signatures for inner class native methods
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main T6257087
  */
 
-import java.nio.file.Paths;
+import java.util.List;
 
 public class T6257087 {
 
@@ -58,13 +58,14 @@
         "#endif";
 
     public static void main(String[] args) throws Exception {
-        ToolBox.JavaToolArgs javahArgs =
-                new ToolBox.JavaToolArgs()
-                .setAllArgs("-cp", System.getProperty("test.classes"), "foo");
-        ToolBox.javah(javahArgs);
+        ToolBox tb = new ToolBox();
+        tb.new JavahTask()
+                .classpath(ToolBox.testClasses)
+                .classes("foo")
+                .run();
 
-        ToolBox.compareLines(Paths.get("foo_bar.h"),
-                ToolBox.splitLines(fooBarGoldenFile, "\n"), null, true);
+        List<String> fooBarFile = tb.readAllLines("foo_bar.h");
+        tb.checkEqual(fooBarFile, tb.split(fooBarGoldenFile, "\n"));
     }
 
 }
--- a/langtools/test/tools/javah/T4942232/MissingParamClassTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javah/T4942232/MissingParamClassTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -27,7 +27,7 @@
  * @summary Verifies that javah won't attempt to generate a header file if a
  * native method in a supplied class contains a parameter type whose corresponding
  * class is missing or not in the classpath
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run compile MissingParamClassTest.java
  * @clean MissingParamClassException
@@ -39,32 +39,21 @@
 
 import java.nio.file.Files;
 import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.List;
 
-//original test: test/tools/javah/MissingParamClassTest.sh
+// Original test: test/tools/javah/MissingParamClassTest.sh
 public class MissingParamClassTest {
 
     public static void main(String[] args) throws Exception {
-        //first steps done now by jtreg
-//"${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d . "${TESTSRC}${FS}ParamClassTest.java" "${TESTSRC}${FS}MissingParamClassException.java"
-//rm -f MissingParamClassException.class
+        ToolBox tb = new ToolBox();
 
-//"${TESTJAVA}${FS}bin${FS}javah" ${TESTTOOLVMOPTS} ParamClassTest 2>${TMP1}
-        List<String> errOutput = new ArrayList<>();
-        ToolBox.JavaToolArgs javahParams =
-            new ToolBox.JavaToolArgs(ToolBox.Expect.FAIL)
-            .setAllArgs("-classpath", System.getProperty("test.classes"), "ParamClassTest")
-            .setErrOutput(errOutput);
-        ToolBox.javah(javahParams);
+        String out = tb.new JavahTask()
+                .classpath(ToolBox.testClasses)
+                .classes("ParamClassTest")
+                .run(ToolBox.Expect.FAIL)
+                .getOutput(ToolBox.OutputKind.DIRECT);
 
-//if [ -f $GENERATED_HEADER_FILE ]; then  fail
-//if [ ! -s ${TMP1} ]; then fail
-        if (Files.exists(Paths.get("ParamClassTest.h")) || errOutput.size() == 0)
+        if (Files.exists(Paths.get("ParamClassTest.h")) || out.isEmpty())
             throw new AssertionError("The only output generated by javah must be an error message");
-        //jtreg again
-//rm -f MissingParamClassException.class ParamClassTest.class
-//rm -f $GENERATED_HEADER_FILE $TMP1
     }
 
 }
--- a/langtools/test/tools/javah/constMacroTest/ConstMacroTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javah/constMacroTest/ConstMacroTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -27,15 +27,15 @@
  * @summary Validates rewritten javah handling of class defined constants and
  * ensures that the appropriate macro definitions are placed in the generated
  * header file.
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main ConstMacroTest
  */
 
 import java.io.*;
-import java.nio.file.Paths;
+import java.util.List;
 
-//original test: test/tools/javah/ConstMacroTest.sh
+// Original test: test/tools/javah/ConstMacroTest.sh
 public class ConstMacroTest {
 
     private static final String subClassConstsGoldenFileTemplate =
@@ -71,27 +71,21 @@
         "#endif\n" +
         "#endif";
 
-    private static final String serialVersionUIDSuffix =
-            ToolBox.isWindows() ? "i64" : "LL"; ;
+    public static void main(String[] args) throws Exception {
+        ToolBox tb = new ToolBox();
 
-    public static void main(String[] args) throws Exception {
-        //first steps are now done by jtreg
-//        cp "${TESTSRC}${FS}SuperClassConsts.java" .
-//        cp "${TESTSRC}${FS}SubClassConsts.java" .
-
-//        "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d . "${TESTSRC}${FS}SubClassConsts.java"
+        tb.new JavahTask()
+                .classpath(ToolBox.testClasses)
+                .classes("SubClassConsts")
+                .run();
 
-//        "${TESTJAVA}${FS}bin${FS}javah" ${TESTTOOLVMOPTS} SubClassConsts
-        ToolBox.JavaToolArgs successParams =
-                new ToolBox.JavaToolArgs()
-                .setAllArgs("-cp", System.getProperty("test.classes"), "SubClassConsts");
-        ToolBox.javah(successParams);
+        String longSuffix = tb.isWindows() ? "i64" : "LL";
+        List<String> subClassConstsGoldenFile = tb.split(
+                String.format(subClassConstsGoldenFileTemplate, longSuffix), "\n");
 
-//        diff ${DIFFOPTS} "${TESTSRC}${FS}${EXPECTED_JAVAH_OUT_FILE}" "${GENERATED_HEADER_FILE}"
-        String subClassConstGoldenFile = String.format(subClassConstsGoldenFileTemplate,
-                serialVersionUIDSuffix);
-        ToolBox.compareLines(Paths.get("SubClassConsts.h"),
-                ToolBox.splitLines(subClassConstGoldenFile, "\n"), null, true);
+        List<String> subClassConstsFile = tb.readAllLines("SubClassConsts.h");
+
+        tb.checkEqual(subClassConstsFile, subClassConstsGoldenFile);
     }
 
 }
--- a/langtools/test/tools/javap/4798312/JavapShouldLoadClassesFromRTJarTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javap/4798312/JavapShouldLoadClassesFromRTJarTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,19 +24,23 @@
 /*
  * @test
  * @bug 4798312
- * @summary In Windows, javap doesnt load classes from rt.jar
- * @library /tools/javac/lib
+ * @summary In Windows, javap doesn't load classes from rt.jar
+ * @library /tools/lib
  * @build ToolBox
  * @run main JavapShouldLoadClassesFromRTJarTest
  */
+
 public class JavapShouldLoadClassesFromRTJarTest {
 
     public static void main(String[] args) throws Exception {
-//        "${TESTJAVA}${FS}bin${FS}javap" ${TESTTOOLVMOPTS} java.lang.String
-        ToolBox.JavaToolArgs params =
-                new ToolBox.JavaToolArgs().
-                setAllArgs("-v", "java.lang.String");
-        if (ToolBox.javap(params).isEmpty())
+        ToolBox tb = new ToolBox();
+        String out = tb.new JavapTask()
+                .options("-v")
+                .classes("java.lang.String")
+                .run()
+                .getOutput(ToolBox.OutputKind.DIRECT);
+
+        if (out.isEmpty())
             throw new AssertionError("javap generated no output");
     }
 
--- a/langtools/test/tools/javap/4866831/PublicInterfaceTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javap/4866831/PublicInterfaceTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,9 +1,5 @@
-
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,23 +25,29 @@
  * @test
  * @bug 4866831
  * @summary Verify that javap marks public interfaces as public
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main PublicInterfaceTest
  */
 
-//original test: test/tools/javap/PublicInterfaceTest.sh
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+// Original test: test/tools/javap/PublicInterfaceTest.sh
 public class PublicInterfaceTest {
     public interface Test {}
 
     public static void main(String[] args) throws Exception {
-//        "$JAVAP" ${TESTTOOLVMOPTS} -classpath "${TESTCLASSES}" NotPackagePrivateInterface | grep public
-        Path pathToClass = Paths.get(System.getProperty("test.classes"),
-                "PublicInterfaceTest$Test.class");
-        ToolBox.JavaToolArgs javapParams =
-                new ToolBox.JavaToolArgs()
-                .setAllArgs(pathToClass.toString());
-        if (!ToolBox.javap(javapParams).contains("public"))
+        ToolBox tb = new ToolBox();
+
+        Path pathToClass = Paths.get(ToolBox.testClasses, "PublicInterfaceTest$Test.class");
+
+        String out = tb.new JavapTask()
+                .classes(pathToClass.toString())
+                .run()
+                .getOutput(ToolBox.OutputKind.DIRECT);
+
+        if (!out.contains("public"))
             throw new AssertionError("The javap output does not contain \"public\"");
     }
 
--- a/langtools/test/tools/javap/stackmap/StackmapTest.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/javap/stackmap/StackmapTest.java	Thu Aug 28 14:53:49 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,15 +25,15 @@
  * @test
  * @bug 6271292
  * @summary Verify that javap prints StackMapTable attribute contents
- * @library /tools/javac/lib
+ * @library /tools/lib
  * @build ToolBox
  * @run main StackmapTest
  */
 
-import java.util.Arrays;
+import java.util.ArrayList;
 import java.util.List;
 
-//original test: test/tools/javap/stackmap/T6271292.sh
+// Original test: test/tools/javap/stackmap/T6271292.sh
 public class StackmapTest {
 
     private static final String TestSrc =
@@ -58,41 +58,42 @@
         "}\n";
 
     private static final String goldenOut =
-        "frame_type = 255 /* full_frame */\n" +
-        "frame_type = 255 /* full_frame */\n" +
-        "frame_type = 73 /* same_locals_1_stack_item */\n" +
-        "frame_type = 255 /* full_frame */\n" +
-        "offset_delta = 19\n" +
-        "offset_delta = 0\n" +
-        "offset_delta = 2\n" +
-        "stack = [ uninitialized 0, uninitialized 0 ]\n" +
-        "stack = [ uninitialized 0, uninitialized 0, double ]\n" +
-        "stack = [ this ]\n" +
-        "stack = [ this, double ]\n" +
-        "locals = [ class \"[Ljava/lang/String;\" ]\n" +
-        "locals = [ class \"[Ljava/lang/String;\" ]\n" +
-        "locals = [ this, int ]\n";
+        "        frame_type = 255 /* full_frame */\n" +
+        "        frame_type = 255 /* full_frame */\n" +
+        "        frame_type = 73 /* same_locals_1_stack_item */\n" +
+        "        frame_type = 255 /* full_frame */\n" +
+        "          offset_delta = 19\n" +
+        "          offset_delta = 0\n" +
+        "          offset_delta = 2\n" +
+        "          stack = [ uninitialized 0, uninitialized 0 ]\n" +
+        "          stack = [ uninitialized 0, uninitialized 0, double ]\n" +
+        "          stack = [ this ]\n" +
+        "          stack = [ this, double ]\n" +
+        "          locals = [ class \"[Ljava/lang/String;\" ]\n" +
+        "          locals = [ class \"[Ljava/lang/String;\" ]\n" +
+        "          locals = [ this, int ]\n";
 
     public static void main(String[] args) throws Exception {
-        //        @compile T6271292.java
-        ToolBox.JavaToolArgs javacParams =
-                new ToolBox.JavaToolArgs().setSources(TestSrc);
-        ToolBox.javac(javacParams);
+        ToolBox tb = new ToolBox();
+
+        tb.new JavacTask()
+                .sources(TestSrc)
+                .run();
 
-//        "${TESTJAVA}${FS}bin${FS}javap" ${TESTTOOLVMOPTS} -classpath "${TESTCLASSES}" -verbose T6271292 > "${JAVAPFILE}"
-        ToolBox.JavaToolArgs javapParams =
-                new ToolBox.JavaToolArgs()
-                .setAllArgs("-v", "Test.class");
-        String out = ToolBox.javap(javapParams);
-        List<String> grepResult = ToolBox.grep("frame_type", out,
-                ToolBox.lineSeparator);
-        grepResult.addAll(ToolBox.grep("offset_delta", out, ToolBox.lineSeparator));
-        grepResult.addAll(ToolBox.grep("stack = ", out, ToolBox.lineSeparator));
-        grepResult.addAll(ToolBox.grep("locals = ", out, ToolBox.lineSeparator));
-        List<String> goldenList = Arrays.asList(goldenOut.split("\n"));
+        List<String> out = tb.new JavapTask()
+                .options("-v")
+                .classes("Test.class")
+                .run()
+                .getOutputLines(ToolBox.OutputKind.DIRECT);
 
-//        diff -w "${OUTFILE}" "${TESTSRC}${FS}T6271292.out"
-        ToolBox.compareLines(goldenList, grepResult, true);
+        List<String> grepResult = new ArrayList<>();
+        grepResult.addAll(tb.grep("frame_type",   out));
+        grepResult.addAll(tb.grep("offset_delta", out));
+        grepResult.addAll(tb.grep("stack = ",     out));
+        grepResult.addAll(tb.grep("locals = ",    out));
+
+        List<String> goldenList = tb.split(goldenOut, "\n");
+        tb.checkEqual(goldenList, grepResult);
     }
 
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/lib/ToolBox.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,1920 @@
+/*
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FilterOutputStream;
+import java.io.FilterWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.net.URI;
+import java.nio.charset.Charset;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Objects;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+import javax.tools.FileObject;
+import javax.tools.ForwardingJavaFileManager;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+
+import com.sun.tools.javac.api.JavacTaskImpl;
+import com.sun.tools.javac.api.JavacTool;
+import java.io.IOError;
+
+/**
+ * Utility methods and classes for writing jtreg tests for
+ * javac, javah, javap, and sjavac. (For javadoc support,
+ * see JavadocTester.)
+ *
+ * <p>There is support for common file operations similar to
+ * shell commands like cat, cp, diff, mv, rm, grep.
+ *
+ * <p>There is also support for invoking various tools, like
+ * javac, javah, javap, jar, java and other JDK tools.
+ *
+ * <p><em>File separators</em>: for convenience, many operations accept strings
+ * to represent filenames. On all platforms on which JDK is supported,
+ * "/" is a legal filename component separator. In particular, even
+ * on Windows, where the official file separator is "\", "/" is a legal
+ * alternative. It is therefore recommended that any client code using
+ * strings to specify filenames should use "/".
+ *
+ * @author Vicente Romero (original)
+ * @author Jonathan Gibbons (revised)
+ */
+public class ToolBox {
+    /** The platform line separator. */
+    public static final String lineSeparator = System.getProperty("line.separator");
+    /** The platform OS name. */
+    public static final String osName = System.getProperty("os.name");
+
+    /** The location of the class files for this test, or null if not set. */
+    public static final String testClasses = System.getProperty("test.classes");
+    /** The location of the source files for this test, or null if not set. */
+    public static final String testSrc = System.getProperty("test.src");
+    /** The location of the test JDK for this test, or null if not set. */
+    public static final String testJDK = System.getProperty("test.jdk");
+
+    /** The current directory. */
+    public static final Path currDir = Paths.get(".");
+
+    /** The stream used for logging output. */
+    public PrintStream out = System.err;
+
+    JavaCompiler compiler;
+    StandardJavaFileManager standardJavaFileManager;
+
+    /**
+     * Checks if the host OS is some version of Windows.
+     * @return true if the host OS is some version of Windows
+     */
+    public boolean isWindows() {
+        return osName.toLowerCase(Locale.ENGLISH).startsWith("windows");
+    }
+
+    /**
+     * Splits a string around matches of the given regular expression.
+     * If the string is empty, an empty list will be returned.
+     * @param text the string to be split
+     * @param sep  the delimiting regular expression
+     * @return the strings between the separators
+     */
+    public List<String> split(String text, String sep) {
+        if (text.isEmpty())
+            return Collections.emptyList();
+        return Arrays.asList(text.split(sep));
+    }
+
+    /**
+     * Checks if two lists of strings are equal.
+     * @param l1 the first list of strings to be compared
+     * @param l2 the second list of strings to be compared
+     * @throws Error if the lists are not equal
+     */
+    public void checkEqual(List<String> l1, List<String> l2) throws Error {
+        if (!Objects.equals(l1, l2)) {
+            // l1 and l2 cannot both be null
+            if (l1 == null)
+                throw new Error("comparison failed: l1 is null");
+            if (l2 == null)
+                throw new Error("comparison failed: l2 is null");
+            // report first difference
+            for (int i = 0; i < Math.min(l1.size(), l2.size()); i++) {
+                String s1 = l1.get(i);
+                String s2 = l1.get(i);
+                if (!Objects.equals(s1, s2)) {
+                    throw new Error("comparison failed, index " + i +
+                            ", (" + s1 + ":" + s2 + ")");
+                }
+            }
+            throw new Error("comparison failed: l1.size=" + l1.size() + ", l2.size=" + l2.size());
+        }
+    }
+
+    /**
+     * Filters a list of strings according to the given regular expression.
+     * @param regex the regular expression
+     * @param lines the strings to be filtered
+     * @return the strings matching the regular expression
+     */
+    public List<String> grep(String regex, List<String> lines) {
+        return grep(Pattern.compile(regex), lines);
+    }
+
+    /**
+     * Filters a list of strings according to the given regular expression.
+     * @param pattern the regular expression
+     * @param lines the strings to be filtered
+     * @return the strings matching the regular expression
+     */
+    public List<String> grep(Pattern pattern, List<String> lines) {
+        return lines.stream()
+                .filter(s -> pattern.matcher(s).find())
+                .collect(Collectors.toList());
+    }
+
+    /**
+     * Copies a file.
+     * If the given destination exists and is a directory, the copy is created
+     * in that directory.  Otherwise, the copy will be placed at the destination,
+     * possibly overwriting any existing file.
+     * <p>Similar to the shell "cp" command: {@code cp from to}.
+     * @param from the file to be copied
+     * @param to where to copy the file
+     * @throws IOException if any error occurred while copying the file
+     */
+    public void copyFile(String from, String to) throws IOException {
+        copyFile(Paths.get(from), Paths.get(to));
+    }
+
+    /**
+     * Copies a file.
+     * If the given destination exists and is a directory, the copy is created
+     * in that directory.  Otherwise, the copy will be placed at the destination,
+     * possibly overwriting any existing file.
+     * <p>Similar to the shell "cp" command: {@code cp from to}.
+     * @param from the file to be copied
+     * @param to where to copy the file
+     * @throws IOException if an error occurred while copying the file
+     */
+    public void copyFile(Path from, Path to) throws IOException {
+        if (Files.isDirectory(to)) {
+            to = to.resolve(from.getFileName());
+        } else {
+            Files.createDirectories(to.getParent());
+        }
+        Files.copy(from, to, StandardCopyOption.REPLACE_EXISTING);
+    }
+
+    /**
+     * Creates one of more directories.
+     * For each of the series of paths, a directory will be created,
+     * including any necessary parent directories.
+     * <p>Similar to the shell command: {@code mkdir -p paths}.
+     * @param paths the directories to be created
+     * @throws IOException if an error occurred while creating the directories
+     */
+    public void createDirectories(String... paths) throws IOException {
+        if (paths.length == 0)
+            throw new IllegalArgumentException("no directories specified");
+        for (String p: paths)
+            Files.createDirectories(Paths.get(p));
+    }
+
+    /**
+     * Creates one or more directories.
+     * For each of the series of paths, a directory will be created,
+     * including any necessary parent directories.
+     * <p>Similar to the shell command: {@code mkdir -p paths}.
+     * @param paths the directories to be created
+     * @throws IOException if an error occurred while creating the directories
+     */
+    public void createDirectories(Path... paths) throws IOException {
+        if (paths.length == 0)
+            throw new IllegalArgumentException("no directories specified");
+        for (Path p: paths)
+            Files.createDirectories(p);
+    }
+
+    /**
+     * Deletes one or more files.
+     * Any directories to be deleted must be empty.
+     * <p>Similar to the shell command: {@code rm files}.
+     * @param files the files to be deleted
+     * @throws IOException if an error occurred while deleting the files
+     */
+    public void deleteFiles(String... files) throws IOException {
+        if (files.length == 0)
+            throw new IllegalArgumentException("no files specified");
+        for (String file: files)
+            Files.delete(Paths.get(file));
+    }
+
+    /**
+     * Moves a file.
+     * If the given destination exists and is a directory, the file will be moved
+     * to that directory.  Otherwise, the file will be moved to the destination,
+     * possibly overwriting any existing file.
+     * <p>Similar to the shell "mv" command: {@code mv from to}.
+     * @param from the file to be moved
+     * @param to where to move the file
+     * @throws IOException if an error occurred while moving the file
+     */
+    public void moveFile(String from, String to) throws IOException {
+        moveFile(Paths.get(from), Paths.get(to));
+    }
+
+    /**
+     * Moves a file.
+     * If the given destination exists and is a directory, the file will be moved
+     * to that directory.  Otherwise, the file will be moved to the destination,
+     * possibly overwriting any existing file.
+     * <p>Similar to the shell "mv" command: {@code mv from to}.
+     * @param from the file to be moved
+     * @param to where to move the file
+     * @throws IOException if an error occurred while moving the file
+     */
+    public void moveFile(Path from, Path to) throws IOException {
+        if (Files.isDirectory(to)) {
+            to = to.resolve(from.getFileName());
+        } else {
+            Files.createDirectories(to.getParent());
+        }
+        Files.move(from, to, StandardCopyOption.REPLACE_EXISTING);
+    }
+
+    /**
+     * Reads the lines of a file.
+     * The file is read using the default character encoding.
+     * @param path the file to be read
+     * @return the lines of the file.
+     * @throws IOException if an error occurred while reading the file
+     */
+    public List<String> readAllLines(String path) throws IOException {
+        return readAllLines(path, null);
+    }
+
+    /**
+     * Reads the lines of a file.
+     * The file is read using the default character encoding.
+     * @param path the file to be read
+     * @return the lines of the file.
+     * @throws IOException if an error occurred while reading the file
+     */
+    public List<String> readAllLines(Path path) throws IOException {
+        return readAllLines(path, null);
+    }
+
+    /**
+     * Reads the lines of a file using the given encoding.
+     * @param path the file to be read
+     * @param encoding the encoding to be used to read the file
+     * @return the lines of the file.
+     * @throws IOException if an error occurred while reading the file
+     */
+    public List<String> readAllLines(String path, String encoding) throws IOException {
+        return readAllLines(Paths.get(path), encoding);
+    }
+
+    /**
+     * Reads the lines of a file using the given encoding.
+     * @param path the file to be read
+     * @param encoding the encoding to be used to read the file
+     * @return the lines of the file.
+     * @throws IOException if an error occurred while reading the file
+     */
+    public List<String> readAllLines(Path path, String encoding) throws IOException {
+        return Files.readAllLines(path, getCharset(encoding));
+    }
+
+    private Charset getCharset(String encoding) {
+        return (encoding == null) ? Charset.defaultCharset() : Charset.forName(encoding);
+    }
+
+    /**
+     * Writes a file containing the given content.
+     * Any necessary directories for the file will be created.
+     * @param path where to write the file
+     * @param content the content for the file
+     * @throws IOException if an error occurred while writing the file
+     */
+    public void writeFile(String path, String content) throws IOException {
+        writeFile(Paths.get(path), content);
+    }
+
+    /**
+     * Writes a file containing the given content.
+     * Any necessary directories for the file will be created.
+     * @param path where to write the file
+     * @param content the content for the file
+     * @throws IOException if an error occurred while writing the file
+     */
+    public void writeFile(Path path, String content) throws IOException {
+        Path dir = path.getParent();
+        if (dir != null)
+            Files.createDirectories(dir);
+        try (BufferedWriter w = Files.newBufferedWriter(path)) {
+            w.write(content);
+        }
+    }
+
+    /**
+     * Writes one or more files containing Java source code.
+     * For each file to be written, the filename will be inferred from the
+     * given base directory, the package declaration (if present) and from the
+     * the name of the first class, interface or enum declared in the file.
+     * <p>For example, if the base directory is /my/dir/ and the content
+     * contains "package p; class C { }", the file will be written to
+     * /my/dir/p/C.java.
+     * <p>Note: the content is analyzed using regular expressions;
+     * errors can occur if any contents have initial comments that might trip
+     * up the analysis.
+     * @param dir the base directory
+     * @param contents the contents of the files to be written
+     * @throws IOException if an error occurred while writing any of the files.
+     */
+    public void writeJavaFiles(Path dir, String... contents) throws IOException {
+        if (contents.length == 0)
+            throw new IllegalArgumentException("no content specified for any files");
+        for (String c: contents) {
+            new JavaSource(c).write(dir);
+        }
+    }
+
+    /**
+     * Returns the path for the binary of a JDK tool within {@link testJDK}.
+     * @param tool the name of the tool
+     * @return the path of the tool
+     */
+    public Path getJDKTool(String tool) {
+        return Paths.get(testJDK, "bin", tool);
+    }
+
+    /**
+     * Returns a string representing the contents of an {@code Iterable} as a list.
+     * @param <T> the type parameter of the {@code Iterable}
+     * @param items the iterable
+     * @return the string
+     */
+    <T> String toString(Iterable<T> items) {
+        return StreamSupport.stream(items.spliterator(), false)
+                .map(Objects::toString)
+                .collect(Collectors.joining(",", "[", "]"));
+    }
+
+    /**
+     * The supertype for tasks.
+     * Complex operations are modelled by building and running a "Task" object.
+     * Tasks are typically configured in a fluent series of calls.
+     */
+    public interface Task {
+        /**
+         * Returns the name of the task.
+         * @return the name of the task
+         */
+        String name();
+
+        /**
+         * Executes the task as currently configured.
+         * @return a Result object containing the results of running the task
+         * @throws TaskError if the outcome of the task was not as expected
+         */
+        Result run() throws TaskError;
+    }
+
+    /**
+     * Exception thrown by {@code Task.run} when the outcome is not as
+     * expected.
+     */
+    public static class TaskError extends Error {
+        /**
+         * Creates a TaskError object with the given message.
+         * @param message the message
+         */
+        public TaskError(String message) {
+            super(message);
+        }
+    }
+
+    /**
+     * An enum to indicate the mode a task should use it is when executed.
+     */
+    public enum Mode {
+        /**
+         * The task should use the interface used by the command
+         * line launcher for the task.
+         * For example, for javac: com.sun.tools.javac.Main.compile
+         */
+        CMDLINE,
+        /**
+         * The task should use a publicly defined API for the task.
+         * For example, for javac: javax.tools.JavaCompiler
+         */
+        API,
+        /**
+         * The task should use the standard launcher for the task.
+         * For example, $JAVA_HOME/bin/javac
+         */
+        EXEC
+    }
+
+    /**
+     * An enum to indicate the expected success or failure of executing a task.
+     */
+    public enum Expect {
+        /** It is expected that the task will complete successfully. */
+        SUCCESS,
+        /** It is expected that the task will not complete successfully. */
+        FAIL
+    }
+
+    /**
+     * An enum to identify the streams that may be written by a {@code Task}.
+     */
+    public enum OutputKind {
+        /** Identifies output written to {@code System.out} or {@code stdout}. */
+        STDOUT,
+        /** Identifies output written to {@code System.err} or {@code stderr}. */
+        STDERR,
+        /** Identifies output written to a stream provided directly to the task. */
+        DIRECT
+    };
+
+    /**
+     * The results from running a {@link Task}.
+     * The results contain the exit code returned when the tool was invoked,
+     * and a map containing the output written to any streams during the
+     * execution of the tool.
+     * All tools support "stdout" and "stderr".
+     * Tools that take an explicit PrintWriter save output written to that
+     * stream as "main".
+     */
+    public class Result {
+
+        final Task task;
+        final int exitCode;
+        final Map<OutputKind, String> outputMap;
+
+        Result(Task task, int exitCode, Map<OutputKind, String> outputMap) {
+            this.task = task;
+            this.exitCode = exitCode;
+            this.outputMap = outputMap;
+        }
+
+        /**
+         * Returns the content of a specified stream.
+         * @param outputKind the kind of the selected stream
+         * @return the content that was written to that stream when the tool
+         *  was executed.
+         */
+        public String getOutput(OutputKind outputKind) {
+            return outputMap.get(outputKind);
+        }
+
+        /**
+         * Returns the content of a named stream as a list of lines.
+         * @param outputKind the kind of the selected stream
+         * @return the content that was written to that stream when the tool
+         *  was executed.
+         */
+        public List<String> getOutputLines(OutputKind outputKind) {
+            return Arrays.asList(outputMap.get(outputKind).split(lineSeparator));
+        }
+
+        /**
+         * Writes the content of the specified stream to the log.
+         * @param kind the kind of the selected stream
+         * @return this Result object
+         */
+        public Result write(OutputKind kind) {
+            String text = getOutput(kind);
+            if (text == null || text.isEmpty())
+                out.println("[" + task.name() + ":" + kind + "]: empty");
+            else {
+                out.println("[" + task.name() + ":" + kind + "]:");
+                out.print(text);
+            }
+            return this;
+        }
+
+        /**
+         * Writes the content of all streams with any content to the log.
+         * @return this Result object
+         */
+        public Result writeAll() {
+            outputMap.forEach((name, text) -> {
+                if (!text.isEmpty()) {
+                    out.println("[" + name + "]:");
+                    out.print(text);
+                }
+            });
+            return this;
+        }
+    }
+
+    /**
+     * A utility base class to simplify the implementation of tasks.
+     * Provides support for running the task in a process and for
+     * capturing output written by the task to stdout, stderr and
+     * other writers where applicable.
+     * @param <T> the implementing subclass
+     */
+    protected static abstract class AbstractTask<T extends AbstractTask<T>> implements Task {
+        protected final Mode mode;
+        private final Map<OutputKind, String> redirects = new EnumMap<>(OutputKind.class);
+        private final Map<String, String> envVars = new HashMap<>();
+        private Expect expect = Expect.SUCCESS;
+        int expectedExitCode = 0;
+
+        /**
+         * Create a task that will execute in the specified mode.
+         * @param mode the mode
+         */
+        protected AbstractTask(Mode mode) {
+            this.mode = mode;
+        }
+
+        /**
+         * Sets the expected outcome of the task and calls {@code run()}.
+         * @param expect the expected outcome
+         * @return the result of calling {@code run()}
+         */
+        public Result run(Expect expect) {
+            expect(expect, Integer.MIN_VALUE);
+            return run();
+        }
+
+        /**
+         * Sets the expected outcome of the task and calls {@code run()}.
+         * @param expect the expected outcome
+         * @param exitCode the expected exit code if the expected outcome
+         *      is {@code FAIL}
+         * @return the result of calling {@code run()}
+         */
+        public Result run(Expect expect, int exitCode) {
+            expect(expect, exitCode);
+            return run();
+        }
+
+        /**
+         * Sets the expected outcome and expected exit code of the task.
+         * The exit code will not be checked if the outcome is
+         * {@code Expect.SUCCESS} or if the exit code is set to
+         * {@code Integer.MIN_VALUE}.
+         * @param expect the expected outcome
+         * @param exitCode the expected exit code
+         */
+        protected void expect(Expect expect, int exitCode) {
+            this.expect = expect;
+            this.expectedExitCode = exitCode;
+        }
+
+        /**
+         * Checks the exit code contained in a {@code Result} against the
+         * expected outcome and exit value
+         * @param result the result object
+         * @return the result object
+         * @throws TaskError if the exit code stored in the result object
+         *      does not match the expected outcome and exit code.
+         */
+        protected Result checkExit(Result result) throws TaskError {
+            switch (expect) {
+                case SUCCESS:
+                    if (result.exitCode != 0) {
+                        result.writeAll();
+                        throw new TaskError("Task " + name() + " failed: rc=" + result.exitCode);
+                    }
+                    break;
+
+                case FAIL:
+                    if (result.exitCode == 0) {
+                        result.writeAll();
+                        throw new TaskError("Task " + name() + " succeeded unexpectedly");
+                    }
+
+                    if (expectedExitCode != Integer.MIN_VALUE
+                            && result.exitCode != expectedExitCode) {
+                        result.writeAll();
+                        throw new TaskError("Task " + name() + "failed with unexpected exit code "
+                            + result.exitCode + ", expected " + expectedExitCode);
+                    }
+                    break;
+            }
+            return result;
+        }
+
+        /**
+         * Sets an environment variable to be used by this task.
+         * @param name the name of the environment variable
+         * @param value the value for the environment variable
+         * @return this task object
+         * @throws IllegalStateException if the task mode is not {@code EXEC}
+         */
+        protected T envVar(String name, String value) {
+            if (mode != Mode.EXEC)
+                throw new IllegalStateException();
+            envVars.put(name, value);
+            return (T) this;
+        }
+
+        /**
+         * Redirects output from an output stream to a file.
+         * @param outputKind the name of the stream to be redirected.
+         * @param path the file
+         * @return this task object
+         * @throws IllegalStateException if the task mode is not {@code EXEC}
+         */
+        protected T redirect(OutputKind outputKind, String path) {
+            if (mode != Mode.EXEC)
+                throw new IllegalStateException();
+            redirects.put(outputKind, path);
+            return (T) this;
+        }
+
+        /**
+         * Returns a {@code ProcessBuilder} initialized with any
+         * redirects and environment variables that have been set.
+         * @return a {@code ProcessBuilder}
+         */
+        protected ProcessBuilder getProcessBuilder() {
+            if (mode != Mode.EXEC)
+                throw new IllegalStateException();
+            ProcessBuilder pb = new ProcessBuilder();
+            if (redirects.get(OutputKind.STDOUT) != null)
+                pb.redirectOutput(new File(redirects.get(OutputKind.STDOUT)));
+            if (redirects.get(OutputKind.STDERR) != null)
+                pb.redirectError(new File(redirects.get(OutputKind.STDERR)));
+            pb.environment().putAll(envVars);
+            return pb;
+        }
+
+        /**
+         * Collects the output from a process and saves it in a {@code Result}.
+         * @param tb the {@code ToolBox} containing the task {@code t}
+         * @param t the task initiating the process
+         * @param p the process
+         * @return a Result object containing the output from the process and its
+         *      exit value.
+         * @throws InterruptedException if the thread is interrupted
+         */
+        protected Result runProcess(ToolBox tb, Task t, Process p) throws InterruptedException {
+            if (mode != Mode.EXEC)
+                throw new IllegalStateException();
+            ProcessOutput sysOut = new ProcessOutput(p.getInputStream()).start();
+            ProcessOutput sysErr = new ProcessOutput(p.getErrorStream()).start();
+            sysOut.waitUntilDone();
+            sysErr.waitUntilDone();
+            int rc = p.waitFor();
+            Map<OutputKind, String> outputMap = new EnumMap<>(OutputKind.class);
+            outputMap.put(OutputKind.STDOUT, sysOut.getOutput());
+            outputMap.put(OutputKind.STDERR, sysErr.getOutput());
+            return checkExit(tb.new Result(t, rc, outputMap));
+        }
+
+        /**
+         * Thread-friendly class to read the output from a process until the stream
+         * is exhausted.
+         */
+        static class ProcessOutput implements Runnable {
+            ProcessOutput(InputStream from) {
+                in = new BufferedReader(new InputStreamReader(from));
+                out = new StringBuilder();
+            }
+
+            ProcessOutput start() {
+                new Thread(this).start();
+                return this;
+            }
+
+            @Override
+            public void run() {
+                try {
+                    String line;
+                    while ((line = in.readLine()) != null) {
+                        out.append(line).append("\n");
+                    }
+                } catch (IOException e) {
+                }
+                synchronized (this) {
+                    done = true;
+                    notifyAll();
+                }
+            }
+
+            synchronized void waitUntilDone() throws InterruptedException {
+                boolean interrupted = false;
+
+                // poll interrupted flag, while waiting for copy to complete
+                while (!(interrupted = Thread.interrupted()) && !done)
+                    wait(1000);
+
+                if (interrupted)
+                    throw new InterruptedException();
+            }
+
+            String getOutput() {
+                return out.toString();
+            }
+
+            private BufferedReader in;
+            private final StringBuilder out;
+            private boolean done;
+        }
+
+        /**
+         * Utility class to simplify the handling of temporarily setting a
+         * new stream for System.out or System.err.
+         */
+        static class StreamOutput {
+            // Functional interface to set a stream.
+            // Expected use: System::setOut, System::setErr
+            private interface Initializer {
+                void set(PrintStream s);
+            }
+
+            private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            private final PrintStream ps = new PrintStream(baos);
+            private final PrintStream prev;
+            private final Initializer init;
+
+            StreamOutput(PrintStream s, Initializer init) {
+                prev = s;
+                init.set(ps);
+                this.init = init;
+            }
+
+            /**
+             * Closes the stream and returns the contents that were written to it.
+             * @return the contents that were written to it.
+             */
+            String close() {
+                init.set(prev);
+                ps.close();
+                return baos.toString();
+            }
+        }
+
+        /**
+         * Utility class to simplify the handling of creating an in-memory PrintWriter.
+         */
+        static class WriterOutput {
+            private final StringWriter sw = new StringWriter();
+            final PrintWriter pw = new PrintWriter(sw);
+
+            /**
+             * Closes the stream and returns the contents that were written to it.
+             * @return the contents that were written to it.
+             */
+            String close() {
+                pw.close();
+                return sw.toString();
+            }
+        }
+    }
+
+    /**
+     * A task to configure and run the Java compiler, javac.
+     */
+    public class JavacTask extends AbstractTask<JavacTask> {
+        private boolean includeStandardOptions;
+        private String classpath;
+        private String sourcepath;
+        private String outdir;
+        private List<String> options;
+        private List<String> classes;
+        private List<String> files;
+        private List<JavaFileObject> fileObjects;
+        private JavaFileManager fileManager;
+
+        /**
+         * Creates a task to execute {@code javac} using API mode.
+         */
+        public JavacTask() {
+            super(Mode.API);
+        }
+
+        /**
+         * Creates a task to execute {@code javac} in a specified mode.
+         * @param mode the mode to be used
+         */
+        public JavacTask(Mode mode) {
+            super(mode);
+        }
+
+        /**
+         * Sets the classpath.
+         * @param classpath the classpath
+         * @return this task object
+         */
+        public JavacTask classpath(String classpath) {
+            this.classpath = classpath;
+            return this;
+        }
+
+        /**
+         * Sets the sourcepath.
+         * @param sourcepath the sourcepath
+         * @return this task object
+         */
+        public JavacTask sourcepath(String sourcepath) {
+            this.sourcepath = sourcepath;
+            return this;
+        }
+
+        /**
+         * Sets the output directory.
+         * @param outdir the output directory
+         * @return this task object
+         */
+        public JavacTask outdir(String outdir) {
+            this.outdir = outdir;
+            return this;
+        }
+
+        /**
+         * Sets the options.
+         * @param options the options
+         * @return this task object
+         */
+        public JavacTask options(String... options) {
+            this.options = Arrays.asList(options);
+            return this;
+        }
+
+        /**
+         * Sets the classes to be analyzed.
+         * @param classes the classes
+         * @return this task object
+         */
+        public JavacTask classes(String... classes) {
+            this.classes = Arrays.asList(classes);
+            return this;
+        }
+
+        /**
+         * Sets the files to be compiled or analyzed.
+         * @param files the files
+         * @return this task object
+         */
+        public JavacTask files(String... files) {
+            this.files = Arrays.asList(files);
+            return this;
+        }
+
+        /**
+         * Sets the files to be compiled or analyzed.
+         * @param files the files
+         * @return this task object
+         */
+        public JavacTask files(Path... files) {
+            this.files = Stream.of(files)
+                    .map(Path::toString)
+                    .collect(Collectors.toList());
+            return this;
+        }
+
+        /**
+         * Sets the sources to be compiled or analyzed.
+         * Each source string is converted into an in-memory object that
+         * can be passed directly to the compiler.
+         * @param sources the sources
+         * @return this task object
+         */
+        public JavacTask sources(String... sources) {
+            fileObjects = Stream.of(sources)
+                    .map(s -> new JavaSource(s))
+                    .collect(Collectors.toList());
+            return this;
+        }
+
+        /**
+         * Sets the file manager to be used by this task.
+         * @param fileManager the file manager
+         * @return this task object
+         */
+        public JavacTask fileManager(JavaFileManager fileManager) {
+            this.fileManager = fileManager;
+            return this;
+        }
+
+        /**
+         * {@inheritDoc}
+         * @return the name "javac"
+         */
+        @Override
+        public String name() {
+            return "javac";
+        }
+
+        /**
+         * Calls the compiler with the arguments as currently configured.
+         * @return a Result object indicating the outcome of the compilation
+         * and the content of any output written to stdout, stderr, or the
+         * main stream by the compiler.
+         * @throws TaskError if the outcome of the task is not as expected.
+         */
+        @Override
+        public Result run() {
+            if (mode == Mode.EXEC)
+                return runExec();
+
+            WriterOutput direct = new WriterOutput();
+            // The following are to catch output to System.out and System.err,
+            // in case these are used instead of the primary (main) stream
+            StreamOutput sysOut = new StreamOutput(System.out, System::setOut);
+            StreamOutput sysErr = new StreamOutput(System.err, System::setErr);
+            int rc;
+            Map<OutputKind, String> outputMap = new HashMap<>();
+            try {
+                switch (mode == null ? Mode.API : mode) {
+                    case API:
+                        rc = runAPI(direct.pw);
+                        break;
+                    case CMDLINE:
+                        rc = runCommand(direct.pw);
+                        break;
+                    default:
+                        throw new IllegalStateException();
+                }
+            } catch (IOException e) {
+                out.println("Exception occurred: " + e);
+                rc = 99;
+            } finally {
+                outputMap.put(OutputKind.STDOUT, sysOut.close());
+                outputMap.put(OutputKind.STDERR, sysErr.close());
+                outputMap.put(OutputKind.DIRECT, direct.close());
+            }
+            return checkExit(new Result(this, rc, outputMap));
+        }
+
+        private int runAPI(PrintWriter pw) throws IOException {
+//            if (compiler == null) {
+                // TODO: allow this to be set externally
+//                compiler = ToolProvider.getSystemJavaCompiler();
+                compiler = JavacTool.create();
+//            }
+
+            if (fileManager == null)
+                fileManager = compiler.getStandardFileManager(null, null, null);
+            if (outdir != null)
+                setLocation(StandardLocation.CLASS_OUTPUT, toFiles(outdir));
+            if (classpath != null)
+                setLocation(StandardLocation.CLASS_PATH, toFiles(classpath));
+            if (sourcepath != null)
+                setLocation(StandardLocation.SOURCE_PATH, toFiles(sourcepath));
+            List<String> allOpts = new ArrayList<>();
+            if (options != null)
+                allOpts.addAll(options);
+
+            Iterable<? extends JavaFileObject> allFiles = joinFiles(files, fileObjects);
+            JavaCompiler.CompilationTask task = compiler.getTask(pw,
+                    fileManager,
+                    null,  // diagnostic listener; should optionally collect diags
+                    allOpts,
+                    classes,
+                    allFiles);
+            return ((JavacTaskImpl) task).doCall().exitCode;
+        }
+
+        private void setLocation(StandardLocation location, List<File> files) throws IOException {
+            if (!(fileManager instanceof StandardJavaFileManager))
+                throw new IllegalStateException("not a StandardJavaFileManager");
+            ((StandardJavaFileManager) fileManager).setLocation(location, files);
+        }
+
+        private int runCommand(PrintWriter pw) {
+            List<String> args = getAllArgs();
+            String[] argsArray = args.toArray(new String[args.size()]);
+            return com.sun.tools.javac.Main.compile(argsArray, pw);
+        }
+
+        private Result runExec() {
+            List<String> args = new ArrayList<>();
+            Path javac = getJDKTool("javac");
+            args.add(javac.toString());
+            if (includeStandardOptions) {
+                args.addAll(split(System.getProperty("test.tool.vm.opts"), " +"));
+                args.addAll(split(System.getProperty("test.compiler.opts"), " +"));
+            }
+            args.addAll(getAllArgs());
+
+            String[] argsArray = args.toArray(new String[args.size()]);
+            ProcessBuilder pb = getProcessBuilder();
+            pb.command(argsArray);
+            try {
+                return runProcess(ToolBox.this, this, pb.start());
+            } catch (IOException | InterruptedException e) {
+                throw new Error(e);
+            }
+        }
+
+        private List<String> getAllArgs() {
+            List<String> args = new ArrayList<>();
+            if (options != null)
+                args.addAll(options);
+            if (outdir != null) {
+                args.add("-d");
+                args.add(outdir);
+            }
+            if (classpath != null) {
+                args.add("-classpath");
+                args.add(classpath);
+            }
+            if (sourcepath != null) {
+                args.add("-sourcepath");
+                args.add(sourcepath);
+            }
+            if (classes != null)
+                args.addAll(classes);
+            if (files != null)
+                args.addAll(files);
+
+            return args;
+        }
+
+        private List<File> toFiles(String path) {
+            List<File> result = new ArrayList<>();
+            for (String s: path.split(File.pathSeparator)) {
+                if (!s.isEmpty())
+                    result.add(new File(s));
+            }
+            return result;
+        }
+
+        private Iterable<? extends JavaFileObject> joinFiles(
+                List<String> files, List<JavaFileObject> fileObjects) {
+            if (files == null)
+                return fileObjects;
+            if (standardJavaFileManager == null)
+                standardJavaFileManager = compiler.getStandardFileManager(null, null, null);
+            Iterable<? extends JavaFileObject> filesAsFileObjects =
+                    standardJavaFileManager.getJavaFileObjectsFromStrings(files);
+            if (fileObjects == null)
+                return filesAsFileObjects;
+            List<JavaFileObject> combinedList = new ArrayList<>();
+            for (JavaFileObject o: filesAsFileObjects)
+                combinedList.add(o);
+            combinedList.addAll(fileObjects);
+            return combinedList;
+        }
+    }
+
+    /**
+     * A task to configure and run the native header tool, javah.
+     */
+    public class JavahTask extends AbstractTask<JavahTask> {
+        private String classpath;
+        private List<String> options;
+        private List<String> classes;
+
+        /**
+         * Create a task to execute {@code javah} using {@code CMDLINE} mode.
+         */
+        public JavahTask() {
+            super(Mode.CMDLINE);
+        }
+
+        /**
+         * Sets the classpath.
+         * @param classpath the classpath
+         * @return this task object
+         */
+        public JavahTask classpath(String classpath) {
+            this.classpath = classpath;
+            return this;
+        }
+
+        /**
+         * Sets the options.
+         * @param options the options
+         * @return this task object
+         */
+        public JavahTask options(String... options) {
+            this.options = Arrays.asList(options);
+            return this;
+        }
+
+        /**
+         * Sets the classes to be analyzed.
+         * @param classes the classes
+         * @return this task object
+         */
+        public JavahTask classes(String... classes) {
+            this.classes = Arrays.asList(classes);
+            return this;
+        }
+
+        /**
+         * {@inheritDoc}
+         * @return the name "javah"
+         */
+        @Override
+        public String name() {
+            return "javah";
+        }
+
+        /**
+         * Calls the javah tool with the arguments as currently configured.
+         * @return a Result object indicating the outcome of the task
+         * and the content of any output written to stdout, stderr, or the
+         * main stream provided to the task.
+         * @throws TaskError if the outcome of the task is not as expected.
+         */
+        @Override
+        public Result run() {
+            List<String> args = new ArrayList<>();
+            if (options != null)
+                args.addAll(options);
+            if (classpath != null) {
+                args.add("-classpath");
+                args.add(classpath);
+            }
+            if (classes != null)
+                args.addAll(classes);
+
+            WriterOutput direct = new WriterOutput();
+            // These are to catch output to System.out and System.err,
+            // in case these are used instead of the primary streams
+            StreamOutput sysOut = new StreamOutput(System.out, System::setOut);
+            StreamOutput sysErr = new StreamOutput(System.err, System::setErr);
+            int rc;
+            Map<OutputKind, String> outputMap = new HashMap<>();
+            try {
+                rc = com.sun.tools.javah.Main.run(args.toArray(new String[args.size()]), direct.pw);
+            } finally {
+                outputMap.put(OutputKind.STDOUT, sysOut.close());
+                outputMap.put(OutputKind.STDERR, sysErr.close());
+                outputMap.put(OutputKind.DIRECT, direct.close());
+            }
+            return checkExit(new Result(this, rc, outputMap));
+        }
+    }
+
+    /**
+     * A task to configure and run the disassembler tool, javap.
+     */
+    public class JavapTask extends AbstractTask<JavapTask> {
+        private String classpath;
+        private List<String> options;
+        private List<String> classes;
+
+        /**
+         * Create a task to execute {@code javap} using {@code CMDLINE} mode.
+         */
+        public JavapTask() {
+            super(Mode.CMDLINE);
+        }
+
+        /**
+         * Sets the classpath.
+         * @param classpath the classpath
+         * @return this task object
+         */
+        public JavapTask classpath(String classpath) {
+            this.classpath = classpath;
+            return this;
+        }
+
+        /**
+         * Sets the options.
+         * @param options the options
+         * @return this task object
+         */
+        public JavapTask options(String... options) {
+            this.options = Arrays.asList(options);
+            return this;
+        }
+
+        /**
+         * Sets the classes to be analyzed.
+         * @param classes the classes
+         * @return this task object
+         */
+        public JavapTask classes(String... classes) {
+            this.classes = Arrays.asList(classes);
+            return this;
+        }
+
+        /**
+         * {@inheritDoc}
+         * @return the name "javap"
+         */
+        @Override
+        public String name() {
+            return "javap";
+        }
+
+        /**
+         * Calls the javap tool with the arguments as currently configured.
+         * @return a Result object indicating the outcome of the task
+         * and the content of any output written to stdout, stderr, or the
+         * main stream.
+         * @throws TaskError if the outcome of the task is not as expected.
+         */
+        @Override
+        public Result run() {
+            List<String> args = new ArrayList<>();
+            if (options != null)
+                args.addAll(options);
+            if (classpath != null) {
+                args.add("-classpath");
+                args.add(classpath);
+            }
+            if (classes != null)
+                args.addAll(classes);
+
+            WriterOutput direct = new WriterOutput();
+            // These are to catch output to System.out and System.err,
+            // in case these are used instead of the primary streams
+            StreamOutput sysOut = new StreamOutput(System.out, System::setOut);
+            StreamOutput sysErr = new StreamOutput(System.err, System::setErr);
+
+            int rc;
+            Map<OutputKind, String> outputMap = new HashMap<>();
+            try {
+                rc = com.sun.tools.javap.Main.run(args.toArray(new String[args.size()]), direct.pw);
+            } finally {
+                outputMap.put(OutputKind.STDOUT, sysOut.close());
+                outputMap.put(OutputKind.STDERR, sysErr.close());
+                outputMap.put(OutputKind.DIRECT, direct.close());
+            }
+            return checkExit(new Result(this, rc, outputMap));
+        }
+    }
+
+    /**
+     * A task to configure and run the jar file utility.
+     */
+    public class JarTask extends AbstractTask<JarTask> {
+        private Path jar;
+        private Manifest manifest;
+        private String classpath;
+        private String mainClass;
+        private Path baseDir;
+        private List<Path> paths;
+
+        /**
+         * Creates a task to write jar files, using API mode.
+         */
+        public JarTask() {
+            super(Mode.API);
+            paths = Collections.emptyList();
+        }
+
+        /**
+         * Creates a JarTask for use with a given jar file.
+         * @param path the file
+         */
+        public JarTask(String path) {
+            this();
+            jar = Paths.get(path);
+        }
+
+        /**
+         * Sets a manifest for the jar file.
+         * @param manifest the manifest
+         * @return this task object
+         */
+        public JarTask manifest(Manifest manifest) {
+            this.manifest = manifest;
+            return this;
+        }
+
+        /**
+         * Sets a manifest for the jar file.
+         * @param manifest a string containing the contents of the manifest
+         * @return this task object
+         * @throws IOException if there is a problem creating the manifest
+         */
+        public JarTask manifest(String manifest) throws IOException {
+            this.manifest = new Manifest(new ByteArrayInputStream(manifest.getBytes()));
+            return this;
+        }
+
+        /**
+         * Sets the classpath to be written to the {@code Class-Path}
+         * entry in the manifest.
+         * @param classpath the classpath
+         * @return this task object
+         */
+        public JarTask classpath(String classpath) {
+            this.classpath = classpath;
+            return this;
+        }
+
+        /**
+         * Sets the class to be written to the {@code Main-Class}
+         * entry in the manifest..
+         * @param mainClass the name of the main class
+         * @return this task object
+         */
+        public JarTask mainClass(String mainClass) {
+            this.mainClass = mainClass;
+            return this;
+        }
+
+        /**
+         * Sets the base directory for files to be written into the jar file.
+         * @param baseDir the base directory
+         * @return this task object
+         */
+        public JarTask baseDir(String baseDir) {
+            this.baseDir = Paths.get(baseDir);
+            return this;
+        }
+
+        /**
+         * Sets the files to be written into the jar file.
+         * @param files the files
+         * @return this task object
+         */
+        public JarTask files(String... files) {
+            this.paths = Stream.of(files)
+                    .map(file -> Paths.get(file))
+                    .collect(Collectors.toList());
+            return this;
+        }
+
+        /**
+         * Provides limited jar command-like functionality.
+         * The supported commands are:
+         * <ul>
+         * <li> jar cf jarfile -C dir files...
+         * <li> jar cfm jarfile manifestfile -C dir files...
+         * </ul>
+         * Any values specified by other configuration methods will be ignored.
+         * @param args arguments in the style of those for the jar command
+         * @return a Result object containing the results of running the task
+         */
+        public Result run(String... args) {
+            if (args.length < 2)
+                throw new IllegalArgumentException();
+
+            ListIterator<String> iter = Arrays.asList(args).listIterator();
+            String first = iter.next();
+            switch (first) {
+                case "cf":
+                    jar = Paths.get(iter.next());
+                    break;
+                case "cfm":
+                    jar = Paths.get(iter.next());
+                    try (InputStream in = Files.newInputStream(Paths.get(iter.next()))) {
+                        manifest = new Manifest(in);
+                    } catch (IOException e) {
+                        throw new IOError(e);
+                    }
+                    break;
+            }
+
+            if (iter.hasNext()) {
+                if (iter.next().equals("-C"))
+                    baseDir = Paths.get(iter.next());
+                else
+                    iter.previous();
+            }
+
+            paths = new ArrayList<>();
+            while (iter.hasNext())
+                paths.add(Paths.get(iter.next()));
+
+            return run();
+        }
+
+        /**
+         * {@inheritDoc}
+         * @return the name "jar"
+         */
+        @Override
+        public String name() {
+            return "jar";
+        }
+
+        /**
+         * Creates a jar file with the arguments as currently configured.
+         * @return a Result object indicating the outcome of the compilation
+         * and the content of any output written to stdout, stderr, or the
+         * main stream by the compiler.
+         * @throws TaskError if the outcome of the task is not as expected.
+         */
+        @Override
+        public Result run() {
+            Manifest m = (manifest == null) ? new Manifest() : manifest;
+            Attributes mainAttrs = m.getMainAttributes();
+            if (mainClass != null)
+                mainAttrs.put(Attributes.Name.MAIN_CLASS, mainClass);
+            if (classpath != null)
+                mainAttrs.put(Attributes.Name.CLASS_PATH, classpath);
+
+            StreamOutput sysOut = new StreamOutput(System.out, System::setOut);
+            StreamOutput sysErr = new StreamOutput(System.err, System::setErr);
+
+            int rc;
+            Map<OutputKind, String> outputMap = new HashMap<>();
+
+            try (OutputStream os = Files.newOutputStream(jar);
+                    JarOutputStream jos = openJar(os, m)) {
+                Path base = (baseDir == null) ? currDir : baseDir;
+                for (Path path: paths) {
+                    Files.walkFileTree(base.resolve(path), new SimpleFileVisitor<Path>() {
+                        @Override
+                        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+                            try {
+                                JarEntry e = new JarEntry(base.relativize(file).toString());
+                                jos.putNextEntry(e);
+                                jos.write(Files.readAllBytes(file));
+                                jos.closeEntry();
+                                return FileVisitResult.CONTINUE;
+                            } catch (IOException e) {
+                                System.err.println("Error adding " + file + " to jar file: " + e);
+                                return FileVisitResult.TERMINATE;
+                            }
+                        }
+                    });
+                }
+                rc = 0;
+            } catch (IOException e) {
+                System.err.println("Error opening " + jar + ": " + e);
+                rc = 1;
+            } finally {
+                outputMap.put(OutputKind.STDOUT, sysOut.close());
+                outputMap.put(OutputKind.STDERR, sysErr.close());
+            }
+            return checkExit(new Result(this, rc, outputMap));
+        }
+
+        private JarOutputStream openJar(OutputStream os, Manifest m) throws IOException {
+            if (m == null || m.getMainAttributes().isEmpty() && m.getEntries().isEmpty()) {
+                return new JarOutputStream(os);
+            } else {
+                if (m.getMainAttributes().get(Attributes.Name.MANIFEST_VERSION) == null)
+                    m.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
+                return new JarOutputStream(os, m);
+            }
+        }
+
+    }
+
+    /**
+     * A task to configure and run the Java launcher.
+     */
+    public class JavaTask extends AbstractTask<JavaTask> {
+        boolean includeStandardOptions = true;
+        private String classpath;
+        private List<String> vmOptions;
+        private String className;
+        private List<String> classArgs;
+
+        /**
+         * Create a task to run the Java launcher, using {@code EXEC} mode.
+         */
+        public JavaTask() {
+            super(Mode.EXEC);
+        }
+
+        /**
+         * Sets the classpath.
+         * @param classpath the classpath
+         * @return this task object
+         */
+        public JavaTask classpath(String classpath) {
+            this.classpath = classpath;
+            return this;
+        }
+
+        /**
+         * Sets the VM options.
+         * @param vmOptions the options
+         * @return this task object
+         */
+        public JavaTask vmOptions(String... vmOptions) {
+            this.vmOptions = Arrays.asList(vmOptions);
+            return this;
+        }
+
+        /**
+         * Sets the name of the class to be executed.
+         * @param className the name of the class
+         * @return this task object
+         */
+        public JavaTask className(String className) {
+            this.className = className;
+            return this;
+        }
+
+        /**
+         * Sets the arguments for the class to be executed.
+         * @param classArgs the arguments
+         * @return this task object
+         */
+        public JavaTask classArgs(String... classArgs) {
+            this.classArgs = Arrays.asList(classArgs);
+            return this;
+        }
+
+        /**
+         * {@inheritDoc}
+         * @return the name "java"
+         */
+        @Override
+        public String name() {
+            return "java";
+        }
+
+        /**
+         * Calls the Java launcher with the arguments as currently configured.
+         * @return a Result object indicating the outcome of the task
+         * and the content of any output written to stdout or stderr.
+         * @throws TaskError if the outcome of the task is not as expected.
+         */
+        @Override
+        public Result run() {
+            List<String> args = new ArrayList<>();
+            args.add(getJDKTool("java").toString());
+            if (includeStandardOptions) {
+                args.addAll(split(System.getProperty("test.vm.opts"), " +"));
+                args.addAll(split(System.getProperty("test.java.opts"), " +"));
+            }
+            if (classpath != null) {
+                args.add("-classpath");
+                args.add(classpath);
+            }
+            if (vmOptions != null)
+                args.addAll(vmOptions);
+            if (className != null)
+                args.add(className);
+            if (classArgs != null)
+                args.addAll(classArgs);
+            ProcessBuilder pb = getProcessBuilder();
+            pb.command(args);
+            try {
+                return runProcess(ToolBox.this, this, pb.start());
+            } catch (IOException | InterruptedException e) {
+                throw new Error(e);
+            }
+        }
+    }
+
+    /**
+     * A task to configure and run a general command.
+     */
+    public class ExecTask extends AbstractTask<ExecTask> {
+        private final String command;
+        private List<String> args;
+
+        /**
+         * Create a task to execute a given command, to be run using {@code EXEC} mode.
+         * @param command the command to be executed
+         */
+        public ExecTask(String command) {
+            super(Mode.EXEC);
+            this.command = command;
+        }
+
+        /**
+         * Create a task to execute a given command, to be run using {@code EXEC} mode.
+         * @param command the command to be executed
+         */
+        public ExecTask(Path command) {
+            super(Mode.EXEC);
+            this.command = command.toString();
+        }
+
+        /**
+         * Sets the arguments for the command to be executed
+         * @param args the arguments
+         * @return this task object
+         */
+        public ExecTask args(String... args) {
+            this.args = Arrays.asList(args);
+            return this;
+        }
+
+        /**
+         * {@inheritDoc}
+         * @return the name "exec"
+         */
+        @Override
+        public String name() {
+            return "exec";
+        }
+
+        /**
+         * Calls the command with the arguments as currently configured.
+         * @return a Result object indicating the outcome of the task
+         * and the content of any output written to stdout or stderr.
+         * @throws TaskError if the outcome of the task is not as expected.
+         */
+        @Override
+        public Result run() {
+            List<String> cmdArgs = new ArrayList<>();
+            cmdArgs.add(command);
+            if (args != null)
+                cmdArgs.addAll(args);
+            ProcessBuilder pb = getProcessBuilder();
+            pb.command(cmdArgs);
+            try {
+                return runProcess(ToolBox.this, this, pb.start());
+            } catch (IOException | InterruptedException e) {
+                throw new Error(e);
+            }
+        }
+    }
+
+    /**
+     * An in-memory Java source file.
+     * It is able to extract the file name from simple source text using
+     * regular expressions.
+     */
+    public static class JavaSource extends SimpleJavaFileObject {
+        private final String source;
+
+        /**
+         * Creates a in-memory file object for Java source code.
+         * @param className the name of the class
+         * @param source the source text
+         */
+        public JavaSource(String className, String source) {
+            super(URI.create(className), JavaFileObject.Kind.SOURCE);
+            this.source = source;
+        }
+
+        /**
+         * Creates a in-memory file object for Java source code.
+         * The name of the class will be inferred from the source code.
+         * @param source the source text
+         */
+        public JavaSource(String source) {
+            super(URI.create(getJavaFileNameFromSource(source)),
+                    JavaFileObject.Kind.SOURCE);
+            this.source = source;
+        }
+
+        /**
+         * Writes the source code to a file in the current directory.
+         * @throws IOException if there is a problem writing the file
+         */
+        public void write() throws IOException {
+            write(currDir);
+        }
+
+        /**
+         * Writes the source code to a file in a specified directory.
+         * @param dir the directory
+         * @throws IOException if there is a problem writing the file
+         */
+        public void write(Path dir) throws IOException {
+            Path file = dir.resolve(getJavaFileNameFromSource(source));
+            Files.createDirectories(file.getParent());
+            try (BufferedWriter out = Files.newBufferedWriter(file)) {
+                out.write(source.replace("\n", lineSeparator));
+            }
+        }
+
+        @Override
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return source;
+        }
+
+        private static Pattern packagePattern =
+                Pattern.compile("package\\s+(((?:\\w+\\.)*)(?:\\w+))");
+        private static Pattern classPattern =
+                Pattern.compile("(?:public\\s+)?(?:class|enum|interface)\\s+(\\w+)");
+
+        /**
+         * Extracts the Java file name from the class declaration.
+         * This method is intended for simple files and uses regular expressions,
+         * so comments matching the pattern can make the method fail.
+         */
+        static String getJavaFileNameFromSource(String source) {
+            String packageName = null;
+
+            Matcher matcher = packagePattern.matcher(source);
+            if (matcher.find())
+                packageName = matcher.group(1).replace(".", "/");
+
+            matcher = classPattern.matcher(source);
+            if (matcher.find()) {
+                String className = matcher.group(1) + ".java";
+                return (packageName == null) ? className : packageName + "/" + className;
+            } else {
+                throw new Error("Could not extract the java class " +
+                        "name from the provided source");
+            }
+        }
+    }
+
+    /**
+     * Extracts the Java file name from the class declaration.
+     * This method is intended for simple files and uses regular expressions,
+     * so comments matching the pattern can make the method fail.
+     * @deprecated This is a legacy method for compatibility with ToolBox v1.
+     *      Use {@link JavaSource#getName JavaSource.getName} instead.
+     * @param source the source text
+     * @return the Java file name inferred from the source
+     */
+    @Deprecated
+    public static String getJavaFileNameFromSource(String source) {
+        return JavaSource.getJavaFileNameFromSource(source);
+    }
+
+    /**
+     * A memory file manager, for saving generated files in memory.
+     * The file manager delegates to a separate file manager for listing and
+     * reading input files.
+     */
+    public static class MemoryFileManager extends ForwardingJavaFileManager {
+        private interface Content {
+            byte[] getBytes();
+            String getString();
+        }
+
+        /**
+         * Maps binary class names to generated content.
+         */
+        final Map<Location, Map<String, Content>> files;
+
+        /**
+         * Construct a memory file manager which stores output files in memory,
+         * and delegates to a default file manager for input files.
+         */
+        public MemoryFileManager() {
+            this(JavacTool.create().getStandardFileManager(null, null, null));
+        }
+
+        /**
+         * Construct a memory file manager which stores output files in memory,
+         * and delegates to a specified file manager for input files.
+         * @param fileManager the file manager to be used for input files
+         */
+        public MemoryFileManager(JavaFileManager fileManager) {
+            super(fileManager);
+            files = new HashMap<>();
+        }
+
+        @Override
+        public JavaFileObject getJavaFileForOutput(Location location,
+                                                   String name,
+                                                   JavaFileObject.Kind kind,
+                                                   FileObject sibling)
+        {
+            return new MemoryFileObject(location, name, kind);
+        }
+
+        /**
+         * Returns the content written to a file in a given location,
+         * or null if no such file has been written.
+         * @param location the location
+         * @param name the name of the file
+         * @return the content as an array of bytes
+         */
+        public byte[] getFileBytes(Location location, String name) {
+            Content content = getFile(location, name);
+            return (content == null) ? null : content.getBytes();
+        }
+
+        /**
+         * Returns the content written to a file in a given location,
+         * or null if no such file has been written.
+         * @param location the location
+         * @param name the name of the file
+         * @return the content as a string
+         */
+        public String getFileString(Location location, String name) {
+            Content content = getFile(location, name);
+            return (content == null) ? null : content.getString();
+        }
+
+        private Content getFile(Location location, String name) {
+            Map<String, Content> filesForLocation = files.get(location);
+            return (filesForLocation == null) ? null : filesForLocation.get(name);
+        }
+
+        private void save(Location location, String name, Content content) {
+            Map<String, Content> filesForLocation = files.get(location);
+            if (filesForLocation == null)
+                files.put(location, filesForLocation = new HashMap<>());
+            filesForLocation.put(name, content);
+        }
+
+        /**
+         * A writable file object stored in memory.
+         */
+        private class MemoryFileObject extends SimpleJavaFileObject {
+            private final Location location;
+            private final String name;
+
+            /**
+             * Constructs a memory file object.
+             * @param name binary name of the class to be stored in this file object
+             */
+            MemoryFileObject(Location location, String name, JavaFileObject.Kind kind) {
+                super(URI.create("mfm:///" + name.replace('.','/') + kind.extension),
+                      Kind.CLASS);
+                this.location = location;
+                this.name = name;
+            }
+
+            @Override
+            public OutputStream openOutputStream() {
+                return new FilterOutputStream(new ByteArrayOutputStream()) {
+                    @Override
+                    public void close() throws IOException {
+                        out.close();
+                        byte[] bytes = ((ByteArrayOutputStream) out).toByteArray();
+                        save(location, name, new Content() {
+                            @Override
+                            public byte[] getBytes() {
+                                return bytes;
+                            }
+                            @Override
+                            public String getString() {
+                                return new String(bytes);
+                            }
+
+                        });
+                    }
+                };
+            }
+
+            @Override
+            public Writer openWriter() {
+                return new FilterWriter(new StringWriter()) {
+                    @Override
+                    public void close() throws IOException {
+                        out.close();
+                        String text = ((StringWriter) out).toString();
+                        save(location, name, new Content() {
+                            @Override
+                            public byte[] getBytes() {
+                                return text.getBytes();
+                            }
+                            @Override
+                            public String getString() {
+                                return text;
+                            }
+
+                        });
+                    }
+                };
+            }
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/sjavac/IdleShutdown.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8044131
+ * @summary Tests the hooks used for detecting idleness of the sjavac server.
+ * @build Wrapper
+ * @run main Wrapper IdleShutdown
+ */
+import java.io.File;
+import java.net.URI;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+
+import com.sun.tools.sjavac.server.CompilationResult;
+import com.sun.tools.sjavac.server.IdleResetSjavac;
+import com.sun.tools.sjavac.server.Sjavac;
+import com.sun.tools.sjavac.server.SysInfo;
+import com.sun.tools.sjavac.server.Terminable;
+
+
+public class IdleShutdown {
+
+    final static long TEST_START = System.currentTimeMillis();
+    final static long TIMEOUT_MS = 3000;
+
+    public static void main(String[] args) throws InterruptedException {
+
+        final AtomicLong timeoutTimestamp = new AtomicLong(-1);
+
+        log("Starting IdleCallbackJavacService with timeout: " + TIMEOUT_MS);
+        Sjavac service = new IdleResetSjavac(
+                new NoopJavacService(),
+                new Terminable() {
+                    public void shutdown(String msg) {
+                        // Record the idle timeout time
+                        log("Timeout detected");
+                        timeoutTimestamp.set(System.currentTimeMillis());
+                    }
+                },
+                TIMEOUT_MS);
+
+        // Make sure it didn't timeout immediately
+        if (timeoutTimestamp.get() != -1)
+            throw new AssertionError("Premature timeout detected.");
+
+        // Call various methods and wait less than TIMEOUT_MS in between
+        Thread.sleep(TIMEOUT_MS - 1000);
+        log("Getting sys info");
+        service.getSysInfo();
+
+        Thread.sleep(TIMEOUT_MS - 1000);
+        log("Getting sys info");
+        service.getSysInfo();
+
+        if (timeoutTimestamp.get() != -1)
+            throw new AssertionError("Premature timeout detected.");
+
+        Thread.sleep(TIMEOUT_MS - 1000);
+        log("Compiling");
+        service.compile("",
+                        "",
+                        new String[0],
+                        Collections.<File>emptyList(),
+                        Collections.<URI>emptySet(),
+                        Collections.<URI>emptySet());
+
+        Thread.sleep(TIMEOUT_MS - 1000);
+        log("Compiling");
+        service.compile("",
+                        "",
+                        new String[0],
+                        Collections.<File>emptyList(),
+                        Collections.<URI>emptySet(),
+                        Collections.<URI>emptySet());
+
+        if (timeoutTimestamp.get() != -1)
+            throw new AssertionError("Premature timeout detected.");
+
+        long expectedTimeout = System.currentTimeMillis() + TIMEOUT_MS;
+
+        // Wait for actual timeout
+        log("Awaiting idle timeout");
+        Thread.sleep(TIMEOUT_MS + 1000);
+
+        // Check result
+        if (timeoutTimestamp.get() == -1)
+            throw new AssertionError("Timeout never occurred");
+
+        long error = Math.abs(expectedTimeout - timeoutTimestamp.get());
+        log("Timeout error: " + error + " ms");
+        if (error > TIMEOUT_MS * .1)
+            throw new AssertionError("Error too big");
+
+        log("Shutting down");
+        service.shutdown();
+    }
+
+    private static void log(String msg) {
+        long logTime = System.currentTimeMillis() - TEST_START;
+        System.out.printf("After %5d ms: %s%n", logTime, msg);
+    }
+
+    private static class NoopJavacService implements Sjavac {
+        @Override
+        public SysInfo getSysInfo() {
+            // Attempt to trigger idle timeout during a call by sleeping
+            try {
+                Thread.sleep(TIMEOUT_MS + 1000);
+            } catch (InterruptedException e) {
+            }
+            return null;
+        }
+        @Override
+        public void shutdown() {
+        }
+        @Override
+        public CompilationResult compile(String protocolId,
+                                         String invocationId,
+                                         String[] args,
+                                         List<File> explicitSources,
+                                         Set<URI> sourcesToCompile,
+                                         Set<URI> visibleSources) {
+            return null;
+        }
+        @Override
+        public String serverSettings() {
+            return "";
+        }
+    }
+}
--- a/langtools/test/tools/sjavac/OptionDecoding.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/sjavac/OptionDecoding.java	Thu Aug 28 14:53:49 2014 -0700
@@ -25,7 +25,7 @@
 
 /*
  * @test
- * @bug 8035063
+ * @bug 8035063 8054465
  * @summary Tests decoding of String[] into Options.
  *
  * @build Wrapper
@@ -192,13 +192,16 @@
         assertEquals(17, options.getNumCores());
         assertEquals("debug", options.getLogLevel());
         assertEquals(false, options.isDefaultPackagePermitted());
-        assertEquals(false, options.isUnidentifiedArtifactPermitted());
+        assertEquals(false, options.areUnidentifiedArtifactsPermitted());
+        assertEquals(false, options.isUnidentifiedArtifactPermitted(Paths.get("bar.txt").toFile().getAbsolutePath()));
 
         options = Options.parseArgs("--permit-unidentified-artifacts",
+                                    "--permit-artifact=bar.txt",
                                     "--permit-sources-without-package");
         assertEquals("info", options.getLogLevel());
         assertEquals(true, options.isDefaultPackagePermitted());
-        assertEquals(true, options.isUnidentifiedArtifactPermitted());
+        assertEquals(true, options.areUnidentifiedArtifactsPermitted());
+        assertEquals(true, options.isUnidentifiedArtifactPermitted(Paths.get("bar.txt").toFile().getAbsolutePath()));
     }
 
     // Test server configuration options
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/sjavac/PooledExecution.java	Thu Aug 28 14:53:49 2014 -0700
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8044131
+ * @summary Makes sure sjavac poolsize option is honored.
+ * @build Wrapper
+ * @run main Wrapper PooledExecution
+ */
+import java.io.File;
+import java.net.URI;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import com.sun.tools.sjavac.comp.PooledSjavac;
+import com.sun.tools.sjavac.server.CompilationResult;
+import com.sun.tools.sjavac.server.Sjavac;
+import com.sun.tools.sjavac.server.SysInfo;
+
+
+public class PooledExecution {
+
+    public static void main(String[] args) throws InterruptedException {
+        new PooledExecutionTest().runTest();
+    }
+
+    static class PooledExecutionTest {
+
+        final int POOL_SIZE = 15;
+        final int NUM_REQUESTS = 100;
+
+        // Number of tasks that has not yet started
+        CountDownLatch leftToStart = new CountDownLatch(NUM_REQUESTS);
+
+        // Highest number of concurrently active request seen
+        int highWaterMark = 0;
+
+        public void runTest() throws InterruptedException {
+            ConcurrencyLoggingService loggingService = new ConcurrencyLoggingService();
+            final Sjavac service = new PooledSjavac(loggingService, POOL_SIZE);
+
+            // Keep track of the number of finished tasks so we can make sure all
+            // tasks finishes gracefully upon shutdown.
+            Thread[] tasks = new Thread[NUM_REQUESTS];
+            final AtomicInteger tasksFinished = new AtomicInteger(0);
+
+            for (int i = 0; i < NUM_REQUESTS; i++) {
+                tasks[i] = new Thread() {
+                    public void run() {
+                        service.compile("",
+                                        "",
+                                        new String[0],
+                                        Collections.<File>emptyList(),
+                                        Collections.<URI>emptySet(),
+                                        Collections.<URI>emptySet());
+                        tasksFinished.incrementAndGet();
+                    }
+                };
+                tasks[i].start();
+            }
+
+            // Wait for all tasks to start (but not necessarily run to completion)
+            leftToStart.await();
+
+            // Shutdown before all tasks are completed
+            System.out.println("Shutting down!");
+            service.shutdown();
+
+            // Wait for all tasks to complete
+            for (Thread t : tasks)
+                t.join();
+
+            if (tasksFinished.get() != NUM_REQUESTS) {
+                throw new AssertionError(tasksFinished.get() + " out of " +
+                        NUM_REQUESTS + " finished. Broken shutdown?");
+            }
+
+            if (highWaterMark > POOL_SIZE) {
+                throw new AssertionError("Pool size overused: " + highWaterMark +
+                                         " used out of " + POOL_SIZE + " allowed.");
+            }
+
+            // Assuming more than POOL_SIZE requests can be processed within 1 sek:
+            if (highWaterMark < POOL_SIZE) {
+                throw new AssertionError("Pool size underused: " + highWaterMark +
+                                         " used out of " + POOL_SIZE + " allowed.");
+            }
+        }
+
+
+        private class ConcurrencyLoggingService implements Sjavac {
+
+            // Keeps track of currently active requests
+            AtomicInteger activeRequests = new AtomicInteger(0);
+
+            @Override
+            public CompilationResult compile(String protocolId,
+                                             String invocationId,
+                                             String[] args,
+                                             List<File> explicitSources,
+                                             Set<URI> sourcesToCompile,
+                                             Set<URI> visibleSources) {
+                leftToStart.countDown();
+                int numActiveRequests = activeRequests.incrementAndGet();
+                System.out.printf("Left to start: %2d / Currently active: %2d%n",
+                                  leftToStart.getCount(),
+                                  numActiveRequests);
+                highWaterMark = Math.max(highWaterMark, numActiveRequests);
+                try {
+                    Thread.sleep(1000);
+                } catch (InterruptedException ie) {
+                    throw new RuntimeException("Interrupted", ie);
+                }
+                activeRequests.decrementAndGet();
+                System.out.println("Task completed");
+                return null;
+            }
+
+            @Override
+            public SysInfo getSysInfo() {
+                return null;
+            }
+
+            @Override
+            public void shutdown() {
+            }
+
+            @Override
+            public String serverSettings() {
+                return "";
+            }
+        }
+    }
+}
--- a/langtools/test/tools/sjavac/SJavac.java	Thu Aug 21 14:16:28 2014 -0700
+++ b/langtools/test/tools/sjavac/SJavac.java	Thu Aug 28 14:53:49 2014 -0700
@@ -25,7 +25,7 @@
 /*
  * @test
  * @summary Test all aspects of sjavac.
- * @bug 8004658 8042441 8042699
+ * @bug 8004658 8042441 8042699 8054461 8054474 8054465
  *
  * @build Wrapper
  * @run main Wrapper SJavac
@@ -99,6 +99,9 @@
         compileCircularSources();
         compileExcludingDependency();
         incrementalCompileTestFullyQualifiedRef();
+        compileWithAtFile();
+        testStateDir();
+        testPermittedArtifact();
 
         delete(gensrc);
         delete(gensrc2);
@@ -463,6 +466,98 @@
                          "bin/javac_state");
     }
 
+   /**
+     * Tests @atfile
+     * @throws Exception If test fails
+     */
+    void compileWithAtFile() throws Exception {
+        System.out.println("\nTest @atfile with command line content.");
+        System.out.println("---------------------------------------");
+
+        delete(gensrc);
+        delete(gensrc2);
+        delete(bin);
+
+        populate(gensrc,
+                 "list.txt",
+                 "-if */alfa/omega/A.java\n-if */beta/B.java\ngensrc\n-d bin\n",
+                 "alfa/omega/A.java",
+                 "package alfa.omega; import beta.B; public class A { B b; }",
+                 "beta/B.java",
+                 "package beta; public class B { }",
+                 "beta/C.java",
+                 "broken");
+        previous_bin_state = collectState(bin);
+        compile("@gensrc/list.txt", "--server:portfile=testserver,background=false");
+
+        Map<String,Long> new_bin_state = collectState(bin);
+        verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
+                         "bin/javac_state",
+                         "bin/alfa/omega/A.class",
+                         "bin/beta/B.class");
+    }
+
+    /**
+     * Tests storing javac_state into another directory.
+     * @throws Exception If test fails
+     */
+    void testStateDir() throws Exception {
+        System.out.println("\nVerify that --state-dir=bar works.");
+        System.out.println("----------------------------------");
+
+        Path bar = defaultfs.getPath("bar");
+        Files.createDirectory(bar);
+
+        delete(gensrc);
+        delete(bin);
+        delete(bar);
+        previous_bin_state = collectState(bin);
+        Map<String,Long> previous_bar_state = collectState(bar);
+
+        populate(gensrc,
+                 "alfa/omega/A.java",
+                 "package alfa.omega; public class A { }");
+
+        compile("--state-dir=bar", "-src", "gensrc", "-d", "bin", serverArg);
+
+        Map<String,Long> new_bin_state = collectState(bin);
+        verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
+                                     "bin/alfa/omega/A.class");
+        Map<String,Long> new_bar_state = collectState(bar);
+        verifyThatFilesHaveBeenAdded(previous_bar_state, new_bar_state,
+                                     "bar/javac_state");
+    }
+
+    /**
+     * Test white listing of external artifacts inside the destination dir.
+     * @throws Exception If test fails
+     */
+    void testPermittedArtifact() throws Exception {
+        System.out.println("\nVerify that --permit-artifact=bar works.");
+        System.out.println("-------------------------------------------");
+
+        delete(gensrc);
+        delete(bin);
+
+        previous_bin_state = collectState(bin);
+
+        populate(gensrc,
+                 "alfa/omega/A.java",
+                 "package alfa.omega; public class A { }");
+
+        populate(bin,
+                 "alfa/omega/AA.class",
+                 "Ugh, a messy build system (tobefixed) wrote this class file, sjavac must not delete it.");
+
+        compile("--log=debug", "--permit-artifact=bin/alfa/omega/AA.class", "-src", "gensrc", "-d", "bin", serverArg);
+
+        Map<String,Long> new_bin_state = collectState(bin);
+        verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
+                                     "bin/alfa/omega/A.class",
+                                     "bin/alfa/omega/AA.class",
+                                     "bin/javac_state");
+    }
+
     void removeFrom(Path dir, String... args) throws IOException {
         for (String filename : args) {
             Path p = dir.resolve(filename);