8054717: SJavac should track changes in the public apis of classpath classes!
authoralundblad
Tue, 09 Jun 2015 15:57:45 +0200
changeset 31115 8d8e98052d5d
parent 31114 d4045e8aaf1e
child 31116 2c8162f88493
8054717: SJavac should track changes in the public apis of classpath classes! Summary: Added functionality for tracking changes in public APIs of classpath classes. Reviewed-by: jlahoda, erikj
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/BuildState.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CleanProperties.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileProperties.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CopyFile.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/JavacState.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Module.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Package.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/PubApiExtractor.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Source.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Transformer.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Util.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/ClientMain.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/Dependencies.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/FileObjectWithLocation.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/JavaFileObjectWithLocation.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/PathAndPackageVerifier.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/PooledSjavac.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/PubAPIs.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/PubapiVisitor.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SjavacImpl.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SmartFileManager.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/dependencies/Dependency.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/dependencies/DependencyCollector.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/dependencies/DependencyScanner.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/dependencies/NewDependencyCollector.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/dependencies/PackageDependency.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/dependencies/PublicApiCollector.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/dependencies/TypeAndSupertypesDependency.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/pubapi/ArrayTypeDesc.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/pubapi/PrimitiveTypeDesc.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/pubapi/PubApi.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/pubapi/PubApiTypeParam.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/pubapi/PubMethod.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/pubapi/PubType.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/pubapi/PubVar.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/pubapi/ReferenceTypeDesc.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/pubapi/TypeDesc.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/pubapi/TypeVarTypeDesc.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/CompilationResult.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/ServerMain.java
langtools/test/tools/sjavac/ApiExtraction.java
langtools/test/tools/sjavac/ClasspathDependencies.java
langtools/test/tools/sjavac/CompileCircularSources.java
langtools/test/tools/sjavac/CompileExcludingDependency.java
langtools/test/tools/sjavac/CompileWithAtFile.java
langtools/test/tools/sjavac/CompileWithInvisibleSources.java
langtools/test/tools/sjavac/CompileWithOverrideSources.java
langtools/test/tools/sjavac/DependencyCollection.java
langtools/test/tools/sjavac/IncCompInheritance.java
langtools/test/tools/sjavac/IncCompileChangeNative.java
langtools/test/tools/sjavac/IncCompileDropClasses.java
langtools/test/tools/sjavac/IncCompileFullyQualifiedRef.java
langtools/test/tools/sjavac/IncCompileNoChanges.java
langtools/test/tools/sjavac/IncCompileUpdateNative.java
langtools/test/tools/sjavac/IncCompileWithChanges.java
langtools/test/tools/sjavac/JavacOptionPrep.java
langtools/test/tools/sjavac/PermittedArtifact.java
langtools/test/tools/sjavac/SJavacTester.java
langtools/test/tools/sjavac/SjavacBase.java
langtools/test/tools/sjavac/StateDir.java
langtools/test/tools/sjavac/test-input/src/nondependency/pkg26/Cls26.java
langtools/test/tools/sjavac/test-input/src/pkg/Test.java
langtools/test/tools/sjavac/test-input/src/pkg10/Cls10.java
langtools/test/tools/sjavac/test-input/src/pkg11/Cls11.java
langtools/test/tools/sjavac/test-input/src/pkg12/Cls12.java
langtools/test/tools/sjavac/test-input/src/pkg13/Cls13.java
langtools/test/tools/sjavac/test-input/src/pkg14/Cls14.java
langtools/test/tools/sjavac/test-input/src/pkg15/Cls15.java
langtools/test/tools/sjavac/test-input/src/pkg16/Cls16.java
langtools/test/tools/sjavac/test-input/src/pkg17/Cls17.java
langtools/test/tools/sjavac/test-input/src/pkg18/Cls18.java
langtools/test/tools/sjavac/test-input/src/pkg19/Cls19.java
langtools/test/tools/sjavac/test-input/src/pkg2/Cls2.java
langtools/test/tools/sjavac/test-input/src/pkg20/Anno20.java
langtools/test/tools/sjavac/test-input/src/pkg21/Cls21.java
langtools/test/tools/sjavac/test-input/src/pkg22/Anno22.java
langtools/test/tools/sjavac/test-input/src/pkg23/Cls23.java
langtools/test/tools/sjavac/test-input/src/pkg24/Cls24.java
langtools/test/tools/sjavac/test-input/src/pkg25/Cls25.java
langtools/test/tools/sjavac/test-input/src/pkg27/Cls27.java
langtools/test/tools/sjavac/test-input/src/pkg28/Cls28.java
langtools/test/tools/sjavac/test-input/src/pkg29/Cls29.java
langtools/test/tools/sjavac/test-input/src/pkg3/Cls3.java
langtools/test/tools/sjavac/test-input/src/pkg30/Cls30.java
langtools/test/tools/sjavac/test-input/src/pkg4/Cls4.java
langtools/test/tools/sjavac/test-input/src/pkg5/Anno5.java
langtools/test/tools/sjavac/test-input/src/pkg6/Cls6.java
langtools/test/tools/sjavac/test-input/src/pkg7/Cls7.java
langtools/test/tools/sjavac/test-input/src/pkg8/Cls8.java
langtools/test/tools/sjavac/test-input/src/pkg9/Cls9.java
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/BuildState.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/BuildState.java	Tue Jun 09 15:57:45 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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,12 +26,13 @@
 package com.sun.tools.sjavac;
 
 import java.io.File;
+import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
 import com.sun.tools.javac.util.Assert;
+import com.sun.tools.sjavac.pubapi.PubApi;
 
 /**
  * The build state class captures the source code and generated artifacts
@@ -77,7 +78,7 @@
      */
     Module findModuleFromPackageName(String pkg) {
         int cp = pkg.indexOf(':');
-        Assert.check(cp != -1);
+        Assert.check(cp != -1, "Could not find package name");
         String mod = pkg.substring(0, cp);
         return lookupModule(mod);
     }
