Merge
authorlana
Thu, 22 May 2014 14:39:05 -0700
changeset 24607 e6dff6ac377e
parent 24601 65de78d28a62 (current diff)
parent 24606 12c0ca21f8dc (diff)
child 24608 71f05b7d5c10
Merge
langtools/src/share/classes/com/sun/tools/javadoc/JavadocClassReader.java
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java	Thu May 22 14:39:05 2014 -0700
@@ -28,6 +28,8 @@
 import java.io.*;
 import java.text.SimpleDateFormat;
 import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import com.sun.javadoc.*;
 import com.sun.tools.doclets.formats.html.markup.*;
@@ -139,42 +141,37 @@
         if (index < 0) {
             return htmlstr;
         }
-        String lowerHtml = StringUtils.toLowerCase(htmlstr);
-        final String docroot = "{@docroot}";
-        // Return index of first occurrence of {@docroot}
-        // Note: {@docRoot} is not case sensitive when passed in w/command line option
-        index = lowerHtml.indexOf(docroot, index);
-        if (index < 0) {
+        Matcher docrootMatcher = docrootPattern.matcher(htmlstr);
+        if (!docrootMatcher.find()) {
             return htmlstr;
         }
         StringBuilder buf = new StringBuilder();
-        int previndex = 0;
-        while (true) {
-            // Search for lowercase version of {@docRoot}
-            index = lowerHtml.indexOf(docroot, previndex);
-            // If next {@docRoot} tag not found, append rest of htmlstr and exit loop
-            if (index < 0) {
-                buf.append(htmlstr.substring(previndex));
-                break;
-            }
-            // If next {@docroot} tag found, append htmlstr up to start of tag
-            buf.append(htmlstr.substring(previndex, index));
-            previndex = index + docroot.length();
-            if (configuration.docrootparent.length() > 0 && htmlstr.startsWith("/..", previndex)) {
+        int prevEnd = 0;
+        do {
+            int match = docrootMatcher.start();
+            // append htmlstr up to start of next {@docroot}
+            buf.append(htmlstr.substring(prevEnd, match));
+            prevEnd = docrootMatcher.end();
+            if (configuration.docrootparent.length() > 0 && htmlstr.startsWith("/..", prevEnd)) {
                 // Insert the absolute link if {@docRoot} is followed by "/..".
                 buf.append(configuration.docrootparent);
-                previndex += 3;
+                prevEnd += 3;
             } else {
                 // Insert relative path where {@docRoot} was located
                 buf.append(pathToRoot.isEmpty() ? "." : pathToRoot.getPath());
             }
             // Append slash if next character is not a slash
-            if (previndex < htmlstr.length() && htmlstr.charAt(previndex) != '/') {
+            if (prevEnd < htmlstr.length() && htmlstr.charAt(prevEnd) != '/') {
                 buf.append('/');
             }
-        }
+        } while (docrootMatcher.find());
+        buf.append(htmlstr.substring(prevEnd));
         return buf.toString();
     }
+    //where:
+        // Note: {@docRoot} is not case sensitive when passed in w/command line option:
+        private static final Pattern docrootPattern =
+                Pattern.compile(Pattern.quote("{@docroot}"), Pattern.CASE_INSENSITIVE);
 
     /**
      * Get the script to show or hide the All classes link.
@@ -1690,13 +1687,13 @@
         }
 
         //Redirect all relative links.
-        int end, begin = StringUtils.toLowerCase(text).indexOf("<a");
+        int end, begin = StringUtils.indexOfIgnoreCase(text, "<a");
         if(begin >= 0){
             StringBuilder textBuff = new StringBuilder(text);
 
             while(begin >=0){
                 if (textBuff.length() > begin + 2 && ! Character.isWhitespace(textBuff.charAt(begin+2))) {
-                    begin = StringUtils.toLowerCase(textBuff.toString()).indexOf("<a", begin + 1);
+                    begin = StringUtils.indexOfIgnoreCase(textBuff.toString(), "<a", begin + 1);
                     continue;
                 }
 
@@ -1736,7 +1733,7 @@
                         + redirectPathFromRoot.resolve(relativeLink).getPath();
                     textBuff.replace(begin, end, relativeLink);
                 }
-                begin = StringUtils.toLowerCase(textBuff.toString()).indexOf("<a", begin + 1);
+                begin = StringUtils.indexOfIgnoreCase(textBuff.toString(), "<a", begin + 1);
             }
             return textBuff.toString();
         }
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java	Thu May 22 14:39:05 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -332,24 +332,6 @@
     }
 
     /**
-     * Parse the &lt;Code&gt; tag and return the text.
-     */
-    protected String parseCodeTag(String tag){
-        if(tag == null){
-            return "";
-        }
-
-        String lc = StringUtils.toLowerCase(tag);
-        int begin = lc.indexOf("<code>");
-        int end = lc.indexOf("</code>");
-        if(begin == -1 || end == -1 || end <= begin){
-            return tag;
-        } else {
-            return tag.substring(begin + 6, end);
-        }
-    }
-
-    /**
      * {@inheritDoc}
      */
     protected static void addImplementsInfo(HtmlDocletWriter writer,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/ClassFinder.java	Thu May 22 14:39:05 2014 -0700
@@ -0,0 +1,537 @@
+/*
+ * 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.javac.code;
+
+import java.io.*;
+import java.util.EnumSet;
+import java.util.Set;
+import javax.lang.model.SourceVersion;
+import javax.tools.JavaFileObject;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileManager.Location;
+import javax.tools.StandardJavaFileManager;
+
+import static javax.tools.StandardLocation.*;
+
+import com.sun.tools.javac.comp.Annotate;
+import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.jvm.ClassReader;
+import com.sun.tools.javac.util.*;
+
+import static com.sun.tools.javac.code.Flags.*;
+import static com.sun.tools.javac.code.Kinds.*;
+
+import static com.sun.tools.javac.main.Option.*;
+
+/**
+ *  This class provides operations to locate class definitions
+ *  from the source and class files on the paths provided to javac.
+ *
+ *  <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 ClassFinder {
+    /** The context key for the class finder. */
+    protected static final Context.Key<ClassFinder> classFinderKey = new Context.Key<>();
+
+    ClassReader reader;
+
+    Annotate annotate;
+
+    /** Switch: verbose output.
+     */
+    boolean verbose;
+
+    /**
+     * Switch: cache completion failures unless -XDdev is used
+     */
+    private boolean cacheCompletionFailure;
+
+    /**
+     * Switch: prefer source files instead of newer when both source
+     * and class are available
+     **/
+    protected boolean preferSource;
+
+    /**
+     * Switch: Search classpath and sourcepath for classes before the
+     * bootclasspath
+     */
+    protected boolean userPathsFirst;
+
+    /** The log to use for verbose output
+     */
+    final Log log;
+
+    /** The symbol table. */
+    Symtab syms;
+
+    /** The name table. */
+    final Names names;
+
+    /** Force a completion failure on this name
+     */
+    final Name completionFailureName;
+
+    /** Access to files
+     */
+    private final JavaFileManager fileManager;
+
+    /** Factory for diagnostics
+     */
+    JCDiagnostic.Factory diagFactory;
+
+    /** Can be reassigned from outside:
+     *  the completer to be used for ".java" files. If this remains unassigned
+     *  ".java" files will not be loaded.
+     */
+    public Completer sourceCompleter = null;
+
+    /** The path name of the class file currently being read.
+     */
+    protected JavaFileObject currentClassFile = null;
+
+    /** The class or method currently being read.
+     */
+    protected Symbol currentOwner = null;
+
+    /**
+     * Completer that delegates to the complete-method of this class.
+     */
+    private final Completer thisCompleter = new Completer() {
+        @Override
+        public void complete(Symbol sym) throws CompletionFailure {
+            ClassFinder.this.complete(sym);
+        }
+    };
+
+    public Completer getCompleter() {
+        return thisCompleter;
+    }
+
+    /** Get the ClassFinder instance for this invocation. */
+    public static ClassFinder instance(Context context) {
+        ClassFinder instance = context.get(classFinderKey);
+        if (instance == null)
+            instance = new ClassFinder(context);
+        return instance;
+    }
+
+    /** Construct a new class reader. */
+    protected ClassFinder(Context context) {
+        context.put(classFinderKey, this);
+        reader = ClassReader.instance(context);
+        names = Names.instance(context);
+        syms = Symtab.instance(context);
+        fileManager = context.get(JavaFileManager.class);
+        if (fileManager == null)
+            throw new AssertionError("FileManager initialization error");
+        diagFactory = JCDiagnostic.Factory.instance(context);
+
+        log = Log.instance(context);
+        annotate = Annotate.instance(context);
+
+        Options options = Options.instance(context);
+        verbose = options.isSet(VERBOSE);
+        cacheCompletionFailure = options.isUnset("dev");
+        preferSource = "source".equals(options.get("-Xprefer"));
+        userPathsFirst = options.isSet(XXUSERPATHSFIRST);
+
+
+        completionFailureName =
+            options.isSet("failcomplete")
+            ? names.fromString(options.get("failcomplete"))
+            : null;
+    }
+
+/************************************************************************
+ * Loading Classes
+ ***********************************************************************/
+
+    /** Completion for classes to be loaded. Before a class is loaded
+     *  we make sure its enclosing class (if any) is loaded.
+     */
+    private void complete(Symbol sym) throws CompletionFailure {
+        if (sym.kind == TYP) {
+            ClassSymbol c = (ClassSymbol)sym;
+            c.members_field = new Scope.ErrorScope(c); // make sure it's always defined
+            annotate.enterStart();
+            try {
+                completeOwners(c.owner);
+                completeEnclosing(c);
+            } finally {
+                // The flush needs to happen only after annotations
+                // are filled in.
+                annotate.enterDoneWithoutFlush();
+            }
+            fillIn(c);
+        } else if (sym.kind == PCK) {
+            PackageSymbol p = (PackageSymbol)sym;
+            try {
+                fillIn(p);
+            } catch (IOException ex) {
+                throw new CompletionFailure(sym, ex.getLocalizedMessage()).initCause(ex);
+            }
+        }
+        if (!reader.filling)
+            annotate.flush(); // finish attaching annotations
+    }
+
+    /** complete up through the enclosing package. */
+    private void completeOwners(Symbol o) {
+        if (o.kind != PCK) completeOwners(o.owner);
+        o.complete();
+    }
+
+    /**
+     * Tries to complete lexically enclosing classes if c looks like a
+     * nested class.  This is similar to completeOwners but handles
+     * the situation when a nested class is accessed directly as it is
+     * possible with the Tree API or javax.lang.model.*.
+     */
+    private void completeEnclosing(ClassSymbol c) {
+        if (c.owner.kind == PCK) {
+            Symbol owner = c.owner;
+            for (Name name : Convert.enclosingCandidates(Convert.shortName(c.name))) {
+                Symbol encl = owner.members().lookup(name).sym;
+                if (encl == null)
+                    encl = syms.classes.get(TypeSymbol.formFlatName(name, owner));
+                if (encl != null)
+                    encl.complete();
+            }
+        }
+    }
+
+    /** Fill in definition of class `c' from corresponding class or
+     *  source file.
+     */
+    private void fillIn(ClassSymbol c) {
+        if (completionFailureName == c.fullname) {
+            throw new CompletionFailure(c, "user-selected completion failure by class name");
+        }
+        currentOwner = c;
+        JavaFileObject classfile = c.classfile;
+        if (classfile != null) {
+            JavaFileObject previousClassFile = currentClassFile;
+            try {
+                if (reader.filling) {
+                    Assert.error("Filling " + classfile.toUri() + " during " + previousClassFile);
+                }
+                currentClassFile = classfile;
+                if (verbose) {
+                    log.printVerbose("loading", currentClassFile.toString());
+                }
+                if (classfile.getKind() == JavaFileObject.Kind.CLASS) {
+                    reader.readClassFile(c);
+                } else {
+                    if (sourceCompleter != null) {
+                        sourceCompleter.complete(c);
+                    } else {
+                        throw new IllegalStateException("Source completer required to read "
+                                                        + classfile.toUri());
+                    }
+                }
+                return;
+            } finally {
+                currentClassFile = previousClassFile;
+            }
+        } else {
+            JCDiagnostic diag =
+                diagFactory.fragment("class.file.not.found", c.flatname);
+            throw
+                newCompletionFailure(c, diag);
+        }
+    }
+    // where
+        /** Static factory for CompletionFailure objects.
+         *  In practice, only one can be used at a time, so we share one
+         *  to reduce the expense of allocating new exception objects.
+         */
+        private CompletionFailure newCompletionFailure(TypeSymbol c,
+                                                       JCDiagnostic diag) {
+            if (!cacheCompletionFailure) {
+                // log.warning("proc.messager",
+                //             Log.getLocalizedString("class.file.not.found", c.flatname));
+                // c.debug.printStackTrace();
+                return new CompletionFailure(c, diag);
+            } else {
+                CompletionFailure result = cachedCompletionFailure;
+                result.sym = c;
+                result.diag = diag;
+                return result;
+            }
+        }
+        private CompletionFailure cachedCompletionFailure =
+            new CompletionFailure(null, (JCDiagnostic) null);
+        {
+            cachedCompletionFailure.setStackTrace(new StackTraceElement[0]);
+        }
+
+
+    /** Load a toplevel class with given fully qualified name
+     *  The class is entered into `classes' only if load was successful.
+     */
+    public ClassSymbol loadClass(Name flatname) throws CompletionFailure {
+        boolean absent = syms.classes.get(flatname) == null;
+        ClassSymbol c = syms.enterClass(flatname);
+        if (c.members_field == null && c.completer != null) {
+            try {
+                c.complete();
+            } catch (CompletionFailure ex) {
+                if (absent) syms.classes.remove(flatname);
+                throw ex;
+            }
+        }
+        return c;
+    }
+
+/************************************************************************
+ * Loading Packages
+ ***********************************************************************/
+
+    /** Include class corresponding to given class file in package,
+     *  unless (1) we already have one the same kind (.class or .java), or
+     *         (2) we have one of the other kind, and the given class file
+     *             is older.
+     */
+    protected void includeClassFile(PackageSymbol p, JavaFileObject file) {
+        if ((p.flags_field & EXISTS) == 0)
+            for (Symbol q = p; q != null && q.kind == PCK; q = q.owner)
+                q.flags_field |= EXISTS;
+        JavaFileObject.Kind kind = file.getKind();
+        int seen;
+        if (kind == JavaFileObject.Kind.CLASS)
+            seen = CLASS_SEEN;
+        else
+            seen = SOURCE_SEEN;
+        String binaryName = fileManager.inferBinaryName(currentLoc, file);
+        int lastDot = binaryName.lastIndexOf(".");
+        Name classname = names.fromString(binaryName.substring(lastDot + 1));
+        boolean isPkgInfo = classname == names.package_info;
+        ClassSymbol c = isPkgInfo
+            ? p.package_info
+            : (ClassSymbol) p.members_field.lookup(classname).sym;
+        if (c == null) {
+            c = syms.enterClass(classname, p);
+            if (c.classfile == null) // only update the file if's it's newly created
+                c.classfile = file;
+            if (isPkgInfo) {
+                p.package_info = c;
+            } else {
+                if (c.owner == p)  // it might be an inner class
+                    p.members_field.enter(c);
+            }
+        } else if (!preferCurrent && c.classfile != null && (c.flags_field & seen) == 0) {
+            // if c.classfile == null, we are currently compiling this class
+            // and no further action is necessary.
+            // if (c.flags_field & seen) != 0, we have already encountered
+            // a file of the same kind; again no further action is necessary.
+            if ((c.flags_field & (CLASS_SEEN | SOURCE_SEEN)) != 0)
+                c.classfile = preferredFileObject(file, c.classfile);
+        }
+        c.flags_field |= seen;
+    }
+
+    /** Implement policy to choose to derive information from a source
+     *  file or a class file when both are present.  May be overridden
+     *  by subclasses.
+     */
+    protected JavaFileObject preferredFileObject(JavaFileObject a,
+                                           JavaFileObject b) {
+
+        if (preferSource)
+            return (a.getKind() == JavaFileObject.Kind.SOURCE) ? a : b;
+        else {
+            long adate = a.getLastModified();
+            long bdate = b.getLastModified();
+            // 6449326: policy for bad lastModifiedTime in ClassReader
+            //assert adate >= 0 && bdate >= 0;
+            return (adate > bdate) ? a : b;
+        }
+    }
+
+    /**
+     * specifies types of files to be read when filling in a package symbol
+     */
+    protected EnumSet<JavaFileObject.Kind> getPackageFileKinds() {
+        return EnumSet.of(JavaFileObject.Kind.CLASS, JavaFileObject.Kind.SOURCE);
+    }
+
+    /**
+     * this is used to support javadoc
+     */
+    protected void extraFileActions(PackageSymbol pack, JavaFileObject fe) {
+    }
+
+    protected Location currentLoc; // FIXME
+
+    private boolean verbosePath = true;
+
+    // Set to true when the currently selected file should be kept
+    private boolean preferCurrent;
+
+    /** Load directory of package into members scope.
+     */
+    private void fillIn(PackageSymbol p) throws IOException {
+        if (p.members_field == null)
+            p.members_field = new Scope(p);
+
+        preferCurrent = false;
+        if (userPathsFirst) {
+            scanUserPaths(p);
+            preferCurrent = true;
+            scanPlatformPath(p);
+        } else {
+            scanPlatformPath(p);
+            scanUserPaths(p);
+        }
+        verbosePath = false;
+    }
+
+    /**
+     * Scans class path and source path for files in given package.
+     */
+    private void scanUserPaths(PackageSymbol p) throws IOException {
+        Set<JavaFileObject.Kind> kinds = getPackageFileKinds();
+
+        Set<JavaFileObject.Kind> classKinds = EnumSet.copyOf(kinds);
+        classKinds.remove(JavaFileObject.Kind.SOURCE);
+        boolean wantClassFiles = !classKinds.isEmpty();
+
+        Set<JavaFileObject.Kind> sourceKinds = EnumSet.copyOf(kinds);
+        sourceKinds.remove(JavaFileObject.Kind.CLASS);
+        boolean wantSourceFiles = !sourceKinds.isEmpty();
+
+        boolean haveSourcePath = fileManager.hasLocation(SOURCE_PATH);
+
+        if (verbose && verbosePath) {
+            if (fileManager instanceof StandardJavaFileManager) {
+                StandardJavaFileManager fm = (StandardJavaFileManager)fileManager;
+                if (haveSourcePath && wantSourceFiles) {
+                    List<File> path = List.nil();
+                    for (File file : fm.getLocation(SOURCE_PATH)) {
+                        path = path.prepend(file);
+                    }
+                    log.printVerbose("sourcepath", path.reverse().toString());
+                } else if (wantSourceFiles) {
+                    List<File> path = List.nil();
+                    for (File file : fm.getLocation(CLASS_PATH)) {
+                        path = path.prepend(file);
+                    }
+                    log.printVerbose("sourcepath", path.reverse().toString());
+                }
+                if (wantClassFiles) {
+                    List<File> path = List.nil();
+                    for (File file : fm.getLocation(PLATFORM_CLASS_PATH)) {
+                        path = path.prepend(file);
+                    }
+                    for (File file : fm.getLocation(CLASS_PATH)) {
+                        path = path.prepend(file);
+                    }
+                    log.printVerbose("classpath",  path.reverse().toString());
+                }
+            }
+        }
+
+        String packageName = p.fullname.toString();
+        if (wantSourceFiles && !haveSourcePath) {
+            fillIn(p, CLASS_PATH,
+                   fileManager.list(CLASS_PATH,
+                                    packageName,
+                                    kinds,
+                                    false));
+        } else {
+            if (wantClassFiles)
+                fillIn(p, CLASS_PATH,
+                       fileManager.list(CLASS_PATH,
+                                        packageName,
+                                        classKinds,
+                                        false));
+            if (wantSourceFiles)
+                fillIn(p, SOURCE_PATH,
+                       fileManager.list(SOURCE_PATH,
+                                        packageName,
+                                        sourceKinds,
+                                        false));
+        }
+    }
+
+    /**
+     * Scans platform class path for files in given package.
+     */
+    private void scanPlatformPath(PackageSymbol p) throws IOException {
+        fillIn(p, PLATFORM_CLASS_PATH,
+               fileManager.list(PLATFORM_CLASS_PATH,
+                                p.fullname.toString(),
+                                EnumSet.of(JavaFileObject.Kind.CLASS),
+                                false));
+    }
+    // where
+        private void fillIn(PackageSymbol p,
+                            Location location,
+                            Iterable<JavaFileObject> files)
+        {
+            currentLoc = location;
+            for (JavaFileObject fo : files) {
+                switch (fo.getKind()) {
+                case CLASS:
+                case SOURCE: {
+                    // TODO pass binaryName to includeClassFile
+                    String binaryName = fileManager.inferBinaryName(currentLoc, fo);
+                    String simpleName = binaryName.substring(binaryName.lastIndexOf(".") + 1);
+                    if (SourceVersion.isIdentifier(simpleName) ||
+                        simpleName.equals("package-info"))
+                        includeClassFile(p, fo);
+                    break;
+                }
+                default:
+                    extraFileActions(p, fo);
+                }
+            }
+        }
+
+    /**
+     * Used for bad class definition files, such as bad .class files or
+     * for .java files with unexpected package or class names.
+     */
+    public static class BadClassFile extends CompletionFailure {
+        private static final long serialVersionUID = 0;
+
+        public BadClassFile(TypeSymbol sym, JavaFileObject file, JCDiagnostic diag,
+                JCDiagnostic.Factory diagFactory) {
+            super(sym, createBadClassFileDiagnostic(file, diag, diagFactory));
+        }
+        // where
+        private static JCDiagnostic createBadClassFileDiagnostic(
+                JavaFileObject file, JCDiagnostic diag, JCDiagnostic.Factory diagFactory) {
+            String key = (file.getKind() == JavaFileObject.Kind.SOURCE
+                        ? "bad.source.file.header" : "bad.class.file.header");
+            return diagFactory.fragment(key, file, diag);
+        }
+    }
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java	Thu May 22 14:39:05 2014 -0700
@@ -50,7 +50,6 @@
 import com.sun.tools.javac.code.Type.MethodType;
 import com.sun.tools.javac.code.Type.UnknownType;
 import com.sun.tools.javac.jvm.ByteCodes;
-import com.sun.tools.javac.jvm.ClassReader;
 import com.sun.tools.javac.jvm.Target;
 import com.sun.tools.javac.util.Assert;
 import com.sun.tools.javac.util.Context;
@@ -470,8 +469,8 @@
         Scope scope = new Scope(predefClass);
         predefClass.members_field = scope;
 
-        // Get the initial completer for Symbols from the ClassReader
-        initialCompleter = ClassReader.instance(context).getCompleter();
+        // Get the initial completer for Symbols from the ClassFinder
+        initialCompleter = ClassFinder.instance(context).getCompleter();
         rootPackage.completer = initialCompleter;
         unnamedPackage.completer = initialCompleter;
 
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Thu May 22 14:39:05 2014 -0700
@@ -42,9 +42,8 @@
 import com.sun.tools.javac.comp.Check;
 import com.sun.tools.javac.comp.Enter;
 import com.sun.tools.javac.comp.Env;
-import com.sun.tools.javac.jvm.ClassReader;
-import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.util.*;
+
 import static com.sun.tools.javac.code.BoundKind.*;
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Scope.*;
@@ -84,7 +83,6 @@
     final boolean allowBoxing;
     final boolean allowCovariantReturns;
     final boolean allowObjectToPrimitiveCast;
-    final ClassReader reader;
     final Check chk;
     final Enter enter;
     JCDiagnostic.Factory diags;
@@ -110,7 +108,6 @@
         allowBoxing = source.allowBoxing();
         allowCovariantReturns = source.allowCovariantReturns();
         allowObjectToPrimitiveCast = source.allowObjectToPrimitiveCast();
-        reader = ClassReader.instance(context);
         chk = Check.instance(context);
         enter = Enter.instance(context);
         capturedName = names.fromString("<captured wildcard>");
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Thu May 22 14:39:05 2014 -0700
@@ -282,7 +282,7 @@
      */
     public Type completionError(DiagnosticPosition pos, CompletionFailure ex) {
         log.error(JCDiagnostic.DiagnosticFlag.NON_DEFERRABLE, pos, "cant.access", ex.sym, ex.getDetailValue());
-        if (ex instanceof ClassReader.BadClassFile
+        if (ex instanceof ClassFinder.BadClassFile
                 && !suppressAbortOnBadClassFile) throw new Abort();
         else return syms.errType;
     }
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java	Thu May 22 14:39:05 2014 -0700
@@ -96,7 +96,6 @@
     Symtab syms;
     Check chk;
     TreeMaker make;
-    ClassReader reader;
     Annotate annotate;
     MemberEnter memberEnter;
     Types types;
@@ -118,7 +117,6 @@
         context.put(enterKey, this);
 
         log = Log.instance(context);
-        reader = ClassReader.instance(context);
         make = TreeMaker.instance(context);
         syms = Symtab.instance(context);
         chk = Check.instance(context);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java	Thu May 22 14:39:05 2014 -0700
@@ -67,25 +67,24 @@
         return instance;
     }
 
-    private Names names;
-    private Log log;
-    private Symtab syms;
-    private Resolve rs;
-    private Check chk;
-    private Attr attr;
+    private final Names names;
+    private final Log log;
+    private final Symtab syms;
+    private final Resolve rs;
+    private final Check chk;
+    private final Attr attr;
     private TreeMaker make;
     private DiagnosticPosition make_pos;
-    private ClassWriter writer;
-    private ClassReader reader;
-    private ConstFold cfolder;
-    private Target target;
-    private Source source;
-    private boolean allowEnums;
+    private final ClassWriter writer;
+    private final ConstFold cfolder;
+    private final Target target;
+    private final Source source;
+    private final boolean allowEnums;
     private final Name dollarAssertionsDisabled;
     private final Name classDollar;
-    private Types types;
-    private boolean debugLower;
-    private PkgInfo pkginfoOpt;
+    private final Types types;
+    private final boolean debugLower;
+    private final PkgInfo pkginfoOpt;
 
     protected Lower(Context context) {
         context.put(lowerKey, this);
@@ -97,7 +96,6 @@
         attr = Attr.instance(context);
         make = TreeMaker.instance(context);
         writer = ClassWriter.instance(context);
-        reader = ClassReader.instance(context);
         cfolder = ConstFold.instance(context);
         target = Target.instance(context);
         source = Source.instance(context);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Thu May 22 14:39:05 2014 -0700
@@ -25,10 +25,7 @@
 
 package com.sun.tools.javac.comp;
 
-import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.Map;
 import java.util.Set;
 
 import javax.tools.JavaFileObject;
@@ -49,6 +46,7 @@
 import static com.sun.tools.javac.code.TypeTag.ERROR;
 import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
+
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 
@@ -75,7 +73,6 @@
     private final Attr attr;
     private final Symtab syms;
     private final TreeMaker make;
-    private final ClassReader reader;
     private final Todo todo;
     private final Annotate annotate;
     private final TypeAnnotations typeAnnotations;
@@ -102,7 +99,6 @@
         attr = Attr.instance(context);
         syms = Symtab.instance(context);
         make = TreeMaker.instance(context);
-        reader = ClassReader.instance(context);
         todo = Todo.instance(context);
         annotate = Annotate.instance(context);
         typeAnnotations = TypeAnnotations.instance(context);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Thu May 22 14:39:05 2014 -0700
@@ -87,7 +87,7 @@
     DeferredAttr deferredAttr;
     Check chk;
     Infer infer;
-    ClassReader reader;
+    ClassFinder finder;
     TreeInfo treeinfo;
     Types types;
     JCDiagnostic.Factory diags;
@@ -121,7 +121,7 @@
         deferredAttr = DeferredAttr.instance(context);
         chk = Check.instance(context);
         infer = Infer.instance(context);
-        reader = ClassReader.instance(context);
+        finder = ClassFinder.instance(context);
         treeinfo = TreeInfo.instance(context);
         types = Types.instance(context);
         diags = JCDiagnostic.Factory.instance(context);
@@ -1886,9 +1886,9 @@
      */
     Symbol loadClass(Env<AttrContext> env, Name name) {
         try {
-            ClassSymbol c = reader.loadClass(name);
+            ClassSymbol c = finder.loadClass(name);
             return isAccessible(env, c) ? c : new AccessError(c);
-        } catch (ClassReader.BadClassFile err) {
+        } catch (ClassFinder.BadClassFile err) {
             throw err;
         } catch (CompletionFailure ex) {
             return typeNotFound;
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassFile.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassFile.java	Thu May 22 14:39:05 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -108,11 +108,21 @@
         V50(50, 0),   // JDK 1.6: stackmaps
         V51(51, 0),   // JDK 1.7
         V52(52, 0);   // JDK 1.8: lambda, type annos, param names
+        // JDK9 still marked as V52 // V53(53, 0);   // JDK 1.9
+
         Version(int major, int minor) {
             this.major = major;
             this.minor = minor;
         }
         public final int major, minor;
+
+        private static final Version MIN = values()[0];
+        /** Return the least version supported, MIN */
+        public static Version MIN() { return MIN; }
+
+        private static final Version MAX = values()[values().length-1];
+        /** Return the largest version supported, MAX */
+        public static Version MAX() { return MAX; }
     }
 
 
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Thu May 22 14:39:05 2014 -0700
@@ -35,13 +35,8 @@
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
-import javax.lang.model.SourceVersion;
 import javax.tools.JavaFileObject;
 import javax.tools.JavaFileManager;
-import javax.tools.JavaFileManager.Location;
-import javax.tools.StandardJavaFileManager;
-
-import static javax.tools.StandardLocation.*;
 
 import com.sun.tools.javac.comp.Annotate;
 import com.sun.tools.javac.code.*;
@@ -120,23 +115,6 @@
     public boolean saveParameterNames;
 
     /**
-     * Switch: cache completion failures unless -XDdev is used
-     */
-    private boolean cacheCompletionFailure;
-
-    /**
-     * Switch: prefer source files instead of newer when both source
-     * and class are available
-     **/
-    public boolean preferSource;
-
-    /**
-     * Switch: Search classpath and sourcepath for classes before the
-     * bootclasspath
-     */
-    public boolean userPathsFirst;
-
-    /**
      * The currently selected profile.
      */
     public final Profile profile;
@@ -153,10 +131,6 @@
     /** The name table. */
     final Names names;
 
-    /** Force a completion failure on this name
-     */
-    final Name completionFailureName;
-
     /** Access to files
      */
     private final JavaFileManager fileManager;
@@ -165,12 +139,6 @@
      */
     JCDiagnostic.Factory diagFactory;
 
-    /** Can be reassigned from outside:
-     *  the completer to be used for ".java" files. If this remains unassigned
-     *  ".java" files will not be loaded.
-     */
-    public SourceCompleter sourceCompleter = null;
-
     /** The current scope where type variables are entered.
      */
     protected Scope typevars;
@@ -227,20 +195,6 @@
      */
     Set<Name> warnedAttrs = new HashSet<>();
 
-    /**
-     * Completer that delegates to the complete-method of this class.
-     */
-    private final Completer thisCompleter = new Completer() {
-        @Override
-        public void complete(Symbol sym) throws CompletionFailure {
-            ClassReader.this.complete(sym);
-        }
-    };
-
-    public Completer getCompleter() {
-        return thisCompleter;
-    }
-
     /** Get the ClassReader instance for this invocation. */
     public static ClassReader instance(Context context) {
         ClassReader instance = context.get(classReaderKey);
@@ -274,17 +228,9 @@
         allowSimplifiedVarargs = source.allowSimplifiedVarargs();
 
         saveParameterNames = options.isSet("save-parameter-names");
-        cacheCompletionFailure = options.isUnset("dev");
-        preferSource = "source".equals(options.get("-Xprefer"));
-        userPathsFirst = options.isSet(XXUSERPATHSFIRST);
 
         profile = Profile.instance(context);
 
-        completionFailureName =
-            options.isSet("failcomplete")
-            ? names.fromString(options.get("failcomplete"))
-            : null;
-
         typevars = new Scope(syms.noSymbol);
 
         lintClassfile = Lint.instance(context).isEnabled(LintCategory.CLASSFILE);
@@ -305,26 +251,12 @@
  * Error Diagnoses
  ***********************************************************************/
 
-
-    public class BadClassFile extends CompletionFailure {
-        private static final long serialVersionUID = 0;
-
-        public BadClassFile(TypeSymbol sym, JavaFileObject file, JCDiagnostic diag) {
-            super(sym, createBadClassFileDiagnostic(file, diag));
-        }
-    }
-    // where
-    private JCDiagnostic createBadClassFileDiagnostic(JavaFileObject file, JCDiagnostic diag) {
-        String key = (file.getKind() == JavaFileObject.Kind.SOURCE
-                    ? "bad.source.file.header" : "bad.class.file.header");
-        return diagFactory.fragment(key, file, diag);
-    }
-
-    public BadClassFile badClassFile(String key, Object... args) {
-        return new BadClassFile (
+    public ClassFinder.BadClassFile badClassFile(String key, Object... args) {
+        return new ClassFinder.BadClassFile (
             currentOwner.enclClass(),
             currentClassFile,
-            diagFactory.fragment(key, args));
+            diagFactory.fragment(key, args),
+            diagFactory);
     }
 
 /************************************************************************
@@ -1501,7 +1433,7 @@
         int tag = nextByte(); // TargetType tag is a byte
 
         if (!TargetType.isValidTargetTypeValue(tag))
-            throw this.badClassFile("bad.type.annotation.value", String.format("0x%02X", tag));
+            throw badClassFile("bad.type.annotation.value", String.format("0x%02X", tag));
 
         TargetType type = TargetType.fromTargetTypeValue(tag);
 
@@ -2080,8 +2012,8 @@
         Type type = readType(nextChar());
         if (currentOwner.isInterface() &&
                 (flags & ABSTRACT) == 0 && !name.equals(names.clinit)) {
-            if (majorVersion > Target.JDK1_8.majorVersion ||
-                    (majorVersion == Target.JDK1_8.majorVersion && minorVersion >= Target.JDK1_8.minorVersion)) {
+            if (majorVersion > Version.V52.major ||
+                    (majorVersion == Version.V52.major && minorVersion >= Version.V52.minor)) {
                 if ((flags & STATIC) == 0) {
                     currentOwner.flags_field |= DEFAULT;
                     flags |= DEFAULT | ABSTRACT;
@@ -2353,20 +2285,20 @@
         }
     }
 
-    /** Read a class file.
+    /** Read a class definition from the bytes in buf.
      */
-    private void readClassFile(ClassSymbol c) throws IOException {
+    private void readClassBuffer(ClassSymbol c) throws IOException {
         int magic = nextInt();
         if (magic != JAVA_MAGIC)
             throw badClassFile("illegal.start.of.class.file");
 
         minorVersion = nextChar();
         majorVersion = nextChar();
-        int maxMajor = Target.MAX().majorVersion;
-        int maxMinor = Target.MAX().minorVersion;
+        int maxMajor = Version.MAX().major;
+        int maxMinor = Version.MAX().minor;
         if (majorVersion > maxMajor ||
             majorVersion * 1000 + minorVersion <
-            Target.MIN().majorVersion * 1000 + Target.MIN().minorVersion)
+            Version.MIN().major * 1000 + Version.MIN().minor)
         {
             if (majorVersion == (maxMajor + 1))
                 log.warning("big.major.version",
@@ -2395,162 +2327,39 @@
         readClass(c);
     }
 
-/************************************************************************
- * Adjusting flags
- ***********************************************************************/
-
-    long adjustFieldFlags(long flags) {
-        return flags;
-    }
-    long adjustMethodFlags(long flags) {
-        if ((flags & ACC_BRIDGE) != 0) {
-            flags &= ~ACC_BRIDGE;
-            flags |= BRIDGE;
-            if (!allowGenerics)
-                flags &= ~SYNTHETIC;
-        }
-        if ((flags & ACC_VARARGS) != 0) {
-            flags &= ~ACC_VARARGS;
-            flags |= VARARGS;
-        }
-        return flags;
-    }
-    long adjustClassFlags(long flags) {
-        return flags & ~ACC_SUPER; // SUPER and SYNCHRONIZED bits overloaded
-    }
-
-/************************************************************************
- * Loading Classes
- ***********************************************************************/
-
-    /** Completion for classes to be loaded. Before a class is loaded
-     *  we make sure its enclosing class (if any) is loaded.
-     */
-    private void complete(Symbol sym) throws CompletionFailure {
-        if (sym.kind == TYP) {
-            ClassSymbol c = (ClassSymbol)sym;
-            c.members_field = new Scope.ErrorScope(c); // make sure it's always defined
-            annotate.enterStart();
-            try {
-                completeOwners(c.owner);
-                completeEnclosing(c);
-            } finally {
-                // The flush needs to happen only after annotations
-                // are filled in.
-                annotate.enterDoneWithoutFlush();
-            }
-            fillIn(c);
-        } else if (sym.kind == PCK) {
-            PackageSymbol p = (PackageSymbol)sym;
-            try {
-                fillIn(p);
-            } catch (IOException ex) {
-                throw new CompletionFailure(sym, ex.getLocalizedMessage()).initCause(ex);
+    public void readClassFile(ClassSymbol c) {
+        currentOwner = c;
+        currentClassFile = c.classfile;
+        warnedAttrs.clear();
+        filling = true;
+        try {
+            bp = 0;
+            buf = readInputStream(buf, c.classfile.openInputStream());
+            readClassBuffer(c);
+            if (!missingTypeVariables.isEmpty() && !foundTypeVariables.isEmpty()) {
+                List<Type> missing = missingTypeVariables;
+                List<Type> found = foundTypeVariables;
+                missingTypeVariables = List.nil();
+                foundTypeVariables = List.nil();
+                filling = false;
+                ClassType ct = (ClassType)currentOwner.type;
+                ct.supertype_field =
+                    types.subst(ct.supertype_field, missing, found);
+                ct.interfaces_field =
+                    types.subst(ct.interfaces_field, missing, found);
+            } else if (missingTypeVariables.isEmpty() !=
+                       foundTypeVariables.isEmpty()) {
+                Name name = missingTypeVariables.head.tsym.name;
+                throw badClassFile("undecl.type.var", name);
             }
-        }
-        if (!filling)
-            annotate.flush(); // finish attaching annotations
-    }
-
-    /** complete up through the enclosing package. */
-    private void completeOwners(Symbol o) {
-        if (o.kind != PCK) completeOwners(o.owner);
-        o.complete();
-    }
-
-    /**
-     * Tries to complete lexically enclosing classes if c looks like a
-     * nested class.  This is similar to completeOwners but handles
-     * the situation when a nested class is accessed directly as it is
-     * possible with the Tree API or javax.lang.model.*.
-     */
-    private void completeEnclosing(ClassSymbol c) {
-        if (c.owner.kind == PCK) {
-            Symbol owner = c.owner;
-            for (Name name : Convert.enclosingCandidates(Convert.shortName(c.name))) {
-                Symbol encl = owner.members().lookup(name).sym;
-                if (encl == null)
-                    encl = syms.classes.get(TypeSymbol.formFlatName(name, owner));
-                if (encl != null)
-                    encl.complete();
-            }
-        }
-    }
-
-    /** We can only read a single class file at a time; this
-     *  flag keeps track of when we are currently reading a class
-     *  file.
-     */
-    private boolean filling = false;
-
-    /** Fill in definition of class `c' from corresponding class or
-     *  source file.
-     */
-    private void fillIn(ClassSymbol c) {
-        if (completionFailureName == c.fullname) {
-            throw new CompletionFailure(c, "user-selected completion failure by class name");
-        }
-        currentOwner = c;
-        warnedAttrs.clear();
-        JavaFileObject classfile = c.classfile;
-        if (classfile != null) {
-            JavaFileObject previousClassFile = currentClassFile;
-            try {
-                if (filling) {
-                    Assert.error("Filling " + classfile.toUri() + " during " + previousClassFile);
-                }
-                currentClassFile = classfile;
-                if (verbose) {
-                    log.printVerbose("loading", currentClassFile.toString());
-                }
-                if (classfile.getKind() == JavaFileObject.Kind.CLASS) {
-                    filling = true;
-                    try {
-                        bp = 0;
-                        buf = readInputStream(buf, classfile.openInputStream());
-                        readClassFile(c);
-                        if (!missingTypeVariables.isEmpty() && !foundTypeVariables.isEmpty()) {
-                            List<Type> missing = missingTypeVariables;
-                            List<Type> found = foundTypeVariables;
-                            missingTypeVariables = List.nil();
-                            foundTypeVariables = List.nil();
-                            filling = false;
-                            ClassType ct = (ClassType)currentOwner.type;
-                            ct.supertype_field =
-                                types.subst(ct.supertype_field, missing, found);
-                            ct.interfaces_field =
-                                types.subst(ct.interfaces_field, missing, found);
-                        } else if (missingTypeVariables.isEmpty() !=
-                                   foundTypeVariables.isEmpty()) {
-                            Name name = missingTypeVariables.head.tsym.name;
-                            throw badClassFile("undecl.type.var", name);
-                        }
-                    } finally {
-                        missingTypeVariables = List.nil();
-                        foundTypeVariables = List.nil();
-                        filling = false;
-                    }
-                } else {
-                    if (sourceCompleter != null) {
-                        sourceCompleter.complete(c);
-                    } else {
-                        throw new IllegalStateException("Source completer required to read "
-                                                        + classfile.toUri());
-                    }
-                }
-                return;
-            } catch (IOException ex) {
-                throw badClassFile("unable.to.access.file", ex.getMessage());
-            } catch (ArrayIndexOutOfBoundsException ex) {
-                throw badClassFile("bad.class.file", c.flatname);
-            } finally {
-                currentClassFile = previousClassFile;
-            }
-        } else {
-            JCDiagnostic diag =
-                diagFactory.fragment("class.file.not.found", c.flatname);
-            throw
-                newCompletionFailure(c, diag);
+        } catch (IOException ex) {
+            throw badClassFile("unable.to.access.file", ex.getMessage());
+        } catch (ArrayIndexOutOfBoundsException ex) {
+            throw badClassFile("bad.class.file", c.flatname);
+        } finally {
+            missingTypeVariables = List.nil();
+            foundTypeVariables = List.nil();
+            filling = false;
         }
     }
     // where
@@ -2590,253 +2399,39 @@
             }
             return buf;
         }
-        /** Static factory for CompletionFailure objects.
-         *  In practice, only one can be used at a time, so we share one
-         *  to reduce the expense of allocating new exception objects.
-         */
-        private CompletionFailure newCompletionFailure(TypeSymbol c,
-                                                       JCDiagnostic diag) {
-            if (!cacheCompletionFailure) {
-                // log.warning("proc.messager",
-                //             Log.getLocalizedString("class.file.not.found", c.flatname));
-                // c.debug.printStackTrace();
-                return new CompletionFailure(c, diag);
-            } else {
-                CompletionFailure result = cachedCompletionFailure;
-                result.sym = c;
-                result.diag = diag;
-                return result;
-            }
-        }
-        private CompletionFailure cachedCompletionFailure =
-            new CompletionFailure(null, (JCDiagnostic) null);
-        {
-            cachedCompletionFailure.setStackTrace(new StackTraceElement[0]);
-        }
 
-
-    /** Load a toplevel class with given fully qualified name
-     *  The class is entered into `classes' only if load was successful.
+    /** We can only read a single class file at a time; this
+     *  flag keeps track of when we are currently reading a class
+     *  file.
      */
-    public ClassSymbol loadClass(Name flatname) throws CompletionFailure {
-        boolean absent = syms.classes.get(flatname) == null;
-        ClassSymbol c = syms.enterClass(flatname);
-        if (c.members_field == null && c.completer != null) {
-            try {
-                c.complete();
-            } catch (CompletionFailure ex) {
-                if (absent) syms.classes.remove(flatname);
-                throw ex;
-            }
-        }
-        return c;
-    }
+    public boolean filling = false;
 
 /************************************************************************
- * Loading Packages
+ * Adjusting flags
  ***********************************************************************/
 
-    /** Include class corresponding to given class file in package,
-     *  unless (1) we already have one the same kind (.class or .java), or
-     *         (2) we have one of the other kind, and the given class file
-     *             is older.
-     */
-    protected void includeClassFile(PackageSymbol p, JavaFileObject file) {
-        if ((p.flags_field & EXISTS) == 0)
-            for (Symbol q = p; q != null && q.kind == PCK; q = q.owner)
-                q.flags_field |= EXISTS;
-        JavaFileObject.Kind kind = file.getKind();
-        int seen;
-        if (kind == JavaFileObject.Kind.CLASS)
-            seen = CLASS_SEEN;
-        else
-            seen = SOURCE_SEEN;
-        String binaryName = fileManager.inferBinaryName(currentLoc, file);
-        int lastDot = binaryName.lastIndexOf(".");
-        Name classname = names.fromString(binaryName.substring(lastDot + 1));
-        boolean isPkgInfo = classname == names.package_info;
-        ClassSymbol c = isPkgInfo
-            ? p.package_info
-            : (ClassSymbol) p.members_field.lookup(classname).sym;
-        if (c == null) {
-            c = syms.enterClass(classname, p);
-            if (c.classfile == null) // only update the file if's it's newly created
-                c.classfile = file;
-            if (isPkgInfo) {
-                p.package_info = c;
-            } else {
-                if (c.owner == p)  // it might be an inner class
-                    p.members_field.enter(c);
-            }
-        } else if (!preferCurrent && c.classfile != null && (c.flags_field & seen) == 0) {
-            // if c.classfile == null, we are currently compiling this class
-            // and no further action is necessary.
-            // if (c.flags_field & seen) != 0, we have already encountered
-            // a file of the same kind; again no further action is necessary.
-            if ((c.flags_field & (CLASS_SEEN | SOURCE_SEEN)) != 0)
-                c.classfile = preferredFileObject(file, c.classfile);
-        }
-        c.flags_field |= seen;
-    }
-
-    /** Implement policy to choose to derive information from a source
-     *  file or a class file when both are present.  May be overridden
-     *  by subclasses.
-     */
-    protected JavaFileObject preferredFileObject(JavaFileObject a,
-                                           JavaFileObject b) {
-
-        if (preferSource)
-            return (a.getKind() == JavaFileObject.Kind.SOURCE) ? a : b;
-        else {
-            long adate = a.getLastModified();
-            long bdate = b.getLastModified();
-            // 6449326: policy for bad lastModifiedTime in ClassReader
-            //assert adate >= 0 && bdate >= 0;
-            return (adate > bdate) ? a : b;
-        }
-    }
-
-    /**
-     * specifies types of files to be read when filling in a package symbol
-     */
-    protected EnumSet<JavaFileObject.Kind> getPackageFileKinds() {
-        return EnumSet.of(JavaFileObject.Kind.CLASS, JavaFileObject.Kind.SOURCE);
-    }
-
-    /**
-     * this is used to support javadoc
-     */
-    protected void extraFileActions(PackageSymbol pack, JavaFileObject fe) {
+    long adjustFieldFlags(long flags) {
+        return flags;
     }
 
-    protected Location currentLoc; // FIXME
-
-    private boolean verbosePath = true;
-
-    // Set to true when the currently selected file should be kept
-    private boolean preferCurrent;
-
-    /** Load directory of package into members scope.
-     */
-    private void fillIn(PackageSymbol p) throws IOException {
-        if (p.members_field == null)
-            p.members_field = new Scope(p);
-
-        preferCurrent = false;
-        if (userPathsFirst) {
-            scanUserPaths(p);
-            preferCurrent = true;
-            scanPlatformPath(p);
-        } else {
-            scanPlatformPath(p);
-            scanUserPaths(p);
+    long adjustMethodFlags(long flags) {
+        if ((flags & ACC_BRIDGE) != 0) {
+            flags &= ~ACC_BRIDGE;
+            flags |= BRIDGE;
+            if (!allowGenerics)
+                flags &= ~SYNTHETIC;
         }
-        verbosePath = false;
+        if ((flags & ACC_VARARGS) != 0) {
+            flags &= ~ACC_VARARGS;
+            flags |= VARARGS;
+        }
+        return flags;
     }
 
-    /**
-     * Scans class path and source path for files in given package.
-     */
-    private void scanUserPaths(PackageSymbol p) throws IOException {
-        Set<JavaFileObject.Kind> kinds = getPackageFileKinds();
-
-        Set<JavaFileObject.Kind> classKinds = EnumSet.copyOf(kinds);
-        classKinds.remove(JavaFileObject.Kind.SOURCE);
-        boolean wantClassFiles = !classKinds.isEmpty();
-
-        Set<JavaFileObject.Kind> sourceKinds = EnumSet.copyOf(kinds);
-        sourceKinds.remove(JavaFileObject.Kind.CLASS);
-        boolean wantSourceFiles = !sourceKinds.isEmpty();
-
-        boolean haveSourcePath = fileManager.hasLocation(SOURCE_PATH);
-
-        if (verbose && verbosePath) {
-            if (fileManager instanceof StandardJavaFileManager) {
-                StandardJavaFileManager fm = (StandardJavaFileManager)fileManager;
-                if (haveSourcePath && wantSourceFiles) {
-                    List<File> path = List.nil();
-                    for (File file : fm.getLocation(SOURCE_PATH)) {
-                        path = path.prepend(file);
-                    }
-                    log.printVerbose("sourcepath", path.reverse().toString());
-                } else if (wantSourceFiles) {
-                    List<File> path = List.nil();
-                    for (File file : fm.getLocation(CLASS_PATH)) {
-                        path = path.prepend(file);
-                    }
-                    log.printVerbose("sourcepath", path.reverse().toString());
-                }
-                if (wantClassFiles) {
-                    List<File> path = List.nil();
-                    for (File file : fm.getLocation(PLATFORM_CLASS_PATH)) {
-                        path = path.prepend(file);
-                    }
-                    for (File file : fm.getLocation(CLASS_PATH)) {
-                        path = path.prepend(file);
-                    }
-                    log.printVerbose("classpath",  path.reverse().toString());
-                }
-            }
-        }
-
-        String packageName = p.fullname.toString();
-        if (wantSourceFiles && !haveSourcePath) {
-            fillIn(p, CLASS_PATH,
-                   fileManager.list(CLASS_PATH,
-                                    packageName,
-                                    kinds,
-                                    false));
-        } else {
-            if (wantClassFiles)
-                fillIn(p, CLASS_PATH,
-                       fileManager.list(CLASS_PATH,
-                                        packageName,
-                                        classKinds,
-                                        false));
-            if (wantSourceFiles)
-                fillIn(p, SOURCE_PATH,
-                       fileManager.list(SOURCE_PATH,
-                                        packageName,
-                                        sourceKinds,
-                                        false));
-        }
+    long adjustClassFlags(long flags) {
+        return flags & ~ACC_SUPER; // SUPER and SYNCHRONIZED bits overloaded
     }
 
-    /**
-     * Scans platform class path for files in given package.
-     */
-    private void scanPlatformPath(PackageSymbol p) throws IOException {
-        fillIn(p, PLATFORM_CLASS_PATH,
-               fileManager.list(PLATFORM_CLASS_PATH,
-                                p.fullname.toString(),
-                                EnumSet.of(JavaFileObject.Kind.CLASS),
-                                false));
-    }
-    // where
-        private void fillIn(PackageSymbol p,
-                            Location location,
-                            Iterable<JavaFileObject> files)
-        {
-            currentLoc = location;
-            for (JavaFileObject fo : files) {
-                switch (fo.getKind()) {
-                case CLASS:
-                case SOURCE: {
-                    // TODO pass binaryName to includeClassFile
-                    String binaryName = fileManager.inferBinaryName(currentLoc, fo);
-                    String simpleName = binaryName.substring(binaryName.lastIndexOf(".") + 1);
-                    if (SourceVersion.isIdentifier(simpleName) ||
-                        simpleName.equals("package-info"))
-                        includeClassFile(p, fo);
-                    break;
-                }
-                default:
-                    extraFileActions(p, fo);
-                }
-            }
-        }
-
     /** Output for "-checkclassfile" option.
      *  @param key The key to look up the correct internationalized string.
      *  @param arg An argument for substitution into the output string.
@@ -2845,12 +2440,6 @@
         log.printLines(key, arg);
     }
 
-
-    public interface SourceCompleter {
-        void complete(ClassSymbol sym)
-            throws CompletionFailure;
-    }
-
     /**
      * A subclass of JavaFileObject for the sourcefile attribute found in a classfile.
      * The attribute is only the last component of the original filename, so is unlikely
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Thu May 22 14:39:05 2014 -0700
@@ -459,11 +459,11 @@
                 poolbuf.appendChar(pool.put(names.fromString((String)value)));
             } else if (value instanceof UniqueType) {
                 Type type = ((UniqueType)value).type;
-                if (type instanceof MethodType) {
+                if (type.hasTag(METHOD)) {
                     poolbuf.appendByte(CONSTANT_MethodType);
                     poolbuf.appendChar(pool.put(typeSig((MethodType)type)));
                 } else {
-                    if (type.hasTag(CLASS)) enterInner((ClassSymbol)type.tsym);
+                    Assert.check(type.hasTag(ARRAY));
                     poolbuf.appendByte(CONSTANT_Class);
                     poolbuf.appendChar(pool.put(xClassName(type)));
                 }
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Pool.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Pool.java	Thu May 22 14:39:05 2014 -0700
@@ -28,6 +28,7 @@
 import com.sun.tools.javac.code.Kinds;
 import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.code.TypeTag;
 import com.sun.tools.javac.code.Type;
 import com.sun.tools.javac.code.Types;
 import com.sun.tools.javac.code.Types.UniqueType;
@@ -127,7 +128,14 @@
         } else if (o instanceof VarSymbol) {
             return new Variable((VarSymbol)o, types);
         } else if (o instanceof Type) {
-            return new UniqueType((Type)o, types);
+            Type t = (Type)o;
+            // ClassRefs can come from ClassSymbols or from Types.
+            // Return the symbol for these types to avoid duplicates
+            // in the constant pool
+            if (t.hasTag(TypeTag.CLASS))
+                return t.tsym;
+            else
+                return new UniqueType(t, types);
         } else {
             return o;
         }
--- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Thu May 22 14:39:05 2014 -0700
@@ -219,6 +219,10 @@
      */
     protected TreeMaker make;
 
+    /** The class finder.
+     */
+    protected ClassFinder finder;
+
     /** The class reader.
      */
     protected ClassReader reader;
@@ -296,13 +300,13 @@
     protected MultiTaskListener taskListener;
 
     /**
-     * SourceCompleter that delegates to the complete-method of this class.
+     * SourceCompleter that delegates to the readSourceFile method of this class.
      */
-    protected final ClassReader.SourceCompleter thisCompleter =
-            new ClassReader.SourceCompleter() {
+    protected final Symbol.Completer sourceCompleter =
+            new Symbol.Completer() {
                 @Override
-                public void complete(ClassSymbol sym) throws CompletionFailure {
-                    JavaCompiler.this.complete(sym);
+                public void complete(Symbol sym) throws CompletionFailure {
+                    readSourceFile((ClassSymbol) sym);
                 }
             };
 
@@ -338,6 +342,7 @@
         names = Names.instance(context);
         log = Log.instance(context);
         diagFactory = JCDiagnostic.Factory.instance(context);
+        finder = ClassFinder.instance(context);
         reader = ClassReader.instance(context);
         make = TreeMaker.instance(context);
         writer = ClassWriter.instance(context);
@@ -355,7 +360,7 @@
         } catch (CompletionFailure ex) {
             // inlined Check.completionError as it is not initialized yet
             log.error("cant.access", ex.sym, ex.getDetailValue());
-            if (ex instanceof ClassReader.BadClassFile)
+            if (ex instanceof ClassFinder.BadClassFile)
                 throw new Abort();
         }
         source = Source.instance(context);
@@ -370,7 +375,7 @@
         types = Types.instance(context);
         taskListener = MultiTaskListener.instance(context);
 
-        reader.sourceCompleter = thisCompleter;
+        finder.sourceCompleter = sourceCompleter;
 
         options = Options.instance(context);
 
@@ -663,7 +668,7 @@
     public Symbol resolveBinaryNameOrIdent(String name) {
         try {
             Name flatname = names.fromString(name.replace("/", "."));
-            return reader.loadClass(flatname);
+            return finder.loadClass(flatname);
         } catch (CompletionFailure ignore) {
             return resolveIdent(name);
         }
@@ -737,22 +742,20 @@
         return null;
     }
 
-    /** Complete compiling a source file that has been accessed
-     *  by the class file reader.
+    /** Compile a source file that has been accessed by the class finder.
      *  @param c          The class the source file of which needs to be compiled.
      */
-    public void complete(ClassSymbol c) throws CompletionFailure {
-        complete(null, c);
+    private void readSourceFile(ClassSymbol c) throws CompletionFailure {
+        readSourceFile(null, c);
     }
 
-    /** Complete a ClassSymbol from source, optionally using the given compilation unit as
+    /** Compile a ClassSymbol from source, optionally using the given compilation unit as
      *  the source tree.
-     *  @param tree the compilation unit int which the given ClassSymbol resides,
+     *  @param tree the compilation unit in which the given ClassSymbol resides,
      *              or null if should be parsed from source
      *  @param c    the ClassSymbol to complete
      */
-    public void complete(JCCompilationUnit tree, ClassSymbol c) throws CompletionFailure {
-//      System.err.println("completing " + c);//DEBUG
+    public void readSourceFile(JCCompilationUnit tree, ClassSymbol c) throws CompletionFailure {
         if (completionFailureName == c.fullname) {
             throw new CompletionFailure(c, "user-selected completion failure by class name");
         }
@@ -791,13 +794,13 @@
                     JCDiagnostic diag =
                         diagFactory.fragment("file.does.not.contain.package",
                                                  c.location());
-                    throw reader.new BadClassFile(c, filename, diag);
+                    throw new ClassFinder.BadClassFile(c, filename, diag, diagFactory);
                 }
             } else {
                 JCDiagnostic diag =
                         diagFactory.fragment("file.doesnt.contain.class",
                                             c.getQualifiedName());
-                throw reader.new BadClassFile(c, filename, diag);
+                throw new ClassFinder.BadClassFile(c, filename, diag, diagFactory);
             }
         }
 
@@ -1663,6 +1666,7 @@
      */
     public void close() {
         rootClasses = null;
+        finder = null;
         reader = null;
         make = null;
         writer = null;
--- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Thu May 22 14:39:05 2014 -0700
@@ -54,8 +54,6 @@
 import com.sun.tools.javac.comp.Enter;
 import com.sun.tools.javac.comp.Env;
 import com.sun.tools.javac.file.JavacFileManager;
-import com.sun.tools.javac.jvm.*;
-import com.sun.tools.javac.jvm.ClassReader.BadClassFile;
 import com.sun.tools.javac.main.JavaCompiler;
 import com.sun.tools.javac.model.JavacElements;
 import com.sun.tools.javac.model.JavacTypes;
@@ -203,7 +201,7 @@
         symtab = Symtab.instance(context);
         names = Names.instance(context);
         enter = Enter.instance(context);
-        initialCompleter = ClassReader.instance(context).getCompleter();
+        initialCompleter = ClassFinder.instance(context).getCompleter();
         chk = Check.instance(context);
         initProcessorClassLoader();
     }
@@ -799,7 +797,7 @@
                                          RoundEnvironment renv) {
         try {
             return proc.process(tes, renv);
-        } catch (BadClassFile ex) {
+        } catch (ClassFinder.BadClassFile ex) {
             log.error("proc.cant.access.1", ex.sym, ex.getDetailValue());
             return false;
         } catch (CompletionFailure ex) {
@@ -1308,7 +1306,7 @@
         }
 
         @Override public void complete(Symbol sym) throws CompletionFailure {
-            compiler.complete(topLevel, (ClassSymbol) sym);
+            compiler.readSourceFile(topLevel, (ClassSymbol) sym);
         }
     }
 
--- a/langtools/src/share/classes/com/sun/tools/javac/util/StringUtils.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/StringUtils.java	Thu May 22 14:39:05 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
 package com.sun.tools.javac.util;
 
 import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /** A collection of utilities for String manipulation.
  *
@@ -50,4 +52,19 @@
         return source.toUpperCase(Locale.US);
     }
 
+    /**Case insensitive version of {@link String#indexOf(java.lang.String)}. Equivalent to
+     * {@code text.indexOf(str)}, except the matching is case insensitive.
+     */
+    public static int indexOfIgnoreCase(String text, String str) {
+        return indexOfIgnoreCase(text, str, 0);
+    }
+
+    /**Case insensitive version of {@link String#indexOf(java.lang.String, int)}. Equivalent to
+     * {@code text.indexOf(str, startIndex)}, except the matching is case insensitive.
+     */
+    public static int indexOfIgnoreCase(String text, String str, int startIndex) {
+        Matcher m = Pattern.compile(Pattern.quote(str), Pattern.CASE_INSENSITIVE).matcher(text);
+        return m.find(startIndex) ? m.start() : -1;
+    }
+
 }
--- a/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java	Thu May 22 14:39:05 2014 -0700
@@ -37,11 +37,19 @@
 import com.sun.tools.javac.api.BasicJavacTask;
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.code.Symbol.CompletionFailure;
+import com.sun.tools.javac.code.Symbol.MethodSymbol;
+import com.sun.tools.javac.code.Symbol.PackageSymbol;
+import com.sun.tools.javac.code.Symbol.VarSymbol;
 import com.sun.tools.javac.code.Type.ClassType;
 import com.sun.tools.javac.comp.Check;
+import com.sun.tools.javac.comp.Enter;
 import com.sun.tools.javac.file.JavacFileManager;
 import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.tree.JCTree.*;
+import com.sun.tools.javac.tree.JCTree.JCClassDecl;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
+import com.sun.tools.javac.tree.JCTree.JCPackageDecl;
 import com.sun.tools.javac.util.Context;
 import com.sun.tools.javac.util.Names;
 
@@ -71,21 +79,21 @@
         return instance;
     }
 
-    private Messager messager;
-
     DocLocale doclocale;
 
+    private final Messager messager;
+
     /** Predefined symbols known to the compiler. */
-    Symtab syms;
+    final Symtab syms;
 
     /** Referenced directly in RootDocImpl. */
-    JavadocClassReader reader;
+    private final ClassFinder finder;
 
     /** Javadoc's own version of the compiler's enter phase. */
-    JavadocEnter enter;
+    final Enter enter;
 
     /** The name table. */
-    Names names;
+    private Names names;
 
     /** The encoding name. */
     private String encoding;
@@ -139,8 +147,8 @@
 
         messager = Messager.instance0(context);
         syms = Symtab.instance(context);
-        reader = JavadocClassReader.instance0(context);
-        enter = JavadocEnter.instance0(context);
+        finder = JavadocClassFinder.instance(context);
+        enter = JavadocEnter.instance(context);
         names = Names.instance(context);
         externalizableSym = syms.enterClass(names.fromString("java.io.Externalizable"));
         chk = Check.instance(context);
@@ -176,7 +184,7 @@
      */
     public ClassDocImpl loadClass(String name) {
         try {
-            ClassSymbol c = reader.loadClass(names.fromString(name));
+            ClassSymbol c = finder.loadClass(names.fromString(name));
             return getClassDoc(c);
         } catch (CompletionFailure ex) {
             chk.completionError(null, ex);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocClassFinder.java	Thu May 22 14:39:05 2014 -0700
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2001, 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.javadoc;
+
+import java.util.EnumSet;
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.javac.code.Symbol.PackageSymbol;
+import com.sun.tools.javac.code.ClassFinder;
+import com.sun.tools.javac.util.Context;
+
+/** Javadoc uses an extended class finder that records package.html entries
+ *
+ *  <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>
+ *
+ *  @author Neal Gafter
+ */
+public class JavadocClassFinder extends ClassFinder {
+
+    public static JavadocClassFinder instance(Context context) {
+        ClassFinder instance = context.get(classFinderKey);
+        if (instance == null)
+            instance = new JavadocClassFinder(context);
+        return (JavadocClassFinder)instance;
+    }
+
+    public static void preRegister(Context context) {
+        context.put(classFinderKey, new Context.Factory<ClassFinder>() {
+            public ClassFinder make(Context c) {
+                return new JavadocClassFinder(c);
+            }
+        });
+    }
+
+    private DocEnv docenv;
+    private EnumSet<JavaFileObject.Kind> all = EnumSet.of(JavaFileObject.Kind.CLASS,
+                                                          JavaFileObject.Kind.SOURCE,
+                                                          JavaFileObject.Kind.HTML);
+    private EnumSet<JavaFileObject.Kind> noSource = EnumSet.of(JavaFileObject.Kind.CLASS,
+                                                               JavaFileObject.Kind.HTML);
+
+    public JavadocClassFinder(Context context) {
+        super(context);
+        docenv = DocEnv.instance(context);
+        preferSource = true;
+    }
+
+    /**
+     * Override getPackageFileKinds to include search for package.html
+     */
+    @Override
+    protected EnumSet<JavaFileObject.Kind> getPackageFileKinds() {
+        return docenv.docClasses ? noSource : all;
+    }
+
+    /**
+     * Override extraFileActions to check for package documentation
+     */
+    @Override
+    protected void extraFileActions(PackageSymbol pack, JavaFileObject fo) {
+        if (fo.isNameCompatible("package", JavaFileObject.Kind.HTML))
+            docenv.getPackageDoc(pack).setDocPath(fo);
+    }
+}
--- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocClassReader.java	Thu May 22 12:54:10 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2001, 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.javadoc;
-
-import java.util.EnumSet;
-import javax.tools.JavaFileObject;
-
-import com.sun.tools.javac.code.Symbol.PackageSymbol;
-import com.sun.tools.javac.jvm.ClassReader;
-import com.sun.tools.javac.util.Context;
-
-/** Javadoc uses an extended class reader that records package.html entries
- *
- *  <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>
- *
- *  @author Neal Gafter
- */
-public class JavadocClassReader extends ClassReader {
-
-    public static JavadocClassReader instance0(Context context) {
-        ClassReader instance = context.get(classReaderKey);
-        if (instance == null)
-            instance = new JavadocClassReader(context);
-        return (JavadocClassReader)instance;
-    }
-
-    public static void preRegister(Context context) {
-        context.put(classReaderKey, new Context.Factory<ClassReader>() {
-            public ClassReader make(Context c) {
-                return new JavadocClassReader(c);
-            }
-        });
-    }
-
-    private DocEnv docenv;
-    private EnumSet<JavaFileObject.Kind> all = EnumSet.of(JavaFileObject.Kind.CLASS,
-                                                          JavaFileObject.Kind.SOURCE,
-                                                          JavaFileObject.Kind.HTML);
-    private EnumSet<JavaFileObject.Kind> noSource = EnumSet.of(JavaFileObject.Kind.CLASS,
-                                                               JavaFileObject.Kind.HTML);
-
-    public JavadocClassReader(Context context) {
-        super(context);
-        docenv = DocEnv.instance(context);
-        preferSource = true;
-    }
-
-    /**
-     * Override getPackageFileKinds to include search for package.html
-     */
-    @Override
-    protected EnumSet<JavaFileObject.Kind> getPackageFileKinds() {
-        return docenv.docClasses ? noSource : all;
-    }
-
-    /**
-     * Override extraFileActions to check for package documentation
-     */
-    @Override
-    protected void extraFileActions(PackageSymbol pack, JavaFileObject fo) {
-        if (fo.isNameCompatible("package", JavaFileObject.Kind.HTML))
-            docenv.getPackageDoc(pack).setDocPath(fo);
-    }
-}
--- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocEnter.java	Thu May 22 14:39:05 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -48,7 +48,7 @@
  *  @author Neal Gafter
  */
 public class JavadocEnter extends Enter {
-    public static JavadocEnter instance0(Context context) {
+    public static JavadocEnter instance(Context context) {
         Enter instance = context.get(enterKey);
         if (instance == null)
             instance = new JavadocEnter(context);
--- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java	Thu May 22 14:39:05 2014 -0700
@@ -33,12 +33,15 @@
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
+
 import javax.tools.JavaFileManager.Location;
 import javax.tools.JavaFileObject;
 import javax.tools.StandardJavaFileManager;
 import javax.tools.StandardLocation;
 
+import com.sun.tools.javac.code.ClassFinder;
 import com.sun.tools.javac.code.Symbol.CompletionFailure;
+import com.sun.tools.javac.comp.Enter;
 import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
@@ -66,8 +69,8 @@
     DocEnv docenv;
 
     final Messager messager;
-    final JavadocClassReader javadocReader;
-    final JavadocEnter javadocEnter;
+    final ClassFinder javadocFinder;
+    final Enter javadocEnter;
     final Set<JavaFileObject> uniquefiles;
 
     /**
@@ -77,8 +80,8 @@
     protected JavadocTool(Context context) {
         super(context);
         messager = Messager.instance0(context);
-        javadocReader = JavadocClassReader.instance0(context);
-        javadocEnter = JavadocEnter.instance0(context);
+        javadocFinder = JavadocClassFinder.instance(context);
+        javadocEnter = JavadocEnter.instance(context);
         uniquefiles = new HashSet<>();
     }
 
@@ -95,8 +98,8 @@
     public static JavadocTool make0(Context context) {
         Messager messager = null;
         try {
-            // force the use of Javadoc's class reader
-            JavadocClassReader.preRegister(context);
+            // force the use of Javadoc's class finder
+            JavadocClassFinder.preRegister(context);
 
             // force the use of Javadoc's own enter phase
             JavadocEnter.preRegister(context);
@@ -137,7 +140,8 @@
         docenv.setEncoding(encoding);
         docenv.docClasses = docClasses;
         docenv.legacyDoclet = legacyDoclet;
-        javadocReader.sourceCompleter = docClasses ? null : thisCompleter;
+
+        javadocFinder.sourceCompleter = docClasses ? null : sourceCompleter;
 
         ListBuffer<String> names = new ListBuffer<>();
         ListBuffer<JCCompilationUnit> classTrees = new ListBuffer<>();
--- a/langtools/test/com/sun/javadoc/testRelativeLinks/TestRelativeLinks.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/test/com/sun/javadoc/testRelativeLinks/TestRelativeLinks.java	Thu May 22 14:39:05 2014 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug      4460354 8014636
+ * @bug      4460354 8014636 8043186
  * @summary  Test to make sure that relative paths are redirected in the
  *           output so that they are not broken.
  * @author   jamieh
--- a/langtools/test/com/sun/javadoc/testRelativeLinks/pkg/C.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/test/com/sun/javadoc/testRelativeLinks/pkg/C.java	Thu May 22 14:39:05 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,7 @@
 public class C {
 
     /**
-     * Here is a relative link in a field:
+     * Here is a relative link in a field:\u0130
      * <a href="relative-field-link.html">relative field link</a>.
      */
     public C field = null;
--- a/langtools/test/com/sun/javadoc/testTopOption/TestTopOption.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/test/com/sun/javadoc/testTopOption/TestTopOption.java	Thu May 22 14:39:05 2014 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug      6227616
+ * @bug      6227616 8043186
  * @summary  Test the new -top option.
  * @author   jamieh
  * @library  ../lib
@@ -43,7 +43,30 @@
         javadoc("-overview", testSrc("overview.html"),
                 "-use",
                 "-top", "TOP TEXT",
-                "-d", "out",
+                "-d", "out-1",
+                "-sourcepath", testSrc,
+                "pkg");
+        checkExit(Exit.OK);
+
+        checkTopText(
+                "pkg/AnnotationType.html",
+                "pkg/class-use/AnnotationType.html",
+                "pkg/Cl.html",
+                "pkg/class-use/Cl.html",
+                "pkg/package-summary.html",
+                "pkg/package-use.html",
+                "overview-summary.html",
+                "overview-tree.html",
+                "constant-values.html",
+                "help-doc.html");
+    }
+
+    @Test
+    void testDocRootRewrite() {
+        javadoc("-overview", testSrc("overview.html"),
+                "-use",
+                "-top", "\u0130{@docroot}TOP TEXT",
+                "-d", "out-2",
                 "-sourcepath", testSrc,
                 "pkg");
         checkExit(Exit.OK);
--- a/langtools/test/tools/javac/6330997/T6330997.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/test/tools/javac/6330997/T6330997.java	Thu May 22 14:39:05 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,7 +36,7 @@
 import java.io.*;
 import java.nio.channels.*;
 import com.sun.tools.javac.api.JavacTaskImpl;
-import com.sun.tools.javac.jvm.ClassReader.BadClassFile;
+import com.sun.tools.javac.code.ClassFinder.BadClassFile;
 import com.sun.tools.javac.main.JavaCompiler;
 import javax.tools.ToolProvider;
 
--- a/langtools/test/tools/javac/MethodParametersTest.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/test/tools/javac/MethodParametersTest.java	Thu May 22 14:39:05 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -129,14 +129,14 @@
         if (out.length() > 0)
             System.err.println(out);
 
-        // Now get the class reader, construct a name for Baz, and load it.
-        com.sun.tools.javac.jvm.ClassReader cr =
-            com.sun.tools.javac.jvm.ClassReader.instance(context);
+        // Now get the class finder, construct a name for Baz, and load it.
+        com.sun.tools.javac.code.ClassFinder cf =
+            com.sun.tools.javac.code.ClassFinder.instance(context);
         Name name = Names.instance(context).fromString(Baz_name);
 
         // Now walk down the language model and check the name of the
         // parameter.
-        final Element baz = cr.loadClass(name);
+        final Element baz = cf.loadClass(name);
         for (Element e : baz.getEnclosedElements()) {
             if (e instanceof ExecutableElement) {
                 final ExecutableElement ee = (ExecutableElement) e;
--- a/langtools/test/tools/javac/T6435291/T6435291.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/test/tools/javac/T6435291/T6435291.java	Thu May 22 14:39:05 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,7 @@
  */
 
 import com.sun.tools.javac.api.JavacTaskImpl;
-import com.sun.tools.javac.jvm.ClassReader.BadClassFile;
+import com.sun.tools.javac.code.ClassFinder.BadClassFile;
 import com.sun.tools.javac.main.JavaCompiler;
 import javax.tools.ToolProvider;
 
--- a/langtools/test/tools/javac/classfiles/attributes/SourceFile/NoSourceFileAttribute.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/SourceFile/NoSourceFileAttribute.java	Thu May 22 14:39:05 2014 -0700
@@ -24,10 +24,11 @@
 /*
  * @test
  * @summary sourcefile attribute test for file compiled without debug information.
+ * @bug 8040129
  * @library /tools/javac/lib ../lib
  * @build SourceFileTestBase TestBase InMemoryFileManager ToolBox
  * @compile -g:none NoSourceFileAttribute.java
- * @run main  NoSourceFileAttribute
+ * @run main NoSourceFileAttribute
  */
 
 import com.sun.tools.classfile.Attribute;
--- a/langtools/test/tools/javac/defaultMethods/BadClassfile.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/test/tools/javac/defaultMethods/BadClassfile.java	Thu May 22 14:39:05 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,8 +32,8 @@
 
 import com.sun.tools.classfile.*;
 import com.sun.tools.javac.api.JavacTaskImpl;
+import com.sun.tools.javac.code.ClassFinder.BadClassFile;
 import com.sun.tools.javac.code.Symbol;
-import com.sun.tools.javac.jvm.ClassReader.BadClassFile;
 import com.sun.tools.javac.jvm.Target;
 import com.sun.tools.javac.util.Assert;
 import com.sun.tools.javac.util.JCDiagnostic;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/jvm/ClassRefDupInConstantPoolTest.java	Thu May 22 14:39:05 2014 -0700
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8015927
+ * @summary Class reference duplicates in constant pool
+ * @clean ClassRefDupInConstantPoolTest$Duplicates.class
+ * @run main ClassRefDupInConstantPoolTest
+ */
+
+import java.util.TreeSet;
+
+import com.sun.tools.classfile.*;
+import com.sun.tools.classfile.ConstantPool.*;
+
+public class ClassRefDupInConstantPoolTest {
+    public static void main(String[] args) throws Exception {
+        ClassFile cls = ClassFile.read(ClassRefDupInConstantPoolTest.class.
+                                       getResourceAsStream("ClassRefDupInConstantPoolTest$Duplicates.class"));
+        ConstantPool pool = cls.constant_pool;
+
+        int duplicates = 0;
+        TreeSet<Integer> set = new TreeSet<>();
+        for (CPInfo i : pool.entries()) {
+            if (i.getTag() == ConstantPool.CONSTANT_Class) {
+                CONSTANT_Class_info ci = (CONSTANT_Class_info)i;
+                if (!set.add(ci.name_index)) {
+                    duplicates++;
+                    System.out.println("DUPLICATE CLASS REF " + ci.getName());
+                }
+            }
+        }
+        if (duplicates > 0)
+            throw new Exception("Test Failed");
+    }
+
+    class Duplicates {
+        String concat(String s1, String s2) {
+            return s1 + (s2 == s1 ? " " : s2);
+        }
+    }
+}
--- a/langtools/test/tools/javac/util/StringUtilsTest.java	Thu May 22 12:54:10 2014 -0700
+++ b/langtools/test/tools/javac/util/StringUtilsTest.java	Thu May 22 14:39:05 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 8029800
+ * @bug 8029800 8043186
  * @summary Unit test StringUtils
  * @run main StringUtilsTest
  */
@@ -44,12 +44,14 @@
         assertEquals("\u0131", "I".toLowerCase());
         assertEquals("\u0130", "i".toUpperCase());
 
-        //verify the StringUtils does what it should
+        //verify the StringUtils.toLowerCase/toUpperCase do what they should:
         assertEquals("i", StringUtils.toLowerCase("I"));
         assertEquals("I", StringUtils.toUpperCase("i"));
 
-        //verify we can use index from indexOf of toLowerCase String in the original:
-        assertEquals(2, StringUtils.toLowerCase("\u0130\u0130lookFor").indexOf("lookfor"));
+        //verify StringUtils.caseInsensitiveIndexOf works:
+        assertEquals(2, StringUtils.indexOfIgnoreCase("  lookFor", "lookfor"));
+        assertEquals(11, StringUtils.indexOfIgnoreCase("  lookFor  LOOKfor", "lookfor", 11));
+        assertEquals(2, StringUtils.indexOfIgnoreCase("\u0130\u0130lookFor", "lookfor"));
     }
 
     void assertEquals(String expected, String actual) {