@@ -154,21 +155,28 @@
      */
     public void calculateDependents() {
         dependents = new HashMap<>();
+
         for (String s : packages.keySet()) {
             Package p = packages.get(s);
-            for (String d : p.dependencies()) {
-                Set<String> ss = dependents.get(d);
-                if (ss == null) {
-                    ss = new HashSet<>();
-                    dependents.put(d, ss);
-                }
+
+            // Collect all dependencies of the classes in this package
+            Set<String> deps = p.typeDependencies()  // maps fqName -> set of dependencies
+                                .values()
+                                .stream()
+                                .reduce(Collections.emptySet(), Util::union);
+
+            // Now reverse the direction
+
+            for (String dep : deps) {
                 // Add the dependent information to the global dependent map.
-                ss.add(s);
-                Package dp = packages.get(d);
+                String depPkgStr = ":" + dep.substring(0, dep.lastIndexOf('.'));
+                dependents.merge(depPkgStr, Collections.singleton(s), Util::union);
+
                 // Also add the dependent information to the package specific map.
                 // Normally, you do not compile java.lang et al. Therefore
                 // there are several packages that p depends upon that you
                 // do not have in your state database. This is perfectly fine.
+                Package dp = packages.get(depPkgStr);
                 if (dp != null) {
                     // But this package did exist in the state database.
                     dp.addDependent(p.name());
@@ -270,11 +278,21 @@
     public void copyPackagesExcept(BuildState prev, Set<String> recompiled, Set<String> removed) {
         for (String pkg : prev.packages().keySet()) {
             // Do not copy recompiled or removed packages.
-            if (recompiled.contains(pkg) || removed.contains(pkg)) continue;
+            if (recompiled.contains(pkg) || removed.contains(pkg))
+                continue;
+
             Module mnew = findModuleFromPackageName(pkg);
             Package pprev = prev.packages().get(pkg);
+
+            // Even though we haven't recompiled this package, we may have
+            // information about its public API: It may be a classpath dependency
+            if (packages.containsKey(pkg)) {
+                pprev.setPubapi(PubApi.mergeTypes(pprev.getPubApi(),
+                                                  packages.get(pkg).getPubApi()));
+            }
+
             mnew.addPackage(pprev);
-            // Do not forget to update the flattened data.
+            // Do not forget to update the flattened data. (See JDK-8071904)
             packages.put(pkg, pprev);
         }
     }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CleanProperties.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CleanProperties.java	Tue Jun 09 15:57:45 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, 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,17 +25,25 @@
 
 package com.sun.tools.sjavac;
 
-import java.io.*;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.io.Writer;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
-import java.util.HashSet;
 import java.util.Map;
 import java.util.Properties;
+import java.util.Set;
 
 import com.sun.tools.sjavac.options.Options;
+import com.sun.tools.sjavac.pubapi.PubApi;
 import com.sun.tools.sjavac.server.Sjavac;
 
 /**
@@ -63,8 +71,10 @@
                              Map<String,Set<String>> oldPackageDependencies,
                              URI destRoot,
                              Map<String,Set<URI>>    packageArtifacts,
-                             Map<String,Set<String>> packageDependencies,
-                             Map<String,String>      packagePublicApis,
+                             Map<String, Map<String, Set<String>>> packageDependencies,
+                             Map<String, Map<String, Set<String>>> packageCpDependencies,
+                             Map<String, PubApi> packagePublicApis,
+                             Map<String, PubApi> dependencyPublicApis,
                              int debugLevel,
                              boolean incremental,
                              int numCores,
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java	Tue Jun 09 15:57:45 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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,12 @@
 import java.net.URI;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Set;
-import java.util.Map;
 
 import com.sun.tools.sjavac.options.Options;
+import com.sun.tools.sjavac.pubapi.PubApi;
 import com.sun.tools.sjavac.server.CompilationResult;
 import com.sun.tools.sjavac.server.Sjavac;
 import com.sun.tools.sjavac.server.SysInfo;
@@ -73,21 +75,25 @@
                              Map<String,Set<String>> oldPackageDependents,
                              URI destRoot,
                              final Map<String,Set<URI>>    packageArtifacts,
-                             final Map<String,Set<String>> packageDependencies,
-                             final Map<String,String>      packagePubapis,
+                             final Map<String,Map<String, Set<String>>> packageDependencies,
+                             final Map<String,Map<String, Set<String>>> packageCpDependencies,
+                             final Map<String, PubApi> packagePubapis,
+                             final Map<String, PubApi> dependencyPubapis,
                              int debugLevel,
                              boolean incremental,
                              int numCores,
                              final PrintStream out,
-                             final PrintStream err)
-    {
+                             final PrintStream err) {
+
+        Log.debug("Performing CompileJavaPackages transform...");
+
         boolean rc = true;
         boolean concurrentCompiles = true;
 
         // Fetch the id.
         final String id = Util.extractStringOption("id", sjavac.serverSettings());
         // Only keep portfile and sjavac settings..
-        String psServerSettings = Util.cleanSubOptions(Util.set("portfile","sjavac","background","keepalive"), sjavac.serverSettings());
+        //String psServerSettings = Util.cleanSubOptions(Util.set("portfile","sjavac","background","keepalive"), sjavac.serverSettings());
 
         // Get maximum heap size from the server!
         SysInfo sysinfo = sjavac.getSysInfo();
@@ -210,20 +216,44 @@
             final CompileChunk cc = compileChunks[i];
 
             // Pass the num_cores and the id (appended with the chunk number) to the server.
-            final String cleanedServerSettings = psServerSettings+",poolsize="+numCores+",id="+id+"-"+i;
-
+            Object lock = new Object();
             requests[i] = new Thread() {
                 @Override
                 public void run() {
                     rn[ii] = sjavac.compile("n/a",
-                                                  id + "-" + ii,
-                                                  args.prepJavacArgs(),
-                                                  Collections.<File>emptyList(),
-                                                  cc.srcs,
-                                                  visibleSources);
-                    packageArtifacts.putAll(rn[ii].packageArtifacts);
-                    packageDependencies.putAll(rn[ii].packageDependencies);
-                    packagePubapis.putAll(rn[ii].packagePubapis);
+                                            id + "-" + ii,
+                                            args.prepJavacArgs(),
+                                            Collections.<File>emptyList(),
+                                            cc.srcs,
+                                            visibleSources);
+                    // In the code below we have to keep in mind that two
+                    // different compilation results may include results for
+                    // the same package.
+                    synchronized (lock) {
+
+                        for (String pkg : rn[ii].packageArtifacts.keySet()) {
+                            Set<URI> pkgArtifacts = rn[ii].packageArtifacts.get(pkg);
+                            packageArtifacts.merge(pkg, pkgArtifacts, Util::union);
+                        }
+
+                        for (String pkg : rn[ii].packageDependencies.keySet()) {
+                            packageDependencies.putIfAbsent(pkg, new HashMap<>());
+                            packageDependencies.get(pkg).putAll(rn[ii].packageDependencies.get(pkg));
+                        }
+
+                        for (String pkg : rn[ii].packageCpDependencies.keySet()) {
+                            packageCpDependencies.putIfAbsent(pkg, new HashMap<>());
+                            packageCpDependencies.get(pkg).putAll(rn[ii].packageCpDependencies.get(pkg));
+                        }
+
+                        for (String pkg : rn[ii].packagePubapis.keySet()) {
+                            packagePubapis.merge(pkg, rn[ii].packagePubapis.get(pkg), PubApi::mergeTypes);
+                        }
+
+                        for (String pkg : rn[ii].dependencyPubapis.keySet()) {
+                            dependencyPubapis.merge(pkg, rn[ii].dependencyPubapis.get(pkg), PubApi::mergeTypes);
+                        }
+                    }
                 }
             };
 
@@ -278,7 +308,6 @@
         return rc;
     }
 
-
     /**
      * Split up the sources into compile chunks. If old package dependents information
      * is available, sort the order of the chunks into the most dependent first!
@@ -294,9 +323,9 @@
      * @return
      */
     CompileChunk[] createCompileChunks(Map<String,Set<URI>> pkgSrcs,
-                                 Map<String,Set<String>> oldPackageDependents,
-                                 int numCompiles,
-                                 int sourcesPerCompile) {
+                                       Map<String,Set<String>> oldPackageDependents,
+                                       int numCompiles,
+                                       int sourcesPerCompile) {
 
         CompileChunk[] compileChunks = new CompileChunk[numCompiles];
         for (int i=0; i<compileChunks.length; ++i) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileProperties.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileProperties.java	Tue Jun 09 15:57:45 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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,27 @@
 
 package com.sun.tools.sjavac;
 
-import java.io.*;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.io.Writer;
 import java.net.URI;
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
-import java.util.HashSet;
-import java.util.Map;
 
 import com.sun.tools.sjavac.options.Options;
+import com.sun.tools.sjavac.pubapi.PubApi;
 import com.sun.tools.sjavac.server.Sjavac;
 
 /**
@@ -70,8 +78,10 @@
                              Map<String,Set<String>> oldPackageDependents,
                              URI destRoot,
                              Map<String,Set<URI>>    packageArtifacts,
-                             Map<String,Set<String>> packageDependencies,
-                             Map<String,String>      packagePublicApis,
+                             Map<String,Map<String, Set<String>>> packageDependencies,
+                             Map<String,Map<String, Set<String>>> packageCpDependencies,
+                             Map<String, PubApi> packagePublicApis,
+                             Map<String, PubApi> dependencyPublicApis,
                              int debugLevel,
                              boolean incremental,
                              int numCores,
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CopyFile.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CopyFile.java	Tue Jun 09 15:57:45 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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,20 @@
 
 package com.sun.tools.sjavac;
 
-import java.io.*;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
 import java.net.URI;
-import java.util.Set;
 import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
 import com.sun.tools.sjavac.options.Options;
+import com.sun.tools.sjavac.pubapi.PubApi;
 import com.sun.tools.sjavac.server.Sjavac;
 
 /**
@@ -58,8 +65,10 @@
                              Map<String,Set<String>> oldPackageDependents,
                              URI destRoot,
                              Map<String,Set<URI>>    packageArtifacts,
-                             Map<String,Set<String>> packageDependencies,
-                             Map<String,String>      packagePubapis,
+                             Map<String,Map<String, Set<String>>> packageDependencies,
+                             Map<String,Map<String, Set<String>>> packageCpDependencies,
+                             Map<String, PubApi> packagePubapis,
+                             Map<String, PubApi> dependencyPubapis,
                              int debugLevel,
                              boolean incremental,
                              int numCores,
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/JavacState.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/JavacState.java	Tue Jun 09 15:57:45 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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,11 +25,17 @@
 
 package com.sun.tools.sjavac;
 
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintStream;
 import java.net.URI;
 import java.nio.file.NoSuchFileException;
 import java.text.SimpleDateFormat;
-import java.util.*;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
@@ -37,8 +43,10 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import com.sun.tools.sjavac.options.Options;
+import com.sun.tools.sjavac.pubapi.PubApi;
 import com.sun.tools.sjavac.server.Sjavac;
 
 /**
@@ -268,24 +276,25 @@
      * Save the javac_state file.
      */
     public void save() throws IOException {
-        if (!needsSaving) return;
+        if (!needsSaving)
+            return;
         try (FileWriter out = new FileWriter(javacState)) {
             StringBuilder b = new StringBuilder();
             long millisNow = System.currentTimeMillis();
             Date d = new Date(millisNow);
-            SimpleDateFormat df =
-                new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
-            b.append("# javac_state ver 0.3 generated "+millisNow+" "+df.format(d)+"\n");
+            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
+            b.append("# javac_state ver 0.4 generated "+millisNow+" "+df.format(d)+"\n");
             b.append("# This format might change at any time. Please do not depend on it.\n");
+            b.append("# R arguments\n");
             b.append("# M module\n");
             b.append("# P package\n");
             b.append("# S C source_tobe_compiled timestamp\n");
             b.append("# S L link_only_source timestamp\n");
             b.append("# G C generated_source timestamp\n");
             b.append("# A artifact timestamp\n");
-            b.append("# D dependency\n");
+            b.append("# D S dependant -> source dependency\n");
+            b.append("# D C dependant -> classpath dependency\n");
             b.append("# I pubapi\n");
-            b.append("# R arguments\n");
             b.append("R ").append(theArgs).append("\n");
 
             // Copy over the javac_state for the packages that did not need recompilation.
@@ -312,6 +321,8 @@
         boolean newCommandLine = false;
         boolean syntaxError = false;
 
+        Log.debug("Loading javac state file: " + db.javacState);
+
         try (BufferedReader in = new BufferedReader(new FileReader(db.javacState))) {
             for (;;) {
                 String l = in.readLine();
@@ -327,11 +338,14 @@
                     } else
                     if (c == 'D') {
                         if (lastModule == null || lastPackage == null) { syntaxError = true; break; }
-                        lastPackage.loadDependency(l);
+                        char depType = l.charAt(2);
+                        if (depType != 'S' && depType != 'C')
+                            throw new RuntimeException("Bad dependency string: " + l);
+                        lastPackage.parseAndAddDependency(l.substring(4), depType == 'C');
                     } else
                     if (c == 'I') {
                         if (lastModule == null || lastPackage == null) { syntaxError = true; break; }
-                        lastPackage.loadPubapi(l);
+                        lastPackage.getPubApi().appendItem(l.substring(2)); // Strip "I "
                     } else
                     if (c == 'A') {
                         if (lastModule == null || lastPackage == null) { syntaxError = true; break; }
@@ -356,7 +370,7 @@
                             int sp = l.indexOf(" ", 18);
                             if (sp != -1) {
                                 String ver = l.substring(18,sp);
-                                if (!ver.equals("0.3")) {
+                                if (!ver.equals("0.4")) {
                     break;
                                  }
                 foundCorrectVerNr = true;
@@ -488,11 +502,92 @@
      * Propagate recompilation through the dependency chains.
      * Avoid re-tainting packages that have already been compiled.
      */
-    public void taintPackagesDependingOnChangedPackages(Set<String> pkgs, Set<String> recentlyCompiled) {
+    public void taintPackagesDependingOnChangedPackages(Set<String> pkgsWithChangedPubApi, Set<String> recentlyCompiled) {
+        // For each to-be-recompiled-candidates...
+        for (Package pkg : new HashSet<>(prev.packages().values())) {
+            // Find out what it depends upon...
+            Set<String> deps = pkg.typeDependencies()
+                                  .values()
+                                  .stream()
+                                  .flatMap(s -> s.stream())
+                                  .collect(Collectors.toSet());
+            for (String dep : deps) {
+                String depPkg = ":" + dep.substring(0, dep.lastIndexOf('.'));
+                if (depPkg.equals(pkg.name()))
+                    continue;
+                // Checking if that dependency has changed
+                if (pkgsWithChangedPubApi.contains(depPkg) && !recentlyCompiled.contains(pkg.name())) {
+                    taintPackage(pkg.name(), "its depending on " + depPkg);
+                }
+            }
+        }
+    }
+
+    /**
+     * Compare the javac_state recorded public apis of packages on the classpath
+     * with the actual public apis on the classpath.
+     */
+    public void taintPackagesDependingOnChangedClasspathPackages() {
+
+        // 1. Collect fully qualified names of all interesting classpath dependencies
+        Set<String> fqDependencies = new HashSet<>();
         for (Package pkg : prev.packages().values()) {
-            for (String dep : pkg.dependencies()) {
-                if (pkgs.contains(dep) && !recentlyCompiled.contains(pkg.name())) {
-                    taintPackage(pkg.name(), " its depending on "+dep);
+            // Check if this package was compiled. If it's presence is recorded
+            // because it was on the class path and we needed to save it's
+            // public api, it's not a candidate for tainting.
+            if (pkg.sources().isEmpty())
+                continue;
+
+            pkg.typeClasspathDependencies().values().forEach(fqDependencies::addAll);
+        }
+
+        // 2. Extract the public APIs from the on disk .class files
+        // (Reason for doing step 1 in a separate phase is to avoid extracting
+        // public APIs of the same class twice.)
+        PubApiExtractor pubApiExtractor = new PubApiExtractor(options);
+        Map<String, PubApi> onDiskPubApi = new HashMap<>();
+        for (String cpDep : fqDependencies) {
+            onDiskPubApi.put(cpDep, pubApiExtractor.getPubApi(cpDep));
+        }
+
+        // 3. Compare them with the public APIs as of last compilation (loaded from javac_state)
+        nextPkg:
+        for (Package pkg : prev.packages().values()) {
+            // Check if this package was compiled. If it's presence is recorded
+            // because it was on the class path and we needed to save it's
+            // public api, it's not a candidate for tainting.
+            if (pkg.sources().isEmpty())
+                continue;
+
+            Set<String> cpDepsOfThisPkg = new HashSet<>();
+            for (Set<String> cpDeps : pkg.typeClasspathDependencies().values())
+                cpDepsOfThisPkg.addAll(cpDeps);
+
+            for (String fqDep : cpDepsOfThisPkg) {
+
+                String depPkg = ":" + fqDep.substring(0, fqDep.lastIndexOf('.'));
+                PubApi prevPkgApi = prev.packages().get(depPkg).getPubApi();
+
+                // This PubApi directly lists the members of the class,
+                // i.e. [ MEMBER1, MEMBER2, ... ]
+                PubApi prevDepApi = prevPkgApi.types.get(fqDep).pubApi;
+
+                // In order to dive *into* the class, we need to add
+                // .types.get(fqDep).pubApi below.
+                PubApi currentDepApi = onDiskPubApi.get(fqDep).types.get(fqDep).pubApi;
+
+                if (!currentDepApi.isBackwardCompatibleWith(prevDepApi)) {
+                    List<String> apiDiff = currentDepApi.diff(prevDepApi);
+                    taintPackage(pkg.name(), "depends on classpath "
+                                + "package which has an updated package api: "
+                                + String.join("\n", apiDiff));
+                    //Log.debug("========================================");
+                    //Log.debug("------ PREV API ------------------------");
+                    //prevDepApi.asListOfStrings().forEach(Log::debug);
+                    //Log.debug("------ CURRENT API ---------------------");
+                    //currentDepApi.asListOfStrings().forEach(Log::debug);
+                    //Log.debug("========================================");
+                    continue nextPkg;
                 }
             }
         }
@@ -660,7 +755,6 @@
         Map<String,Transformer> suffixRules = new HashMap<>();
         suffixRules.put(".java", compileJavaPackages);
         compileJavaPackages.setExtra(args);
-
         rcValue[0] = perform(sjavac, binDir, suffixRules);
         recentlyCompiled.addAll(taintedPackages());
         clearTaintedPackages();
@@ -668,6 +762,11 @@
         taintPackagesDependingOnChangedPackages(packagesWithChangedPublicApis, recentlyCompiled);
         packagesWithChangedPublicApis = new HashSet<>();
         return again && rcValue[0];
+
+        // TODO: Figure out why 'again' checks packagesWithChangedPublicAPis.
+        // (It shouldn't matter if packages had changed pub apis as long as no
+        // one depends on them. Wouldn't it make more sense to let 'again'
+        // depend on taintedPackages?)
     }
 
     /**
@@ -699,68 +798,101 @@
         Map<Transformer,Map<String,Set<URI>>> groupedSources = new HashMap<>();
         for (Source src : now.sources().values()) {
             Transformer t = suffixRules.get(src.suffix());
-               if (t != null) {
+            if (t != null) {
                 if (taintedPackages.contains(src.pkg().name()) && !src.isLinkedOnly()) {
                     addFileToTransform(groupedSources, t, src);
                 }
             }
         }
         // Go through the transforms and transform them.
-        for (Map.Entry<Transformer,Map<String,Set<URI>>> e : groupedSources.entrySet()) {
+        for (Map.Entry<Transformer, Map<String, Set<URI>>> e : groupedSources.entrySet()) {
             Transformer t = e.getKey();
-            Map<String,Set<URI>> srcs = e.getValue();
-            // These maps need to be synchronized since multiple threads will be writing results into them.
-            Map<String,Set<URI>> packageArtifacts =
-                    Collections.synchronizedMap(new HashMap<String,Set<URI>>());
-            Map<String,Set<String>> packageDependencies =
-                    Collections.synchronizedMap(new HashMap<String,Set<String>>());
-            Map<String,String> packagePublicApis =
-                    Collections.synchronizedMap(new HashMap<String, String>());
+            Map<String, Set<URI>> srcs = e.getValue();
+            // These maps need to be synchronized since multiple threads will be
+            // writing results into them.
+            Map<String, Set<URI>> packageArtifacts = Collections.synchronizedMap(new HashMap<>());
+            Map<String, Map<String, Set<String>>> packageDependencies = Collections.synchronizedMap(new HashMap<>());
+            Map<String, Map<String, Set<String>>> packageCpDependencies = Collections.synchronizedMap(new HashMap<>());
+            Map<String, PubApi> packagePublicApis = Collections.synchronizedMap(new HashMap<>());
+            Map<String, PubApi> dependencyPublicApis = Collections.synchronizedMap(new HashMap<>());
 
-            boolean  r = t.transform(sjavac,
-                                     srcs,
-                                     visibleSrcs,
-                                     visibleClasses,
-                                     prev.dependents(),
-                                     outputDir.toURI(),
-                                     packageArtifacts,
-                                     packageDependencies,
-                                     packagePublicApis,
-                                     0,
-                                     isIncremental(),
-                                     numCores,
-                                     out,
-                                     err);
-            if (!r) rc = false;
+            boolean r = t.transform(sjavac,
+                                    srcs,
+                                    visibleSrcs,
+                                    visibleClasses,
+                                    prev.dependents(),
+                                    outputDir.toURI(),
+                                    packageArtifacts,
+                                    packageDependencies,
+                                    packageCpDependencies,
+                                    packagePublicApis,
+                                    dependencyPublicApis,
+                                    0,
+                                    isIncremental(),
+                                    numCores,
+                                    out,
+                                    err);
+            if (!r)
+                rc = false;
 
             for (String p : srcs.keySet()) {
                 recompiledPackages.add(p);
             }
             // The transform is done! Extract all the artifacts and store the info into the Package objects.
-            for (Map.Entry<String,Set<URI>> a : packageArtifacts.entrySet()) {
+            for (Map.Entry<String, Set<URI>> a : packageArtifacts.entrySet()) {
                 Module mnow = now.findModuleFromPackageName(a.getKey());
                 mnow.addArtifacts(a.getKey(), a.getValue());
             }
             // Extract all the dependencies and store the info into the Package objects.
-            for (Map.Entry<String,Set<String>> a : packageDependencies.entrySet()) {
-                Set<String> deps = a.getValue();
+            for (Map.Entry<String, Map<String, Set<String>>> a : packageDependencies.entrySet()) {
+                Map<String, Set<String>> deps = a.getValue();
                 Module mnow = now.findModuleFromPackageName(a.getKey());
-                mnow.setDependencies(a.getKey(), deps);
+                mnow.setDependencies(a.getKey(), deps, false);
+            }
+            for (Map.Entry<String, Map<String, Set<String>>> a : packageCpDependencies.entrySet()) {
+                Map<String, Set<String>> deps = a.getValue();
+                Module mnow = now.findModuleFromPackageName(a.getKey());
+                mnow.setDependencies(a.getKey(), deps, true);
             }
-            // Extract all the pubapis and store the info into the Package objects.
-            for (Map.Entry<String,String> a : packagePublicApis.entrySet()) {
-                Module mprev = prev.findModuleFromPackageName(a.getKey());
-                List<String> pubapi = Package.pubapiToList(a.getValue());
-                Module mnow = now.findModuleFromPackageName(a.getKey());
-                mnow.setPubapi(a.getKey(), pubapi);
-                if (mprev.hasPubapiChanged(a.getKey(), pubapi)) {
+
+            // This map contains the public api of the types that this
+            // compilation depended upon. This means that it may not contain
+            // full packages. In other words, we shouldn't remove knowledge of
+            // public apis but merge these with what we already have.
+            for (Map.Entry<String, PubApi> a : dependencyPublicApis.entrySet()) {
+                String pkg = a.getKey();
+                PubApi packagePartialPubApi = a.getValue();
+                Package pkgNow = now.findModuleFromPackageName(pkg).lookupPackage(pkg);
+                PubApi currentPubApi = pkgNow.getPubApi();
+                PubApi newPubApi = PubApi.mergeTypes(currentPubApi, packagePartialPubApi);
+                pkgNow.setPubapi(newPubApi);
+
+                // See JDK-8071904
+                if (now.packages().containsKey(pkg))
+                    now.packages().get(pkg).setPubapi(newPubApi);
+                else
+                    now.packages().put(pkg, pkgNow);
+            }
+
+            // The packagePublicApis cover entire packages (since sjavac compiles
+            // stuff on package level). This means that if a type is missing
+            // in the public api of a given package, it means that it has been
+            // removed. In other words, we should *set* the pubapi to whatever
+            // this map contains, and not merge it with what we already have.
+            for (Map.Entry<String, PubApi> a : packagePublicApis.entrySet()) {
+                String pkg = a.getKey();
+                PubApi newPubApi = a.getValue();
+                Module mprev = prev.findModuleFromPackageName(pkg);
+                Module mnow = now.findModuleFromPackageName(pkg);
+                mnow.setPubapi(pkg, newPubApi);
+                if (mprev.hasPubapiChanged(pkg, newPubApi)) {
                     // Aha! The pubapi of this package has changed!
                     // It can also be a new compile from scratch.
-                    if (mprev.lookupPackage(a.getKey()).existsInJavacState()) {
+                    if (mprev.lookupPackage(pkg).existsInJavacState()) {
                         // This is an incremental compile! The pubapi
                         // did change. Trigger recompilation of dependents.
-                        packagesWithChangedPublicApis.add(a.getKey());
-                        Log.info("The pubapi of "+Util.justPackageName(a.getKey())+" has changed!");
+                        packagesWithChangedPublicApis.add(pkg);
+                        Log.info("The API of " + Util.justPackageName(pkg) + " has changed!");
                     }
                 }
             }
@@ -791,17 +923,21 @@
     }
 
     /**
-     * Compare the calculate source list, with an explicit list, usually supplied from the makefile.
-     * Used to detect bugs where the makefile and sjavac have different opinions on which files
-     * should be compiled.
+     * Compare the calculate source list, with an explicit list, usually
+     * supplied from the makefile. 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 {
-        // If we are building on win32 using for example cygwin the paths in the makefile source list
+    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.
+        // We need to adjust our calculated sources to be identical, if
+        // necessary.
         boolean mightNeedRewriting = File.pathSeparatorChar == ';';
 
-        if (makefileSourceList == null) return;
+        if (makefileSourceList == null)
+            return;
 
         Set<String> calculatedSources = new HashSet<>();
         Set<String> listedSources = new HashSet<>();
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Module.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Module.java	Tue Jun 09 15:57:45 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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,11 @@
 import java.io.File;
 import java.net.URI;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import com.sun.tools.sjavac.pubapi.PubApi;
+
 /**
  * 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.
@@ -86,8 +87,7 @@
         return new Module(name, "");
     }
 
-    public static void saveModules(Map<String,Module> ms, StringBuilder b)
-    {
+    public static void saveModules(Map<String,Module> ms, StringBuilder b) {
         for (Module m : ms.values()) {
             m.save(b);
         }
@@ -98,6 +98,7 @@
     }
 
     public Package lookupPackage(String pkg) {
+        // See JDK-8071904
         Package p = packages.get(pkg);
         if (p == null) {
             p = new Package(this, pkg);
@@ -124,18 +125,17 @@
         }
     }
 
-    public void setDependencies(String pkg, Set<String> deps) {
-        Package p = lookupPackage(pkg);
-        p.setDependencies(deps);
+    public void setDependencies(String pkg, Map<String, Set<String>> deps, boolean cp) {
+        lookupPackage(pkg).setDependencies(deps, cp);
     }
 
-    public void setPubapi(String pkg, List<String> ps) {
+    public void setPubapi(String pkg, PubApi ps) {
         Package p = lookupPackage(pkg);
         p.setPubapi(ps);
     }
 
-    public boolean hasPubapiChanged(String pkg, List<String> ps) {
+    public boolean hasPubapiChanged(String pkg, PubApi newPubApi) {
         Package p = lookupPackage(pkg);
-        return p.hasPubapiChanged(ps);
+        return p.hasPubApiChanged(newPubApi);
     }
 }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Package.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Package.java	Tue Jun 09 15:57:45 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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,11 +31,16 @@
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Stream;
+
 import com.sun.tools.javac.util.Assert;
+import com.sun.tools.sjavac.pubapi.PubApi;
 
 /**
  * The Package class maintains meta information about a package.
@@ -71,12 +76,16 @@
     // The directory path to the package. If the package belongs to a module,
     // then that module's file system name is part of the path.
     private String dirname;
-    // This package depends on these packages.
-    private Set<String> dependencies = new HashSet<>();
     // This package has the following dependents, that depend on this package.
     private Set<String> dependents = new HashSet<>();
+
+    // Fully qualified name of class in this package -> fully qualified name of dependency
+    private Map<String, Set<String>> dependencies = new TreeMap<>();
+    // Fully qualified name of class in this package -> fully qualified name of dependency on class path
+    private Map<String, Set<String>> cpDependencies = new TreeMap<>();
+
     // This is the public api of this package.
-    private List<String> pubapi = new ArrayList<>();
+    private PubApi pubApi = new PubApi();
     // Map from source file name to Source info object.
     private Map<String,Source> sources = new HashMap<>();
     // This package generated these artifacts.
@@ -85,7 +94,6 @@
     public Package(Module m, String n) {
         int c = n.indexOf(":");
         Assert.check(c != -1);
-        String mn = n.substring(0,c);
         Assert.check(m.name().equals(m.name()));
         name = n;
         dirname = n.replace('.', File.separatorChar);
@@ -100,9 +108,11 @@
     public String dirname() { return dirname; }
     public Map<String,Source> sources() { return sources; }
     public Map<String,File> artifacts() { return artifacts; }
-    public List<String> pubapi() { return pubapi; }
+    public PubApi getPubApi() { return pubApi; }
 
-    public Set<String> dependencies() { return dependencies; }
+    public Map<String,Set<String>> typeDependencies() { return dependencies; }
+    public Map<String,Set<String>> typeClasspathDependencies() { return cpDependencies; }
+
     public Set<String> dependents() { return dependents; }
 
     @Override
@@ -124,70 +134,48 @@
         sources.put(s.file().getPath(), s);
     }
 
-    public void addDependency(String d) {
-        dependencies.add(d);
+    private static Pattern DEP_PATTERN = Pattern.compile("(.*) -> (.*)");
+    public void parseAndAddDependency(String d, boolean cp) {
+        Matcher m = DEP_PATTERN.matcher(d);
+        if (!m.matches())
+            throw new IllegalArgumentException("Bad dependency string: " + d);
+        addDependency(m.group(1), m.group(2), cp);
+    }
+
+    public void addDependency(String fullyQualifiedFrom,
+                              String fullyQualifiedTo,
+                              boolean cp) {
+        Map<String, Set<String>> map = cp ? cpDependencies : dependencies;
+        if (!map.containsKey(fullyQualifiedFrom))
+            map.put(fullyQualifiedFrom, new HashSet<>());
+        map.get(fullyQualifiedFrom).add(fullyQualifiedTo);
     }
 
     public void addDependent(String d) {
         dependents.add(d);
     }
 
-    public void addPubapi(String p) {
-        pubapi.add(p);
-    }
-
     /**
      * Check if we have knowledge in the javac state that
      * describe the results of compiling this package before.
      */
     public boolean existsInJavacState() {
-        return artifacts.size() > 0 || pubapi.size() > 0;
+        return artifacts.size() > 0 || !pubApi.isEmpty();
     }
 
-    public static List<String> pubapiToList(String ps)
-    {
-        String[] lines = ps.split("\n");
-        List<String> r = new ArrayList<>();
-        for (String l : lines) {
-            r.add(l);
-        }
-        return r;
+    public boolean hasPubApiChanged(PubApi newPubApi) {
+        return !newPubApi.isBackwardCompatibleWith(pubApi);
     }
 
-    public boolean hasPubapiChanged(List<String> ps) {
-        Iterator<String> i = ps.iterator();
-        Iterator<String> j = pubapi.iterator();
-        int line = 0;
-        while (i.hasNext() && j.hasNext()) {
-            String is = i.next();
-            String js = j.next();
-            if (!is.equals(js)) {
-                Log.debug("Change in pubapi for package "+name+" line "+line);
-                Log.debug("Old: "+js);
-                Log.debug("New: "+is);
-                return true;
-            }
-            line++;
-        }
-        if ((i.hasNext() && !j.hasNext() ) ||
-            (!i.hasNext() && j.hasNext())) {
-            Log.debug("Change in pubapi for package "+name);
-            if (i.hasNext()) {
-                Log.debug("New has more lines!");
-            } else {
-                Log.debug("Old has more lines!");
-            }
-            return true;
-        }
-        return false;
+    public void setPubapi(PubApi newPubApi) {
+        pubApi = newPubApi;
     }
 
-    public void setPubapi(List<String> ps) {
-        pubapi = ps;
-    }
-
-    public void setDependencies(Set<String> ds) {
-        dependencies = ds;
+    public void setDependencies(Map<String, Set<String>> ds, boolean cp) {
+        (cp ? cpDependencies : dependencies).clear();
+        for (String fullyQualifiedFrom : ds.keySet())
+            for (String fullyQualifiedTo : ds.get(fullyQualifiedFrom))
+                addDependency(fullyQualifiedFrom, fullyQualifiedTo, cp);
     }
 
     public void save(StringBuilder b) {
@@ -203,31 +191,28 @@
         return new Package(module, name);
     }
 
-    public void loadDependency(String l) {
-        String n = l.substring(2);
-        addDependency(n);
-    }
+    public void saveDependencies(StringBuilder b) {
 
-    public void loadPubapi(String l) {
-        String pi = l.substring(2);
-        addPubapi(pi);
-    }
+        // Dependencies where *to* is among sources
+        for (String fullyQualifiedFrom : dependencies.keySet()) {
+            for (String fullyQualifiedTo : dependencies.get(fullyQualifiedFrom)) {
+                b.append(String.format("D S %s -> %s%n", fullyQualifiedFrom, fullyQualifiedTo));
+            }
+        }
 
-    public void saveDependencies(StringBuilder b) {
-        List<String> sorted_dependencies = new ArrayList<>();
-        for (String key : dependencies) {
-            sorted_dependencies.add(key);
-        }
-        Collections.sort(sorted_dependencies);
-        for (String a : sorted_dependencies) {
-            b.append("D "+a+"\n");
+        // Dependencies where *to* is on class path
+        for (String fullyQualifiedFrom : cpDependencies.keySet()) {
+            for (String fullyQualifiedTo : cpDependencies.get(fullyQualifiedFrom)) {
+                b.append(String.format("D C %s -> %s%n", fullyQualifiedFrom, fullyQualifiedTo));
+            }
         }
     }
 
     public void savePubapi(StringBuilder b) {
-        for (String l : pubapi) {
-            b.append("I "+l+"\n");
-        }
+        pubApi.asListOfStrings()
+              .stream()
+              .flatMap(l -> Stream.of("I ", l, "\n"))
+              .forEach(b::append);
     }
 
     public static void savePackages(Map<String,Package> packages, StringBuilder b) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/PubApiExtractor.java	Tue Jun 09 15:57:45 2015 +0200
@@ -0,0 +1,85 @@
+/*
+ * 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;
+
+import java.io.PrintWriter;
+import java.util.Arrays;
+
+import javax.tools.JavaCompiler.CompilationTask;
+import javax.tools.JavaFileManager;
+
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.code.ClassFinder;
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.main.JavaCompiler;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Name;
+import com.sun.tools.javac.util.Names;
+import com.sun.tools.sjavac.comp.PubapiVisitor;
+import com.sun.tools.sjavac.comp.SmartFileManager;
+import com.sun.tools.sjavac.options.Options;
+import com.sun.tools.sjavac.pubapi.PubApi;
+
+public class PubApiExtractor {
+    // Setup a compiler context for finding classes in the classpath
+    // and to execute annotation processors.
+    Context context;
+    CompilationTask task;
+
+    /**
+     * Setup a compilation context, used for reading public apis of classes on the classpath
+     * as well as annotation processors.
+     */
+    public PubApiExtractor(Options options) {
+        JavacTool compiler = com.sun.tools.javac.api.JavacTool.create();
+        SmartFileManager fileManager = new SmartFileManager(compiler.getStandardFileManager(null, null, null));
+        context = new com.sun.tools.javac.util.Context();
+        String[] args = options.prepJavacArgs();
+        task = compiler.getTask(new PrintWriter(System.err),
+                                fileManager,
+                                null,
+                                Arrays.asList(args),
+                                null,
+                                null,
+                                context);
+        // Trigger a creation of the JavaCompiler, necessary to get a sourceCompleter for ClassFinder.
+        // The sourceCompleter is used for build situations where a classpath class references other classes
+        // that happens to be on the sourcepath.
+        JavaCompiler.instance(context);
+
+//        context.put(JavaFileManager.class, fileManager);
+    }
+
+    public PubApi getPubApi(String fullyQualifiedClassName) {
+        ClassFinder cr = ClassFinder.instance(context);
+        Names ns = Names.instance(context);
+        Name n = ns.fromString(fullyQualifiedClassName);
+        ClassSymbol cs = cr.loadClass(n);
+        PubapiVisitor v = new PubapiVisitor();
+        v.visit(cs);
+        return v.getCollectedPubApi();
+    }
+}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Source.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Source.java	Tue Jun 09 15:57:45 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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
@@ -373,8 +373,6 @@
         return currentModule;
     }
 
-    private static boolean gurka = false;
-
     static private void scanDirectory(File dir, int rootPrefix, File root,
                                       Set<String> suffixes,
                                       List<String> excludes, List<String> includes,
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Transformer.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Transformer.java	Tue Jun 09 15:57:45 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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,10 +27,11 @@
 
 import java.io.PrintStream;
 import java.net.URI;
+import java.util.Map;
 import java.util.Set;
-import java.util.Map;
 
 import com.sun.tools.sjavac.options.Options;
+import com.sun.tools.sjavac.pubapi.PubApi;
 import com.sun.tools.sjavac.server.Sjavac;
 
 /**
@@ -89,8 +90,10 @@
                       Map<String,Set<String>> oldPackageDependencies,
                       URI destRoot,
                       Map<String,Set<URI>>    packageArtifacts,
-                      Map<String,Set<String>> packageDependencies,
-                      Map<String,String>      packagePublicApis,
+                      Map<String, Map<String, Set<String>>> packageDependencies,   // Package name -> Fully Qualified Type [from] -> Set of fully qualified type [to]
+                      Map<String, Map<String, Set<String>>> packageCpDependencies, // Package name -> Fully Qualified Type [from] -> Set of fully qualified type [to]
+                      Map<String, PubApi>     packagePublicApis,
+                      Map<String, PubApi>     dependencyApis,
                       int debugLevel,
                       boolean incremental,
                       int numCores,
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Util.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Util.java	Tue Jun 09 15:57:45 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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,9 +30,13 @@
 import java.io.StringWriter;
 import java.nio.file.Path;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
 import java.util.StringTokenizer;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 /**
  * Utilities.
@@ -107,6 +111,20 @@
     }
 
     /**
+     * Extract the package name from a fully qualified class name.
+     *
+     * Example: Given "pkg.subpkg.A" this method returns ":pkg.subpkg".
+     * Given "C" this method returns ":".
+     *
+     * @returns package name of the given class name
+     */
+    public static String pkgNameOfClassName(String fqClassName) {
+        int i = fqClassName.lastIndexOf('.');
+        String pkg = i == -1 ? "" : fqClassName.substring(0, i);
+        return ":" + pkg;
+    }
+
+    /**
      * Clean out unwanted sub options supplied inside a primary option.
      * For example to only had portfile remaining from:
      *    settings="--server:id=foo,portfile=bar"
@@ -183,6 +201,13 @@
         return union;
     }
 
+    public static <E> Set<E> subtract(Set<? extends E> orig,
+                                      Set<? extends E> toSubtract) {
+        Set<E> difference = new HashSet<>(orig);
+        difference.removeAll(toSubtract);
+        return difference;
+    }
+
     public static String getStackTrace(Throwable t) {
         StringWriter sw = new StringWriter();
         t.printStackTrace(new PrintWriter(sw));
@@ -193,4 +218,16 @@
     public static File pathToFile(Path path) {
         return path == null ? null : path.toFile();
     }
+
+    public static <E> Set<E> intersection(Collection<? extends E> c1,
+                                          Collection<? extends E> c2) {
+        Set<E> intersection = new HashSet<E>(c1);
+        intersection.retainAll(c2);
+        return intersection;
+    }
+
+    public static <I, T> Map<I, T> indexBy(Collection<? extends T> c,
+                                           Function<? super T, ? extends I> indexFunction) {
+        return c.stream().collect(Collectors.toMap(indexFunction, o -> o));
+    }
 }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/ClientMain.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/ClientMain.java	Tue Jun 09 15:57:45 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, 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
@@ -93,6 +93,11 @@
         if (hdrdir != null && !createIfMissing(hdrdir))
             return -1;
 
+        Log.debug("==========================================================");
+        Log.debug("Launching sjavac client with the following parameters:");
+        Log.debug("    " + options.getStateArgsString());
+        Log.debug("==========================================================");
+
         // Load the prev build state database.
         JavacState javac_state = JavacState.load(options, out, err);
 
@@ -167,6 +172,9 @@
         javac_state.now().checkInternalState("checking linked sources", true, sources_to_link_to);
         javac_state.setVisibleSources(sources_to_link_to);
 
+        int round = 0;
+        printRound(round);
+
         // If there is any change in the source files, taint packages
         // and mark the database in need of saving.
         javac_state.checkSourceStatus(false);
@@ -188,6 +196,10 @@
         // Go through all sources and taint all packages that miss artifacts.
         javac_state.taintPackagesThatMissArtifacts();
 
+        // Check recorded classpath public apis. Taint packages that depend on
+        // classpath classes whose public apis have changed.
+        javac_state.taintPackagesDependingOnChangedClasspathPackages();
+
         // Now clean out all known artifacts belonging to tainted packages.
         javac_state.deleteClassArtifactsInTaintedPackages();
         // Copy files, for example property files, images files, xml files etc etc.
@@ -231,11 +243,22 @@
             }
 
             do {
+                if (round > 0)
+                    printRound(round);
                 // Clean out artifacts in tainted packages.
                 javac_state.deleteClassArtifactsInTaintedPackages();
                 again = javac_state.performJavaCompilations(sjavac, options, recently_compiled, rc);
-                if (!rc[0]) break;
+                if (!rc[0]) {
+                    Log.debug("Compilation failed.");
+                    break;
+                }
+                if (!again) {
+                    Log.debug("Nothing left to do.");
+                }
+                round++;
             } while (again);
+            Log.debug("No need to do another round.");
+
             // Only update the state if the compile went well.
             if (rc[0]) {
                 javac_state.save();
@@ -323,4 +346,10 @@
         }
     }
 
+    private static void printRound(int round) {
+        Log.debug("****************************************");
+        Log.debug("* Round " + round + "                              *");
+        Log.debug("****************************************");
+    }
+
 }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/Dependencies.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,181 +0,0 @@
-/*
- * Copyright (c) 1999, 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 javax.lang.model.element.Element;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-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;
-
-/** 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>
- */
-public class Dependencies {
-    protected static final Context.Key<Dependencies> dependenciesKey = new Context.Key<>();
-
-    // The log to be used for error reporting.
-    protected Log log;
-    // Map from package name to packages that the package depends upon.
-    protected Map<Name,Set<Name>> deps;
-    // This is the set of all packages that are supplied
-    // through the java files at the command line.
-    protected Set<Name> explicitPackages;
-
-    // Map from a package name to its public api.
-    // Will the Name encode the module in the future?
-    // If not, this will have to change to map from Module+Name to public api.
-    protected Map<Name,StringBuffer> publicApiPerClass;
-
-    public static Dependencies instance(Context context) {
-        Dependencies instance = context.get(dependenciesKey);
-        if (instance == null)
-            instance = new Dependencies(context);
-        return instance;
-    }
-
-    private Dependencies(Context context) {
-        context.put(dependenciesKey, this);
-        log = Log.instance(context);
-        deps = new HashMap<>();
-        explicitPackages = new HashSet<>();
-        publicApiPerClass = new HashMap<>();
-    }
-
-    /**
-     * Fetch the set of dependencies that are relevant to the compile
-     * that has just been performed. I.e. we are only interested in
-     * dependencies for classes that were explicitly compiled.
-     * @return
-     */
-    public Map<String,Set<String>> getDependencies() {
-        Map<String,Set<String>> new_deps = new HashMap<>();
-        if (explicitPackages == null) return new_deps;
-        for (Name pkg : explicitPackages) {
-            Set<Name> set = deps.get(pkg);
-            if (set != null) {
-                Set<String> new_set = new_deps.get(pkg.toString());
-                if (new_set == null) {
-                    new_set = new HashSet<>();
-                    // Modules beware....
-                    new_deps.put(":"+pkg.toString(), new_set);
-                }
-                for (Name d : set) {
-                    new_set.add(":"+d.toString());
-                }
-            }
-        }
-        return new_deps;
-    }
-
-    static class CompareNames implements Comparator<Name> {
-         public int compare(Name a, Name b) {
-             return a.toString().compareTo(b.toString());
-         }
-
-    }
-
-    /**
-     * Convert the map from class names to their pubapi to a map
-     * from package names to their pubapi (which is the sorted concatenation
-     * of all the class pubapis)
-     */
-    public Map<String,String> getPubapis() {
-        Map<String,String> publicApiPerPackage = new HashMap<>();
-        if (publicApiPerClass == null) return publicApiPerPackage;
-        Name[] keys = publicApiPerClass.keySet().toArray(new Name[0]);
-        Arrays.sort(keys, new CompareNames());
-        StringBuffer newPublicApi = new StringBuffer();
-        int i=0;
-        String prevPkg = "";
-        for (Name k : keys) {
-            String cn = k.toString();
-            String pn = "";
-            int dp = cn.lastIndexOf('.');
-            if (dp != -1) {
-                pn = cn.substring(0,dp);
-            }
-            if (!pn.equals(prevPkg)) {
-                if (!prevPkg.equals("")) {
-                    // Add default module name ":"
-                    publicApiPerPackage.put(":"+prevPkg, newPublicApi.toString());
-                }
-                newPublicApi = new StringBuffer();
-                prevPkg = pn;
-            }
-            newPublicApi.append(publicApiPerClass.get(k));
-            i++;
-        }
-        if (!prevPkg.equals(""))
-            publicApiPerPackage.put(":"+prevPkg, newPublicApi.toString());
-        return publicApiPerPackage;
-    }
-
-    /**
-     * Visit the api of a class and construct a pubapi string and
-     * store it into the pubapi_perclass map.
-     */
-    public void visitPubapi(Element e) {
-        Name n = ((ClassSymbol)e).fullname;
-        Name p = ((ClassSymbol)e).packge().fullname;
-        StringBuffer sb = publicApiPerClass.get(n);
-        Assert.check(sb == null);
-        sb = new StringBuffer();
-        PubapiVisitor v = new PubapiVisitor(sb);
-        v.visit(e);
-        if (sb.length()>0) {
-            publicApiPerClass.put(n, sb);
-        }
-        explicitPackages.add(p);
-     }
-
-    /**
-     * Collect a dependency. curr_pkg is marked as depending on dep_pkg.
-     */
-    public void collect(Name currPkg, Name depPkg) {
-        if (!currPkg.equals(depPkg)) {
-            Set<Name> theset = deps.get(currPkg);
-            if (theset==null) {
-                theset = new HashSet<>();
-                deps.put(currPkg, theset);
-            }
-            theset.add(depPkg);
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/FileObjectWithLocation.java	Tue Jun 09 15:57:45 2015 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014, 2015, 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 javax.tools.FileObject;
+import javax.tools.ForwardingFileObject;
+import javax.tools.JavaFileManager.Location;
+
+import com.sun.tools.javac.api.ClientCodeWrapper.Trusted;
+
+@Trusted
+public class FileObjectWithLocation<F extends FileObject> extends ForwardingFileObject<F> {
+
+    private final Location loc;
+
+    public FileObjectWithLocation(F delegate, Location loc) {
+        super(delegate);
+        this.loc = loc;
+    }
+
+    public Location getLocation() {
+        return loc;
+    }
+
+    public FileObject getDelegate() {
+        return fileObject;
+    }
+
+    public String toString() {
+        return "FileObjectWithLocation[" + fileObject + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/JavaFileObjectWithLocation.java	Tue Jun 09 15:57:45 2015 +0200
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2014, 2015, 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 javax.tools.ForwardingJavaFileObject;
+import javax.tools.JavaFileManager.Location;
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.javac.api.ClientCodeWrapper.Trusted;
+
+@Trusted
+public class JavaFileObjectWithLocation<F extends JavaFileObject> extends ForwardingJavaFileObject<F> {
+
+    private final Location loc;
+
+    public JavaFileObjectWithLocation(F delegate, Location loc) {
+        super(delegate);
+        this.loc = loc;
+    }
+
+    public Location getLocation() {
+        return loc;
+    }
+
+    public F getDelegate() {
+        return fileObject;
+    }
+
+    public String toString() {
+        return "JavaFileObjectWithLocation[loc: " + loc + ", " + fileObject + "]";
+    }
+
+    @Override
+    public int hashCode() {
+        return loc.hashCode() ^ fileObject.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof JavaFileObjectWithLocation))
+            return false;
+        JavaFileObjectWithLocation<?> other = (JavaFileObjectWithLocation<?>) obj;
+        return loc.equals(other.loc) && fileObject.equals(other.fileObject);
+    }
+}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/PathAndPackageVerifier.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/PathAndPackageVerifier.java	Tue Jun 09 15:57:45 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, 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
@@ -41,6 +41,7 @@
 import com.sun.tools.javac.util.DefinedBy;
 import com.sun.tools.javac.util.DefinedBy.Api;
 import com.sun.tools.javac.util.Name;
+import com.sun.tools.sjavac.Log;
 
 public class PathAndPackageVerifier implements TaskListener {
 
@@ -50,30 +51,37 @@
 
     @Override
     @DefinedBy(Api.COMPILER_TREE)
-    public void started(TaskEvent e) {
+    public void finished(TaskEvent e) {
+        if (e.getKind() == TaskEvent.Kind.ANALYZE) {
+
+            CompilationUnitTree cu = e.getCompilationUnit();
+            if (cu == null)
+                return;
+
+            JavaFileObject jfo = cu.getSourceFile();
+            if (jfo == null)
+                return; // No source file -> package doesn't matter
+
+            JCTree pkg = (JCTree) cu.getPackageName();
+            if (pkg == null)
+                return; // Default package. See JDK-8048144.
+
+            Path dir = Paths.get(jfo.toUri()).normalize().getParent();
+            if (!checkPathAndPackage(dir, pkg))
+                misplacedCompilationUnits.add(cu);
+        }
+
+        if (e.getKind() == TaskEvent.Kind.COMPILATION) {
+            for (CompilationUnitTree cu : misplacedCompilationUnits) {
+                Log.error("Misplaced compilation unit.");
+                Log.error("    Directory: " + Paths.get(cu.getSourceFile().toUri()).getParent());
+                Log.error("    Package:   " + cu.getPackageName());
+            }
+        }
     }
 
-    @Override
-    @DefinedBy(Api.COMPILER_TREE)
-    public void finished(TaskEvent e) {
-        if (e.getKind() != TaskEvent.Kind.ANALYZE)
-            return;
-
-        CompilationUnitTree cu = e.getCompilationUnit();
-        if (cu == null)
-            return;
-
-        JavaFileObject jfo = cu.getSourceFile();
-        if (jfo == null)
-            return; // No source file -> package doesn't matter
-
-        JCTree pkg = (JCTree) cu.getPackageName();
-        if (pkg == null)
-            return; // Default package. See JDK-8048144.
-
-        Path dir = Paths.get(jfo.toUri()).normalize().getParent();
-        if (!checkPathAndPackage(dir, pkg))
-            misplacedCompilationUnits.add(cu);
+    public boolean errorsDiscovered() {
+        return misplacedCompilationUnits.size() > 0;
     }
 
     /* Returns true if dir matches pkgName.
@@ -94,10 +102,6 @@
         return !pkgIter.hasNext(); /*&& !pathIter.hasNext() See JDK-8059598 */
     }
 
-    public Set<CompilationUnitTree> getMisplacedCompilationUnits() {
-        return misplacedCompilationUnits;
-    }
-
     /* Iterates over the names of the parents of the given path:
      * Example: dir1/dir2/dir3  results in  dir3 -> dir2 -> dir1
      */
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/PooledSjavac.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/PooledSjavac.java	Tue Jun 09 15:57:45 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, 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,12 +29,9 @@
 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;
@@ -58,28 +55,13 @@
     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;
-            }
-        });
+        pool = Executors.newFixedThreadPool(poolsize);
     }
 
     @Override
     public SysInfo getSysInfo() {
         try {
-            return pool.submit(new Callable<SysInfo>() {
-                @Override
-                public SysInfo call() throws Exception {
-                    return delegate.getSysInfo();
-                }
-            }).get();
+            return pool.submit(() -> delegate.getSysInfo()).get();
         } catch (Exception e) {
             e.printStackTrace();
             throw new RuntimeException("Error during getSysInfo", e);
@@ -94,16 +76,13 @@
                                      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);
-                }
+            return pool.submit(() -> {
+                return delegate.compile(protocolId,
+                                        invocationId,
+                                        args,
+                                        explicitSources,
+                                        sourcesToCompile,
+                                        visibleSources);
             }).get();
         } catch (Exception e) {
             e.printStackTrace();
@@ -113,6 +92,7 @@
 
     @Override
     public void shutdown() {
+        Log.debug("Shutting down PooledSjavac");
         pool.shutdown(); // Disable new tasks from being submitted
         try {
             // Wait a while for existing tasks to terminate
@@ -122,8 +102,6 @@
                 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();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/PubAPIs.java	Tue Jun 09 15:57:45 2015 +0200
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 1999, 2015, 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.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.lang.model.element.Element;
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.sjavac.pubapi.PubApi;
+
+/**
+ * Utility class containing public API information.
+ *
+ *  <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 PubAPIs {
+    protected static final Context.Key<PubAPIs> pubApisKey = new Context.Key<>();
+
+    // The log to be used for error reporting.
+    protected Log log;
+
+    // Map from a class name to its public api.
+    // Will the Name encode the module in the future?
+    // If not, this will have to change to map from Module+Name to public api.
+    protected Map<ClassSymbol, PubApi> publicApiPerClass = new HashMap<>();
+
+    public static PubAPIs instance(Context context) {
+        PubAPIs instance = context.get(pubApisKey);
+        if (instance == null)
+            instance = new PubAPIs(context);
+        return instance;
+    }
+
+    private PubAPIs(Context context) {
+        context.put(pubApisKey, this);
+        log = Log.instance(context);
+    }
+
+    /**
+     * Convert the map from class names to their pubapi to a map
+     * from package names to their pubapi.
+     */
+    public Map<String, PubApi> getPubapis(Collection<JavaFileObject> explicitJFOs, boolean explicits) {
+
+        // Maps ":java.lang" to a package level pub api (with only types on top level)
+        Map<String, PubApi> result = new HashMap<>();
+        for (ClassSymbol cs : publicApiPerClass.keySet()) {
+
+            boolean amongExplicits = explicitJFOs.contains(cs.sourcefile);
+            if (explicits != amongExplicits)
+                continue;
+
+            String pkg = ":" + cs.packge().fullname;
+            PubApi currentPubApi = result.getOrDefault(pkg, new PubApi());
+            result.put(pkg, PubApi.mergeTypes(currentPubApi, publicApiPerClass.get(cs)));
+        }
+
+        return result;
+    }
+
+    /**
+     * Visit the api of a class and construct a pubapi and
+     * store it into the pubapi_perclass map.
+     */
+    @SuppressWarnings("deprecation")
+    public void visitPubapi(Element e) {
+
+        // Skip anonymous classes for now
+        if (e == null)
+            return;
+
+        PubapiVisitor v = new PubapiVisitor();
+        v.visit(e);
+        publicApiPerClass.put((ClassSymbol) e, v.getCollectedPubApi());
+    }
+}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/PubapiVisitor.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/PubapiVisitor.java	Tue Jun 09 15:57:45 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, 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,17 +25,28 @@
 
 package com.sun.tools.sjavac.comp;
 
-import java.util.Iterator;
+import static javax.lang.model.element.Modifier.PRIVATE;
+
 import java.util.List;
-import javax.lang.model.element.Modifier;
+import java.util.stream.Collectors;
+
+import javax.lang.model.element.Element;
 import javax.lang.model.element.ExecutableElement;
 import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.TypeParameterElement;
 import javax.lang.model.element.VariableElement;
 import javax.lang.model.type.TypeMirror;
 import javax.lang.model.util.ElementScanner9;
 
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
 import com.sun.tools.javac.util.DefinedBy;
 import com.sun.tools.javac.util.DefinedBy.Api;
+import com.sun.tools.sjavac.pubapi.PubApi;
+import com.sun.tools.sjavac.pubapi.PubApiTypeParam;
+import com.sun.tools.sjavac.pubapi.PubMethod;
+import com.sun.tools.sjavac.pubapi.PubType;
+import com.sun.tools.sjavac.pubapi.PubVar;
+import com.sun.tools.sjavac.pubapi.TypeDesc;
 
 /** Utility class that constructs a textual representation
  * of the public api of a class.
@@ -47,40 +58,67 @@
  */
 public class PubapiVisitor extends ElementScanner9<Void, Void> {
 
-    StringBuffer sb;
-    // Important that it is 1! Part of protocol over wire, silly yes.
-    // Fix please.
-    int indent = 1;
+    private PubApi collectedApi = new PubApi();
 
-    public PubapiVisitor(StringBuffer sb) {
-        this.sb = sb;
-    }
-
-    String depth(int l) {
-        return "                                              ".substring(0, l);
+    private boolean isNonPrivate(Element e) {
+        return !e.getModifiers().contains(PRIVATE);
     }
 
     @Override @DefinedBy(Api.LANGUAGE_MODEL)
     public Void visitType(TypeElement e, Void p) {
-        if (e.getModifiers().contains(Modifier.PUBLIC)
-            || e.getModifiers().contains(Modifier.PROTECTED))
-        {
-            sb.append(depth(indent) + "TYPE " + e.getQualifiedName() + "\n");
-            indent += 2;
-            Void v = super.visitType(e, p);
-            indent -= 2;
-            return v;
+        if (isNonPrivate(e)) {
+            PubApi prevApi = collectedApi;
+            collectedApi = new PubApi();
+            super.visitType(e, p);
+            if (!isAnonymous(e)) {
+                String name = ((ClassSymbol) e).flatname.toString();
+                PubType t = new PubType(e.getModifiers(),
+                                        name,
+                                        //e.getQualifiedName().toString(),
+                                        collectedApi);
+                prevApi.types.put(t.fqName, t);
+            }
+            collectedApi = prevApi;
         }
         return null;
     }
 
+    private boolean isAnonymous(TypeElement e) {
+        return e.getQualifiedName().length() == 0;
+    }
+
+    private static String encodeChar(int c) {
+        return String.format("\\u%04x", c);
+    }
+
     @Override @DefinedBy(Api.LANGUAGE_MODEL)
     public Void visitVariable(VariableElement e, Void p) {
-        if (e.getModifiers().contains(Modifier.PUBLIC)
-            || e.getModifiers().contains(Modifier.PROTECTED)) {
-            sb.append(depth(indent)).append("VAR ")
-                    .append(makeVariableString(e)).append("\n");
+        if (isNonPrivate(e)) {
+            Object constVal = e.getConstantValue();
+            String constValStr = null;
+            // TODO: This doesn't seem to be entirely accurate. What if I change
+            // from, say, 0 to 0L? (And the field is public final static so that
+            // it could get inlined.)
+            if (constVal != null) {
+                if (e.asType().toString().equals("char")) {
+                    // What type is 'value'? Is it already a char?
+                    char c = constVal.toString().charAt(0);
+                    constValStr = "'" + encodeChar(c) + "'";
+                } else {
+                    constValStr = constVal.toString()
+                                          .chars()
+                                          .mapToObj(PubapiVisitor::encodeChar)
+                                          .collect(Collectors.joining("", "\"", "\""));
+                }
+            }
+
+            PubVar v = new PubVar(e.getModifiers(),
+                                  TypeDesc.fromType(e.asType()),
+                                  e.toString(),
+                                  constValStr);
+            collectedApi.variables.put(v.identifier, v);
         }
+
         // Safe to not recurse here, because the only thing
         // to visit here is the constructor of a variable declaration.
         // If it happens to contain an anonymous inner class (which it might)
@@ -91,70 +129,38 @@
 
     @Override @DefinedBy(Api.LANGUAGE_MODEL)
     public Void visitExecutable(ExecutableElement e, Void p) {
-        if (e.getModifiers().contains(Modifier.PUBLIC)
-            || e.getModifiers().contains(Modifier.PROTECTED)) {
-            sb.append(depth(indent)).append("METHOD ")
-                    .append(makeMethodString(e)).append("\n");
+        if (isNonPrivate(e)) {
+            PubMethod m = new PubMethod(e.getModifiers(),
+                                        getTypeParameters(e.getTypeParameters()),
+                                        TypeDesc.fromType(e.getReturnType()),
+                                        e.getSimpleName().toString(),
+                                        getTypeDescs(getParamTypes(e)),
+                                        getTypeDescs(e.getThrownTypes()));
+            collectedApi.methods.put(m.asSignatureString(), m);
         }
         return null;
     }
 
-    /**
-     * Creates a String representation of a method element with everything
-     * necessary to track all public aspects of it in an API.
-     * @param e Element to create String for.
-     * @return String representation of element.
-     */
-    protected String makeMethodString(ExecutableElement e) {
-        StringBuilder result = new StringBuilder();
-        for (Modifier modifier : e.getModifiers()) {
-            result.append(modifier.toString());
-            result.append(" ");
-        }
-        result.append(e.getReturnType().toString());
-        result.append(" ");
-        result.append(e.toString());
-
-        List<? extends TypeMirror> thrownTypes = e.getThrownTypes();
-        if (!thrownTypes.isEmpty()) {
-            result.append(" throws ");
-            for (Iterator<? extends TypeMirror> iterator = thrownTypes
-                    .iterator(); iterator.hasNext();) {
-                TypeMirror typeMirror = iterator.next();
-                result.append(typeMirror.toString());
-                if (iterator.hasNext()) {
-                    result.append(", ");
-                }
-            }
-        }
-        return result.toString();
+    private List<PubApiTypeParam> getTypeParameters(List<? extends TypeParameterElement> elements) {
+        return elements.stream()
+                       .map(e -> new PubApiTypeParam(e.getSimpleName().toString(), getTypeDescs(e.getBounds())))
+                       .collect(Collectors.toList());
     }
 
-    /**
-     * Creates a String representation of a variable element with everything
-     * necessary to track all public aspects of it in an API.
-     * @param e Element to create String for.
-     * @return String representation of element.
-     */
-    protected String makeVariableString(VariableElement e) {
-        StringBuilder result = new StringBuilder();
-        for (Modifier modifier : e.getModifiers()) {
-            result.append(modifier.toString());
-            result.append(" ");
-        }
-        result.append(e.asType().toString());
-        result.append(" ");
-        result.append(e.toString());
-        Object value = e.getConstantValue();
-        if (value != null) {
-            result.append(" = ");
-            if (e.asType().toString().equals("char")) {
-                int v = (int)value.toString().charAt(0);
-                result.append("'\\u"+Integer.toString(v,16)+"'");
-            } else {
-                result.append(value.toString());
-            }
-        }
-        return result.toString();
+    private List<TypeMirror> getParamTypes(ExecutableElement e) {
+        return e.getParameters()
+                .stream()
+                .map(VariableElement::asType)
+                .collect(Collectors.toList());
+    }
+
+    private List<TypeDesc> getTypeDescs(List<? extends TypeMirror> list) {
+        return list.stream()
+                   .map(TypeDesc::fromType)
+                   .collect(Collectors.toList());
+    }
+
+    public PubApi getCollectedPubApi() {
+        return collectedApi;
     }
 }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SjavacImpl.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SjavacImpl.java	Tue Jun 09 15:57:45 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, 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,24 +29,25 @@
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.net.URI;
-import java.nio.file.Paths;
 import java.util.Arrays;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 
 import javax.tools.JavaFileObject;
 import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
 
-import com.sun.source.tree.CompilationUnitTree;
 import com.sun.tools.javac.api.JavacTaskImpl;
 import com.sun.tools.javac.api.JavacTool;
-import com.sun.tools.javac.code.Symbol.ClassSymbol;
-import com.sun.tools.javac.code.Symbol.PackageSymbol;
 import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Dependencies;
 import com.sun.tools.javac.util.ListBuffer;
 import com.sun.tools.javac.util.Options;
+import com.sun.tools.sjavac.Log;
 import com.sun.tools.sjavac.Util;
-import com.sun.tools.sjavac.comp.dependencies.DependencyCollector;
+import com.sun.tools.sjavac.comp.dependencies.NewDependencyCollector;
 import com.sun.tools.sjavac.comp.dependencies.PublicApiCollector;
 import com.sun.tools.sjavac.server.CompilationResult;
 import com.sun.tools.sjavac.server.Sjavac;
@@ -76,86 +77,79 @@
                                      List<File> explicitSources,
                                      Set<URI> sourcesToCompile,
                                      Set<URI> visibleSources) {
-        JavacTool compiler = JavacTool.create();
-        try (StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null)) {
-            SmartFileManager smartFileManager = new SmartFileManager(fileManager);
+
+        JavacTool compiler = (JavacTool) ToolProvider.getSystemJavaCompiler();
+        try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) {
+            SmartFileManager sfm = new SmartFileManager(fm);
             Context context = new Context();
 
-            // Now setup the actual compilation....
+            Dependencies.GraphDependencies.preRegister(context);
+
+            // 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);
+            // First deal with explicit source files on cmdline and in at file
+            ListBuffer<JavaFileObject> explicitJFOs = new ListBuffer<>();
+            for (JavaFileObject jfo : fm.getJavaFileObjectsFromFiles(explicitSources)) {
+                explicitJFOs.append(SmartFileManager.locWrap(jfo, StandardLocation.SOURCE_PATH));
             }
-            // Now deal with sources supplied as source_to_compile.
+            // Now deal with sources supplied as source_to_compile
             ListBuffer<File> sourcesToCompileFiles = new ListBuffer<>();
-            for (URI u : sourcesToCompile) {
+            for (URI u : sourcesToCompile)
                 sourcesToCompileFiles.append(new File(u));
-            }
-            for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(sourcesToCompileFiles)) {
-                compilationUnits.append(i);
-            }
 
-            // Create a new logger.
+            for (JavaFileObject jfo : fm.getJavaFileObjectsFromFiles(sourcesToCompileFiles))
+                explicitJFOs.append(SmartFileManager.locWrap(jfo, StandardLocation.SOURCE_PATH));
+
+            // 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;
-            DependencyCollector depsCollector = new DependencyCollector();
-            PublicApiCollector pubApiCollector = new PublicApiCollector();
+            PublicApiCollector pubApiCollector = new PublicApiCollector(context, explicitJFOs);
             PathAndPackageVerifier papVerifier = new PathAndPackageVerifier();
+            NewDependencyCollector depsCollector = new NewDependencyCollector(context, explicitJFOs);
             try {
-                if (compilationUnits.size() > 0) {
-                    smartFileManager.setVisibleSources(visibleSources);
-                    smartFileManager.cleanArtifacts();
-                    smartFileManager.setLog(stdout);
+                if (explicitJFOs.size() > 0) {
+                    sfm.setVisibleSources(visibleSources);
+                    sfm.cleanArtifacts();
+                    sfm.setLog(stdout);
 
                     // Do the compilation!
                     JavacTaskImpl task =
                             (JavacTaskImpl) compiler.getTask(stderr,
-                                                             smartFileManager,
+                                                             sfm,
                                                              null,
                                                              Arrays.asList(args),
                                                              null,
-                                                             compilationUnits,
+                                                             explicitJFOs,
                                                              context);
-                    smartFileManager.setSymbolFileEnabled(!Options.instance(context).isSet("ignore.symbol.file"));
+                    sfm.setSymbolFileEnabled(!Options.instance(context).isSet("ignore.symbol.file"));
                     task.addTaskListener(depsCollector);
                     task.addTaskListener(pubApiCollector);
                     task.addTaskListener(papVerifier);
+                    logJavacInvocation(args);
                     rc = task.doCall();
-                    smartFileManager.flush();
+                    Log.debug("javac returned with code " + rc);
+                    sfm.flush();
                 }
             } catch (Exception e) {
+                Log.error(Util.getStackTrace(e));
                 stderrLog.append(Util.getStackTrace(e));
                 rc = com.sun.tools.javac.main.Main.Result.ERROR;
             }
 
-            compilationResult.packageArtifacts = smartFileManager.getPackageArtifacts();
+            compilationResult.packageArtifacts = sfm.getPackageArtifacts();
 
-            Dependencies deps = Dependencies.instance(context);
-            for (PackageSymbol from : depsCollector.getSourcePackages()) {
-                for (PackageSymbol to : depsCollector.getDependenciesForPkg(from))
-                    deps.collect(from.fullname, to.fullname);
-            }
-
-            for (ClassSymbol cs : pubApiCollector.getClassSymbols())
-                deps.visitPubapi(cs);
+            if (papVerifier.errorsDiscovered())
+                rc = com.sun.tools.javac.main.Main.Result.ERROR;
 
-            if (papVerifier.getMisplacedCompilationUnits().size() > 0) {
-                for (CompilationUnitTree cu : papVerifier.getMisplacedCompilationUnits()) {
-                    System.err.println("Misplaced compilation unit.");
-                    System.err.println("    Directory: " + Paths.get(cu.getSourceFile().toUri()).getParent());
-                    System.err.println("    Package:   " + cu.getPackageName());
-                }
-                rc = com.sun.tools.javac.main.Main.Result.ERROR;
-            }
+            compilationResult.packageDependencies = depsCollector.getDependencies(false);
+            compilationResult.packageCpDependencies = depsCollector.getDependencies(true);
 
-            compilationResult.packageDependencies = deps.getDependencies();
-            compilationResult.packagePubapis = deps.getPubapis();
+            compilationResult.packagePubapis = pubApiCollector.getPubApis(true);     // pubApis.getPubapis(explicitJFOs, true);
+            compilationResult.dependencyPubapis = pubApiCollector.getPubApis(false); // pubApis.getPubapis(explicitJFOs, false);
             compilationResult.stdout = stdoutLog.toString();
             compilationResult.stderr = stderrLog.toString();
             compilationResult.returnCode = rc.exitCode;
@@ -172,10 +166,22 @@
         // ... maybe we should wait for any current request to finish?
     }
 
-
     @Override
     public String serverSettings() {
         return "";
     }
 
+    private void logJavacInvocation(String[] args) {
+        Log.debug("Invoking javac with args");
+        Iterator<String> argIter = Arrays.asList(args).iterator();
+        while (argIter.hasNext()) {
+            String arg = argIter.next();
+            String line = "    " + arg;
+            if (arg.matches("\\-(d|cp|classpath|sourcepath|source|target)")
+                    && argIter.hasNext()) {
+                line += " " + argIter.next();
+            }
+            Log.debug(line);
+        }
+    }
 }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SmartFileManager.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SmartFileManager.java	Tue Jun 09 15:57:45 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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
@@ -91,6 +91,12 @@
         ((JavacFileManager) fileManager).setSymbolFileEnabled(b);
     }
 
+    @DefinedBy(Api.COMPILER)
+    public String inferBinaryName(Location location, JavaFileObject file) {
+        return super.inferBinaryName(location, locUnwrap(file));
+    }
+
+
     public Map<String,Set<URI>> getPackageArtifacts() {
         return packageArtifacts;
     }
@@ -100,10 +106,11 @@
                                          String packageName,
                                          Set<Kind> kinds,
                                          boolean recurse) throws IOException {
+        // TODO: Do this lazily by returning an iterable with a filtering Iterator
         // Acquire the list of files.
         Iterable<JavaFileObject> files = super.list(location, packageName, kinds, recurse);
         if (visibleSources.isEmpty()) {
-            return files;
+            return locWrapMany(files, location);
         }
         // Now filter!
         ListBuffer<JavaFileObject> filteredFiles = new ListBuffer<>();
@@ -116,12 +123,8 @@
                 filteredFiles.add(f);
             }
         }
-        return filteredFiles;
-    }
 
-    @Override @DefinedBy(Api.COMPILER)
-    public boolean hasLocation(Location location) {
-        return super.hasLocation(location);
+        return locWrapMany(filteredFiles, location);
     }
 
     @Override @DefinedBy(Api.COMPILER)
@@ -129,6 +132,7 @@
                                               String className,
                                               Kind kind) throws IOException {
         JavaFileObject file = super.getJavaFileForInput(location, className, kind);
+        file = locWrap(file, location);
         if (file == null || visibleSources.isEmpty()) {
             return file;
         }
@@ -145,6 +149,7 @@
                                                Kind kind,
                                                FileObject sibling) throws IOException {
         JavaFileObject file = super.getJavaFileForOutput(location, className, kind, sibling);
+        file = locWrap(file, location);
         if (file == null) return file;
         int dp = className.lastIndexOf('.');
         String pkg_name = "";
@@ -162,6 +167,7 @@
                                       String packageName,
                                       String relativeName) throws IOException {
         FileObject file =  super.getFileForInput(location, packageName, relativeName);
+        file = locWrap(file, location);
         if (file == null || visibleSources.isEmpty()) {
             return file;
         }
@@ -177,11 +183,12 @@
                                        String packageName,
                                        String relativeName,
                                        FileObject sibling) throws IOException {
-        FileObject file = super.getFileForOutput(location, packageName, relativeName, sibling);
+        FileObject superFile = super.getFileForOutput(location, packageName, relativeName, sibling);
+        FileObject file = locWrap(superFile, location);
         if (file == null) return file;
-        if (location.equals(StandardLocation.NATIVE_HEADER_OUTPUT) &&
-                file instanceof JavaFileObject) {
-           file = new SmartFileObject((JavaFileObject)file, stdout);
+
+        if (location.equals(StandardLocation.NATIVE_HEADER_OUTPUT) && superFile instanceof JavaFileObject) {
+           file = new SmartFileObject((JavaFileObject) file, stdout);
            packageName = ":" + packageNameFromFileName(relativeName);
         }
         if (packageName.equals("")) {
@@ -191,7 +198,7 @@
         return file;
     }
 
-    private String packageNameFromFileName(String fn) {
+    private static String packageNameFromFileName(String fn) {
         StringBuilder sb = new StringBuilder();
         int p = fn.indexOf('_'), pp = 0;
         while (p != -1) {
@@ -204,16 +211,6 @@
         return sb.toString();
     }
 
-    @Override @DefinedBy(Api.COMPILER)
-    public void flush() throws IOException {
-        super.flush();
-    }
-
-    @Override @DefinedBy(Api.COMPILER)
-    public void close() throws IOException {
-        super.close();
-    }
-
     void addArtifact(String pkgName, URI art) {
         Set<URI> s = packageArtifacts.get(pkgName);
         if (s == null) {
@@ -222,4 +219,50 @@
         }
         s.add(art);
     }
+
+    public static JavaFileObject locWrap(JavaFileObject jfo, Location loc) {
+
+        // From sjavac's perspective platform classes are not interesting and
+        // there is no need to track the location for these file objects.
+        // Also, there exists some jfo instanceof checks which breaks if
+        // the jfos for platform classes are wrapped.
+        if (loc == StandardLocation.PLATFORM_CLASS_PATH)
+            return jfo;
+
+        return jfo == null ? null : new JavaFileObjectWithLocation<>(jfo, loc);
+    }
+
+    private static FileObject locWrap(FileObject fo, Location loc) {
+        if (fo instanceof JavaFileObject)
+            return locWrap((JavaFileObject) fo, loc);
+        return fo == null ? null : new FileObjectWithLocation<>(fo, loc);
+    }
+
+    @DefinedBy(Api.COMPILER)
+    @Override
+    public boolean isSameFile(FileObject a, FileObject b) {
+        return super.isSameFile(locUnwrap(a), locUnwrap(b));
+    }
+
+    private static ListBuffer<JavaFileObject> locWrapMany(Iterable<JavaFileObject> jfos,
+                                                          Location loc) {
+        ListBuffer<JavaFileObject> locWrapped = new ListBuffer<>();
+        for (JavaFileObject f : jfos)
+            locWrapped.add(locWrap(f, loc));
+        return locWrapped;
+    }
+
+    private static FileObject locUnwrap(FileObject fo) {
+        if (fo instanceof FileObjectWithLocation<?>)
+            return ((FileObjectWithLocation<?>) fo).getDelegate();
+        if (fo instanceof JavaFileObjectWithLocation<?>)
+            return ((JavaFileObjectWithLocation<?>) fo).getDelegate();
+        return fo;
+    }
+
+    private static JavaFileObject locUnwrap(JavaFileObject fo) {
+        if (fo instanceof JavaFileObjectWithLocation<?>)
+            return ((JavaFileObjectWithLocation<?>) fo).getDelegate();
+        return fo;
+    }
 }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/dependencies/Dependency.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +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.dependencies;
-
-import java.util.Set;
-
-import com.sun.tools.javac.code.Symbol.PackageSymbol;
-
-interface Dependency {
-    Set<PackageSymbol> getPackages();
-}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/dependencies/DependencyCollector.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +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.dependencies;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import com.sun.source.util.TaskEvent;
-import com.sun.source.util.TaskListener;
-import com.sun.tools.javac.code.Symbol.PackageSymbol;
-import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
-import com.sun.tools.javac.util.DefinedBy;
-import com.sun.tools.javac.util.DefinedBy.Api;
-import com.sun.tools.sjavac.Util;
-
-public class DependencyCollector implements TaskListener {
-
-    Map<PackageSymbol, Set<PackageSymbol>> collectedDependencies = new HashMap<>();
-
-    @Override
-    @DefinedBy(Api.COMPILER_TREE)
-    public void started(TaskEvent e) {
-    }
-
-    @Override
-    @DefinedBy(Api.COMPILER_TREE)
-    public void finished(TaskEvent e) {
-        if (e.getKind() == TaskEvent.Kind.ANALYZE) {
-            JCCompilationUnit cu = (JCCompilationUnit) e.getCompilationUnit();
-            PackageSymbol thisPkg = cu.packge;
-            if (thisPkg == null) {
-                // Compilation unit in default package. See JDK-8048144.
-                return;
-            }
-            DependencyScanner ds = new DependencyScanner();
-            cu.accept(ds);
-            Set<PackageSymbol> pkgDeps = ds.getResult()
-                                           .stream()
-                                           .flatMap(dep -> dep.getPackages().stream())
-                                           .collect(Collectors.toSet());
-            collectedDependencies.merge(thisPkg, pkgDeps, Util::union);
-        }
-    }
-
-    public Set<PackageSymbol> getSourcePackages() {
-        return collectedDependencies.keySet();
-    }
-
-    public Set<PackageSymbol> getDependenciesForPkg(PackageSymbol ps) {
-        return collectedDependencies.get(ps);
-    }
-}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/dependencies/DependencyScanner.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +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.dependencies;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import com.sun.tools.javac.code.Symbol;
-import com.sun.tools.javac.code.Symbol.ClassSymbol;
-import com.sun.tools.javac.code.Symbol.PackageSymbol;
-import com.sun.tools.javac.code.Type;
-import com.sun.tools.javac.code.TypeTag;
-import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
-import com.sun.tools.javac.tree.JCTree.JCIdent;
-import com.sun.tools.javac.tree.TreeScanner;
-
-class DependencyScanner extends TreeScanner {
-
-    public final Set<Dependency> dependencies = new HashSet<>();
-
-    private boolean isValidDependency(Type t) {
-        if (t == null || t.isPrimitiveOrVoid() || t.isErroneous())
-            return false;
-        TypeTag tag = t.getTag();
-        return tag != TypeTag.PACKAGE
-            && tag != TypeTag.METHOD
-            && tag != TypeTag.ARRAY
-            && tag != TypeTag.TYPEVAR;
-    }
-
-    @Override
-    public void visitIdent(JCIdent tree) {
-        if (isValidDependency(tree.type))
-            dependencies.add(new TypeAndSupertypesDependency(tree.type.tsym));
-        super.visitIdent(tree);
-    }
-
-    @Override
-    public void visitSelect(JCFieldAccess tree) {
-        if (tree.getIdentifier().contentEquals("*")) {
-            Symbol sym = tree.selected instanceof JCIdent ? ((JCIdent) tree.selected).sym
-                                                          : ((JCFieldAccess) tree.selected).sym;
-            if (sym instanceof ClassSymbol) {
-                ClassSymbol clsSym = (ClassSymbol) sym;
-                dependencies.add(new TypeAndSupertypesDependency(clsSym.type.tsym));
-            } else {
-                dependencies.add(new PackageDependency((PackageSymbol) sym));
-            }
-        } else if (tree.type != null && tree.type.hasTag(TypeTag.METHOD)) {  // Method call? Depend on the result (even though we never access it elsewhere)
-            Type retType = tree.type.getReturnType();
-            if (isValidDependency(retType))
-                dependencies.add(new TypeAndSupertypesDependency(retType.tsym));
-        } else if (isValidDependency(tree.type)) {
-            dependencies.add(new TypeAndSupertypesDependency(tree.type.tsym));
-        }
-        super.visitSelect(tree);
-    }
-
-    public Set<Dependency> getResult() {
-        return dependencies;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/dependencies/NewDependencyCollector.java	Tue Jun 09 15:57:45 2015 +0200
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2015, 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.dependencies;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.tools.JavaFileManager.Location;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardLocation;
+
+import com.sun.source.util.TaskEvent;
+import com.sun.source.util.TaskListener;
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.DefinedBy;
+import com.sun.tools.javac.util.DefinedBy.Api;
+import com.sun.tools.javac.util.Dependencies.GraphDependencies;
+import com.sun.tools.javac.util.Dependencies.GraphDependencies.CompletionNode;
+import com.sun.tools.javac.util.GraphUtils.Node;
+import com.sun.tools.sjavac.Util;
+import com.sun.tools.sjavac.comp.JavaFileObjectWithLocation;
+import com.sun.tools.sjavac.comp.PubAPIs;
+
+
+public class NewDependencyCollector implements TaskListener {
+
+    private final Context context;
+    private final Collection<JavaFileObject> explicitJFOs;
+
+    private Map<String, Map<String, Set<String>>> deps;
+    private Map<String, Map<String, Set<String>>> cpDeps;
+
+    public NewDependencyCollector(Context context,
+                                  Collection<JavaFileObject> explicitJFOs) {
+        this.context = context;
+        this.explicitJFOs = explicitJFOs;
+    }
+
+    @Override
+    @DefinedBy(Api.COMPILER_TREE)
+    public void finished(TaskEvent e) {
+        if (e.getKind() == TaskEvent.Kind.COMPILATION) {
+            collectPubApisOfDependencies(context, explicitJFOs);
+            deps = getDependencies(context, explicitJFOs, false);
+            cpDeps = getDependencies(context, explicitJFOs, true);
+        }
+    }
+
+    public Map<String, Map<String, Set<String>>> getDependencies(boolean cp) {
+        return cp ? cpDeps : deps;
+    }
+
+    private Set<CompletionNode> getDependencyNodes(Context context,
+                                                   Collection<JavaFileObject> explicitJFOs,
+                                                   boolean explicits) {
+        GraphDependencies deps = (GraphDependencies) GraphDependencies.instance(context);
+
+        return deps.getNodes()
+                   .stream()
+                   .filter(n -> n instanceof CompletionNode)
+                   .map(n -> (CompletionNode) n)
+                   .filter(n -> n.getClassSymbol().fullname != null)
+                   .filter(n -> explicits == explicitJFOs.contains(n.getClassSymbol().classfile))
+                   .collect(Collectors.toSet());
+    }
+
+    private void collectPubApisOfDependencies(Context context,
+                                              Collection<JavaFileObject> explicitJFOs) {
+        PubAPIs pubApis = PubAPIs.instance(context);
+        for (CompletionNode cDepNode : getDependencyNodes(context, explicitJFOs, false)) {
+            ClassSymbol cs = cDepNode.getClassSymbol().outermostClass();
+            Location loc = getLocationOf(cs);
+            // We're completely ignorant of PLATFORM_CLASS_PATH classes
+            if (loc == StandardLocation.CLASS_PATH || loc == StandardLocation.SOURCE_PATH)
+                pubApis.visitPubapi(cs);
+        }
+    }
+
+    private Location getLocationOf(ClassSymbol cs) {
+        JavaFileObject jfo = cs.outermostClass().classfile;
+        if (jfo instanceof JavaFileObjectWithLocation) {
+            return ((JavaFileObjectWithLocation<?>) jfo).getLocation();
+        }
+
+        // jfo is most likely on PLATFORM_CLASS_PATH.
+        // See notes in SmartFileManager::locWrap
+
+        return null;
+    }
+
+    // :Package -> fully qualified class name [from] -> set of fully qualified class names [to]
+    private Map<String, Map<String, Set<String>>> getDependencies(Context context,
+                                                                  Collection<JavaFileObject> explicitJFOs,
+                                                                  boolean cp) {
+        Map<String, Map<String, Set<String>>> result = new HashMap<>();
+
+        for (CompletionNode cnode : getDependencyNodes(context, explicitJFOs, true)) {
+
+            String fqDep = cnode.getClassSymbol().outermostClass().flatname.toString();
+            String depPkg = Util.pkgNameOfClassName(fqDep);
+
+            Map<String, Set<String>> depsForThisClass = result.get(depPkg);
+            if (depsForThisClass == null)
+                result.put(depPkg, depsForThisClass = new HashMap<>());
+
+            for (Node<?,?> depNode : cnode.getDependenciesByKind(GraphDependencies.Node.DependencyKind.REQUIRES)) {
+                boolean isCompletionNode = depNode instanceof CompletionNode;
+                if (isCompletionNode) {
+                    CompletionNode cDepNode = (CompletionNode) depNode;
+                    if (cDepNode == cnode)
+                        continue;
+                    if (cDepNode.getClassSymbol().fullname == null) // Anonymous class
+                        continue;
+                    Location depLoc = getLocationOf(cDepNode.getClassSymbol());
+                    boolean relevant = (cp  && depLoc == StandardLocation.CLASS_PATH)
+                                    || (!cp && depLoc == StandardLocation.SOURCE_PATH);
+                    if (!relevant)
+                        continue;
+
+                    Set<String> fqDeps = depsForThisClass.get(fqDep);
+                    if (fqDeps == null)
+                        depsForThisClass.put(fqDep, fqDeps = new HashSet<>());
+                    fqDeps.add(cDepNode.getClassSymbol().outermostClass().flatname.toString());
+                }
+            }
+        }
+        return result;
+    }
+
+}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/dependencies/PackageDependency.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +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.dependencies;
-
-import java.util.Collections;
-import java.util.Set;
-
-import com.sun.tools.javac.code.Symbol.PackageSymbol;
-
-public class PackageDependency implements Dependency {
-    PackageSymbol ps;
-    public PackageDependency(PackageSymbol ps) {
-        this.ps = ps;
-    }
-    @Override
-    public Set<PackageSymbol> getPackages() {
-        return Collections.singleton(ps);
-    }
-}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/dependencies/PublicApiCollector.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/dependencies/PublicApiCollector.java	Tue Jun 09 15:57:45 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, 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
@@ -22,40 +22,91 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+
 package com.sun.tools.sjavac.comp.dependencies;
 
+import java.util.Collection;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
 
+import javax.tools.JavaFileObject;
+
 import com.sun.source.tree.Tree;
 import com.sun.source.util.TaskEvent;
 import com.sun.source.util.TaskListener;
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
+import com.sun.tools.javac.util.Context;
 import com.sun.tools.javac.util.DefinedBy;
 import com.sun.tools.javac.util.DefinedBy.Api;
+import com.sun.tools.sjavac.Log;
+import com.sun.tools.sjavac.comp.PubAPIs;
+import com.sun.tools.sjavac.pubapi.PubApi;
+
 
 public class PublicApiCollector implements TaskListener {
 
-    final Set<ClassSymbol> classSymbols = new HashSet<>();
+    private Context context;
+    private final Set<ClassSymbol> classSymbols = new HashSet<>();
+    private final Collection<JavaFileObject> explicitJFOs;
 
-    @Override
-    @DefinedBy(Api.COMPILER_TREE)
-    public void started(TaskEvent e) {
+    // Result collected upon compilation task finished
+    private Map<String, PubApi> explicitPubApis;
+    private Map<String, PubApi> nonExplicitPubApis;
+
+    public PublicApiCollector(Context context,
+                              Collection<JavaFileObject> explicitJFOs) {
+        this.context = context;
+        this.explicitJFOs = explicitJFOs;
     }
 
     @Override
     @DefinedBy(Api.COMPILER_TREE)
     public void finished(TaskEvent e) {
-        if (e.getKind() == TaskEvent.Kind.ANALYZE) {
-            for (Tree t : e.getCompilationUnit().getTypeDecls()) {
-                if (t instanceof JCClassDecl)  // Can also be a JCSkip
-                    classSymbols.add(((JCClassDecl) t).sym);
-            }
+        switch (e.getKind()) {
+        case ANALYZE:
+            collectClassSymbols((JCCompilationUnit) e.getCompilationUnit());
+            break;
+        case COMPILATION:
+            Log.debug("Compilation finished");
+            Log.debug("Extracting pub APIs for the following symbols:");
+            for (ClassSymbol cs : classSymbols)
+                Log.debug("    " + cs.fullname);
+            extractPubApis();
+
+            // Save result for later retrieval. (Important that we do this
+            // before we return from this method, because we may not access
+            // symbols after compilation is finished.)
+            PubAPIs pa = PubAPIs.instance(context);
+            explicitPubApis = pa.getPubapis(explicitJFOs, true);
+            nonExplicitPubApis = pa.getPubapis(explicitJFOs, false);
+
+            Log.debug("done");
+            break;
         }
     }
 
-    public Set<ClassSymbol> getClassSymbols() {
-        return classSymbols;
+    private void collectClassSymbols(JCCompilationUnit cu) {
+        for (Tree t : cu.getTypeDecls()) {
+            if (t instanceof JCClassDecl)  // Can also be a JCSkip
+                classSymbols.add(((JCClassDecl) t).sym);
+        }
+    }
+
+    private void extractPubApis() {
+        // To handle incremental builds (subsequent sjavac invocations) we need
+        // to keep track of the public API of what we depend upon.
+        //
+        // During the recompilation loop (within a single sjavac invocation) we
+        // need to keep track of public API of what we're compiling to decide if
+        // any dependants needs to be tainted.
+        PubAPIs pubApis = PubAPIs.instance(context);
+        classSymbols.forEach(pubApis::visitPubapi);
+    }
+
+    public Map<String, PubApi> getPubApis(boolean explicit) {
+        return explicit ? explicitPubApis : nonExplicitPubApis;
     }
 }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/dependencies/TypeAndSupertypesDependency.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +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.dependencies;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Objects;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import com.sun.tools.javac.code.Symbol.ClassSymbol;
-import com.sun.tools.javac.code.Symbol.PackageSymbol;
-import com.sun.tools.javac.code.Symbol.TypeSymbol;
-import com.sun.tools.javac.code.Kinds;
-import com.sun.tools.javac.code.Type;
-
-import static com.sun.tools.javac.code.Kinds.Kind.*;
-
-public class TypeAndSupertypesDependency implements Dependency {
-
-    protected TypeSymbol type;
-
-    public TypeAndSupertypesDependency(TypeSymbol type) {
-        this.type = Objects.requireNonNull(type);
-    }
-
-    private Set<TypeSymbol> allSupertypes(TypeSymbol t) {
-        if (t == null)
-            return Collections.emptySet();
-        Set<TypeSymbol> result = new HashSet<>();
-        result.add(t);
-        if (t instanceof ClassSymbol) {
-            ClassSymbol cs = (ClassSymbol) t;
-            result.addAll(allSupertypes(cs.getSuperclass().tsym));
-            for (Type it : cs.getInterfaces())
-                result.addAll(allSupertypes(it.tsym));
-        }
-        return result;
-    }
-
-    @Override
-    public Set<PackageSymbol> getPackages() {
-        if (type.kind == ERR)
-            return Collections.emptySet();
-        if (type instanceof ClassSymbol) {
-            return allSupertypes(type).stream()
-                                      .map(TypeSymbol::packge)
-                                      .collect(Collectors.toSet());
-        }
-        throw new AssertionError("Could not get package name for " + type);
-    }
-}
-
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.java	Tue Jun 09 15:57:45 2015 +0200
@@ -316,9 +316,19 @@
             args.add(concatenateSourceLocations(classSearchPaths));
         }
 
+        // Enable dependency generation
+        args.add("-XDcompletionDeps=source,class");
+
         // This can't be anything but 'none'. Enforced by sjavac main method.
         args.add("-implicit:" + implicitPolicy);
 
+        // If this option is not used, Object for instance is erroneously
+        // picked up from PLATFORM_CLASS_PATH instead of CLASS_PATH.
+        //
+        // Discussing this further led to the decision of letting bootclasspath
+        // be a dummy (empty) directory when building the JDK.
+        //args.add("-XXuserPathsFirst");
+
         // Append javac-options (i.e. pass through options not recognized by
         // sjavac to javac.)
         args.addAll(javacArgs);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/pubapi/ArrayTypeDesc.java	Tue Jun 09 15:57:45 2015 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014, 2015, 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.pubapi;
+
+import java.io.Serializable;
+
+import javax.lang.model.type.TypeKind;
+
+public class ArrayTypeDesc extends TypeDesc implements Serializable {
+
+    private static final long serialVersionUID = -1177329549163314996L;
+
+    TypeDesc compTypeDesc;
+
+    public ArrayTypeDesc(TypeDesc compTypeDesc) {
+        super(TypeKind.ARRAY);
+        this.compTypeDesc = compTypeDesc;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!super.equals(obj))
+            return false;
+        return compTypeDesc.equals(((ArrayTypeDesc) obj).compTypeDesc);
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ compTypeDesc.hashCode();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/pubapi/PrimitiveTypeDesc.java	Tue Jun 09 15:57:45 2015 +0200
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, 2015, 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.pubapi;
+
+import java.io.Serializable;
+
+import javax.lang.model.type.TypeKind;
+
+import com.sun.tools.javac.util.StringUtils;
+
+public class PrimitiveTypeDesc extends TypeDesc implements Serializable {
+
+    private static final long serialVersionUID = 6051065543149129106L;
+
+    public PrimitiveTypeDesc(TypeKind typeKind) {
+        super(typeKind);
+        if (!typeKind.isPrimitive() && typeKind != TypeKind.VOID)
+            throw new IllegalArgumentException("Only primitives or void accepted");
+    }
+
+    // This class has no fields, so the inherited hashCode and equals should do fine.
+
+    @Override
+    public String toString() {
+        return StringUtils.toLowerCase(typeKind.toString());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/pubapi/PubApi.java	Tue Jun 09 15:57:45 2015 +0200
@@ -0,0 +1,434 @@
+/*
+ * Copyright (c) 2014, 2015, 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.pubapi;
+
+
+import static com.sun.tools.sjavac.Util.union;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import javax.lang.model.element.Modifier;
+
+import com.sun.tools.javac.util.Assert;
+import com.sun.tools.javac.util.StringUtils;
+
+public class PubApi implements Serializable {
+
+    private static final long serialVersionUID = 5926627347801986850L;
+
+    // Used to have Set here. Problem is that the objects are mutated during
+    // javac_state loading, causing them to change hash codes. We could probably
+    // change back to Set once javac_state loading is cleaned up.
+    public final Map<String, PubType> types = new HashMap<>();
+    public final Map<String, PubVar> variables = new HashMap<>();
+    public final Map<String, PubMethod> methods = new HashMap<>();
+
+    public PubApi() {
+    }
+
+    public PubApi(Collection<PubType> types,
+                  Collection<PubVar> variables,
+                  Collection<PubMethod> methods) {
+        types.forEach(this::addPubType);
+        variables.forEach(this::addPubVar);
+        methods.forEach(this::addPubMethod);
+    }
+
+    // Currently this is implemented as equality. This is far from optimal. It
+    // should preferably make sure that all previous methods are still available
+    // and no abstract methods are added. It should also be aware of inheritance
+    // of course.
+    public boolean isBackwardCompatibleWith(PubApi older) {
+        return equals(older);
+    }
+
+    private static String typeLine(PubType type) {
+        if (type.fqName.isEmpty())
+            throw new RuntimeException("empty class name " + type);
+        return String.format("TYPE %s%s", asString(type.modifiers), type.fqName);
+    }
+
+    private static String varLine(PubVar var) {
+        return String.format("VAR %s%s %s%s",
+                             asString(var.modifiers),
+                             TypeDesc.encodeAsString(var.type),
+                             var.identifier,
+                             var.getConstValue().map(v -> " = " + v).orElse(""));
+    }
+
+    private static String methodLine(PubMethod method) {
+        return String.format("METHOD %s%s%s %s(%s)%s",
+                             asString(method.modifiers),
+                             method.typeParams.isEmpty() ? "" : ("<" + method.typeParams.stream().map(PubApiTypeParam::asString).collect(Collectors.joining(",")) + "> "),
+                             TypeDesc.encodeAsString(method.returnType),
+                             method.identifier,
+                             commaSeparated(method.paramTypes),
+                             method.throwDecls.isEmpty()
+                                 ? ""
+                                 : " throws " + commaSeparated(method.throwDecls));
+    }
+
+    public List<String> asListOfStrings() {
+        List<String> lines = new ArrayList<>();
+
+        // Types
+        types.values()
+             .stream()
+             .sorted(Comparator.comparing(PubApi::typeLine))
+             .forEach(type -> {
+                 lines.add(typeLine(type));
+                 for (String subline : type.pubApi.asListOfStrings())
+                     lines.add("  " + subline);
+             });
+
+        // Variables
+        variables.values()
+                 .stream()
+                 .map(PubApi::varLine)
+                 .sorted()
+                 .forEach(lines::add);
+
+        // Methods
+        methods.values()
+               .stream()
+               .map(PubApi::methodLine)
+               .sorted()
+               .forEach(lines::add);
+
+        return lines;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (getClass() != obj.getClass())
+            return false;
+        PubApi other = (PubApi) obj;
+        return types.equals(other.types)
+            && variables.equals(other.variables)
+            && methods.equals(other.methods);
+    }
+
+    @Override
+    public int hashCode() {
+        return types.keySet().hashCode()
+             ^ variables.keySet().hashCode()
+             ^ methods.keySet().hashCode();
+    }
+
+    private static String commaSeparated(List<TypeDesc> typeDescs) {
+        return typeDescs.stream()
+                        .map(TypeDesc::encodeAsString)
+                        .collect(Collectors.joining(","));
+    }
+
+    // Create space separated list of modifiers (with a trailing space)
+    private static String asString(Set<Modifier> modifiers) {
+        return modifiers.stream()
+                        .map(mod -> mod + " ")
+                        .sorted()
+                        .collect(Collectors.joining());
+    }
+
+    // Used to combine class PubApis to package level PubApis
+    public static PubApi mergeTypes(PubApi api1, PubApi api2) {
+        Assert.check(api1.methods.isEmpty(), "Can only merge types.");
+        Assert.check(api2.methods.isEmpty(), "Can only merge types.");
+        Assert.check(api1.variables.isEmpty(), "Can only merge types.");
+        Assert.check(api2.variables.isEmpty(), "Can only merge types.");
+        PubApi merged = new PubApi();
+        merged.types.putAll(api1.types);
+        merged.types.putAll(api2.types);
+        return merged;
+    }
+
+
+    // Used for line-by-line parsing
+    private PubType lastInsertedType = null;
+
+    private final static String MODIFIERS = Stream.of(Modifier.values())
+                                                  .map(Modifier::name)
+                                                  .map(StringUtils::toLowerCase)
+                                                  .collect(Collectors.joining("|", "(", ")"));
+
+    private final static Pattern MOD_PATTERN = Pattern.compile("(" + MODIFIERS + " )*");
+    private final static Pattern METHOD_PATTERN = Pattern.compile("(?<ret>.+?) (?<name>\\S+)\\((?<params>.*)\\)( throws (?<throws>.*))?");
+    private final static Pattern VAR_PATTERN = Pattern.compile("VAR (?<modifiers>("+MODIFIERS+" )*)(?<type>.+?) (?<id>\\S+)( = (?<val>.*))?");
+    private final static Pattern TYPE_PATTERN = Pattern.compile("TYPE (?<modifiers>("+MODIFIERS+" )*)(?<fullyQualified>\\S+)");
+
+    public void appendItem(String l) {
+        try {
+            if (l.startsWith("  ")) {
+                lastInsertedType.pubApi.appendItem(l.substring(2));
+                return;
+            }
+
+            if (l.startsWith("METHOD")) {
+                l = l.substring("METHOD ".length());
+                Set<Modifier> modifiers = new HashSet<>();
+                Matcher modMatcher = MOD_PATTERN.matcher(l);
+                if (modMatcher.find()) {
+                    String modifiersStr = modMatcher.group();
+                    modifiers.addAll(parseModifiers(modifiersStr));
+                    l = l.substring(modifiersStr.length());
+                }
+                List<PubApiTypeParam> typeParams = new ArrayList<>();
+                if (l.startsWith("<")) {
+                    int closingPos = findClosingTag(l, 0);
+                    String str = l.substring(1, closingPos);
+                    l = l.substring(closingPos+1);
+                    typeParams.addAll(parseTypeParams(splitOnTopLevelCommas(str)));
+                }
+                Matcher mm = METHOD_PATTERN.matcher(l);
+                if (!mm.matches())
+                    throw new AssertionError("Could not parse return type, identifier, parameter types or throws declaration of method: " + l);
+
+                List<String> params = splitOnTopLevelCommas(mm.group("params"));
+                String th = Optional.ofNullable(mm.group("throws")).orElse("");
+                List<String> throwz = splitOnTopLevelCommas(th);
+                PubMethod m = new PubMethod(modifiers,
+                                            typeParams,
+                                            TypeDesc.decodeString(mm.group("ret")),
+                                            mm.group("name"),
+                                            parseTypeDescs(params),
+                                            parseTypeDescs(throwz));
+                addPubMethod(m);
+                return;
+            }
+
+            Matcher vm = VAR_PATTERN.matcher(l);
+            if (vm.matches()) {
+                addPubVar(new PubVar(parseModifiers(vm.group("modifiers")),
+                                     TypeDesc.decodeString(vm.group("type")),
+                                     vm.group("id"),
+                                     vm.group("val")));
+                return;
+            }
+
+            Matcher tm = TYPE_PATTERN.matcher(l);
+            if (tm.matches()) {
+                addPubType(new PubType(parseModifiers(tm.group("modifiers")),
+                                       tm.group("fullyQualified"),
+                                       new PubApi()));
+                return;
+            }
+
+            throw new AssertionError("No matching line pattern.");
+        } catch (Throwable e) {
+            throw new AssertionError("Could not parse API line: " + l, e);
+        }
+    }
+
+    public void addPubType(PubType t) {
+        types.put(t.fqName, t);
+        lastInsertedType = t;
+    }
+
+    public void addPubVar(PubVar v) {
+        variables.put(v.identifier, v);
+    }
+
+    public void addPubMethod(PubMethod m) {
+        methods.put(m.asSignatureString(), m);
+    }
+
+    private static List<TypeDesc> parseTypeDescs(List<String> strs) {
+        return strs.stream()
+                   .map(TypeDesc::decodeString)
+                   .collect(Collectors.toList());
+    }
+
+    private static List<PubApiTypeParam> parseTypeParams(List<String> strs) {
+        return strs.stream().map(PubApi::parseTypeParam).collect(Collectors.toList());
+    }
+
+    // Parse a type parameter string. Example input:
+    //     identifier
+    //     identifier extends Type (& Type)*
+    private static PubApiTypeParam parseTypeParam(String typeParamString) {
+        int extPos = typeParamString.indexOf(" extends ");
+        if (extPos == -1)
+            return new PubApiTypeParam(typeParamString, Collections.emptyList());
+        String identifier = typeParamString.substring(0, extPos);
+        String rest = typeParamString.substring(extPos + " extends ".length());
+        List<TypeDesc> bounds = parseTypeDescs(splitOnTopLevelChars(rest, '&'));
+        return new PubApiTypeParam(identifier, bounds);
+    }
+
+    public Set<Modifier> parseModifiers(String modifiers) {
+        if (modifiers == null)
+            return Collections.emptySet();
+        return Stream.of(modifiers.split(" "))
+                     .map(String::trim)
+                     .map(StringUtils::toUpperCase)
+                     .filter(s -> !s.isEmpty())
+                     .map(Modifier::valueOf)
+                     .collect(Collectors.toSet());
+    }
+
+    // Find closing tag of the opening tag at the given 'pos'.
+    private static int findClosingTag(String l, int pos) {
+        while (true) {
+            pos = pos + 1;
+            if (l.charAt(pos) == '>')
+                return pos;
+            if (l.charAt(pos) == '<')
+                pos = findClosingTag(l, pos);
+        }
+    }
+
+    public List<String> splitOnTopLevelCommas(String s) {
+        return splitOnTopLevelChars(s, ',');
+    }
+
+    public static List<String> splitOnTopLevelChars(String s, char split) {
+        if (s.isEmpty())
+            return Collections.emptyList();
+        List<String> result = new ArrayList<>();
+        StringBuilder buf = new StringBuilder();
+        int depth = 0;
+        for (char c : s.toCharArray()) {
+            if (c == split && depth == 0) {
+                result.add(buf.toString().trim());
+                buf = new StringBuilder();
+            } else {
+                if (c == '<') depth++;
+                if (c == '>') depth--;
+                buf.append(c);
+            }
+        }
+        result.add(buf.toString().trim());
+        return result;
+    }
+
+    public boolean isEmpty() {
+        return types.isEmpty() && variables.isEmpty() && methods.isEmpty();
+    }
+
+    // Used for descriptive debug messages when figuring out what triggers
+    // recompilation.
+    public List<String> diff(PubApi prevApi) {
+        return diff("", prevApi);
+    }
+    private List<String> diff(String scopePrefix, PubApi prevApi) {
+
+        List<String> diffs = new ArrayList<>();
+
+        for (String typeKey : union(types.keySet(), prevApi.types.keySet())) {
+            PubType type = types.get(typeKey);
+            PubType prevType = prevApi.types.get(typeKey);
+            if (prevType == null) {
+                diffs.add("Type " + scopePrefix + typeKey + " was added");
+            } else if (type == null) {
+                diffs.add("Type " + scopePrefix + typeKey + " was removed");
+            } else {
+                // Check modifiers
+                if (!type.modifiers.equals(prevType.modifiers)) {
+                    diffs.add("Modifiers for type " + scopePrefix + typeKey
+                            + " changed from " + prevType.modifiers + " to "
+                            + type.modifiers);
+                }
+
+                // Recursively check types pub API
+                diffs.addAll(type.pubApi.diff(prevType.pubApi));
+            }
+        }
+
+        for (String varKey : union(variables.keySet(), prevApi.variables.keySet())) {
+            PubVar var = variables.get(varKey);
+            PubVar prevVar = prevApi.variables.get(varKey);
+            if (prevVar == null) {
+                diffs.add("Variable " + scopePrefix + varKey + " was added");
+            } else if (var == null) {
+                diffs.add("Variable " + scopePrefix + varKey + " was removed");
+            } else {
+                if (!var.modifiers.equals(prevVar.modifiers)) {
+                    diffs.add("Modifiers for var " + scopePrefix + varKey
+                            + " changed from " + prevVar.modifiers + " to "
+                            + var.modifiers);
+                }
+                if (!var.type.equals(prevVar.type)) {
+                    diffs.add("Type of " + scopePrefix + varKey
+                            + " changed from " + prevVar.type + " to "
+                            + var.type);
+                }
+                if (!var.getConstValue().equals(prevVar.getConstValue())) {
+                    diffs.add("Const value of " + scopePrefix + varKey
+                            + " changed from " + prevVar.getConstValue().orElse("<none>")
+                            + " to " + var.getConstValue().orElse("<none>"));
+                }
+            }
+        }
+
+        for (String methodKey : union(methods.keySet(), prevApi.methods.keySet())) {
+            PubMethod method = methods.get(methodKey);
+            PubMethod prevMethod = prevApi.methods.get(methodKey);
+            if (prevMethod == null) {
+                diffs.add("Method " + scopePrefix + methodKey + " was added");
+            } else if (method == null) {
+                diffs.add("Method " + scopePrefix + methodKey + " was removed");
+            } else {
+                if (!method.modifiers.equals(prevMethod.modifiers)) {
+                    diffs.add("Modifiers for method " + scopePrefix + methodKey
+                            + " changed from " + prevMethod.modifiers + " to "
+                            + method.modifiers);
+                }
+                if (!method.typeParams.equals(prevMethod.typeParams)) {
+                    diffs.add("Type parameters for method " + scopePrefix
+                            + methodKey + " changed from " + prevMethod.typeParams
+                            + " to " + method.typeParams);
+                }
+                if (!method.throwDecls.equals(prevMethod.throwDecls)) {
+                    diffs.add("Throw decl for method " + scopePrefix + methodKey
+                            + " changed from " + prevMethod.throwDecls + " to "
+                            + " to " + method.throwDecls);
+                }
+            }
+        }
+
+        return diffs;
+    }
+
+    public String toString() {
+        return String.format("%s[types: %s, variables: %s, methods: %s]",
+                             getClass().getSimpleName(),
+                             types.values(),
+                             variables.values(),
+                             methods.values());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/pubapi/PubApiTypeParam.java	Tue Jun 09 15:57:45 2015 +0200
@@ -0,0 +1,49 @@
+package com.sun.tools.sjavac.pubapi;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class PubApiTypeParam implements Serializable {
+
+    private static final long serialVersionUID = 8899204612014329162L;
+
+    private final String identifier;
+    private final List<TypeDesc> bounds;
+
+    public PubApiTypeParam(String identifier, List<TypeDesc> bounds) {
+        this.identifier = identifier;
+        this.bounds = bounds;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (getClass() != obj.getClass())
+            return false;
+        PubApiTypeParam other = (PubApiTypeParam) obj;
+        return identifier.equals(other.identifier)
+            && bounds.equals(other.bounds);
+    }
+
+    @Override
+    public int hashCode() {
+        return identifier.hashCode() ^ bounds.hashCode();
+    }
+
+    public String asString() {
+        if (bounds.isEmpty())
+            return identifier;
+        String boundsStr = bounds.stream()
+                                 .map(TypeDesc::encodeAsString)
+                                 .collect(Collectors.joining(" & "));
+        return identifier + " extends " + boundsStr;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("%s[id: %s, bounds: %s]",
+                             getClass().getSimpleName(),
+                             identifier,
+                             bounds);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/pubapi/PubMethod.java	Tue Jun 09 15:57:45 2015 +0200
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2014, 2015, 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.pubapi;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.lang.model.element.Modifier;
+
+public class PubMethod implements Serializable {
+
+    private static final long serialVersionUID = -7813050194553446243L;
+
+    Set<Modifier> modifiers;
+    List<PubApiTypeParam> typeParams;
+    TypeDesc returnType;
+    String identifier;
+    List<TypeDesc> paramTypes;
+    List<TypeDesc> throwDecls;
+
+    public PubMethod(Set<Modifier> modifiers,
+                     List<PubApiTypeParam> typeParams,
+                     TypeDesc returnType,
+                     String identifier,
+                     List<TypeDesc> paramTypes,
+                     List<TypeDesc> throwDecls) {
+        this.modifiers = modifiers;
+        this.typeParams = typeParams;
+        this.returnType = returnType;
+        this.identifier = identifier;
+        this.paramTypes = paramTypes;
+        this.throwDecls = throwDecls;
+    }
+
+    // We need to include return type and type parameters to be sure to have
+    // different values for different methods. (A method can be overloaded with
+    // the only difference being the upper bound of the return type.)
+    public String asSignatureString() {
+        StringBuilder sb = new StringBuilder();
+
+        // <A extends String, Serializable, B extends List>
+        if (typeParams.size() > 0) {
+            sb.append(typeParams.stream()
+                                .map(PubApiTypeParam::asString)
+                                .collect(Collectors.joining(",", "<", "> ")));
+        }
+        sb.append(TypeDesc.encodeAsString(returnType));
+        sb.append(" ");
+        sb.append(identifier);
+        sb.append("(");
+        sb.append(paramTypes.stream()
+                            .map(TypeDesc::encodeAsString)
+                            .collect(Collectors.joining(",")));
+        sb.append(")");
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (getClass() != obj.getClass())
+            return false;
+        PubMethod other = (PubMethod) obj;
+        return modifiers.equals(other.modifiers)
+            && typeParams.equals(other.typeParams)
+            && returnType.equals(other.returnType)
+            && identifier.equals(other.identifier)
+            && paramTypes.equals(other.paramTypes)
+            && throwDecls.equals(other.throwDecls);
+    }
+
+    @Override
+    public int hashCode() {
+        return modifiers.hashCode()
+             ^ typeParams.hashCode()
+             ^ returnType.hashCode()
+             ^ identifier.hashCode()
+             ^ paramTypes.hashCode()
+             ^ throwDecls.hashCode();
+    }
+
+    public String toString() {
+        return String.format("%s[modifiers: %s, typeParams: %s, retType: %s, identifier: %s, params: %s, throws: %s]",
+                             getClass().getSimpleName(),
+                             modifiers,
+                             typeParams,
+                             returnType,
+                             identifier,
+                             paramTypes,
+                             throwDecls);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/pubapi/PubType.java	Tue Jun 09 15:57:45 2015 +0200
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2014, 2015, 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.pubapi;
+
+import java.io.Serializable;
+import java.util.Set;
+
+import javax.lang.model.element.Modifier;
+
+public class PubType implements Serializable {
+
+    private static final long serialVersionUID = -7423416049253889793L;
+
+    public final Set<Modifier> modifiers;
+    public final String fqName;
+    public final PubApi pubApi;
+
+    public PubType(Set<Modifier> modifiers,
+                   String fqName,
+                   PubApi pubApi) {
+        this.modifiers = modifiers;
+        this.fqName = fqName;
+        this.pubApi = pubApi;
+    }
+
+    public String getFqName() {
+        return fqName.toString();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (getClass() != obj.getClass())
+            return false;
+        PubType other = (PubType) obj;
+        return modifiers.equals(other.modifiers)
+            && fqName.equals(other.fqName)
+            && pubApi.equals(other.pubApi);
+    }
+
+    @Override
+    public int hashCode() {
+        return modifiers.hashCode() ^ fqName.hashCode() ^ pubApi.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return String.format("%s[modifiers: %s, fqName: %s, pubApi: %s]",
+                             getClass().getSimpleName(),
+                             modifiers,
+                             fqName,
+                             pubApi);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/pubapi/PubVar.java	Tue Jun 09 15:57:45 2015 +0200
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2014, 2015, 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.pubapi;
+
+import java.io.Serializable;
+import java.util.Optional;
+import java.util.Set;
+
+import javax.lang.model.element.Modifier;
+
+public class PubVar implements Serializable {
+
+    private static final long serialVersionUID = 5806536061153374575L;
+
+    public final Set<Modifier> modifiers;
+    public final TypeDesc type;
+    public final String identifier;
+    private final String constValue;
+
+    public PubVar(Set<Modifier> modifiers,
+                  TypeDesc type,
+                  String identifier,
+                  String constValue) {
+        this.modifiers = modifiers;
+        this.type = type;
+        this.identifier = identifier;
+        this.constValue = constValue;
+    }
+
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (getClass() != obj.getClass())
+            return false;
+        PubVar other = (PubVar) obj;
+        return modifiers.equals(other.modifiers)
+            && type.equals(other.type)
+            && identifier.equals(other.identifier)
+            && getConstValue().equals(other.getConstValue());
+    }
+
+    @Override
+    public int hashCode() {
+        return modifiers.hashCode()
+             ^ type.hashCode()
+             ^ identifier.hashCode()
+             ^ getConstValue().hashCode();
+    }
+
+    public String toString() {
+        return String.format("%s[modifiers: %s, type: %s, identifier: %s, constValue: %s]",
+                             getClass().getSimpleName(),
+                             modifiers,
+                             type,
+                             identifier,
+                             constValue);
+    }
+
+    public Optional<String> getConstValue() {
+        return Optional.ofNullable(constValue);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/pubapi/ReferenceTypeDesc.java	Tue Jun 09 15:57:45 2015 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2014, 2015, 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.pubapi;
+
+import java.io.Serializable;
+
+import javax.lang.model.type.TypeKind;
+
+public class ReferenceTypeDesc extends TypeDesc implements Serializable {
+
+    private static final long serialVersionUID = 3357616754544796372L;
+
+    // Example: "java.util.Vector<java.lang.String>"
+    String javaType;
+
+    public ReferenceTypeDesc(String javaType) {
+        super(TypeKind.DECLARED);
+        this.javaType = javaType;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!super.equals(obj))
+            return false;
+        return javaType.equals(((ReferenceTypeDesc) obj).javaType);
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ javaType.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return String.format("%s[type: %s]", getClass().getSimpleName(), javaType);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/pubapi/TypeDesc.java	Tue Jun 09 15:57:45 2015 +0200
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2014, 2015, 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.pubapi;
+
+import java.io.Serializable;
+
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ErrorType;
+import javax.lang.model.type.NoType;
+import javax.lang.model.type.PrimitiveType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
+import javax.lang.model.type.TypeVisitor;
+import javax.lang.model.util.SimpleTypeVisitor9;
+
+import com.sun.tools.javac.code.Type.ClassType;
+import com.sun.tools.javac.util.DefinedBy;
+import com.sun.tools.javac.util.DefinedBy.Api;
+import com.sun.tools.javac.util.StringUtils;
+
+public abstract class TypeDesc implements Serializable {
+
+    private static final long serialVersionUID = -8201634143915519172L;
+
+    TypeKind typeKind;
+
+    public TypeDesc(TypeKind typeKind) {
+        this.typeKind = typeKind;
+    }
+
+    public static TypeDesc decodeString(String s) {
+        s = s.trim();
+        if (s.endsWith("[]")) {
+            String componentPart = s.substring(0, s.length()-2);
+            return new ArrayTypeDesc(decodeString(componentPart));
+        }
+
+        if (s.startsWith("#"))
+            return new TypeVarTypeDesc(s.substring(1));
+
+        if (s.matches("boolean|byte|char|double|float|int|long|short|void")) {
+            TypeKind tk = TypeKind.valueOf(StringUtils.toUpperCase(s));
+            return new PrimitiveTypeDesc(tk);
+        }
+
+        return new ReferenceTypeDesc(s);
+    }
+
+    public static String encodeAsString(TypeDesc td) {
+        if (td.typeKind.isPrimitive() || td.typeKind == TypeKind.VOID)
+            return StringUtils.toLowerCase(td.typeKind.toString());
+
+        if (td.typeKind == TypeKind.ARRAY)
+            return encodeAsString(((ArrayTypeDesc) td).compTypeDesc) + "[]";
+
+        if (td.typeKind == TypeKind.TYPEVAR)
+            return "#" + ((TypeVarTypeDesc) td).identifier;
+
+        if (td.typeKind == TypeKind.DECLARED)
+            return ((ReferenceTypeDesc) td).javaType.toString();
+
+        throw new AssertionError("Unhandled type: " + td.typeKind);
+    }
+
+    public static TypeDesc fromType(TypeMirror type) {
+        TypeVisitor<TypeDesc, Void> v = new SimpleTypeVisitor9<TypeDesc, Void>() {
+            @Override @DefinedBy(Api.LANGUAGE_MODEL)
+            public TypeDesc visitArray(ArrayType t, Void p) {
+                return new ArrayTypeDesc(t.getComponentType().accept(this, p));
+            }
+
+            @Override @DefinedBy(Api.LANGUAGE_MODEL)
+            public TypeDesc visitDeclared(DeclaredType t, Void p) {
+                return new ReferenceTypeDesc(((ClassType) t).tsym.flatName().toString());
+            }
+
+            @Override @DefinedBy(Api.LANGUAGE_MODEL)
+            public TypeDesc visitNoType(NoType t, Void p) {
+                return new PrimitiveTypeDesc(TypeKind.VOID);
+            }
+
+            @Override @DefinedBy(Api.LANGUAGE_MODEL)
+            public TypeDesc visitTypeVariable(TypeVariable t, Void p) {
+                return new TypeVarTypeDesc(t.toString());
+            }
+
+            @Override @DefinedBy(Api.LANGUAGE_MODEL)
+            public TypeDesc visitPrimitive(PrimitiveType t, Void p) {
+                return new PrimitiveTypeDesc(t.getKind());
+            }
+
+            @Override @DefinedBy(Api.LANGUAGE_MODEL)
+            public TypeDesc visitError(ErrorType t, Void p) {
+                return new ReferenceTypeDesc("<error type>");
+            }
+        };
+
+        TypeDesc td = v.visit(type);
+        if (td == null)
+            throw new AssertionError("Unhandled type mirror: " + type + " (" + type.getClass() + ")");
+        return td;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (getClass() != obj.getClass())
+            return false;
+        return typeKind.equals(((TypeDesc) obj).typeKind);
+    }
+
+    @Override
+    public int hashCode() {
+        return typeKind.hashCode();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/pubapi/TypeVarTypeDesc.java	Tue Jun 09 15:57:45 2015 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014, 2015, 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.pubapi;
+
+import java.io.Serializable;
+
+import javax.lang.model.type.TypeKind;
+
+public class TypeVarTypeDesc extends TypeDesc implements Serializable {
+
+    private static final long serialVersionUID = 3357616754544796373L;
+
+    String identifier; // Example: "T"
+
+    public TypeVarTypeDesc(String identifier) {
+        super(TypeKind.TYPEVAR);
+        this.identifier = identifier;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!super.equals(obj))
+            return false;
+        return identifier.equals(((TypeVarTypeDesc) obj).identifier);
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ identifier.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return String.format("%s[identifier: %s]",
+                             getClass().getSimpleName(),
+                             identifier);
+    }
+}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/CompilationResult.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/CompilationResult.java	Tue Jun 09 15:57:45 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, 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,6 +31,8 @@
 import java.util.Map;
 import java.util.Set;
 
+import com.sun.tools.sjavac.pubapi.PubApi;
+
 /**
  *
  *  <p><b>This is NOT part of any supported API.
@@ -47,8 +49,10 @@
 
     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 Map<String, Map<String, Set<String>>> packageDependencies = new HashMap<>();
+    public Map<String, Map<String, Set<String>>> packageCpDependencies = new HashMap<>();
+    public Map<String, PubApi> packagePubapis = new HashMap<>();
+    public Map<String, PubApi> dependencyPubapis = new HashMap<>();
     public String stdout = "";
     public String stderr = "";
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/ServerMain.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/ServerMain.java	Tue Jun 09 15:57:45 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, 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,6 +27,8 @@
 
 import java.io.IOException;
 
+import com.sun.tools.sjavac.Log;
+
 /**
  *  <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.
@@ -36,6 +38,8 @@
 public class ServerMain {
     public static int run(String[] args) {
 
+        Log.initializeLog(System.out, System.err);
+
         // Any options other than --startserver?
         if (args.length > 1) {
             System.err.println("When spawning a background server, only a single --startserver argument is allowed.");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/sjavac/ApiExtraction.java	Tue Jun 09 15:57:45 2015 +0200
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2015, 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 8054717
+ * @summary Make sure extraction of non-private APIs work as expected.
+ * @library /tools/lib
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ *          jdk.compiler/com.sun.tools.javac.file
+ *          jdk.compiler/com.sun.tools.javac.main
+ *          jdk.compiler/com.sun.tools.sjavac
+ * @build Wrapper ToolBox
+ * @run main Wrapper ApiExtraction
+ */
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
+import static javax.lang.model.element.Modifier.FINAL;
+import static javax.lang.model.element.Modifier.PROTECTED;
+import static javax.lang.model.element.Modifier.PUBLIC;
+import static javax.lang.model.element.Modifier.STATIC;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.lang.model.type.TypeKind;
+
+import com.sun.tools.sjavac.PubApiExtractor;
+import com.sun.tools.sjavac.options.Options;
+import com.sun.tools.sjavac.pubapi.PrimitiveTypeDesc;
+import com.sun.tools.sjavac.pubapi.PubApi;
+import com.sun.tools.sjavac.pubapi.PubMethod;
+import com.sun.tools.sjavac.pubapi.PubType;
+import com.sun.tools.sjavac.pubapi.PubVar;
+import com.sun.tools.sjavac.pubapi.ReferenceTypeDesc;
+
+
+public class ApiExtraction {
+    public static void main(String[] args) throws IOException {
+
+        String testSrc = String.join("\n",
+                "import java.util.*;",
+                "public final class TestClass extends Thread {",
+
+                // Fields with various combination of modifiers
+                "    private String s1 = \"str 1\";",
+                "    public String s2 = \"str 2\";",
+                "    protected final String s3 = \"str 3\";",
+                "    static String s4 = \"str 4\";",
+
+                // Methods with various combinations of types and modifiers
+                "    protected void m1() {}",
+                "    public static Map<Integer, List<String>> m2() {",
+                "        return null;",
+                "    }",
+                "    final void m3(Set<Map<Integer, Map<String, String>>> s) {}",
+
+                // Some inner classes
+                "    static class DummyInner1 implements Runnable {",
+                "        protected int field;",
+                "        public void run() {}",
+                "    }",
+                "    final class DummyInner2 { }",
+                "}");
+
+        // Create class file to extract API from
+        new ToolBox().new JavacTask().sources(testSrc).run();
+
+        // Extract PubApi
+        Options options = Options.parseArgs("-d", "bin", "-cp", ".");
+        PubApiExtractor pubApiExtr = new PubApiExtractor(options);
+        PubApi actualApi = pubApiExtr.getPubApi("TestClass");
+
+        // Validate result
+        PubApi expectedApi = getExpectedPubApi();
+        if (!expectedApi.equals(actualApi)) {
+            List<String> diffs = expectedApi.diff(actualApi);
+            System.out.println(diffs.size() + " differences found.");
+            for (String diff : diffs) {
+                System.out.println(diff);
+            }
+            throw new AssertionError("Actual API differs from expected API.");
+        }
+    }
+
+    private static PubApi getExpectedPubApi() {
+
+        ReferenceTypeDesc string = new ReferenceTypeDesc("java.lang.String");
+
+        // Fields
+        // (s1 is private and therefore not included)
+        PubVar s2 = new PubVar(setOf(PUBLIC), string, "s2", null);
+        PubVar s4 = new PubVar(setOf(STATIC), string, "s4", null);
+        PubVar s3 = new PubVar(setOf(PROTECTED, FINAL), string, "s3",
+                                   "\"\\u0073\\u0074\\u0072\\u0020\\u0033\"");
+
+        // Methods
+        PubMethod init = new PubMethod(setOf(PUBLIC),
+                                       emptyList(),
+                                       new PrimitiveTypeDesc(TypeKind.VOID),
+                                       "<init>",
+                                       emptyList(),
+                                       emptyList());
+
+        PubMethod clinit = new PubMethod(setOf(STATIC),
+                                         emptyList(),
+                                         new PrimitiveTypeDesc(TypeKind.VOID),
+                                         "<clinit>",
+                                         emptyList(),
+                                         emptyList());
+
+        PubMethod m1 = new PubMethod(setOf(PROTECTED),
+                                     emptyList(),
+                                     new PrimitiveTypeDesc(TypeKind.VOID),
+                                     "m1",
+                                     emptyList(),
+                                     emptyList());
+
+        PubMethod m2 = new PubMethod(setOf(PUBLIC, STATIC),
+                                     emptyList(),
+                                     new ReferenceTypeDesc("java.util.Map"),
+                                     "m2",
+                                     emptyList(),
+                                     emptyList());
+
+        PubMethod m3 = new PubMethod(setOf(FINAL),
+                                     emptyList(),
+                                     new PrimitiveTypeDesc(TypeKind.VOID),
+                                     "m3",
+                                     asList(new ReferenceTypeDesc("java.util.Set")),
+                                     emptyList());
+
+        // Complete class
+        PubType testClass = new PubType(setOf(PUBLIC, FINAL),
+                                        "TestClass",
+                                        new PubApi(asList(getDummyInner1(), getDummyInner2()),
+                                                   asList(s2, s3, s4),
+                                                   asList(init, clinit, m1, m2, m3)));
+
+        // Wrap in "package level" PubApi
+        return new PubApi(asList(testClass), emptyList(), emptyList());
+    }
+
+    private static PubType getDummyInner1() {
+        PubMethod init = new PubMethod(setOf(),
+                                       emptyList(),
+                                       new PrimitiveTypeDesc(TypeKind.VOID),
+                                       "<init>",
+                                       emptyList(),
+                                       emptyList());
+
+        PubMethod run = new PubMethod(setOf(PUBLIC),
+                                      emptyList(),
+                                      new PrimitiveTypeDesc(TypeKind.VOID),
+                                      "run",
+                                      emptyList(),
+                                      emptyList());
+
+        PubVar field = new PubVar(setOf(PROTECTED),
+                                  new PrimitiveTypeDesc(TypeKind.INT),
+                                  "field",
+                                  null);
+
+        return new PubType(setOf(STATIC),
+                           "TestClass$DummyInner1",
+                           new PubApi(emptyList(),
+                                      asList(field),
+                                      asList(init, run)));
+    }
+
+    private static PubType getDummyInner2() {
+        PubMethod init = new PubMethod(setOf(),
+                                       emptyList(),
+                                       new PrimitiveTypeDesc(TypeKind.VOID),
+                                       "<init>",
+                                       emptyList(),
+                                       emptyList());
+
+        return new PubType(setOf(FINAL),
+                           "TestClass$DummyInner2",
+                           new PubApi(emptyList(),
+                                      emptyList(),
+                                      asList(init)));
+    }
+
+    @SafeVarargs
+    private static <T> Set<T> setOf(T... elements) {
+        return new HashSet<>(asList(elements));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/sjavac/ClasspathDependencies.java	Tue Jun 09 15:57:45 2015 +0200
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2015, 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 8054717
+ * @summary Make sure changes of public API on classpath triggers recompilation
+ * @library /tools/lib
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ *          jdk.compiler/com.sun.tools.javac.file
+ *          jdk.compiler/com.sun.tools.javac.main
+ *          jdk.compiler/com.sun.tools.sjavac
+ * @build Wrapper ToolBox
+ * @run main Wrapper ClasspathDependencies
+ */
+
+import static com.sun.tools.javac.util.Assert.check;
+
+import java.io.IOException;
+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.attribute.BasicFileAttributes;
+import java.nio.file.attribute.FileTime;
+
+public class ClasspathDependencies extends SjavacBase {
+
+    static final String server = "--server:portfile=testserver,background=false";
+
+    public static void main(String... args) throws Exception {
+
+        Path root = Paths.get(ClasspathDependencies.class.getSimpleName() + "Test");
+
+        delete(root);
+
+        Path src = root.resolve("src");
+        Path classes = root.resolve("classes");
+        Path srcDep = root.resolve("srcDep");
+        Path classesDep = root.resolve("classesDep");
+
+        ////////////////////////////////////////////////////////////////////////
+        headline("Create a test dependency, Dep.class, and put it in the classpath dir");
+        String depCode = "package dep; public class Dep { public void m1() {} }";
+        toolbox.writeFile(srcDep.resolve("dep/Dep.java"), depCode);
+        int rc = compile(server, "-d", classesDep, srcDep);
+        check(rc == 0, "Compilation failed unexpectedly");
+
+        ////////////////////////////////////////////////////////////////////////
+        headline("Compile and link against the Dep.class");
+        toolbox.writeFile(src.resolve("pkg/C.java"),
+                          "package pkg;" +
+                          "import dep.Dep;" +
+                          "public class C { Dep dep; public void m() { new Dep().m1(); } }");
+        rc = compile(server, "-d", classes, src, "-cp", classesDep);
+        check(rc == 0, "Compilation failed unexpectedly");
+        FileTime modTime1 = Files.getLastModifiedTime(classes.resolve("pkg/C.class"));
+
+        ////////////////////////////////////////////////////////////////////////
+        headline("Update dependency (without changing the public api)");
+        Thread.sleep(2000);
+        depCode = depCode.replaceAll("}$", "private void m2() {} }");
+        toolbox.writeFile(srcDep.resolve("dep/Dep.java"), depCode);
+        rc = compile(server, "-d", classesDep, srcDep);
+        check(rc == 0, "Compilation failed unexpectedly");
+
+        ////////////////////////////////////////////////////////////////////////
+        headline("Make sure that this does not trigger recompilation of C.java");
+        rc = compile(server, "-d", classes, src, "-cp", classesDep);
+        check(rc == 0, "Compilation failed unexpectedly");
+        FileTime modTime2 = Files.getLastModifiedTime(classes.resolve("pkg/C.class"));
+        check(modTime1.equals(modTime2), "Recompilation erroneously triggered");
+
+        ////////////////////////////////////////////////////////////////////////
+        headline("Update public API of dependency");
+        Thread.sleep(2000);
+        depCode = depCode.replace("m1()", "m1(String... arg)");
+        toolbox.writeFile(srcDep.resolve("dep/Dep.java"), depCode);
+        rc = compile(server, "-d", classesDep, srcDep);
+        check(rc == 0, "Compilation failed unexpectedly");
+
+        ////////////////////////////////////////////////////////////////////////
+        headline("Make sure that recompilation of C.java is triggered");
+        rc = compile(server, "-d", classes, src, "-cp", classesDep);
+        check(rc == 0, "Compilation failed unexpectedly");
+        FileTime modTime3 = Files.getLastModifiedTime(classes.resolve("pkg/C.class"));
+        check(modTime2.compareTo(modTime3) < 0, "Recompilation not triggered");
+    }
+
+    static void headline(String str) {
+        System.out.println();
+        System.out.println(str);
+        System.out.println(str.replaceAll(".", "-"));
+    }
+
+    static void delete(Path root) throws IOException {
+        if (!Files.exists(root))
+            return;
+        Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
+                 @Override
+                 public FileVisitResult visitFile(Path f, BasicFileAttributes a)
+                         throws IOException {
+                     Files.delete(f);
+                     return FileVisitResult.CONTINUE;
+                 }
+
+                 @Override
+                 public FileVisitResult postVisitDirectory(Path dir, IOException e)
+                         throws IOException {
+                     if (e != null)
+                         throw e;
+                     if (!dir.equals(root))
+                         Files.delete(dir);
+                     return FileVisitResult.CONTINUE;
+                 }
+            });
+    }
+
+}
--- a/langtools/test/tools/sjavac/CompileCircularSources.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/test/tools/sjavac/CompileCircularSources.java	Tue Jun 09 15:57:45 2015 +0200
@@ -48,27 +48,33 @@
     }
 
     void test() throws Exception {
-        Files.createDirectory(BIN);
+        clean(TEST_ROOT);
+        Files.createDirectories(BIN);
         clean(GENSRC, BIN);
 
         Map<String,Long> previous_bin_state = collectState(BIN);
 
         ToolBox tb = new ToolBox();
         tb.writeFile(GENSRC.resolve("alfa/omega/A.java"),
-                 "package alfa.omega; public class A { beta.B b; }");
+                     "package alfa.omega; public class A { beta.B b; }");
         tb.writeFile(GENSRC.resolve("beta/B.java"),
-                 "package beta; public class B { gamma.C c; }");
+                     "package beta; public class B { gamma.C c; }");
         tb.writeFile(GENSRC.resolve("gamma/C.java"),
-                 "package gamma; public class C { alfa.omega.A a; }");
+                     "package gamma; public class C { alfa.omega.A a; }");
 
-        compile("gensrc", "-d", "bin", "-h", "headers", "-j", "3",
-                SERVER_ARG,"--log=debug");
+        compile(GENSRC.toString(),
+                "-d", BIN.toString(),
+                "-h", HEADERS.toString(),
+                "-j", "3",
+                SERVER_ARG,
+                "--log=debug");
         Map<String,Long> new_bin_state = collectState(BIN);
-        verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
-                                     "bin/alfa/omega/A.class",
-                                     "bin/beta/B.class",
-                                     "bin/gamma/C.class",
-                                     "bin/javac_state");
+        verifyThatFilesHaveBeenAdded(previous_bin_state,
+                                     new_bin_state,
+                                     BIN + "/alfa/omega/A.class",
+                                     BIN + "/beta/B.class",
+                                     BIN + "/gamma/C.class",
+                                     BIN + "/javac_state");
         clean(GENSRC, BIN);
     }
 }
--- a/langtools/test/tools/sjavac/CompileExcludingDependency.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/test/tools/sjavac/CompileExcludingDependency.java	Tue Jun 09 15:57:45 2015 +0200
@@ -49,22 +49,27 @@
 
     // Verify that excluding classes from compilation but not from linking works
     void test() throws Exception {
-        Files.createDirectory(BIN);
+        clean(TEST_ROOT);
+        Files.createDirectories(BIN);
         clean(GENSRC,BIN);
         Map<String,Long> previous_bin_state = collectState(BIN);
         ToolBox tb = new ToolBox();
         tb.writeFile(GENSRC.resolve("alfa/omega/A.java"),
-                 "package alfa.omega; public class A { beta.B b; }");
+                     "package alfa.omega; public class A { beta.B b; }");
         tb.writeFile(GENSRC.resolve("beta/B.java"),
-                 "package beta; public class B { }");
+                     "package beta; public class B { }");
 
-        compile("-x", "beta", "-src", "gensrc", "-x", "alfa/omega", "-sourcepath", "gensrc",
-                "-d", "bin", SERVER_ARG);
+        compile("-x", "beta",
+                "-src", GENSRC.toString(),
+                "-x", "alfa/omega",
+                "-sourcepath", GENSRC.toString(),
+                "-d", BIN.toString(),
+                SERVER_ARG);
 
         Map<String,Long> new_bin_state = collectState(BIN);
         verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
-                                     "bin/alfa/omega/A.class",
-                                     "bin/javac_state");
+                                     BIN + "/alfa/omega/A.class",
+                                     BIN + "/javac_state");
         clean(GENSRC, BIN);
     }
 }
--- a/langtools/test/tools/sjavac/CompileWithAtFile.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/test/tools/sjavac/CompileWithAtFile.java	Tue Jun 09 15:57:45 2015 +0200
@@ -48,9 +48,13 @@
     }
 
     void test() throws Exception {
+        clean(TEST_ROOT);
         ToolBox tb = new ToolBox();
         tb.writeFile(GENSRC.resolve("list.txt"),
-                 "-if */alfa/omega/A.java\n-if */beta/B.java\ngensrc\n-d bin\n");
+                     "-if */alfa/omega/A.java\n" +
+                     "-if */beta/B.java\n" +
+                     GENSRC + "\n" +
+                     "-d " + BIN + "\n");
         tb.writeFile(GENSRC.resolve("alfa/omega/A.java"),
                  "package alfa.omega; import beta.B; public class A { B b; }");
         tb.writeFile(GENSRC.resolve("beta/B.java"),
@@ -60,13 +64,14 @@
 
         Files.createDirectory(BIN);
         Map<String,Long> previous_bin_state = collectState(BIN);
-        compile("@gensrc/list.txt", "--server:portfile=testserver,background=false");
+
+        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");
+                         BIN + "/javac_state",
+                         BIN + "/alfa/omega/A.class",
+                         BIN + "/beta/B.class");
         clean(GENSRC, BIN);
     }
 }
--- a/langtools/test/tools/sjavac/CompileWithInvisibleSources.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/test/tools/sjavac/CompileWithInvisibleSources.java	Tue Jun 09 15:57:45 2015 +0200
@@ -51,35 +51,45 @@
     // gensrc2 contains broken code in beta.B, thus exclude that package
     // gensrc3 contains a proper beta.B
     void test() throws Exception {
-        Files.createDirectory(BIN);
+        clean(TEST_ROOT);
+        Files.createDirectories(BIN);
         clean(GENSRC, GENSRC2, GENSRC3, BIN);
 
         Map<String,Long> previous_bin_state = collectState(BIN);
 
         ToolBox tb = new ToolBox();
         tb.writeFile(GENSRC.resolve("alfa/omega/A.java"),
-                 "package alfa.omega; import beta.B; import gamma.C; public class A { B b; C c; }");
+                     "package alfa.omega; import beta.B; import gamma.C; public class A { B b; C c; }");
         tb.writeFile(GENSRC2.resolve("beta/B.java"),
-                 "package beta; public class B { broken");
+                     "package beta; public class B { broken");
         tb.writeFile(GENSRC2.resolve("gamma/C.java"),
-                 "package gamma; public class C { }");
+                     "package gamma; public class C { }");
         tb.writeFile(GENSRC3.resolve("beta/B.java"),
-                 "package beta; public class B { }");
+                     "package beta; public class B { }");
 
-        compile("gensrc", "-x", "beta", "-sourcepath", "gensrc2",
-                "-sourcepath", "gensrc3", "-d", "bin", "-h", "headers", "-j", "1",
+        compile(GENSRC.toString(),
+                "-x", "beta",
+                "-sourcepath", GENSRC2.toString(),
+                "-sourcepath", GENSRC3.toString(),
+                "-d", BIN.toString(),
+                "-h", HEADERS.toString(),
+                "-j", "1",
                 SERVER_ARG);
 
         System.out.println("The first compile went well!");
         Map<String,Long> new_bin_state = collectState(BIN);
         verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
-                                     "bin/alfa/omega/A.class",
-                                     "bin/javac_state");
+                                     BIN + "/alfa/omega/A.class",
+                                     BIN + "/javac_state");
 
         System.out.println("----- Compile with exluded beta went well!");
         clean(BIN);
-        compileExpectFailure("gensrc", "-sourcepath", "gensrc2", "-sourcepath", "gensrc3",
-                             "-d", "bin", "-h", "headers", "-j", "1",
+        compileExpectFailure(GENSRC.toString(),
+                             "-sourcepath", GENSRC2.toString(),
+                             "-sourcepath", GENSRC3.toString(),
+                             "-d", BIN.toString(),
+                             "-h", HEADERS.toString(),
+                             "-j", "1",
                              SERVER_ARG);
 
         System.out.println("----- Compile without exluded beta failed, as expected! Good!");
--- a/langtools/test/tools/sjavac/CompileWithOverrideSources.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/test/tools/sjavac/CompileWithOverrideSources.java	Tue Jun 09 15:57:45 2015 +0200
@@ -50,33 +50,43 @@
     // Compile gensrc and gensrc2. However do not compile broken beta.B in gensrc,
     // only compile ok beta.B in gensrc2
     void test() throws Exception {
-        Files.createDirectory(BIN);
+        clean(TEST_ROOT);
+        Files.createDirectories(BIN);
         clean(GENSRC, GENSRC2, GENSRC3, BIN);
 
         Map<String,Long> previous_bin_state = collectState(BIN);
         ToolBox tb = new ToolBox();
         tb.writeFile(GENSRC.resolve("alfa/omega/A.java"),
-                 "package alfa.omega; import beta.B; import gamma.C; public class A { B b; C c; }");
+                     "package alfa.omega; import beta.B; import gamma.C; public class A { B b; C c; }");
         tb.writeFile(GENSRC.resolve("beta/B.java"),
-                 "package beta; public class B { broken");
+                     "package beta; public class B { broken");
         tb.writeFile(GENSRC.resolve("gamma/C.java"),
-                 "package gamma; public class C { }");
+                     "package gamma; public class C { }");
 
         tb.writeFile(GENSRC2.resolve("beta/B.java"),
-                 "package beta; public class B { }");
+                     "package beta; public class B { }");
 
-        compile("-x", "beta", "gensrc", "gensrc2", "-d", "bin", "-h", "headers", "-j", "1",
+        compile("-x", "beta",
+                GENSRC.toString(),
+                GENSRC2.toString(),
+                "-d", BIN.toString(),
+                "-h", HEADERS.toString(),
+                "-j", "1",
                 SERVER_ARG);
         Map<String,Long> new_bin_state = collectState(BIN);
         verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
-                                     "bin/alfa/omega/A.class",
-                                     "bin/beta/B.class",
-                                     "bin/gamma/C.class",
-                                     "bin/javac_state");
+                                     BIN + "/alfa/omega/A.class",
+                                     BIN + "/beta/B.class",
+                                     BIN + "/gamma/C.class",
+                                     BIN + "/javac_state");
 
         System.out.println("----- Compile with exluded beta went well!");
         clean(BIN);
-        compileExpectFailure("gensrc", "gensrc2", "-d", "bin", "-h", "headers", "-j", "1",
+        compileExpectFailure(GENSRC.toString(),
+                             GENSRC2.toString(),
+                             "-d", BIN.toString(),
+                             "-h", HEADERS.toString(),
+                             "-j", "1",
                              SERVER_ARG);
 
         System.out.println("----- Compile without exluded beta failed, as expected! Good!");
--- a/langtools/test/tools/sjavac/DependencyCollection.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2014, 2015, 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 8056258 8048609
- * @summary Ensures that the DependencyCollector covers various cases.
- * @library /tools/lib
- * @modules jdk.compiler/com.sun.tools.javac.api
- *          jdk.compiler/com.sun.tools.javac.code
- *          jdk.compiler/com.sun.tools.javac.file
- *          jdk.compiler/com.sun.tools.javac.main
- *          jdk.compiler/com.sun.tools.javac.util
- *          jdk.compiler/com.sun.tools.sjavac.comp
- *          jdk.compiler/com.sun.tools.sjavac.comp.dependencies
- * @build Wrapper ToolBox
- * @run main Wrapper DependencyCollection
- */
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
-import javax.tools.JavaCompiler;
-import javax.tools.JavaFileObject;
-import javax.tools.StandardJavaFileManager;
-import javax.tools.ToolProvider;
-
-import com.sun.tools.javac.api.JavacTaskImpl;
-import com.sun.tools.javac.code.Symbol.PackageSymbol;
-import com.sun.tools.sjavac.comp.SmartFileManager;
-import com.sun.tools.sjavac.comp.dependencies.DependencyCollector;
-
-public class DependencyCollection {
-
-    public static void main(String[] args) throws IOException {
-        Path src = Paths.get(ToolBox.testSrc, "test-input", "src");
-
-        JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
-        try (StandardJavaFileManager fileManager = javac.getStandardFileManager(null, null, null)) {
-            SmartFileManager smartFileManager = new SmartFileManager(fileManager);
-            smartFileManager.setSymbolFileEnabled(false);
-            Iterable<? extends JavaFileObject> fileObjects =
-                    fileManager.getJavaFileObjectsFromFiles(Arrays.asList(src.resolve("pkg/Test.java").toFile()));
-            JavacTaskImpl task = (JavacTaskImpl) javac.getTask(new PrintWriter(System.out),
-                                                               smartFileManager,
-                                                               null,
-                                                               Arrays.asList("-d", "classes",
-                                                                             "-sourcepath", src.toAbsolutePath().toString()),
-                                                               null,
-                                                               fileObjects);
-            DependencyCollector depsCollector = new DependencyCollector();
-            task.addTaskListener(depsCollector);
-            task.doCall();
-
-            // Find pkg symbol
-            PackageSymbol pkg = findPkgSymbolWithName(depsCollector.getSourcePackages(), "pkg");
-            Set<PackageSymbol> foundDependencies = depsCollector.getDependenciesForPkg(pkg);
-
-            // Print dependencies
-            System.out.println("Found dependencies:");
-            foundDependencies.stream()
-                             .sorted(Comparator.comparing(DependencyCollection::extractNumber))
-                             .forEach(p -> System.out.println("    " + p));
-
-            // Check result
-            Set<Integer> found = foundDependencies.stream()
-                                                  .map(DependencyCollection::extractNumber)
-                                                  .collect(Collectors.toSet());
-            found.remove(-1); // Dependencies with no number (java.lang etc)
-            Set<Integer> expected = new HashSet<>();
-            for (int i = 2; i <= 30; i++) {
-                if (i == 15) continue;  // Case 15 correspond to the type of a throw-away return value.
-                expected.add(i);
-            }
-
-            Set<Integer> missing = new HashSet<>(expected);
-            missing.removeAll(found);
-            if (missing.size() > 0) {
-                System.out.println("Missing dependencies:");
-                missing.forEach(i -> System.out.println("    Dependency " + i));
-            }
-
-            Set<Integer> unexpected = new HashSet<>(found);
-            unexpected.removeAll(expected);
-            if (unexpected.size() > 0) {
-                System.out.println("Unexpected dependencies found:");
-                unexpected.forEach(i -> System.out.println("    Dependency " + i));
-            }
-
-            if (missing.size() > 0 || unexpected.size() > 0)
-                throw new AssertionError("Missing and/or unexpected dependencies found.");
-        }
-    }
-
-    private static PackageSymbol findPkgSymbolWithName(Set<PackageSymbol> syms, String name) {
-        for (PackageSymbol ps : syms)
-            if (ps.fullname.toString().equals("pkg"))
-                return ps;
-        throw new AssertionError("Could not find package named \"pkg\".");
-    }
-
-    public static int extractNumber(PackageSymbol p) {
-        Matcher m = Pattern.compile("\\d+").matcher(p.fullname.toString());
-        if (!m.find())
-            return -1;
-        return Integer.parseInt(m.group());
-    }
-}
--- a/langtools/test/tools/sjavac/IncCompInheritance.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/test/tools/sjavac/IncCompInheritance.java	Tue Jun 09 15:57:45 2015 +0200
@@ -60,6 +60,7 @@
             throw new AssertionError("Compilation failed unexpectedly");
 
         // Remove method A.m
+        Thread.sleep(2500); // Make sure we get a new timestamp
         String aModified = "package pkga; public class A { }";
         toolbox.writeFile(src.resolve("pkga/A.java"), aModified);
 
--- a/langtools/test/tools/sjavac/IncCompileChangeNative.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/test/tools/sjavac/IncCompileChangeNative.java	Tue Jun 09 15:57:45 2015 +0200
@@ -51,9 +51,10 @@
     ToolBox tb = new ToolBox();
 
     void test() throws Exception {
-        Files.createDirectory(GENSRC);
-        Files.createDirectory(BIN);
-        Files.createDirectory(HEADERS);
+        clean(TEST_ROOT);
+        Files.createDirectories(GENSRC);
+        Files.createDirectories(BIN);
+        Files.createDirectories(HEADERS);
 
         initialCompile();
         incrementalCompileDropAllNatives();
@@ -70,21 +71,25 @@
         System.out.println("\nIn incrementalCompileDropAllNatives() ");
         System.out.println("Verify that beta_B.h is removed");
         tb.writeFile(GENSRC.resolve("beta/B.java"),
-                       "package beta; import alfa.omega.A; public class B {"+
-                       "private int b() { return A.DEFINITION; } }");
+                     "package beta; import alfa.omega.A; " +
+                     "public class B { private int b() { return A.DEFINITION; } }");
 
-        compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
-                SERVER_ARG, "--log=debug");
+        compile(GENSRC.toString(),
+                "-d", BIN.toString(),
+                "-h", HEADERS.toString(),
+                "-j", "1",
+                SERVER_ARG,
+                "--log=debug");
         Map<String,Long> new_bin_state = collectState(BIN);
         verifyNewerFiles(previous_bin_state, new_bin_state,
-                         "bin/beta/B.class",
-                         "bin/beta/BINT.class",
-                         "bin/javac_state");
+                         BIN + "/beta/B.class",
+                         BIN + "/beta/BINT.class",
+                         BIN + "/javac_state");
         previous_bin_state = new_bin_state;
 
         Map<String,Long> new_headers_state = collectState(HEADERS);
         verifyThatFilesHaveBeenRemoved(previous_headers_state, new_headers_state,
-                                       "headers/beta_B.h");
+                                       HEADERS + "/beta_B.h");
         previous_headers_state = new_headers_state;
     }
 
@@ -94,22 +99,26 @@
         System.out.println("\nIn incrementalCompileAddNative() ");
         System.out.println("Verify that beta_B.h is added again");
         tb.writeFile(GENSRC.resolve("beta/B.java"),
-                       "package beta; import alfa.omega.A; public class B {"+
-                       "private int b() { return A.DEFINITION; } "+
-                 "@java.lang.annotation.Native final static int alfa = 42; }");
+                     "package beta; import alfa.omega.A; public class B {"+
+                     "private int b() { return A.DEFINITION; } "+
+                     "@java.lang.annotation.Native final static int alfa = 42; }");
 
-        compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
-                SERVER_ARG, "--log=debug");
+        compile(GENSRC.toString(),
+                "-d", BIN.toString(),
+                "-h", HEADERS.toString(),
+                "-j", "1",
+                SERVER_ARG,
+                "--log=debug");
         Map<String,Long> new_bin_state = collectState(BIN);
         verifyNewerFiles(previous_bin_state, new_bin_state,
-                         "bin/beta/B.class",
-                         "bin/beta/BINT.class",
-                         "bin/javac_state");
+                         BIN + "/beta/B.class",
+                         BIN + "/beta/BINT.class",
+                         BIN + "/javac_state");
         previous_bin_state = new_bin_state;
 
         Map<String,Long> new_headers_state = collectState(HEADERS);
         verifyThatFilesHaveBeenAdded(previous_headers_state, new_headers_state,
-                                     "headers/beta_B.h");
+                                     HEADERS + "/beta_B.h");
         previous_headers_state = new_headers_state;
     }
 }
--- a/langtools/test/tools/sjavac/IncCompileDropClasses.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/test/tools/sjavac/IncCompileDropClasses.java	Tue Jun 09 15:57:45 2015 +0200
@@ -51,9 +51,10 @@
     ToolBox tb = new ToolBox();
 
     void test() throws Exception {
-        Files.createDirectory(GENSRC);
-        Files.createDirectory(BIN);
-        Files.createDirectory(HEADERS);
+        clean(TEST_ROOT);
+        Files.createDirectories(GENSRC);
+        Files.createDirectories(BIN);
+        Files.createDirectories(HEADERS);
 
         initialCompile();
         incrementalCompileDroppingClasses();
@@ -68,15 +69,19 @@
         System.out.println("\nIn incrementalCompileDroppingClasses() ");
         System.out.println("Testing that deleting AA.java deletes all generated inner class including AA.class");
         removeFrom(GENSRC, "alfa/omega/AA.java");
-        compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
-                SERVER_ARG, "--log=debug");
+        compile(GENSRC.toString(),
+                "-d", BIN.toString(),
+                "-h", HEADERS.toString(),
+                "-j", "1",
+                SERVER_ARG,
+                "--log=debug");
         Map<String,Long> new_bin_state = collectState(BIN);
         verifyThatFilesHaveBeenRemoved(previous_bin_state, new_bin_state,
-                                       "bin/alfa/omega/AA$1.class",
-                                       "bin/alfa/omega/AA$AAAA.class",
-                                       "bin/alfa/omega/AA$AAA.class",
-                                       "bin/alfa/omega/AAAAA.class",
-                                       "bin/alfa/omega/AA.class");
+                                       BIN + "/alfa/omega/AA$1.class",
+                                       BIN + "/alfa/omega/AA$AAAA.class",
+                                       BIN + "/alfa/omega/AA$AAA.class",
+                                       BIN + "/alfa/omega/AAAAA.class",
+                                       BIN + "/alfa/omega/AA.class");
 
         previous_bin_state = new_bin_state;
         Map<String,Long> new_headers_state = collectState(HEADERS);
--- a/langtools/test/tools/sjavac/IncCompileFullyQualifiedRef.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/test/tools/sjavac/IncCompileFullyQualifiedRef.java	Tue Jun 09 15:57:45 2015 +0200
@@ -27,6 +27,7 @@
  * @test
  * @summary Verify that "alfa.omega.A a" does create a proper dependency
  * @bug 8054689
+ * @ignore Requires dependency code to deal with in-method dependencies.
  * @author Fredrik O
  * @author sogoel (rewrite)
  * @library /tools/lib
@@ -38,8 +39,7 @@
  * @run main Wrapper IncCompileFullyQualifiedRef
  */
 
-import java.util.*;
-import java.nio.file.*;
+import java.util.Map;
 
 public class IncCompileFullyQualifiedRef extends SJavacTester {
     public static void main(String... args) throws Exception {
@@ -48,36 +48,43 @@
     }
 
     void test() throws Exception {
+        clean(TEST_ROOT);
         ToolBox tb = new ToolBox();
         tb.writeFile(GENSRC.resolve("alfa/omega/A.java"),
-                 "package alfa.omega; public class A { "+
-                 "  public final static int DEFINITION = 18; "+
-                 "  public void hello() { }"+
-                 "}");
+                     "package alfa.omega; public class A { "+
+                     "  public final static int DEFINITION = 18; "+
+                     "  public void hello() { }"+
+                     "}");
         tb.writeFile(GENSRC.resolve("beta/B.java"),
-                 "package beta; public class B { "+
-                 "  public void world() { alfa.omega.A a; }"+
-                 "}");
+                     "package beta; public class B { "+
+                     "  public void world() { alfa.omega.A a; }"+
+                     "}");
 
-        compile("gensrc", "-d", "bin", "-j", "1",
-                SERVER_ARG, "--log=debug");
+        compile(GENSRC.toString(),
+                "-d", BIN.toString(),
+                "-j", "1",
+                SERVER_ARG,
+                "--log=debug");
         Map<String,Long> previous_bin_state = collectState(BIN);
 
         // Change pubapi of A, this should trigger a recompile of B.
         tb.writeFile(GENSRC.resolve("alfa/omega/A.java"),
-                 "package alfa.omega; public class A { "+
-                 "  public final static int DEFINITION = 19; "+
-                 "  public void hello() { }"+
-                 "}");
+                     "package alfa.omega; public class A { "+
+                     "  public final static int DEFINITION = 19; "+
+                     "  public void hello() { }"+
+                     "}");
 
-        compile("gensrc", "-d", "bin", "-j", "1",
-                SERVER_ARG, "--log=debug");
+        compile(GENSRC.toString(),
+                "-d", BIN.toString(),
+                "-j", "1",
+                SERVER_ARG,
+                "--log=debug");
         Map<String,Long> new_bin_state = collectState(BIN);
 
         verifyNewerFiles(previous_bin_state, new_bin_state,
-                         "bin/alfa/omega/A.class",
-                         "bin/beta/B.class",
-                         "bin/javac_state");
+                         BIN + "/alfa/omega/A.class",
+                         BIN + "/beta/B.class",
+                         BIN + "/javac_state");
         clean(GENSRC,BIN);
     }
 }
--- a/langtools/test/tools/sjavac/IncCompileNoChanges.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/test/tools/sjavac/IncCompileNoChanges.java	Tue Jun 09 15:57:45 2015 +0200
@@ -50,9 +50,10 @@
     Map<String,Long> previous_headers_state;
 
     void test() throws Exception {
-        Files.createDirectory(GENSRC);
-        Files.createDirectory(BIN);
-        Files.createDirectory(HEADERS);
+        clean(Paths.get(getClass().getSimpleName()));
+        Files.createDirectories(GENSRC);
+        Files.createDirectories(BIN);
+        Files.createDirectories(HEADERS);
 
         initialCompile();
         incrementalCompileNoChanges();
@@ -66,8 +67,12 @@
         previous_headers_state = collectState(HEADERS);
         System.out.println("\nIn incrementalCompileNoChanges() ");
         System.out.println("Testing that no change in sources implies no change in binaries");
-        compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
-                SERVER_ARG, "--log=debug");
+        compile(GENSRC.toString(),
+                "-d", BIN.toString(),
+                "-h", HEADERS.toString(),
+                "-j", "1",
+                SERVER_ARG,
+                "--log=debug");
         Map<String,Long> new_bin_state = collectState(BIN);
         verifyEqual(new_bin_state, previous_bin_state);
         Map<String,Long> new_headers_state = collectState(HEADERS);
--- a/langtools/test/tools/sjavac/IncCompileUpdateNative.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/test/tools/sjavac/IncCompileUpdateNative.java	Tue Jun 09 15:57:45 2015 +0200
@@ -51,9 +51,10 @@
     ToolBox tb = new ToolBox();
 
     void test() throws Exception {
-        Files.createDirectory(GENSRC);
-        Files.createDirectory(BIN);
-        Files.createDirectory(HEADERS);
+        clean(TEST_ROOT);
+        Files.createDirectories(GENSRC);
+        Files.createDirectories(BIN);
+        Files.createDirectories(HEADERS);
 
         initialCompile();
         incrementalCompileChangeNative();
@@ -69,22 +70,26 @@
         System.out.println("\nIn incrementalCompileChangeNative() ");
         System.out.println("Verify that beta_B.h is rewritten again");
         tb.writeFile(GENSRC.resolve("beta/B.java"),
-                       "package beta; import alfa.omega.A; public class B {"+
-                       "private int b() { return A.DEFINITION; } "+
-                 "@java.lang.annotation.Native final static int alfa = 43; }");
+                     "package beta; import alfa.omega.A; public class B {"+
+                     "private int b() { return A.DEFINITION; } "+
+                      "@java.lang.annotation.Native final static int alfa = 43; }");
 
-        compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
-                SERVER_ARG, "--log=debug");
+        compile(GENSRC.toString(),
+                "-d", BIN.toString(),
+                "-h", HEADERS.toString(),
+                "-j", "1",
+                SERVER_ARG,
+                "--log=debug");
         Map<String,Long> new_bin_state = collectState(BIN);
         verifyNewerFiles(previous_bin_state, new_bin_state,
-                         "bin/beta/B.class",
-                         "bin/beta/BINT.class",
-                         "bin/javac_state");
+                         BIN + "/beta/B.class",
+                         BIN + "/beta/BINT.class",
+                         BIN + "/javac_state");
         previous_bin_state = new_bin_state;
 
         Map<String,Long> new_headers_state = collectState(HEADERS);
         verifyNewerFiles(previous_headers_state, new_headers_state,
-                         "headers/beta_B.h");
+                         HEADERS + "/beta_B.h");
         previous_headers_state = new_headers_state;
     }
 }
--- a/langtools/test/tools/sjavac/IncCompileWithChanges.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/test/tools/sjavac/IncCompileWithChanges.java	Tue Jun 09 15:57:45 2015 +0200
@@ -24,6 +24,7 @@
 /*
  * @test
  * @summary Verify incremental changes in gensrc are handled as expected
+ * @ignore Requires dependency code to deal with in-method dependencies.
  * @bug 8054689
  * @author Fredrik O
  * @author sogoel (rewrite)
@@ -51,14 +52,13 @@
     ToolBox tb = new ToolBox();
 
     void test() throws Exception {
-        Files.createDirectory(GENSRC);
-        Files.createDirectory(BIN);
-        Files.createDirectory(HEADERS);
+        clean(TEST_ROOT);
+        Files.createDirectories(GENSRC);
+        Files.createDirectories(BIN);
+        Files.createDirectories(HEADERS);
 
         initialCompile();
         incrementalCompileWithChange();
-
-        clean(GENSRC, BIN, HEADERS);
     }
 
     /* Update A.java with a new timestamp and new final static definition.
@@ -72,24 +72,29 @@
         System.out.println("A.java updated to trigger a recompile");
         System.out.println("Generated native header should not be updated since native api of B was not modified");
         tb.writeFile(GENSRC.resolve("alfa/omega/A.java"),
-                       "package alfa.omega; public class A implements AINT { "+
-                 "public final static int DEFINITION = 18; public void aint() { } private void foo() { } }");
+                     "package alfa.omega; public class A implements AINT { " +
+                     "public final static int DEFINITION = 18;" +
+                     "public void aint() { } private void foo() { } }");
 
-        compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
-                SERVER_ARG, "--log=debug");
+        compile(GENSRC.toString(),
+                "-d", BIN.toString(),
+                "-h", HEADERS.toString(),
+                "-j", "1",
+                SERVER_ARG,
+                "--log=debug");
         Map<String,Long> new_bin_state = collectState(BIN);
 
         verifyNewerFiles(previous_bin_state, new_bin_state,
-                         "bin/alfa/omega/A.class",
-                         "bin/alfa/omega/AINT.class",
-                         "bin/alfa/omega/AA$AAAA.class",
-                         "bin/alfa/omega/AAAAA.class",
-                         "bin/alfa/omega/AA$AAA.class",
-                         "bin/alfa/omega/AA.class",
-                         "bin/alfa/omega/AA$1.class",
-                         "bin/beta/B.class",
-                         "bin/beta/BINT.class",
-                         "bin/javac_state");
+                         BIN + "/alfa/omega/A.class",
+                         BIN + "/alfa/omega/AINT.class",
+                         BIN + "/alfa/omega/AA$AAAA.class",
+                         BIN + "/alfa/omega/AAAAA.class",
+                         BIN + "/alfa/omega/AA$AAA.class",
+                         BIN + "/alfa/omega/AA.class",
+                         BIN + "/alfa/omega/AA$1.class",
+                         BIN + "/beta/B.class",
+                         BIN + "/beta/BINT.class",
+                         BIN + "/javac_state");
         previous_bin_state = new_bin_state;
 
         Map<String,Long> new_headers_state = collectState(HEADERS);
--- a/langtools/test/tools/sjavac/JavacOptionPrep.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/test/tools/sjavac/JavacOptionPrep.java	Tue Jun 09 15:57:45 2015 +0200
@@ -83,6 +83,7 @@
 
         // Check the result
         boolean destDirFound = false;
+        boolean userPathsFirst = false;
         boolean headerDirFound = false;
         boolean gensrcDirFound = false;
         boolean classPathFound = false;
@@ -95,6 +96,11 @@
 
             String option = javacArgIter.next();
 
+            // Ignore this option for now. When the file=... requirement goes
+            // away, this will be easier to handle.
+            if (option.startsWith("-XDcompletionDeps"))
+                continue;
+
             switch (option) {
             case "-classpath":
             case "-cp":
@@ -166,7 +172,6 @@
 
         if (!implicitNoneFound)
             throw new AssertionError("\"-implicit:none\" not found.");
-
     }
 
     static void assertEquals(Object expected, Object actual) {
--- a/langtools/test/tools/sjavac/PermittedArtifact.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/test/tools/sjavac/PermittedArtifact.java	Tue Jun 09 15:57:45 2015 +0200
@@ -38,12 +38,8 @@
  * @run main Wrapper PermittedArtifact
  */
 
-import java.lang.reflect.Method;
-import java.util.*;
-import java.io.*;
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.nio.charset.*;
+import java.nio.file.Files;
+import java.util.Map;
 
 public class PermittedArtifact extends SJavacTester {
     public static void main(String... args) throws Exception {
@@ -53,26 +49,31 @@
 
     //Verify that --permit-artifact=bin works
     void test() throws Exception {
-        Files.createDirectory(BIN);
+        clean(TEST_ROOT);
+        Files.createDirectories(BIN);
         clean(GENSRC, BIN);
 
         Map<String,Long> previous_bin_state = collectState(BIN);
 
-        new ToolBox().writeFile(GENSRC+"/alfa/omega/A.java",
-                "package alfa.omega; public class A { }");
+        ToolBox tb = new ToolBox();
+        tb.writeFile(GENSRC + "/alfa/omega/A.java",
+                     "package alfa.omega; public class A { }");
 
-        new ToolBox().writeFile(BIN+"/alfa/omega/AA.class",
-                 "Ugh, a messy build system (tobefixed) wrote this class file, "
-                         + "sjavac must not delete it.");
+        tb.writeFile(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", SERVER_ARG);
+        compile("--log=debug",
+                "--permit-artifact=" + BIN + "/alfa/omega/AA.class",
+                "-src", GENSRC.toString(),
+                "-d", BIN.toString(),
+                SERVER_ARG);
 
         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");
+                                     BIN + "/alfa/omega/A.class",
+                                     BIN + "/alfa/omega/AA.class",
+                                     BIN + "/javac_state");
         clean(GENSRC, BIN);
     }
 }
--- a/langtools/test/tools/sjavac/SJavacTester.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/test/tools/sjavac/SJavacTester.java	Tue Jun 09 15:57:45 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
 import java.io.*;
 import java.nio.file.*;
 import java.nio.file.attribute.*;
-import java.nio.charset.*;
 
 import com.sun.tools.sjavac.Main;
 
@@ -35,16 +34,18 @@
             + "portfile=testportfile,"
             + "background=false";
 
+    final Path TEST_ROOT = Paths.get(getClass().getSimpleName());
+
     // Generated sources that will test aspects of sjavac
-    static final Path GENSRC = Paths.get("gensrc");
+    final Path GENSRC = TEST_ROOT.resolve("gensrc");
     // Gensrc dirs used to test merging of serveral source roots.
-    static final Path GENSRC2 = Paths.get("gensrc2");
-    static final Path GENSRC3= Paths.get("gensrc3");
+    final Path GENSRC2 = TEST_ROOT.resolve("gensrc2");
+    final Path GENSRC3 = TEST_ROOT.resolve("gensrc3");
 
     // Dir for compiled classes.
-    static final Path BIN = Paths.get("bin");
+    final Path BIN = TEST_ROOT.resolve("bin");
     // Dir for c-header files.
-    Path HEADERS = Paths.get("headers");
+    final Path HEADERS = TEST_ROOT.resolve("headers");
 
     // Remember the previous bin and headers state here.
     Map<String,Long> previous_bin_state;
@@ -54,10 +55,10 @@
         System.out.println("\nInitial compile of gensrc.");
         ToolBox tb = new ToolBox();
         tb.writeFile(GENSRC.resolve("alfa/omega/AINT.java"),
-            "package alfa.omega; public interface AINT { void aint(); }");
+                     "package alfa.omega; public interface AINT { void aint(); }");
         tb.writeFile(GENSRC.resolve("alfa/omega/A.java"),
-            "package alfa.omega; public class A implements AINT { "+
-                 "public final static int DEFINITION = 17; public void aint() { } }");
+                     "package alfa.omega; public class A implements AINT { "+
+                     "public final static int DEFINITION = 17; public void aint() { } }");
         tb.writeFile(GENSRC.resolve("alfa/omega/AA.java"),
             "package alfa.omega;"+
             "// A package private class, not contributing to the public api.\n"+
@@ -79,13 +80,17 @@
             "    // from outside of this source file, therefore it is ok.\n"+
             "}\n");
         tb.writeFile(GENSRC.resolve("beta/BINT.java"),
-            "package beta;public interface BINT { void foo(); }");
+                     "package beta;public interface BINT { void foo(); }");
         tb.writeFile(GENSRC.resolve("beta/B.java"),
-            "package beta; import alfa.omega.A; public class B {"+
-            "private int b() { return A.DEFINITION; } native void foo(); }");
+                     "package beta; import alfa.omega.A; public class B {"+
+                     "private int b() { return A.DEFINITION; } native void foo(); }");
 
-        compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
-                SERVER_ARG, "--log=debug");
+        compile(GENSRC.toString(),
+                "-d", BIN.toString(),
+                "-h", HEADERS.toString(),
+                "-j", "1",
+                SERVER_ARG,
+                "--log=debug");
     }
 
     void removeFrom(Path dir, String... args) throws IOException {
--- a/langtools/test/tools/sjavac/SjavacBase.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/test/tools/sjavac/SjavacBase.java	Tue Jun 09 15:57:45 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, 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,7 +37,7 @@
      */
     public static int compile(Object... args) throws ReflectiveOperationException {
         // Use reflection to avoid a compile-time dependency on sjavac Main
-        System.err.println("compile: " + Arrays.toString(args));
+        System.out.println("compile: " + Arrays.toString(args));
         Class<?> c = Class.forName("com.sun.tools.sjavac.Main");
         Method m = c.getDeclaredMethod("go", String[].class);
         String[] strArgs = new String[args.length];
--- a/langtools/test/tools/sjavac/StateDir.java	Tue Jun 09 11:52:13 2015 +0200
+++ b/langtools/test/tools/sjavac/StateDir.java	Tue Jun 09 15:57:45 2015 +0200
@@ -48,28 +48,29 @@
     }
 
     void test() throws Exception {
-        Path bar = Paths.get("bar");
-        Files.createDirectory(bar);
-        Files.createDirectory(BIN);
-
-        clean(GENSRC, BIN, bar);
+        clean(TEST_ROOT);
+        Path BAR = TEST_ROOT.resolve("bar");
+        Files.createDirectories(BAR);
+        Files.createDirectories(BIN);
 
         Map<String,Long> previous_bin_state = collectState(BIN);
-        Map<String,Long> previous_bar_state = collectState(bar);
+        Map<String,Long> previous_bar_state = collectState(BAR);
 
         ToolBox tb = new ToolBox();
         tb.writeFile(GENSRC.resolve("alfa/omega/A.java"),
-                "package alfa.omega; public class A { }");
+                     "package alfa.omega; public class A { }");
 
-        compile("--state-dir=bar", "-src", "gensrc", "-d", "bin",
+        compile("--state-dir=" + BAR,
+                "-src", GENSRC.toString(),
+                "-d", BIN.toString(),
                 SJavacTester.SERVER_ARG);
 
         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);
+                                     BIN + "/alfa/omega/A.class");
+        Map<String,Long> new_bar_state = collectState(BAR);
         verifyThatFilesHaveBeenAdded(previous_bar_state, new_bar_state,
-                                     "bar/javac_state");
-        clean(GENSRC, BIN, bar);
+                                     BAR + "/javac_state");
+        clean(GENSRC, BIN, BAR);
     }
 }
--- a/langtools/test/tools/sjavac/test-input/src/nondependency/pkg26/Cls26.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +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 nondependency.pkg26;
-
-public class Cls26 {
-}
--- a/langtools/test/tools/sjavac/test-input/src/pkg/Test.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +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.
- */
-// Use fully qualified names to avoid accidentally capturing dependencies in import statements.
-
-package pkg;
-
-import pkg2.*;                                          // pkg2 as a whole
-import pkg3.Cls3;                                       // pkg3.Cls3
-import pkg25.Cls25;                                     // pkg25.Cls25
-import nondependency.pkg26.Cls26;                       // pkg26.Cls26 (but not nondependency)
-import pkg28.Cls28.Inner28;                             // pkg29.Cls28, pkg29.Cls28.Inner28
-import static pkg29.Cls29.Inner29;                      // pkg29.Cls29, pkg29.Cls29.Inner29
-import static pkg30.Cls30.*;                            // pkg30.Cls30 as a whole
-
-@pkg5.Anno5                                             // pkg5.Anno5
-public class Test<S extends pkg23.Cls23>                // pkg23.Cls23
-        extends pkg4.Cls4/*extends pkg11.Cls11*/<pkg6.Cls6/*extends pkg12.Cls12*/>   // pkg4.Cls4, pkg11.Cls11, pkg6.Cls6, pkg12.Cls12
-        implements pkg7.Cls7, pkg8.Cls8<pkg9.Cls9> {    // pkg7.Cls7, pkg8.Cls8, pkg9.Cls9
-
-    pkg27.Cls27 cls27[][][] = new pkg27.Cls27[0][0][0]; // pkg27.Cls27
-
-    pkg2.Cls2 cls2;
-    pkg19.Cls19 f19;                                    // pkg19.Cls19
-
-    public static void main(String[] args) {            // java.lang.String
-        pkg10.Cls10 o = new pkg10.Cls10();              // pkg10.Cls10
-
-        o.getCls13().getCls14().getCls15();             // pkg13.Cls13, pkg14.Cls14, pkg15.Cls15
-        pkg23.Cls23.f24 = null;                         // pkg23.Cls23, pkg24.Cls24
-    }
-
-    static pkg16.Cls16 m1(pkg17.Cls17 o) {              // pkg16.Cls16, pkg17.Cls17
-        return null;
-    }
-
-    public <T extends pkg18.Cls18> void m2() {          // pkg18.Cls18
-    }
-
-    public <T> T m3() {
-        T t;
-        t = null;
-        return t;
-    }
-
-    @pkg20.Anno20(pkg21.Cls21.class)                    // pkg20.Anno20, pkg21.Cls21
-    private void m3(@pkg22.Anno22 String s) {           // pkg22.Anno22
-        Runnable r = () -> { System.out.println("hello"); };
-    }
-
-    private void m4() throws Cls25 {                    // pkg25.Cls25
-    }
-}
--- a/langtools/test/tools/sjavac/test-input/src/pkg10/Cls10.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +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 pkg10;
-public class Cls10 {
-    public pkg13.Cls13 getCls13() {
-        return null;
-    }
-}
--- a/langtools/test/tools/sjavac/test-input/src/pkg11/Cls11.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +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 pkg11; public class Cls11 { }
--- a/langtools/test/tools/sjavac/test-input/src/pkg12/Cls12.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +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 pkg12; public class Cls12 { }
--- a/langtools/test/tools/sjavac/test-input/src/pkg13/Cls13.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +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 pkg13;
-public class Cls13 {
-    public pkg14.Cls14 getCls14() {
-        return null;
-    }
-}
--- a/langtools/test/tools/sjavac/test-input/src/pkg14/Cls14.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +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 pkg14;
-public class Cls14 {
-    public int[] getCls15() {
-        return null;
-    }
-}
--- a/langtools/test/tools/sjavac/test-input/src/pkg15/Cls15.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +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 pkg15; public class Cls15 { }
--- a/langtools/test/tools/sjavac/test-input/src/pkg16/Cls16.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +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 pkg16; public class Cls16 { }
--- a/langtools/test/tools/sjavac/test-input/src/pkg17/Cls17.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +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 pkg17; public class Cls17 { }
--- a/langtools/test/tools/sjavac/test-input/src/pkg18/Cls18.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +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 pkg18; public class Cls18 { }
--- a/langtools/test/tools/sjavac/test-input/src/pkg19/Cls19.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +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 pkg19; public class Cls19 { }
--- a/langtools/test/tools/sjavac/test-input/src/pkg2/Cls2.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +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 pkg2; public class Cls2 { }
--- a/langtools/test/tools/sjavac/test-input/src/pkg20/Anno20.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +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 pkg20;
-public @interface Anno20 {
-    Class<?> value();
-}
--- a/langtools/test/tools/sjavac/test-input/src/pkg21/Cls21.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +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 pkg21; public class Cls21 { }
--- a/langtools/test/tools/sjavac/test-input/src/pkg22/Anno22.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +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 pkg22;
-public @interface Anno22 {
-}
--- a/langtools/test/tools/sjavac/test-input/src/pkg23/Cls23.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +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 pkg23;
-public class Cls23 {
-    public static pkg24.Cls24 f24;
-}
--- a/langtools/test/tools/sjavac/test-input/src/pkg24/Cls24.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +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 pkg24; public class Cls24 { }
--- a/langtools/test/tools/sjavac/test-input/src/pkg25/Cls25.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +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 pkg25;
-
-public class Cls25 extends Throwable {
-}
--- a/langtools/test/tools/sjavac/test-input/src/pkg27/Cls27.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +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 pkg27;
-public class Cls27 {}
--- a/langtools/test/tools/sjavac/test-input/src/pkg28/Cls28.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +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 pkg28;
-public class Cls28 {
-    public static class Inner28 {}
-}
--- a/langtools/test/tools/sjavac/test-input/src/pkg29/Cls29.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +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 pkg29;
-public class Cls29 {
-    public static class Inner29 {}
-}
--- a/langtools/test/tools/sjavac/test-input/src/pkg3/Cls3.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +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 pkg3; public class Cls3 { }
--- a/langtools/test/tools/sjavac/test-input/src/pkg30/Cls30.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +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 pkg30;
-
-public class Cls30 {
-}
--- a/langtools/test/tools/sjavac/test-input/src/pkg4/Cls4.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +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 pkg4;
-public class Cls4<T> extends pkg11.Cls11 {
-}
--- a/langtools/test/tools/sjavac/test-input/src/pkg5/Anno5.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +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 pkg5;
-public @interface Anno5 {
-}
--- a/langtools/test/tools/sjavac/test-input/src/pkg6/Cls6.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +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 pkg6;
-public class Cls6 extends pkg12.Cls12 {
-}
--- a/langtools/test/tools/sjavac/test-input/src/pkg7/Cls7.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +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 pkg7;
-public interface Cls7 {
-}
--- a/langtools/test/tools/sjavac/test-input/src/pkg8/Cls8.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +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 pkg8;
-public interface Cls8<T> {
-}
--- a/langtools/test/tools/sjavac/test-input/src/pkg9/Cls9.java	Tue Jun 09 11:52:13 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +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 pkg9; public class Cls9 { }