changeset 1625:e6ee43b3e247 jdk8-b64

Merge
author lana
date Fri, 02 Nov 2012 17:55:34 -0700
parents 26831b6fcc4a bf76f4190ef8
children 056d828ac1e1 6dc8616cea9b
files src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DirectoryManager.java src/share/classes/com/sun/tools/doclets/internal/toolkit/util/SourcePath.java src/share/classes/com/sun/tools/javac/code/TypeTags.java
diffstat 153 files changed, 4658 insertions(+), 2251 deletions(-) [+]
line wrap: on
line diff
--- a/make/tools/genstubs/GenStubs.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/make/tools/genstubs/GenStubs.java	Fri Nov 02 17:55:34 2012 -0700
@@ -35,7 +35,7 @@
 import com.sun.source.util.JavacTask;
 import com.sun.tools.javac.api.JavacTool;
 import com.sun.tools.javac.code.Flags;
-import com.sun.tools.javac.code.TypeTags;
+import com.sun.tools.javac.code.TypeTag;
 import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
 import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
@@ -244,23 +244,23 @@
                 else {
                     String t = tree.vartype.toString();
                     if (t.equals("boolean"))
-                        tree.init = new JCLiteral(TypeTags.BOOLEAN, 0) { };
+                        tree.init = new JCLiteral(TypeTag.BOOLEAN, 0) { };
                     else if (t.equals("byte"))
-                        tree.init = new JCLiteral(TypeTags.BYTE, 0) { };
+                        tree.init = new JCLiteral(TypeTag.BYTE, 0) { };
                     else if (t.equals("char"))
-                        tree.init = new JCLiteral(TypeTags.CHAR, 0) { };
+                        tree.init = new JCLiteral(TypeTag.CHAR, 0) { };
                     else if (t.equals("double"))
-                        tree.init = new JCLiteral(TypeTags.DOUBLE, 0.d) { };
+                        tree.init = new JCLiteral(TypeTag.DOUBLE, 0.d) { };
                     else if (t.equals("float"))
-                        tree.init = new JCLiteral(TypeTags.FLOAT, 0.f) { };
+                        tree.init = new JCLiteral(TypeTag.FLOAT, 0.f) { };
                     else if (t.equals("int"))
-                        tree.init = new JCLiteral(TypeTags.INT, 0) { };
+                        tree.init = new JCLiteral(TypeTag.INT, 0) { };
                     else if (t.equals("long"))
-                        tree.init = new JCLiteral(TypeTags.LONG, 0) { };
+                        tree.init = new JCLiteral(TypeTag.LONG, 0) { };
                     else if (t.equals("short"))
-                        tree.init = new JCLiteral(TypeTags.SHORT, 0) { };
+                        tree.init = new JCLiteral(TypeTag.SHORT, 0) { };
                     else
-                        tree.init = new JCLiteral(TypeTags.BOT, null) { };
+                        tree.init = new JCLiteral(TypeTag.BOT, null) { };
                 }
             }
             result = tree;
--- a/src/share/classes/com/sun/javadoc/SerialFieldTag.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/javadoc/SerialFieldTag.java	Fri Nov 02 17:55:34 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -46,7 +46,7 @@
 public interface SerialFieldTag extends Tag, Comparable<Object> {
 
     /**
-     * Return the serialziable field name.
+     * Return the serializable field name.
      */
     public String fieldName();
 
--- a/src/share/classes/com/sun/tools/doclets/formats/html/AbstractIndexWriter.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/AbstractIndexWriter.java	Fri Nov 02 17:55:34 2012 -0700
@@ -56,32 +56,18 @@
     protected IndexBuilder indexbuilder;
 
     /**
-     * This constructor will be used by {@link SplitIndexWriter}. Initialises
+     * This constructor will be used by {@link SplitIndexWriter}. Initializes
      * path to this file and relative path from this file.
      *
+     * @param configuration  The current configuration
      * @param path       Path to the file which is getting generated.
-     * @param filename   Name of the file which is getting genrated.
-     * @param relpath    Relative path from this file to the current directory.
      * @param indexbuilder Unicode based Index from {@link IndexBuilder}
      */
     protected AbstractIndexWriter(ConfigurationImpl configuration,
-                                  String path, String filename,
-                                  String relpath, IndexBuilder indexbuilder)
+                                  DocPath path,
+                                  IndexBuilder indexbuilder)
                                   throws IOException {
-        super(configuration, path, filename, relpath);
-        this.indexbuilder = indexbuilder;
-    }
-
-    /**
-     * This Constructor will be used by {@link SingleIndexWriter}.
-     *
-     * @param filename   Name of the file which is getting genrated.
-     * @param indexbuilder Unicode based Index form {@link IndexBuilder}
-     */
-    protected AbstractIndexWriter(ConfigurationImpl configuration,
-                                  String filename, IndexBuilder indexbuilder)
-                                  throws IOException {
-        super(configuration, filename);
+        super(configuration, path);
         this.indexbuilder = indexbuilder;
     }
 
--- a/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java	Fri Nov 02 17:55:34 2012 -0700
@@ -27,9 +27,11 @@
 
 import java.io.*;
 import java.util.*;
+
 import com.sun.javadoc.*;
 import com.sun.tools.doclets.formats.html.markup.*;
 import com.sun.tools.doclets.internal.toolkit.*;
+import com.sun.tools.doclets.internal.toolkit.util.DocPath;
 
 /**
  * Abstract class to generate the overview files in
@@ -52,14 +54,14 @@
     protected PackageDoc[] packages;
 
     /**
-     * Constructor. Also initialises the packages variable.
+     * Constructor. Also initializes the packages variable.
      *
+     * @param configuration  The current configuration
      * @param filename Name of the package index file to be generated.
      */
     public AbstractPackageIndexWriter(ConfigurationImpl configuration,
-                                      String filename) throws IOException {
+                                      DocPath filename) throws IOException {
         super(configuration, filename);
-        this.relativepathNoSlash = ".";
         packages = configuration.packages;
     }
 
--- a/src/share/classes/com/sun/tools/doclets/formats/html/AbstractTreeWriter.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/AbstractTreeWriter.java	Fri Nov 02 17:55:34 2012 -0700
@@ -56,46 +56,23 @@
     private static final String LI_CIRCLE  = "circle";
 
     /**
-     * Constructor initilises classtree variable. This constructor will be used
+     * Constructor initializes classtree variable. This constructor will be used
      * while generating global tree file "overview-tree.html".
      *
+     * @param configuration  The current configuration
      * @param filename   File to be generated.
      * @param classtree  Tree built by {@link ClassTree}.
      * @throws IOException
      * @throws DocletAbortException
      */
     protected AbstractTreeWriter(ConfigurationImpl configuration,
-                                 String filename, ClassTree classtree)
+                                 DocPath filename, ClassTree classtree)
                                  throws IOException {
         super(configuration, filename);
         this.classtree = classtree;
     }
 
     /**
-     * Create appropriate directory for the package and also initilise the
-     * relative path from this generated file to the current or
-     * the destination directory. This constructor will be used while
-     * generating "package tree" file.
-     *
-     * @param path Directories in this path will be created if they are not
-     * already there.
-     * @param filename Name of the package tree file to be generated.
-     * @param classtree The tree built using {@link ClassTree}.
-     * for the package pkg.
-     * @param pkg PackageDoc for which tree file will be generated.
-     * @throws IOException
-     * @throws DocletAbortException
-     */
-    protected AbstractTreeWriter(ConfigurationImpl configuration,
-                                 String path, String filename,
-                                 ClassTree classtree, PackageDoc pkg)
-                                 throws IOException {
-        super(configuration,
-              path, filename, DirectoryManager.getRelativePath(pkg.name()));
-        this.classtree = classtree;
-    }
-
-    /**
      * Add each level of the class tree. For each sub-class or
      * sub-interface indents the next level information.
      * Recurses itself to add subclasses info.
--- a/src/share/classes/com/sun/tools/doclets/formats/html/AllClassesFrameWriter.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/AllClassesFrameWriter.java	Fri Nov 02 17:55:34 2012 -0700
@@ -51,16 +51,6 @@
 public class AllClassesFrameWriter extends HtmlDocletWriter {
 
     /**
-     * The name of the output file with frames
-     */
-    public static final String OUTPUT_FILE_NAME_FRAMES = "allclasses-frame.html";
-
-    /**
-     * The name of the output file without frames
-     */
-    public static final String OUTPUT_FILE_NAME_NOFRAMES = "allclasses-noframe.html";
-
-    /**
      * Index of all the classes.
      */
     protected IndexBuilder indexbuilder;
@@ -71,13 +61,16 @@
     final HtmlTree BR = new HtmlTree(HtmlTag.BR);
 
     /**
-     * Construct AllClassesFrameWriter object. Also initilises the indexbuilder
+     * Construct AllClassesFrameWriter object. Also initializes the indexbuilder
      * variable in this class.
+     * @param configuration  The current configuration
+     * @param filename       Path to the file which is getting generated.
+     * @param indexbuilder   Unicode based Index from {@link IndexBuilder}
      * @throws IOException
      * @throws DocletAbortException
      */
     public AllClassesFrameWriter(ConfigurationImpl configuration,
-                                 String filename, IndexBuilder indexbuilder)
+                                 DocPath filename, IndexBuilder indexbuilder)
                               throws IOException {
         super(configuration, filename);
         this.indexbuilder = indexbuilder;
@@ -94,13 +87,13 @@
     public static void generate(ConfigurationImpl configuration,
                                 IndexBuilder indexbuilder) {
         AllClassesFrameWriter allclassgen;
-        String filename = OUTPUT_FILE_NAME_FRAMES;
+        DocPath filename = DocPaths.ALLCLASSES_FRAME;
         try {
             allclassgen = new AllClassesFrameWriter(configuration,
                                                     filename, indexbuilder);
             allclassgen.buildAllClassesFile(true);
             allclassgen.close();
-            filename = OUTPUT_FILE_NAME_NOFRAMES;
+            filename = DocPaths.ALLCLASSES_NOFRAME;
             allclassgen = new AllClassesFrameWriter(configuration,
                                                     filename, indexbuilder);
             allclassgen.buildAllClassesFile(false);
--- a/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeOptionalMemberWriterImpl.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeOptionalMemberWriterImpl.java	Fri Nov 02 17:55:34 2012 -0700
@@ -141,7 +141,7 @@
      */
     protected Content getNavSummaryLink(ClassDoc cd, boolean link) {
         if (link) {
-            return writer.getHyperLink("", "annotation_type_optional_element_summary",
+            return writer.getHyperLink("annotation_type_optional_element_summary",
                     writer.getResource("doclet.navAnnotationTypeOptionalMember"));
         } else {
             return writer.getResource("doclet.navAnnotationTypeOptionalMember");
--- a/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java	Fri Nov 02 17:55:34 2012 -0700
@@ -260,7 +260,7 @@
      */
     protected Content getNavSummaryLink(ClassDoc cd, boolean link) {
         if (link) {
-            return writer.getHyperLink("", "annotation_type_required_element_summary",
+            return writer.getHyperLink("annotation_type_required_element_summary",
                     writer.getResource("doclet.navAnnotationTypeRequiredMember"));
         } else {
             return writer.getResource("doclet.navAnnotationTypeRequiredMember");
@@ -272,7 +272,7 @@
      */
     protected void addNavDetailLink(boolean link, Content liNav) {
         if (link) {
-            liNav.addContent(writer.getHyperLink("", "annotation_type_element_detail",
+            liNav.addContent(writer.getHyperLink("annotation_type_element_detail",
                     writer.getResource("doclet.navAnnotationTypeMember")));
         } else {
             liNav.addContent(writer.getResource("doclet.navAnnotationTypeMember"));
--- a/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java	Fri Nov 02 17:55:34 2012 -0700
@@ -65,13 +65,10 @@
      * @param prevType the previous class that was documented.
      * @param nextType the next class being documented.
      */
-    public AnnotationTypeWriterImpl (AnnotationTypeDoc annotationType,
+    public AnnotationTypeWriterImpl(AnnotationTypeDoc annotationType,
             Type prevType, Type nextType)
-    throws Exception {
-        super(ConfigurationImpl.getInstance(),
-              DirectoryManager.getDirectoryPath(annotationType.containingPackage()),
-              annotationType.name() + ".html",
-              DirectoryManager.getRelativePath(annotationType.containingPackage().name()));
+            throws Exception {
+        super(ConfigurationImpl.getInstance(), DocPath.forClass(annotationType));
         this.annotationType = annotationType;
         configuration.currentcd = annotationType.asClassDoc();
         this.prev = prevType;
@@ -84,7 +81,7 @@
      * @return a content tree for the package link
      */
     protected Content getNavLinkPackage() {
-        Content linkContent = getHyperLink("package-summary.html", "",
+        Content linkContent = getHyperLink(DocPaths.PACKAGE_SUMMARY,
                 packageLabel);
         Content li = HtmlTree.LI(linkContent);
         return li;
@@ -106,7 +103,7 @@
      * @return a content tree for the class use link
      */
     protected Content getNavLinkClassUse() {
-        Content linkContent = getHyperLink("class-use/" + filename, "", useLabel);
+        Content linkContent = getHyperLink(DocPaths.CLASS_USE.resolve(filename), useLabel);
         Content li = HtmlTree.LI(linkContent);
         return li;
     }
@@ -289,8 +286,8 @@
      * {@inheritDoc}
      */
     protected Content getNavLinkTree() {
-        Content treeLinkContent = getHyperLink("package-tree.html",
-                "", treeLabel, "", "");
+        Content treeLinkContent = getHyperLink(DocPaths.PACKAGE_TREE,
+                treeLabel, "", "");
         Content li = HtmlTree.LI(treeLinkContent);
         return li;
     }
--- a/src/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java	Fri Nov 02 17:55:34 2012 -0700
@@ -82,7 +82,6 @@
     final String methodUseTableSummary;
     final String constructorUseTableSummary;
 
-
     /**
      * Constructor.
      *
@@ -91,10 +90,9 @@
      * @throws DocletAbortException
      */
     public ClassUseWriter(ConfigurationImpl configuration,
-                          ClassUseMapper mapper, String path,
-                          String filename, String relpath,
+                          ClassUseMapper mapper, DocPath filename,
                           ClassDoc classdoc) throws IOException {
-        super(configuration, path, filename, relpath);
+        super(configuration, filename);
         this.classdoc = classdoc;
         if (mapper.classToPackageAnnotations.containsKey(classdoc.qualifiedName()))
                 pkgToPackageAnnotations = new HashSet<PackageDoc>(mapper.classToPackageAnnotations.get(classdoc.qualifiedName()));
@@ -199,23 +197,19 @@
     public static void generate(ConfigurationImpl configuration,
                                 ClassUseMapper mapper, ClassDoc classdoc) {
         ClassUseWriter clsgen;
-        String path = DirectoryManager.getDirectoryPath(classdoc.
-                                                            containingPackage());
-        path += "class-use" + DirectoryManager.URL_FILE_SEPARATOR;
-        String filename = classdoc.name() + ".html";
-        String pkgname = classdoc.containingPackage().name();
-        pkgname += (pkgname.length() > 0)? ".class-use": "class-use";
-        String relpath = DirectoryManager.getRelativePath(pkgname);
+        DocPath path = DocPath.forPackage(classdoc)
+                .resolve(DocPaths.CLASS_USE)
+                .resolve(DocPath.forName(classdoc));
         try {
             clsgen = new ClassUseWriter(configuration,
-                                        mapper, path, filename,
-                                        relpath, classdoc);
+                                        mapper, path,
+                                        classdoc);
             clsgen.generateClassUseFile();
             clsgen.close();
         } catch (IOException exc) {
             configuration.standardmessage.
                 error("doclet.exception_encountered",
-                      exc.toString(), filename);
+                      exc.toString(), path.getPath());
             throw new DocletAbortException();
         }
     }
@@ -359,7 +353,7 @@
      */
     protected void addPackageUse(PackageDoc pkg, Content contentTree) throws IOException {
         Content tdFirst = HtmlTree.TD(HtmlStyle.colFirst,
-                getHyperLink("", pkg.name(), new StringContent(Util.getPackageName(pkg))));
+                getHyperLink(pkg.name(), new StringContent(Util.getPackageName(pkg))));
         contentTree.addContent(tdFirst);
         HtmlTree tdLast = new HtmlTree(HtmlTag.TD);
         tdLast.addStyle(HtmlStyle.colLast);
@@ -470,8 +464,8 @@
      * @return a content tree for the package link
      */
     protected Content getNavLinkPackage() {
-        Content linkContent = getHyperLink("../package-summary.html", "",
-                packageLabel);
+        Content linkContent =
+                getHyperLink(DocPath.parent.resolve(DocPaths.PACKAGE_SUMMARY), packageLabel);
         Content li = HtmlTree.LI(linkContent);
         return li;
     }
@@ -506,8 +500,8 @@
      */
     protected Content getNavLinkTree() {
         Content linkContent = classdoc.containingPackage().isIncluded() ?
-            getHyperLink("../package-tree.html", "", treeLabel) :
-            getHyperLink(relativePath + "overview-tree.html", "", treeLabel);
+            getHyperLink(DocPath.parent.resolve(DocPaths.PACKAGE_TREE), treeLabel) :
+            getHyperLink(pathToRoot.resolve(DocPaths.OVERVIEW_TREE), treeLabel);
         Content li = HtmlTree.LI(linkContent);
         return li;
     }
--- a/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java	Fri Nov 02 17:55:34 2012 -0700
@@ -72,11 +72,8 @@
      */
     public ClassWriterImpl (ClassDoc classDoc,
             ClassDoc prevClass, ClassDoc nextClass, ClassTree classTree)
-    throws Exception {
-        super(ConfigurationImpl.getInstance(),
-              DirectoryManager.getDirectoryPath(classDoc.containingPackage()),
-              classDoc.name() + ".html",
-              DirectoryManager.getRelativePath(classDoc.containingPackage().name()));
+            throws Exception {
+        super(ConfigurationImpl.getInstance(), DocPath.forClass(classDoc));
         this.classDoc = classDoc;
         configuration.currentcd = classDoc;
         this.classtree = classTree;
@@ -90,7 +87,7 @@
      * @return a content tree for the package link
      */
     protected Content getNavLinkPackage() {
-        Content linkContent = getHyperLink("package-summary.html", "",
+        Content linkContent = getHyperLink(DocPaths.PACKAGE_SUMMARY,
                 packageLabel);
         Content li = HtmlTree.LI(linkContent);
         return li;
@@ -112,7 +109,7 @@
      * @return a content tree for the class use link
      */
     protected Content getNavLinkClassUse() {
-        Content linkContent = getHyperLink("class-use/" + filename, "", useLabel);
+        Content linkContent = getHyperLink(DocPaths.CLASS_USE.resolve(filename), useLabel);
         Content li = HtmlTree.LI(linkContent);
         return li;
     }
@@ -567,8 +564,8 @@
      * {@inheritDoc}
      */
     protected Content getNavLinkTree() {
-        Content treeLinkContent = getHyperLink("package-tree.html",
-                "", treeLabel, "", "");
+        Content treeLinkContent = getHyperLink(DocPaths.PACKAGE_TREE,
+                treeLabel, "", "");
         Content li = HtmlTree.LI(treeLinkContent);
         return li;
     }
--- a/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java	Fri Nov 02 17:55:34 2012 -0700
@@ -25,7 +25,6 @@
 
 package com.sun.tools.doclets.formats.html;
 
-import java.io.*;
 import java.net.*;
 import java.util.*;
 
@@ -46,6 +45,11 @@
  * use "-helpfile" option when already "-nohelp" option is used.
  * </p>
  *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ *
  * @author Robert Field.
  * @author Atul Dambalkar.
  * @author Jamie Ho
@@ -62,11 +66,6 @@
     public static final String BUILD_DATE = System.getProperty("java.version");
 
     /**
-     * The name of the constant values file.
-     */
-    public static final String CONSTANTS_FILE_NAME = "constant-values.html";
-
-    /**
      * Argument for command line option "-header".
      */
     public String header = "";
@@ -179,7 +178,7 @@
      * First file to appear in the right-hand frame in the generated
      * documentation.
      */
-    public String topFile = "";
+    public DocPath topFile = DocPath.empty;
 
     /**
      * The classdoc for the class file getting generated.
@@ -367,7 +366,7 @@
                         "-helpfile"));
                     return false;
                 }
-                File help = new File(os[1]);
+                DocFile help = DocFile.createFileForInput(this, os[1]);
                 if (!help.exists()) {
                     reporter.printError(getText("doclet.File_not_found", os[1]));
                     return false;
@@ -447,18 +446,17 @@
             return;
         }
         if (createoverview) {
-            topFile = "overview-summary.html";
+            topFile = DocPaths.OVERVIEW_SUMMARY;
         } else {
             if (packages.length == 1 && packages[0].name().equals("")) {
                 if (root.classes().length > 0) {
                     ClassDoc[] classarr = root.classes();
                     Arrays.sort(classarr);
                     ClassDoc cd = getValidClass(classarr);
-                    topFile = DirectoryManager.getPathToClass(cd);
+                    topFile = DocPath.forClass(cd);
                 }
             } else {
-                topFile = DirectoryManager.getPathToPackage(packages[0],
-                                                            "package-summary.html");
+                topFile = DocPath.forPackage(packages[0]).resolve(DocPaths.PACKAGE_SUMMARY);
             }
         }
     }
--- a/src/share/classes/com/sun/tools/doclets/formats/html/ConstantsSummaryWriterImpl.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/ConstantsSummaryWriterImpl.java	Fri Nov 02 17:55:34 2012 -0700
@@ -69,7 +69,7 @@
      */
     public ConstantsSummaryWriterImpl(ConfigurationImpl configuration)
             throws IOException {
-        super(configuration, ConfigurationImpl.CONSTANTS_FILE_NAME);
+        super(configuration, DocPaths.CONSTANT_VALUES);
         this.configuration = configuration;
         constantsTableSummary = configuration.getText("doclet.Constants_Table_Summary",
                 configuration.getText("doclet.Constants_Summary"));
@@ -107,13 +107,13 @@
         //add link to summary
         Content link;
         if (packageName.length() == 0) {
-            link = getHyperLink("#" + DocletConstants.UNNAMED_PACKAGE_ANCHOR,
-                    "", defaultPackageLabel, "", "");
+            link = getHyperLink(DocLink.fragment(DocletConstants.UNNAMED_PACKAGE_ANCHOR),
+                    defaultPackageLabel, "", "");
         } else {
             Content packageNameContent = getPackageLabel(parsedPackageName);
             packageNameContent.addContent(".*");
-            link = getHyperLink("#" + parsedPackageName,
-                    "", packageNameContent, "", "");
+            link = getHyperLink(DocLink.fragment(parsedPackageName),
+                    packageNameContent, "", "");
             printedPackageHeaders.add(parsedPackageName);
         }
         contentListTree.addContent(HtmlTree.LI(link));
--- a/src/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java	Fri Nov 02 17:55:34 2012 -0700
@@ -280,7 +280,7 @@
      */
     protected Content getNavSummaryLink(ClassDoc cd, boolean link) {
         if (link) {
-            return writer.getHyperLink("", "constructor_summary",
+            return writer.getHyperLink("constructor_summary",
                     writer.getResource("doclet.navConstructor"));
         } else {
             return writer.getResource("doclet.navConstructor");
@@ -292,7 +292,7 @@
      */
     protected void addNavDetailLink(boolean link, Content liNav) {
         if (link) {
-            liNav.addContent(writer.getHyperLink("", "constructor_detail",
+            liNav.addContent(writer.getHyperLink("constructor_detail",
                     writer.getResource("doclet.navConstructor")));
         } else {
             liNav.addContent(writer.getResource("doclet.navConstructor"));
--- a/src/share/classes/com/sun/tools/doclets/formats/html/DeprecatedListWriter.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/DeprecatedListWriter.java	Fri Nov 02 17:55:34 2012 -0700
@@ -95,7 +95,7 @@
      * @param filename the file to be generated.
      */
     public DeprecatedListWriter(ConfigurationImpl configuration,
-                                String filename) throws IOException {
+                                DocPath filename) throws IOException {
         super(configuration, filename);
         this.configuration = configuration;
         NestedClassWriterImpl classW = new NestedClassWriterImpl(this);
@@ -116,7 +116,7 @@
      * @param configuration the current configuration of the doclet.
      */
     public static void generate(ConfigurationImpl configuration) {
-        String filename = "deprecated-list.html";
+        DocPath filename = DocPaths.DEPRECATED_LIST;
         try {
             DeprecatedListWriter depr =
                    new DeprecatedListWriter(configuration, filename);
@@ -180,7 +180,7 @@
     private void addIndexLink(DeprecatedAPIListBuilder builder,
             int type, Content contentTree) {
         if (builder.hasDocumentation(type)) {
-            Content li = HtmlTree.LI(getHyperLink("#" + ANCHORS[type],
+            Content li = HtmlTree.LI(getHyperLink(ANCHORS[type],
                     getResource(HEADING_KEYS[type])));
             contentTree.addContent(li);
         }
--- a/src/share/classes/com/sun/tools/doclets/formats/html/EnumConstantWriterImpl.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/EnumConstantWriterImpl.java	Fri Nov 02 17:55:34 2012 -0700
@@ -263,7 +263,7 @@
      */
     protected Content getNavSummaryLink(ClassDoc cd, boolean link) {
         if (link) {
-            return writer.getHyperLink("", (cd == null)?
+            return writer.getHyperLink((cd == null)?
                 "enum_constant_summary":
                 "enum_constants_inherited_from_class_" +
                 configuration().getClassName(cd),
@@ -278,7 +278,7 @@
      */
     protected void addNavDetailLink(boolean link, Content liNav) {
         if (link) {
-            liNav.addContent(writer.getHyperLink("", "enum_constant_detail",
+            liNav.addContent(writer.getHyperLink("enum_constant_detail",
                     writer.getResource("doclet.navEnum")));
         } else {
             liNav.addContent(writer.getResource("doclet.navEnum"));
--- a/src/share/classes/com/sun/tools/doclets/formats/html/FieldWriterImpl.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/FieldWriterImpl.java	Fri Nov 02 17:55:34 2012 -0700
@@ -293,7 +293,7 @@
      */
     protected Content getNavSummaryLink(ClassDoc cd, boolean link) {
         if (link) {
-            return writer.getHyperLink("", (cd == null)?
+            return writer.getHyperLink((cd == null)?
                 "field_summary":
                 "fields_inherited_from_class_" +
                 configuration().getClassName(cd),
@@ -308,7 +308,7 @@
      */
     protected void addNavDetailLink(boolean link, Content liNav) {
         if (link) {
-            liNav.addContent(writer.getHyperLink("", "field_detail",
+            liNav.addContent(writer.getHyperLink("field_detail",
                     writer.getResource("doclet.navField")));
         } else {
             liNav.addContent(writer.getResource("doclet.navField"));
--- a/src/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java	Fri Nov 02 17:55:34 2012 -0700
@@ -63,7 +63,7 @@
      * @param filename File to be generated.
      */
     public FrameOutputWriter(ConfigurationImpl configuration,
-                             String filename) throws IOException {
+                             DocPath filename) throws IOException {
         super(configuration, filename);
     noOfPackages = configuration.packages.length;
     }
@@ -77,9 +77,9 @@
      */
     public static void generate(ConfigurationImpl configuration) {
         FrameOutputWriter framegen;
-        String filename = "";
+        DocPath filename = DocPath.empty;
         try {
-            filename = "index.html";
+            filename = DocPaths.INDEX;
             framegen = new FrameOutputWriter(configuration, filename);
             framegen.generateFrameFile();
             framegen.close();
@@ -92,7 +92,7 @@
     }
 
     /**
-     * Generate the contants in the "index.html" file. Print the frame details
+     * Generate the constants in the "index.html" file. Print the frame details
      * as well as warning if browser is not supporting the Html frames.
      */
     protected void generateFrameFile() throws IOException {
@@ -155,8 +155,8 @@
      * @param contentTree the content tree to which the information will be added
      */
     private void addAllPackagesFrameTag(Content contentTree) {
-        HtmlTree frame = HtmlTree.FRAME("overview-frame.html", "packageListFrame",
-                configuration.getText("doclet.All_Packages"));
+        HtmlTree frame = HtmlTree.FRAME(DocPaths.OVERVIEW_FRAME.getPath(),
+                "packageListFrame", configuration.getText("doclet.All_Packages"));
         contentTree.addContent(frame);
     }
 
@@ -166,8 +166,8 @@
      * @param contentTree the content tree to which the information will be added
      */
     private void addAllClassesFrameTag(Content contentTree) {
-        HtmlTree frame = HtmlTree.FRAME("allclasses-frame.html", "packageFrame",
-                configuration.getText("doclet.All_classes_and_interfaces"));
+        HtmlTree frame = HtmlTree.FRAME(DocPaths.ALLCLASSES_FRAME.getPath(),
+                "packageFrame", configuration.getText("doclet.All_classes_and_interfaces"));
         contentTree.addContent(frame);
     }
 
@@ -177,7 +177,7 @@
      * @param contentTree the content tree to which the information will be added
      */
     private void addClassFrameTag(Content contentTree) {
-        HtmlTree frame = HtmlTree.FRAME(configuration.topFile, "classFrame",
+        HtmlTree frame = HtmlTree.FRAME(configuration.topFile.getPath(), "classFrame",
                 configuration.getText("doclet.Package_class_and_interface_descriptions"),
                 SCROLL_YES);
         contentTree.addContent(frame);
--- a/src/share/classes/com/sun/tools/doclets/formats/html/HelpWriter.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/HelpWriter.java	Fri Nov 02 17:55:34 2012 -0700
@@ -49,7 +49,7 @@
      * @param filename File to be generated.
      */
     public HelpWriter(ConfigurationImpl configuration,
-                      String filename) throws IOException {
+                      DocPath filename) throws IOException {
         super(configuration, filename);
     }
 
@@ -62,9 +62,9 @@
      */
     public static void generate(ConfigurationImpl configuration) {
         HelpWriter helpgen;
-        String filename = "";
+        DocPath filename = DocPath.empty;
         try {
-            filename = "help-doc.html";
+            filename = DocPaths.HELP_DOC;
             helpgen = new HelpWriter(configuration, filename);
             helpgen.generateHelpFile();
             helpgen.close();
@@ -113,7 +113,7 @@
                 getResource("doclet.Overview"));
             Content liOverview = HtmlTree.LI(HtmlStyle.blockList, overviewHeading);
             Content line3 = getResource("doclet.Help_line_3",
-                    getHyperLinkString("overview-summary.html",
+                    getHyperLinkString(DocPaths.OVERVIEW_SUMMARY,
                     configuration.getText("doclet.Overview")));
             Content overviewPara = HtmlTree.P(line3);
             liOverview.addContent(overviewPara);
@@ -234,7 +234,7 @@
                     getResource("doclet.Help_line_16"));
             Content liTree = HtmlTree.LI(HtmlStyle.blockList, treeHead);
             Content line17 = getResource("doclet.Help_line_17_with_tree_link",
-                    getHyperLinkString("overview-tree.html",
+                    getHyperLinkString(DocPaths.OVERVIEW_TREE,
                     configuration.getText("doclet.Class_Hierarchy")));
             Content treePara = HtmlTree.P(line17);
             liTree.addContent(treePara);
@@ -252,7 +252,7 @@
                     getResource("doclet.Deprecated_API"));
             Content liDeprecated = HtmlTree.LI(HtmlStyle.blockList, dHead);
             Content line20 = getResource("doclet.Help_line_20_with_deprecated_api_link",
-                    getHyperLinkString("deprecated-list.html",
+                    getHyperLinkString(DocPaths.DEPRECATED_LIST,
                     configuration.getText("doclet.Deprecated_API")));
             Content dPara = HtmlTree.P(line20);
             liDeprecated.addContent(dPara);
@@ -261,10 +261,10 @@
         if (configuration.createindex) {
             String indexlink;
             if (configuration.splitindex) {
-                indexlink = getHyperLinkString("index-files/index-1.html",
+                indexlink = getHyperLinkString(DocPaths.INDEX_FILES.resolve(DocPaths.indexN(1)),
                         configuration.getText("doclet.Index"));
             } else {
-                indexlink = getHyperLinkString("index-all.html",
+                indexlink = getHyperLinkString(DocPaths.INDEX_ALL,
                         configuration.getText("doclet.Index"));
             }
             Content indexHead = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING,
@@ -293,7 +293,7 @@
                 getResource("doclet.All_Classes"));
         Content liAllClasses = HtmlTree.LI(HtmlStyle.blockList, allclassesHead);
         Content line27 = getResource("doclet.Help_line_27",
-                getHyperLinkString("allclasses-noframe.html",
+                getHyperLinkString(DocPaths.ALLCLASSES_NOFRAME,
                 configuration.getText("doclet.All_Classes")));
         Content allclassesPara = HtmlTree.P(line27);
         liAllClasses.addContent(allclassesPara);
@@ -309,7 +309,7 @@
                 getResource("doclet.Constants_Summary"));
         Content liConst = HtmlTree.LI(HtmlStyle.blockList, constHead);
         Content line29 = getResource("doclet.Help_line_29",
-                getHyperLinkString("constant-values.html",
+                getHyperLinkString(DocPaths.CONSTANT_VALUES,
                 configuration.getText("doclet.Constants_Summary")));
         Content constPara = HtmlTree.P(line29);
         liConst.addContent(constPara);
@@ -325,6 +325,7 @@
      *
      * @return a content tree for the help label
      */
+    @Override
     protected Content getNavLinkHelp() {
         Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, helpLabel);
         return li;
--- a/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java	Fri Nov 02 17:55:34 2012 -0700
@@ -94,31 +94,22 @@
             throws Exception {
         super.generateOtherFiles(root, classtree);
         if (configuration.linksource) {
-            if (configuration.destDirName.length() > 0) {
-                SourceToHTMLConverter.convertRoot(configuration,
-                    root, configuration.destDirName + File.separator
-                    + DocletConstants.SOURCE_OUTPUT_DIR_NAME);
-            } else {
-                SourceToHTMLConverter.convertRoot(configuration,
-                    root, DocletConstants.SOURCE_OUTPUT_DIR_NAME);
-            }
+            SourceToHTMLConverter.convertRoot(configuration,
+                root, DocPaths.SOURCE_OUTPUT);
         }
 
-        if (configuration.topFile.length() == 0) {
+        if (configuration.topFile.isEmpty()) {
             configuration.standardmessage.
                 error("doclet.No_Non_Deprecated_Classes_To_Document");
             return;
         }
         boolean nodeprecated = configuration.nodeprecated;
-        String configdestdir = configuration.destDirName;
-        String confighelpfile = configuration.helpfile;
-        String configstylefile = configuration.stylesheetfile;
-        performCopy(configdestdir, confighelpfile);
-        performCopy(configdestdir, configstylefile);
-        Util.copyResourceFile(configuration, "background.gif", false);
-        Util.copyResourceFile(configuration, "tab.gif", false);
-        Util.copyResourceFile(configuration, "titlebar.gif", false);
-        Util.copyResourceFile(configuration, "titlebar_end.gif", false);
+        performCopy(configuration.helpfile);
+        performCopy(configuration.stylesheetfile);
+        copyResourceFile("background.gif");
+        copyResourceFile("tab.gif");
+        copyResourceFile("titlebar.gif");
+        copyResourceFile("titlebar_end.gif");
         // do early to reduce memory footprint
         if (configuration.classuse) {
             ClassUseWriter.generate(configuration, classtree);
@@ -155,9 +146,8 @@
         // If a stylesheet file is not specified, copy the default stylesheet
         // and replace newline with platform-specific newline.
         if (configuration.stylesheetfile.length() == 0) {
-            Util.copyFile(configuration, "stylesheet.css", Util.RESOURCESDIR,
-                    (configdestdir.isEmpty()) ?
-                        System.getProperty("user.dir") : configdestdir, false, true);
+            DocFile f = DocFile.createFileForOutput(configuration, DocPaths.STYLESHEET);
+            f.copyResource(DocPaths.RESOURCES.resolve(DocPaths.STYLESHEET), false, true);
         }
     }
 
@@ -258,29 +248,33 @@
         return (ConfigurationImpl.getInstance()).validOptions(options, reporter);
     }
 
-    private void performCopy(String configdestdir, String filename) {
+    /**
+     * Copy a file in the resources directory to the destination directory.
+     * @param resource   The name of the resource file to copy
+     */
+    private void copyResourceFile(String resource) {
+        DocPath p = DocPaths.RESOURCES.resolve(resource);
+        DocFile f = DocFile.createFileForOutput(configuration, p);
+        f.copyResource(p, false, false);
+    }
+
+    private void performCopy(String filename) {
+        if (filename.isEmpty())
+            return;
+
         try {
-            String destdir = (configdestdir.length() > 0) ?
-                configdestdir + File.separatorChar: "";
-            if (filename.length() > 0) {
-                File helpstylefile = new File(filename);
-                String parent = helpstylefile.getParent();
-                String helpstylefilename = (parent == null)?
-                    filename:
-                    filename.substring(parent.length() + 1);
-                File desthelpfile = new File(destdir + helpstylefilename);
-                if (!desthelpfile.getCanonicalPath().equals(
-                        helpstylefile.getCanonicalPath())) {
-                    configuration.message.
-                        notice((SourcePosition) null,
-                            "doclet.Copying_File_0_To_File_1",
-                            helpstylefile.toString(), desthelpfile.toString());
-                    Util.copyFile(desthelpfile, helpstylefile);
-                }
-            }
+            DocFile fromfile = DocFile.createFileForInput(configuration, filename);
+            DocPath path = DocPath.create(fromfile.getName());
+            DocFile toFile = DocFile.createFileForOutput(configuration, path);
+            if (toFile.isSameFile(fromfile))
+                return;
+
+            configuration.message.notice((SourcePosition) null,
+                    "doclet.Copying_File_0_To_File_1",
+                    fromfile.toString(), path.getPath());
+            toFile.copyFile(fromfile);
         } catch (IOException exc) {
-            configuration.message.
-                error((SourcePosition) null,
+            configuration.message.error((SourcePosition) null,
                     "doclet.perform_copy_exception_encountered",
                     exc.toString());
             throw new DocletAbortException();
--- a/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java	Fri Nov 02 17:55:34 2012 -0700
@@ -55,32 +55,24 @@
     /**
      * Relative path from the file getting generated to the destination
      * directory. For example, if the file getting generated is
-     * "java/lang/Object.html", then the relative path string is "../../".
+     * "java/lang/Object.html", then the path to the root is "../..".
      * This string can be empty if the file getting generated is in
      * the destination directory.
      */
-    public String relativePath = "";
+    public final DocPath pathToRoot;
 
     /**
-     * Same as relativepath, but normalized to never be empty or
-     * end with a slash.
-     */
-    public String relativepathNoSlash = "";
-
-    /**
-     * Platform-dependent directory path from the current or the
+     * Platform-independent path from the current or the
      * destination directory to the file getting generated.
      * Used when creating the file.
-     * For example, if the file getting generated is
-     * "java/lang/Object.html", then the path string is "java/lang".
      */
-    public String path = "";
+    public final DocPath path;
 
     /**
      * Name of the file getting generated. If the file getting generated is
      * "java/lang/Object.html", then the filename is "Object.html".
      */
-    public String filename = "";
+    public final DocPath filename;
 
     /**
      * The display length used for indentation while generating the class page.
@@ -100,33 +92,15 @@
     /**
      * Constructor to construct the HtmlStandardWriter object.
      *
-     * @param filename File to be generated.
+     * @param path File to be generated.
      */
-    public HtmlDocletWriter(ConfigurationImpl configuration,
-                              String filename) throws IOException {
-        super(configuration, filename);
-        this.configuration = configuration;
-        this.filename = filename;
-    }
-
-    /**
-     * Constructor to construct the HtmlStandardWriter object.
-     *
-     * @param path         Platform-dependent {@link #path} used when
-     *                     creating file.
-     * @param filename     Name of file to be generated.
-     * @param relativePath Value for the variable {@link #relativePath}.
-     */
-    public HtmlDocletWriter(ConfigurationImpl configuration,
-                              String path, String filename,
-                              String relativePath) throws IOException {
-        super(configuration, path, filename);
+    public HtmlDocletWriter(ConfigurationImpl configuration, DocPath path)
+            throws IOException {
+        super(configuration, path);
         this.configuration = configuration;
         this.path = path;
-        this.relativePath = relativePath;
-        this.relativepathNoSlash =
-            DirectoryManager.getPathNoTrailingSlash(this.relativePath);
-        this.filename = filename;
+        this.pathToRoot = path.parent().invert();
+        this.filename = path.basename();
     }
 
     /**
@@ -165,8 +139,9 @@
         int previndex = 0;
         while (true) {
             if (configuration.docrootparent.length() > 0) {
+                final String docroot_parent = "{@docroot}/..";
                 // Search for lowercase version of {@docRoot}/..
-                index = lowerHtml.indexOf("{@docroot}/..", previndex);
+                index = lowerHtml.indexOf(docroot_parent, previndex);
                 // If next {@docRoot}/.. pattern not found, append rest of htmlstr and exit loop
                 if (index < 0) {
                     buf.append(htmlstr.substring(previndex));
@@ -174,17 +149,18 @@
                 }
                 // If next {@docroot}/.. pattern found, append htmlstr up to start of tag
                 buf.append(htmlstr.substring(previndex, index));
-                previndex = index + 13;  // length for {@docroot}/.. string
+                previndex = index + docroot_parent.length();
                 // Insert docrootparent absolute path where {@docRoot}/.. was located
 
                 buf.append(configuration.docrootparent);
                 // Append slash if next character is not a slash
                 if (previndex < htmlstr.length() && htmlstr.charAt(previndex) != '/') {
-                    buf.append(DirectoryManager.URL_FILE_SEPARATOR);
+                    buf.append('/');
                 }
             } else {
+                final String docroot = "{@docroot}";
                 // Search for lowercase version of {@docRoot}
-                index = lowerHtml.indexOf("{@docroot}", previndex);
+                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));
@@ -192,13 +168,12 @@
                 }
                 // If next {@docroot} tag found, append htmlstr up to start of tag
                 buf.append(htmlstr.substring(previndex, index));
-                previndex = index + 10;  // length for {@docroot} string
+                previndex = index + docroot.length();
                 // Insert relative path where {@docRoot} was located
-                buf.append(relativepathNoSlash);
+                buf.append(pathToRoot.isEmpty() ? "." : pathToRoot.getPath());
                 // Append slash if next character is not a slash
-                if (relativepathNoSlash.length() > 0 && previndex < htmlstr.length() &&
-                        htmlstr.charAt(previndex) != '/') {
-                    buf.append(DirectoryManager.URL_FILE_SEPARATOR);
+                if (previndex < htmlstr.length() && htmlstr.charAt(previndex) != '/') {
+                    buf.append('/');
                 }
             }
         }
@@ -312,7 +287,7 @@
      */
     public Content getTargetPackageLink(PackageDoc pd, String target,
             Content label) {
-        return getHyperLink(pathString(pd, "package-summary.html"), "", label, "", target);
+        return getHyperLink(pathString(pd, DocPaths.PACKAGE_SUMMARY), label, "", target);
     }
 
     /**
@@ -432,9 +407,10 @@
                 allClassesId += "navbar_top";
                 Content a = getMarkerAnchor("navbar_top");
                 navDiv.addContent(a);
-                Content skipLinkContent = getHyperLink("",
-                        "skip-navbar_top", HtmlTree.EMPTY, configuration.getText(
-                        "doclet.Skip_navigation_links"), "");
+                Content skipLinkContent = getHyperLink(DocLink.fragment("skip-navbar_top"),
+                        HtmlTree.EMPTY,
+                        configuration.getText("doclet.Skip_navigation_links"),
+                        "");
                 navDiv.addContent(skipLinkContent);
             } else {
                 body.addContent(HtmlConstants.START_OF_BOTTOM_NAVBAR);
@@ -442,9 +418,10 @@
                 allClassesId += "navbar_bottom";
                 Content a = getMarkerAnchor("navbar_bottom");
                 navDiv.addContent(a);
-                Content skipLinkContent = getHyperLink("",
-                        "skip-navbar_bottom", HtmlTree.EMPTY, configuration.getText(
-                        "doclet.Skip_navigation_links"), "");
+                Content skipLinkContent = getHyperLink(DocLink.fragment("skip-navbar_bottom"),
+                        HtmlTree.EMPTY,
+                        configuration.getText("doclet.Skip_navigation_links"),
+                        "");
                 navDiv.addContent(skipLinkContent);
             }
             if (header) {
@@ -539,8 +516,8 @@
      * @return a content tree for the link
      */
     protected Content getNavLinkContents() {
-        Content linkContent = getHyperLink(relativePath +
-                "overview-summary.html", "", overviewLabel, "", "");
+        Content linkContent = getHyperLink(pathToRoot.resolve(DocPaths.OVERVIEW_SUMMARY),
+                overviewLabel, "", "");
         Content li = HtmlTree.LI(linkContent);
         return li;
     }
@@ -584,10 +561,10 @@
      * @param prev File name for the prev link
      * @return a content tree for the link
      */
-    public Content getNavLinkPrevious(String prev) {
+    public Content getNavLinkPrevious(DocPath prev) {
         Content li;
         if (prev != null) {
-            li = HtmlTree.LI(getHyperLink(prev, "", prevLabel, "", ""));
+            li = HtmlTree.LI(getHyperLink(prev, prevLabel, "", ""));
         }
         else
             li = HtmlTree.LI(prevLabel);
@@ -601,10 +578,10 @@
      * @param next File name for the next link
      * @return a content tree for the link
      */
-    public Content getNavLinkNext(String next) {
+    public Content getNavLinkNext(DocPath next) {
         Content li;
         if (next != null) {
-            li = HtmlTree.LI(getHyperLink(next, "", nextLabel, "", ""));
+            li = HtmlTree.LI(getHyperLink(next, nextLabel, "", ""));
         }
         else
             li = HtmlTree.LI(nextLabel);
@@ -617,9 +594,9 @@
      * @param link File to be linked, "index.html"
      * @return a content tree for the link
      */
-    protected Content getNavShowLists(String link) {
-        Content framesContent = getHyperLink(link + "?" + path +
-                filename, "", framesLabel, "", "_top");
+    protected Content getNavShowLists(DocPath link) {
+        DocLink dl = new DocLink(link, path.getPath(), null);
+        Content framesContent = getHyperLink(dl, framesLabel, "", "_top");
         Content li = HtmlTree.LI(framesContent);
         return li;
     }
@@ -630,7 +607,7 @@
      * @return a content tree for the link
      */
     protected Content getNavShowLists() {
-        return getNavShowLists(relativePath + "index.html");
+        return getNavShowLists(pathToRoot.resolve(DocPaths.INDEX));
     }
 
     /**
@@ -639,8 +616,8 @@
      * @param link File to be linked
      * @return a content tree for the link
      */
-    protected Content getNavHideLists(String link) {
-        Content noFramesContent = getHyperLink(link, "", noframesLabel, "", "_top");
+    protected Content getNavHideLists(DocPath link) {
+        Content noFramesContent = getHyperLink(link, noframesLabel, "", "_top");
         Content li = HtmlTree.LI(noFramesContent);
         return li;
     }
@@ -658,11 +635,11 @@
         PackageDoc[] packages = configuration.root.specifiedPackages();
         if (packages.length == 1 && configuration.root.specifiedClasses().length == 0) {
             treeLinkContent = getHyperLink(pathString(packages[0],
-                    "package-tree.html"), "", treeLabel,
+                    DocPaths.PACKAGE_TREE), treeLabel,
                     "", "");
         } else {
-            treeLinkContent = getHyperLink(relativePath + "overview-tree.html",
-                    "", treeLabel, "", "");
+            treeLinkContent = getHyperLink(pathToRoot.resolve(DocPaths.OVERVIEW_TREE),
+                    treeLabel, "", "");
         }
         Content li = HtmlTree.LI(treeLinkContent);
         return li;
@@ -675,7 +652,7 @@
      * @return a content tree for the link
      */
     protected Content getNavLinkMainTree(String label) {
-        Content mainTreeContent = getHyperLink(relativePath + "overview-tree.html",
+        Content mainTreeContent = getHyperLink(pathToRoot.resolve(DocPaths.OVERVIEW_TREE),
                 new StringContent(label));
         Content li = HtmlTree.LI(mainTreeContent);
         return li;
@@ -697,8 +674,8 @@
      * @return a content tree for the link
      */
     protected Content getNavLinkDeprecated() {
-        Content linkContent = getHyperLink(relativePath +
-                "deprecated-list.html", "", deprecatedLabel, "", "");
+        Content linkContent = getHyperLink(pathToRoot.resolve(DocPaths.DEPRECATED_LIST),
+                deprecatedLabel, "", "");
         Content li = HtmlTree.LI(linkContent);
         return li;
     }
@@ -711,8 +688,8 @@
      * @return a content tree for the link
      */
     protected Content getNavLinkClassIndex() {
-        Content allClassesContent = getHyperLink(relativePath +
-                AllClassesFrameWriter.OUTPUT_FILE_NAME_NOFRAMES, "",
+        Content allClassesContent = getHyperLink(pathToRoot.resolve(
+                DocPaths.ALLCLASSES_NOFRAME),
                 allclassesLabel, "", "");
         Content li = HtmlTree.LI(allClassesContent);
         return li;
@@ -724,9 +701,10 @@
      * @return a content tree for the link
      */
     protected Content getNavLinkIndex() {
-        Content linkContent = getHyperLink(relativePath +(configuration.splitindex?
-            DirectoryManager.getPath("index-files") + fileseparator: "") +
-            (configuration.splitindex?"index-1.html" : "index-all.html"), "",
+        Content linkContent = getHyperLink(pathToRoot.resolve(
+                (configuration.splitindex
+                    ? DocPaths.INDEX_FILES.resolve(DocPaths.indexN(1))
+                    : DocPaths.INDEX_ALL)),
             indexLabel, "", "");
         Content li = HtmlTree.LI(linkContent);
         return li;
@@ -740,16 +718,15 @@
      * @return a content tree for the link
      */
     protected Content getNavLinkHelp() {
-        String helpfilenm = configuration.helpfile;
-        if (helpfilenm.equals("")) {
-            helpfilenm = "help-doc.html";
+        String helpfile = configuration.helpfile;
+        DocPath helpfilenm;
+        if (helpfile.isEmpty()) {
+            helpfilenm = DocPaths.HELP_DOC;
         } else {
-            int lastsep;
-            if ((lastsep = helpfilenm.lastIndexOf(File.separatorChar)) != -1) {
-                helpfilenm = helpfilenm.substring(lastsep + 1);
-            }
+            DocFile file = DocFile.createFileForInput(configuration, helpfile);
+            helpfilenm = DocPath.create(file.getName());
         }
-        Content linkContent = getHyperLink(relativePath + helpfilenm, "",
+        Content linkContent = getHyperLink(pathToRoot.resolve(helpfilenm),
                 helpLabel, "", "");
         Content li = HtmlTree.LI(linkContent);
         return li;
@@ -884,25 +861,12 @@
     }
 
     /**
-     * Return path to the class page for a classdoc. For example, the class
-     * name is "java.lang.Object" and if the current file getting generated is
-     * "java/io/File.html", then the path string to the class, returned is
-     * "../../java/lang.Object.html".
-     *
-     * @param cd Class to which the path is requested.
-     */
-    protected String pathToClass(ClassDoc cd) {
-        return pathString(cd.containingPackage(), cd.name() + ".html");
-    }
-
-    /**
-     * Return the path to the class page for a classdoc. Works same as
-     * {@link #pathToClass(ClassDoc)}.
+     * Return the path to the class page for a classdoc.
      *
      * @param cd   Class to which the path is requested.
      * @param name Name of the file(doesn't include path).
      */
-    protected String pathString(ClassDoc cd, String name) {
+    protected DocPath pathString(ClassDoc cd, DocPath name) {
         return pathString(cd.containingPackage(), name);
     }
 
@@ -915,10 +879,8 @@
      * @param pd Package in which the file name is assumed to be.
      * @param name File name, to which path string is.
      */
-    protected String pathString(PackageDoc pd, String name) {
-        StringBuilder buf = new StringBuilder(relativePath);
-        buf.append(DirectoryManager.getPathToPackage(pd, name));
-        return buf.toString();
+    protected DocPath pathString(PackageDoc pd, DocPath name) {
+        return pathToRoot.resolve(DocPath.forPackage(pd).resolve(name));
     }
 
     /**
@@ -956,12 +918,12 @@
             }
         }
         if (included || pkg == null) {
-            return getHyperLinkString(pathString(pkg, "package-summary.html"),
-                                "", label, isStrong, style);
+            return getHyperLinkString(pathString(pkg, DocPaths.PACKAGE_SUMMARY),
+                                label, isStrong, style);
         } else {
-            String crossPkgLink = getCrossPackageLink(Util.getPackageName(pkg));
+            DocLink crossPkgLink = getCrossPackageLink(Util.getPackageName(pkg));
             if (crossPkgLink != null) {
-                return getHyperLinkString(crossPkgLink, "", label, isStrong, style);
+                return getHyperLinkString(crossPkgLink, label, isStrong, style);
             } else {
                 return label;
             }
@@ -987,12 +949,12 @@
             }
         }
         if (included || pkg == null) {
-            return getHyperLink(pathString(pkg, "package-summary.html"),
-                                "", label);
+            return getHyperLink(pathString(pkg, DocPaths.PACKAGE_SUMMARY),
+                    label);
         } else {
-            String crossPkgLink = getCrossPackageLink(Util.getPackageName(pkg));
+            DocLink crossPkgLink = getCrossPackageLink(Util.getPackageName(pkg));
             if (crossPkgLink != null) {
-                return getHyperLink(crossPkgLink, "", label);
+                return getHyperLink(crossPkgLink, label);
             } else {
                 return label;
             }
@@ -1020,10 +982,10 @@
             //d must be a class doc since in has no containing class.
             cd = (ClassDoc) doc;
         }
-        String href = relativePath + DocletConstants.SOURCE_OUTPUT_DIR_NAME
-                + DirectoryManager.getDirectoryPath(cd.containingPackage())
-                + cd.name() + ".html#" + SourceToHTMLConverter.getAnchorName(doc);
-        Content linkContent = getHyperLink(href, "", label, "", "");
+        DocPath href = pathToRoot
+                .resolve(DocPaths.SOURCE_OUTPUT)
+                .resolve(DocPath.forClass(cd));
+        Content linkContent = getHyperLink(href.fragment(SourceToHTMLConverter.getAnchorName(doc)), label, "", "");
         htmltree.addContent(linkContent);
     }
 
@@ -1036,7 +998,7 @@
      */
     public String getLink(LinkInfoImpl linkInfo) {
         LinkFactoryImpl factory = new LinkFactoryImpl(this);
-        String link = ((LinkOutputImpl) factory.getLinkOutput(linkInfo)).toString();
+        String link = factory.getLinkOutput(linkInfo).toString();
         displayLength += linkInfo.displayLength;
         return link;
     }
@@ -1049,8 +1011,7 @@
      */
     public String getTypeParameterLinks(LinkInfoImpl linkInfo) {
         LinkFactoryImpl factory = new LinkFactoryImpl(this);
-        return ((LinkOutputImpl)
-            factory.getTypeParameterLinks(linkInfo, false)).toString();
+        return factory.getTypeParameterLinks(linkInfo, false).toString();
     }
 
     /*************************************************************
@@ -1070,10 +1031,10 @@
     public String getCrossClassLink(String qualifiedClassName, String refMemName,
                                     String label, boolean strong, String style,
                                     boolean code) {
-        String className = "",
-            packageName = qualifiedClassName == null ? "" : qualifiedClassName;
+        String className = "";
+        String packageName = qualifiedClassName == null ? "" : qualifiedClassName;
         int periodIndex;
-        while((periodIndex = packageName.lastIndexOf('.')) != -1) {
+        while ((periodIndex = packageName.lastIndexOf('.')) != -1) {
             className = packageName.substring(periodIndex + 1, packageName.length()) +
                 (className.length() > 0 ? "." + className : "");
             String defaultLabel = code ? codeText(className) : className;
@@ -1084,11 +1045,12 @@
                 //the -link option.  There are ways to determine if an external package
                 //exists, but no way to determine if the external class exists.  We just
                 //have to assume that it does.
-                return getHyperLinkString(
-                    configuration.extern.getExternalLink(packageName, relativePath,
-                                className + ".html?is-external=true"),
-                    refMemName == null ? "" : refMemName,
-                    label == null || label.length() == 0 ? defaultLabel : label,
+                DocLink link = configuration.extern.getExternalLink(packageName, pathToRoot,
+                                className + ".html", refMemName);
+                return getHyperLinkString(link,
+                    (label == null) || label.length() == 0 ? defaultLabel : label,
+
+
                     strong, style,
                     configuration.getText("doclet.Href_Class_Or_Interface_Title", packageName),
                     "");
@@ -1104,9 +1066,9 @@
         return configuration.extern.isExternal(cd);
     }
 
-    public String getCrossPackageLink(String pkgName) {
-        return configuration.extern.getExternalLink(pkgName, relativePath,
-            "package-summary.html?is-external=true");
+    public DocLink getCrossPackageLink(String pkgName) {
+        return configuration.extern.getExternalLink(pkgName, pathToRoot,
+            DocPaths.PACKAGE_SUMMARY.getPath());
     }
 
     /**
@@ -1134,7 +1096,7 @@
 
     /**
      * Retrieve the class link with the package portion of the label in
-     * plain text.  If the qualifier is excluded, it willnot be included in the
+     * plain text.  If the qualifier is excluded, it will not be included in the
      * link label.
      *
      * @param cd the class to link to.
@@ -1318,10 +1280,11 @@
                 return getPackageLinkString(refPackage, label, false);
             } else {
                 //@see is not referencing an included class or package.  Check for cross links.
-                String classCrossLink, packageCrossLink = getCrossPackageLink(refClassName);
+                String classCrossLink;
+                DocLink packageCrossLink = getCrossPackageLink(refClassName);
                 if (packageCrossLink != null) {
                     //Package cross link found
-                    return getHyperLinkString(packageCrossLink, "",
+                    return getHyperLinkString(packageCrossLink,
                         (label.isEmpty() ? text : label), false);
                 } else if ((classCrossLink = getCrossClassLink(refClassName,
                         refMemName, label, false, "", !plain)) != null) {
@@ -1450,7 +1413,7 @@
      * @param doc the doc for which the comment tags will be generated
      * @param tags the first sentence tags for the doc
      * @param depr true if it is deprecated
-     * @param first true if the first sentenge tags should be added
+     * @param first true if the first sentence tags should be added
      * @param htmltree the documentation tree to which the comment tags will be added
      */
     private void addCommentTags(Doc doc, Tag[] tags, boolean depr,
@@ -1561,7 +1524,7 @@
 
     /**
      * Suppose a piece of documentation has a relative link.  When you copy
-     * that documetation to another place such as the index or class-use page,
+     * that documentation to another place such as the index or class-use page,
      * that relative link will no longer work.  We should redirect those links
      * so that they will work again.
      * <p>
@@ -1587,21 +1550,17 @@
             return text;
         }
 
-        String redirectPathFromRoot;
+        DocPath redirectPathFromRoot;
         if (doc instanceof ClassDoc) {
-            redirectPathFromRoot = DirectoryManager.getDirectoryPath(((ClassDoc) doc).containingPackage());
+            redirectPathFromRoot = DocPath.forPackage(((ClassDoc) doc).containingPackage());
         } else if (doc instanceof MemberDoc) {
-            redirectPathFromRoot = DirectoryManager.getDirectoryPath(((MemberDoc) doc).containingPackage());
+            redirectPathFromRoot = DocPath.forPackage(((MemberDoc) doc).containingPackage());
         } else if (doc instanceof PackageDoc) {
-            redirectPathFromRoot = DirectoryManager.getDirectoryPath((PackageDoc) doc);
+            redirectPathFromRoot = DocPath.forPackage((PackageDoc) doc);
         } else {
             return text;
         }
 
-        if (! redirectPathFromRoot.endsWith(DirectoryManager.URL_FILE_SEPARATOR)) {
-            redirectPathFromRoot += DirectoryManager.URL_FILE_SEPARATOR;
-        }
-
         //Redirect all relative links.
         int end, begin = text.toLowerCase().indexOf("<a");
         if(begin >= 0){
@@ -1627,22 +1586,21 @@
                     //might be missing '>' character because the href has an inline tag.
                     break;
                 }
-                if(textBuff.substring(begin, end).indexOf("\"") != -1){
+                if (textBuff.substring(begin, end).indexOf("\"") != -1){
                     begin = textBuff.indexOf("\"", begin) + 1;
                     end = textBuff.indexOf("\"", begin +1);
-                    if(begin == 0 || end == -1){
+                    if (begin == 0 || end == -1){
                         //Link is missing a quote.
                         break;
                     }
                 }
                 String relativeLink = textBuff.substring(begin, end);
-                if(!(relativeLink.toLowerCase().startsWith("mailto:") ||
-                     relativeLink.toLowerCase().startsWith("http:") ||
-                     relativeLink.toLowerCase().startsWith("https:") ||
-                     relativeLink.toLowerCase().startsWith("file:"))){
-                     relativeLink = "{@"+(new DocRootTaglet()).getName() + "}"
-                        + redirectPathFromRoot
-                        + relativeLink;
+                if (!(relativeLink.toLowerCase().startsWith("mailto:") ||
+                        relativeLink.toLowerCase().startsWith("http:") ||
+                        relativeLink.toLowerCase().startsWith("https:") ||
+                        relativeLink.toLowerCase().startsWith("file:"))) {
+                    relativeLink = "{@"+(new DocRootTaglet()).getName() + "}/"
+                        + redirectPathFromRoot.resolve(relativeLink).getPath();
                     textBuff.replace(begin, end, relativeLink);
                 }
                 begin = textBuff.toString().toLowerCase().indexOf("<a", begin + 1);
@@ -1714,18 +1672,17 @@
      * @return an HtmlTree for the lINK tag which provides the stylesheet location
      */
     public HtmlTree getStyleSheetProperties() {
-        String filename = configuration.stylesheetfile;
-        if (filename.length() > 0) {
-            File stylefile = new File(filename);
-            String parent = stylefile.getParent();
-            filename = (parent == null)?
-                filename:
-                filename.substring(parent.length() + 1);
+        String stylesheetfile = configuration.stylesheetfile;
+        DocPath stylesheet;
+        if (stylesheetfile.isEmpty()) {
+            stylesheet = DocPaths.STYLESHEET;
         } else {
-            filename = "stylesheet.css";
+            DocFile file = DocFile.createFileForInput(configuration, stylesheetfile);
+            stylesheet = DocPath.create(file.getName());
         }
-        filename = relativePath + filename;
-        HtmlTree link = HtmlTree.LINK("stylesheet", "text/css", filename, "Style");
+        HtmlTree link = HtmlTree.LINK("stylesheet", "text/css",
+                pathToRoot.resolve(stylesheet).getPath(),
+                "Style");
         return link;
     }
 
--- a/src/share/classes/com/sun/tools/doclets/formats/html/LinkFactoryImpl.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/LinkFactoryImpl.java	Fri Nov 02 17:55:34 2012 -0700
@@ -78,11 +78,12 @@
         LinkOutputImpl linkOutput = new LinkOutputImpl();
         if (classDoc.isIncluded()) {
             if (configuration.isGeneratedDoc(classDoc)) {
-                String filename = pathString(classLinkInfo);
+                DocPath filename = getPath(classLinkInfo);
                 if (linkInfo.linkToSelf ||
-                                !(linkInfo.classDoc.name() + ".html").equals(m_writer.filename)) {
-                        linkOutput.append(m_writer.getHyperLinkString(filename,
-                            classLinkInfo.where, label.toString(),
+                                !(DocPath.forName(classDoc)).equals(m_writer.filename)) {
+                        linkOutput.append(m_writer.getHyperLinkString(
+                                filename.fragment(classLinkInfo.where),
+                            label.toString(),
                             classLinkInfo.isStrong, classLinkInfo.styleName,
                             title, classLinkInfo.target));
                         if (noLabel && !classLinkInfo.excludeTypeParameterLinks) {
@@ -161,16 +162,12 @@
      *
      * @param linkInfo the information about the link.
      */
-    private String pathString(LinkInfoImpl linkInfo) {
+    private DocPath getPath(LinkInfoImpl linkInfo) {
         if (linkInfo.context == LinkInfoImpl.PACKAGE_FRAME) {
             //Not really necessary to do this but we want to be consistent
             //with 1.4.2 output.
-            return linkInfo.classDoc.name() + ".html";
+            return DocPath.forName(linkInfo.classDoc);
         }
-        StringBuilder buf = new StringBuilder(m_writer.relativePath);
-        buf.append(DirectoryManager.getPathToPackage(
-            linkInfo.classDoc.containingPackage(),
-            linkInfo.classDoc.name() + ".html"));
-        return buf.toString();
+        return m_writer.pathToRoot.resolve(DocPath.forClass(linkInfo.classDoc));
     }
 }
--- a/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java	Fri Nov 02 17:55:34 2012 -0700
@@ -400,7 +400,7 @@
      */
     protected Content getNavSummaryLink(ClassDoc cd, boolean link) {
         if (link) {
-            return writer.getHyperLink("", (cd == null)?
+            return writer.getHyperLink((cd == null)?
                 "method_summary":
                 "methods_inherited_from_class_" +
                 configuration().getClassName(cd),
@@ -415,7 +415,7 @@
      */
     protected void addNavDetailLink(boolean link, Content liNav) {
         if (link) {
-            liNav.addContent(writer.getHyperLink("", "method_detail",
+            liNav.addContent(writer.getHyperLink("method_detail",
                     writer.getResource("doclet.navMethod")));
         } else {
             liNav.addContent(writer.getResource("doclet.navMethod"));
--- a/src/share/classes/com/sun/tools/doclets/formats/html/NestedClassWriterImpl.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/NestedClassWriterImpl.java	Fri Nov 02 17:55:34 2012 -0700
@@ -203,9 +203,8 @@
      */
     protected Content getNavSummaryLink(ClassDoc cd, boolean link) {
         if (link) {
-            return writer.getHyperLink("", (cd == null) ? "nested_class_summary":
-                "nested_classes_inherited_from_class_" +
-                cd.qualifiedName(),
+            return writer.getHyperLink((cd == null) ? "nested_class_summary":
+                "nested_classes_inherited_from_class_" + cd.qualifiedName(),
                 writer.getResource("doclet.navNested"));
         } else {
             return writer.getResource("doclet.navNested");
--- a/src/share/classes/com/sun/tools/doclets/formats/html/PackageFrameWriter.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/PackageFrameWriter.java	Fri Nov 02 17:55:34 2012 -0700
@@ -60,17 +60,12 @@
     private Set<ClassDoc> documentedClasses;
 
     /**
-     * The name of the output file.
-     */
-    public static final String OUTPUT_FILE_NAME = "package-frame.html";
-
-    /**
      * Constructor to construct PackageFrameWriter object and to generate
      * "package-frame.html" file in the respective package directory.
      * For example for package "java.lang" this will generate file
      * "package-frame.html" file in the "java/lang" directory. It will also
      * create "java/lang" directory in the current or the destination directory
-     * if it doesen't exist.
+     * if it doesn't exist.
      *
      * @param configuration the configuration of the doclet.
      * @param packageDoc PackageDoc under consideration.
@@ -78,7 +73,7 @@
     public PackageFrameWriter(ConfigurationImpl configuration,
                               PackageDoc packageDoc)
                               throws IOException {
-        super(configuration, DirectoryManager.getDirectoryPath(packageDoc), OUTPUT_FILE_NAME, DirectoryManager.getRelativePath(packageDoc));
+        super(configuration, DocPath.forPackage(packageDoc).resolve(DocPaths.PACKAGE_FRAME));
         this.packageDoc = packageDoc;
         if (configuration.root.specifiedPackages().length == 0) {
             documentedClasses = new HashSet<ClassDoc>(Arrays.asList(configuration.root.classes()));
@@ -113,7 +108,7 @@
         } catch (IOException exc) {
             configuration.standardmessage.error(
                     "doclet.exception_encountered",
-                    exc.toString(), OUTPUT_FILE_NAME);
+                    exc.toString(), DocPaths.PACKAGE_FRAME.getPath());
             throw new DocletAbortException();
         }
     }
--- a/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexFrameWriter.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexFrameWriter.java	Fri Nov 02 17:55:34 2012 -0700
@@ -52,7 +52,7 @@
      * @param filename Name of the package index file to be generated.
      */
     public PackageIndexFrameWriter(ConfigurationImpl configuration,
-                                   String filename) throws IOException {
+                                   DocPath filename) throws IOException {
         super(configuration, filename);
     }
 
@@ -62,7 +62,7 @@
      */
     public static void generate(ConfigurationImpl configuration) {
         PackageIndexFrameWriter packgen;
-        String filename = "overview-frame.html";
+        DocPath filename = DocPaths.OVERVIEW_FRAME;
         try {
             packgen = new PackageIndexFrameWriter(configuration, filename);
             packgen.buildPackageIndexFile("doclet.Window_Overview", false);
@@ -109,12 +109,12 @@
         if (pd.name().length() > 0) {
             packageLabel = getPackageLabel(pd.name());
             packageLinkContent = getHyperLink(pathString(pd,
-                    "package-frame.html"), "", packageLabel, "",
+                     DocPaths.PACKAGE_FRAME), packageLabel, "",
                     "packageFrame");
         } else {
             packageLabel = new RawHtml("&lt;unnamed package&gt;");
-            packageLinkContent = getHyperLink("package-frame.html",
-                    "", packageLabel, "", "packageFrame");
+            packageLinkContent = getHyperLink(DocPaths.PACKAGE_FRAME,
+                    packageLabel, "", "packageFrame");
         }
         Content li = HtmlTree.LI(packageLinkContent);
         return li;
@@ -148,7 +148,7 @@
      * @param body the Content object to which the all classes link should be added
      */
     protected void addAllClassesLink(Content body) {
-        Content linkContent = getHyperLink("allclasses-frame.html", "",
+        Content linkContent = getHyperLink(DocPaths.ALLCLASSES_FRAME,
                 allclassesLabel, "", "packageFrame");
         Content div = HtmlTree.DIV(HtmlStyle.indexHeader, linkContent);
         body.addContent(div);
--- a/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java	Fri Nov 02 17:55:34 2012 -0700
@@ -36,7 +36,7 @@
 /**
  * Generate the package index page "overview-summary.html" for the right-hand
  * frame. A click on the package name on this page will update the same frame
- * with the "pacakge-summary.html" file for the clicked package.
+ * with the "package-summary.html" file for the clicked package.
  *
  *  <p><b>This is NOT part of any supported API.
  *  If you write code that depends on this, you do so at your own risk.
@@ -73,7 +73,7 @@
      * @see Group
      */
     public PackageIndexWriter(ConfigurationImpl configuration,
-                              String filename)
+                              DocPath filename)
                        throws IOException {
         super(configuration, filename);
         this.root = configuration.root;
@@ -88,7 +88,7 @@
      */
     public static void generate(ConfigurationImpl configuration) {
         PackageIndexWriter packgen;
-        String filename = "overview-summary.html";
+        DocPath filename = DocPaths.OVERVIEW_SUMMARY;
         try {
             packgen = new PackageIndexWriter(configuration, filename);
             packgen.buildPackageIndexFile("doclet.Window_Overview_Summary", true);
@@ -178,7 +178,7 @@
             Content see = seeLabel;
             see.addContent(" ");
             Content descPara = HtmlTree.P(see);
-            Content descLink = getHyperLink("", "overview_description",
+            Content descLink = getHyperLink(DocLink.fragment("overview_description"),
                 descriptionLabel, "", "");
             descPara.addContent(descLink);
             div.addContent(descPara);
--- a/src/share/classes/com/sun/tools/doclets/formats/html/PackageTreeWriter.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/PackageTreeWriter.java	Fri Nov 02 17:55:34 2012 -0700
@@ -67,15 +67,14 @@
      * @throws DocletAbortException
      */
     public PackageTreeWriter(ConfigurationImpl configuration,
-                             String path, String filename,
+                             DocPath path,
                              PackageDoc packagedoc,
                              PackageDoc prev, PackageDoc next)
                       throws IOException {
-        super(configuration, path, filename,
+        super(configuration, path,
               new ClassTree(
                 configuration.classDocCatalog.allClasses(packagedoc),
-                configuration),
-              packagedoc);
+                configuration));
         this.packagedoc = packagedoc;
         this.prev = prev;
         this.next = next;
@@ -96,17 +95,16 @@
                                 PackageDoc pkg, PackageDoc prev,
                                 PackageDoc next, boolean noDeprecated) {
         PackageTreeWriter packgen;
-        String path = DirectoryManager.getDirectoryPath(pkg);
-        String filename = "package-tree.html";
+        DocPath path = DocPath.forPackage(pkg).resolve(DocPaths.PACKAGE_TREE);
         try {
-            packgen = new PackageTreeWriter(configuration, path, filename, pkg,
+            packgen = new PackageTreeWriter(configuration, path, pkg,
                 prev, next);
             packgen.generatePackageTreeFile();
             packgen.close();
         } catch (IOException exc) {
             configuration.standardmessage.error(
                         "doclet.exception_encountered",
-                        exc.toString(), filename);
+                        exc.toString(), path.getPath());
             throw new DocletAbortException();
         }
     }
@@ -175,9 +173,8 @@
         if (prev == null) {
             return getNavLinkPrevious(null);
         } else {
-            String path = DirectoryManager.getRelativePath(packagedoc.name(),
-                    prev.name());
-            return getNavLinkPrevious(path + "package-tree.html");
+            DocPath path = DocPath.relativePath(packagedoc, prev);
+            return getNavLinkPrevious(path.resolve(DocPaths.PACKAGE_TREE));
         }
     }
 
@@ -190,9 +187,8 @@
         if (next == null) {
             return getNavLinkNext(null);
         } else {
-            String path = DirectoryManager.getRelativePath(packagedoc.name(),
-                    next.name());
-            return getNavLinkNext(path + "package-tree.html");
+            DocPath path = DocPath.relativePath(packagedoc, next);
+            return getNavLinkNext(path.resolve(DocPaths.PACKAGE_TREE));
         }
     }
 
@@ -202,7 +198,7 @@
      * @return a content tree for the package link
      */
     protected Content getNavLinkPackage() {
-        Content linkContent = getHyperLink("package-summary.html", "",
+        Content linkContent = getHyperLink(DocPaths.PACKAGE_SUMMARY,
                 packageLabel);
         Content li = HtmlTree.LI(linkContent);
         return li;
--- a/src/share/classes/com/sun/tools/doclets/formats/html/PackageUseWriter.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/PackageUseWriter.java	Fri Nov 02 17:55:34 2012 -0700
@@ -57,11 +57,9 @@
      * @throws DocletAbortException
      */
     public PackageUseWriter(ConfigurationImpl configuration,
-                            ClassUseMapper mapper, String filename,
+                            ClassUseMapper mapper, DocPath filename,
                             PackageDoc pkgdoc) throws IOException {
-        super(configuration, DirectoryManager.getDirectoryPath(pkgdoc),
-              filename,
-              DirectoryManager.getRelativePath(pkgdoc.name()));
+        super(configuration, DocPath.forPackage(pkgdoc).resolve(filename));
         this.pkgdoc = pkgdoc;
 
         // by examining all classes in this package, find what packages
@@ -98,7 +96,7 @@
     public static void generate(ConfigurationImpl configuration,
                                 ClassUseMapper mapper, PackageDoc pkgdoc) {
         PackageUseWriter pkgusegen;
-        String filename = "package-use.html";
+        DocPath filename = DocPaths.PACKAGE_USE;
         try {
             pkgusegen = new PackageUseWriter(configuration,
                                              mapper, filename, pkgdoc);
@@ -232,10 +230,10 @@
      */
     protected void addClassRow(ClassDoc usedClass, String packageName,
             Content contentTree) {
-        String path = pathString(usedClass,
-                "class-use/" + usedClass.name() + ".html");
+        DocPath dp = pathString(usedClass,
+                DocPaths.CLASS_USE.resolve(DocPath.forName(usedClass)));
         Content td = HtmlTree.TD(HtmlStyle.colOne,
-                getHyperLink(path, packageName, new StringContent(usedClass.name())));
+                getHyperLink(dp.fragment(packageName), new StringContent(usedClass.name())));
         addIndexComment(usedClass, td);
         contentTree.addContent(td);
     }
@@ -248,7 +246,7 @@
      */
     protected void addPackageUse(PackageDoc pkg, Content contentTree) throws IOException {
         Content tdFirst = HtmlTree.TD(HtmlStyle.colFirst,
-                getHyperLink("", Util.getPackageName(pkg),
+                getHyperLink(Util.getPackageName(pkg),
                 new RawHtml(Util.getPackageName(pkg))));
         contentTree.addContent(tdFirst);
         HtmlTree tdLast = new HtmlTree(HtmlTag.TD);
@@ -288,7 +286,7 @@
      * @return a content tree for the package link
      */
     protected Content getNavLinkPackage() {
-        Content linkContent = getHyperLink("package-summary.html", "",
+        Content linkContent = getHyperLink(DocPaths.PACKAGE_SUMMARY,
                 packageLabel);
         Content li = HtmlTree.LI(linkContent);
         return li;
@@ -310,7 +308,7 @@
      * @return a content tree for the tree link
      */
     protected Content getNavLinkTree() {
-        Content linkContent = getHyperLink("package-tree.html", "",
+        Content linkContent = getHyperLink(DocPaths.PACKAGE_TREE,
                 treeLabel);
         Content li = HtmlTree.LI(linkContent);
         return li;
--- a/src/share/classes/com/sun/tools/doclets/formats/html/PackageWriterImpl.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/PackageWriterImpl.java	Fri Nov 02 17:55:34 2012 -0700
@@ -65,17 +65,12 @@
     protected PackageDoc packageDoc;
 
     /**
-     * The name of the output file.
-     */
-    private static final String OUTPUT_FILE_NAME = "package-summary.html";
-
-    /**
      * Constructor to construct PackageWriter object and to generate
      * "package-summary.html" file in the respective package directory.
      * For example for package "java.lang" this will generate file
      * "package-summary.html" file in the "java/lang" directory. It will also
      * create "java/lang" directory in the current or the destination directory
-     * if it doesen't exist.
+     * if it doesn't exist.
      *
      * @param configuration the configuration of the doclet.
      * @param packageDoc    PackageDoc under consideration.
@@ -83,25 +78,15 @@
      * @param next            Next package in the sorted array.
      */
     public PackageWriterImpl(ConfigurationImpl configuration,
-        PackageDoc packageDoc, PackageDoc prev, PackageDoc next)
-    throws IOException {
-        super(configuration, DirectoryManager.getDirectoryPath(packageDoc), OUTPUT_FILE_NAME,
-             DirectoryManager.getRelativePath(packageDoc.name()));
+            PackageDoc packageDoc, PackageDoc prev, PackageDoc next)
+            throws IOException {
+        super(configuration, DocPath.forPackage(packageDoc).resolve(DocPaths.PACKAGE_SUMMARY));
         this.prev = prev;
         this.next = next;
         this.packageDoc = packageDoc;
     }
 
     /**
-     * Return the name of the output file.
-     *
-     * @return the name of the output file.
-     */
-    public String getOutputFileName() {
-        return OUTPUT_FILE_NAME;
-    }
-
-    /**
      * {@inheritDoc}
      */
     public Content getPackageHeader(String heading) {
@@ -127,7 +112,7 @@
             addSummaryComment(packageDoc, docSummaryDiv);
             div.addContent(docSummaryDiv);
             Content space = getSpace();
-            Content descLink = getHyperLink("", "package_description",
+            Content descLink = getHyperLink(DocLink.fragment("package_description"),
                     descriptionLabel, "", "");
             Content descPara = new HtmlTree(HtmlTag.P, seeLabel, space, descLink);
             div.addContent(descPara);
@@ -265,7 +250,7 @@
      * @return a content tree for the class use link
      */
     protected Content getNavLinkClassUse() {
-        Content useLink = getHyperLink("package-use.html", "",
+        Content useLink = getHyperLink(DocPaths.PACKAGE_USE,
                 useLabel, "", "");
         Content li = HtmlTree.LI(useLink);
         return li;
@@ -281,9 +266,8 @@
         if (prev == null) {
             li = HtmlTree.LI(prevpackageLabel);
         } else {
-            String path = DirectoryManager.getRelativePath(packageDoc.name(),
-                                                           prev.name());
-            li = HtmlTree.LI(getHyperLink(path + "package-summary.html", "",
+            DocPath path = DocPath.relativePath(packageDoc, prev);
+            li = HtmlTree.LI(getHyperLink(path.resolve(DocPaths.PACKAGE_SUMMARY),
                 prevpackageLabel, "", ""));
         }
         return li;
@@ -299,9 +283,8 @@
         if (next == null) {
             li = HtmlTree.LI(nextpackageLabel);
         } else {
-            String path = DirectoryManager.getRelativePath(packageDoc.name(),
-                                                           next.name());
-            li = HtmlTree.LI(getHyperLink(path + "package-summary.html", "",
+            DocPath path = DocPath.relativePath(packageDoc, next);
+            li = HtmlTree.LI(getHyperLink(path.resolve(DocPaths.PACKAGE_SUMMARY),
                 nextpackageLabel, "", ""));
         }
         return li;
@@ -314,7 +297,7 @@
      * @return a content tree for the tree link
      */
     protected Content getNavLinkTree() {
-        Content useLink = getHyperLink("package-tree.html", "",
+        Content useLink = getHyperLink(DocPaths.PACKAGE_TREE,
                 treeLabel, "", "");
         Content li = HtmlTree.LI(useLink);
         return li;
--- a/src/share/classes/com/sun/tools/doclets/formats/html/SerializedFormWriterImpl.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/SerializedFormWriterImpl.java	Fri Nov 02 17:55:34 2012 -0700
@@ -29,6 +29,7 @@
 import com.sun.javadoc.*;
 import com.sun.tools.doclets.formats.html.markup.*;
 import com.sun.tools.doclets.internal.toolkit.*;
+import com.sun.tools.doclets.internal.toolkit.util.DocPaths;
 import com.sun.tools.doclets.internal.toolkit.util.DocletAbortException;
 
 /**
@@ -44,14 +45,12 @@
 public class SerializedFormWriterImpl extends SubWriterHolderWriter
     implements SerializedFormWriter {
 
-    private static final String FILE_NAME = "serialized-form.html";
-
     /**
      * @throws IOException
      * @throws DocletAbortException
      */
     public SerializedFormWriterImpl() throws IOException {
-        super(ConfigurationImpl.getInstance(), FILE_NAME);
+        super(ConfigurationImpl.getInstance(), DocPaths.SERIALIZED_FORM);
     }
 
     /**
--- a/src/share/classes/com/sun/tools/doclets/formats/html/SingleIndexWriter.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/SingleIndexWriter.java	Fri Nov 02 17:55:34 2012 -0700
@@ -55,11 +55,9 @@
      * @param indexbuilder Unicode based Index from {@link IndexBuilder}
      */
     public SingleIndexWriter(ConfigurationImpl configuration,
-                             String filename,
+                             DocPath filename,
                              IndexBuilder indexbuilder) throws IOException {
         super(configuration, filename, indexbuilder);
-        relativepathNoSlash = ".";
-        relativePath = "./";
     }
 
     /**
@@ -71,7 +69,7 @@
     public static void generate(ConfigurationImpl configuration,
                                 IndexBuilder indexbuilder) {
         SingleIndexWriter indexgen;
-        String filename = "index-all.html";
+        DocPath filename = DocPaths.INDEX_ALL;
         try {
             indexgen = new SingleIndexWriter(configuration,
                                              filename, indexbuilder);
@@ -117,7 +115,7 @@
         for (int i = 0; i < indexbuilder.elements().length; i++) {
             String unicode = (indexbuilder.elements())[i].toString();
             contentTree.addContent(
-                    getHyperLink("#_" + unicode + "_", new StringContent(unicode)));
+                    getHyperLink("_" + unicode + "_", new StringContent(unicode)));
             contentTree.addContent(getSpace());
         }
     }
--- a/src/share/classes/com/sun/tools/doclets/formats/html/SourceToHTMLConverter.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/SourceToHTMLConverter.java	Fri Nov 02 17:55:34 2012 -0700
@@ -26,11 +26,13 @@
 package com.sun.tools.doclets.formats.html;
 
 import java.io.*;
+
 import javax.tools.FileObject;
+
 import com.sun.javadoc.*;
+import com.sun.tools.doclets.formats.html.markup.*;
 import com.sun.tools.doclets.internal.toolkit.*;
 import com.sun.tools.doclets.internal.toolkit.util.*;
-import com.sun.tools.doclets.formats.html.markup.*;
 
 /**
  * Converts Java Source Code to HTML.
@@ -62,7 +64,7 @@
      * Relative path from the documentation root to the file that is being
      * generated.
      */
-    private static String relativePath = "";
+    private static DocPath relativePath = DocPath.empty;
 
     /**
      * Source is converted to HTML using static methods below.
@@ -77,7 +79,7 @@
      * @param outputdir the name of the directory to output to.
      */
     public static void convertRoot(ConfigurationImpl configuration, RootDoc rd,
-            String outputdir) {
+            DocPath outputdir) {
         if (rd == null || outputdir == null) {
             return;
         }
@@ -95,8 +97,7 @@
             // package files to HTML.
             if (!(configuration.nodeprecated &&
                     (Util.isDeprecated(cds[i]) || Util.isDeprecated(cds[i].containingPackage()))))
-                convertClass(configuration, cds[i],
-                        getPackageOutputDir(outputdir, cds[i].containingPackage()));
+                convertClass(configuration, cds[i], outputdir);
         }
     }
 
@@ -108,11 +109,10 @@
      * @param outputdir the name of the directory to output to.
      */
     public static void convertPackage(ConfigurationImpl configuration, PackageDoc pd,
-            String outputdir) {
-        if (pd == null || outputdir == null) {
+            DocPath outputdir) {
+        if (pd == null) {
             return;
         }
-        String classOutputdir = getPackageOutputDir(outputdir, pd);
         ClassDoc[] cds = pd.allClasses();
         for (int i = 0; i < cds.length; i++) {
             // If -nodeprecated option is set and the class is marked as deprecated,
@@ -120,23 +120,11 @@
             // containing package deprecation since it is already check in
             // the calling method above.
             if (!(configuration.nodeprecated && Util.isDeprecated(cds[i])))
-                convertClass(configuration, cds[i], classOutputdir);
+                convertClass(configuration, cds[i], outputdir);
         }
     }
 
     /**
-     * Return the directory write output to for the given package.
-     *
-     * @param outputDir the directory to output to.
-     * @param pd the Package to generate output for.
-     * @return the package output directory as a String.
-     */
-    private static String getPackageOutputDir(String outputDir, PackageDoc pd) {
-        return outputDir + File.separator +
-            DirectoryManager.getDirectoryPath(pd) + File.separator;
-    }
-
-    /**
      * Convert the given Class to an HTML.
      *
      * @param configuration the configuration.
@@ -144,8 +132,8 @@
      * @param outputdir the name of the directory to output to.
      */
     public static void convertClass(ConfigurationImpl configuration, ClassDoc cd,
-            String outputdir) {
-        if (cd == null || outputdir == null) {
+            DocPath outputdir) {
+        if (cd == null) {
             return;
         }
         try {
@@ -168,8 +156,9 @@
             LineNumberReader reader = new LineNumberReader(r);
             int lineno = 1;
             String line;
-            relativePath = DirectoryManager.getRelativePath(DocletConstants.SOURCE_OUTPUT_DIR_NAME) +
-                    DirectoryManager.getRelativePath(cd.containingPackage());
+            relativePath = DocPaths.SOURCE_OUTPUT
+                    .resolve(DocPath.forPackage(cd))
+                    .invert();
             Content body = getHeader();
             Content pre = new HtmlTree(HtmlTag.PRE);
             try {
@@ -184,8 +173,8 @@
             addBlankLines(pre);
             Content div = HtmlTree.DIV(HtmlStyle.sourceContainer, pre);
             body.addContent(div);
-            writeToFile(body, outputdir, cd.name(), configuration);
-        } catch (Exception e){
+            writeToFile(body, outputdir.resolve(DocPath.forClass(cd)), configuration);
+        } catch (IOException e) {
             e.printStackTrace();
         }
     }
@@ -194,12 +183,11 @@
      * Write the output to the file.
      *
      * @param body the documentation content to be written to the file.
-     * @param outputDir the directory to output to.
-     * @param className the name of the class that I am converting to HTML.
+     * @param path the path for the file.
      * @param configuration the Doclet configuration to pass notices to.
      */
-    private static void writeToFile(Content body, String outputDir,
-            String className, ConfigurationImpl configuration) throws IOException {
+    private static void writeToFile(Content body, DocPath path,
+            ConfigurationImpl configuration) throws IOException {
         Content htmlDocType = DocType.Transitional();
         Content head = new HtmlTree(HtmlTag.HEAD);
         head.addContent(HtmlTree.TITLE(new StringContent(
@@ -208,15 +196,15 @@
         Content htmlTree = HtmlTree.HTML(configuration.getLocale().getLanguage(),
                 head, body);
         Content htmlDocument = new HtmlDocument(htmlDocType, htmlTree);
-        File dir = new File(outputDir);
-        dir.mkdirs();
-        File newFile = new File(dir, className + ".html");
-        configuration.message.notice("doclet.Generating_0", newFile.getPath());
-        FileOutputStream fout = new FileOutputStream(newFile);
-        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fout));
-        bw.write(htmlDocument.toString());
-        bw.close();
-        fout.close();
+        configuration.message.notice("doclet.Generating_0", path.getPath());
+        DocFile df = DocFile.createFileForOutput(configuration, path);
+        Writer w = df.openWriter();
+        try {
+            htmlDocument.write(w, true);
+        } finally {
+            w.close();
+        }
+
     }
 
     /**
@@ -227,17 +215,15 @@
      */
     public static HtmlTree getStyleSheetProperties(ConfigurationImpl configuration) {
         String filename = configuration.stylesheetfile;
+        DocPath stylesheet;
         if (filename.length() > 0) {
-            File stylefile = new File(filename);
-            String parent = stylefile.getParent();
-            filename = (parent == null)?
-                filename:
-                filename.substring(parent.length() + 1);
+            DocFile file = DocFile.createFileForInput(configuration, filename);
+            stylesheet = DocPath.create(file.getName());
         } else {
-            filename = "stylesheet.css";
+            stylesheet = DocPaths.STYLESHEET;
         }
-        filename = relativePath + filename;
-        HtmlTree link = HtmlTree.LINK("stylesheet", "text/css", filename, "Style");
+        DocPath p = relativePath.resolve(stylesheet);
+        HtmlTree link = HtmlTree.LINK("stylesheet", "text/css", p.getPath(), "Style");
         return link;
     }
 
--- a/src/share/classes/com/sun/tools/doclets/formats/html/SplitIndexWriter.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/SplitIndexWriter.java	Fri Nov 02 17:55:34 2012 -0700
@@ -62,15 +62,13 @@
      * from this file.
      *
      * @param path       Path to the file which is getting generated.
-     * @param filename   Name of the file which is getting genrated.
-     * @param relpath    Relative path from this file to the current directory.
      * @param indexbuilder Unicode based Index from {@link IndexBuilder}
      */
     public SplitIndexWriter(ConfigurationImpl configuration,
-                            String path, String filename,
-                            String relpath, IndexBuilder indexbuilder,
+                            DocPath path,
+                            IndexBuilder indexbuilder,
                             int prev, int next) throws IOException {
-        super(configuration, path, filename, relpath, indexbuilder);
+        super(configuration, path, indexbuilder);
         this.prev = prev;
         this.next = next;
     }
@@ -85,17 +83,16 @@
     public static void generate(ConfigurationImpl configuration,
                                 IndexBuilder indexbuilder) {
         SplitIndexWriter indexgen;
-        String filename = "";
-        String path = DirectoryManager.getPath("index-files");
-        String relpath = DirectoryManager.getRelativePath("index-files");
+        DocPath filename = DocPath.empty;
+        DocPath path = DocPaths.INDEX_FILES;
         try {
             for (int i = 0; i < indexbuilder.elements().length; i++) {
                 int j = i + 1;
                 int prev = (j == 1)? -1: i;
                 int next = (j == indexbuilder.elements().length)? -1: j + 1;
-                filename = "index-" + j +".html";
+                filename = DocPaths.indexN(j);
                 indexgen = new SplitIndexWriter(configuration,
-                                                path, filename, relpath,
+                                                path.resolve(filename),
                                                 indexbuilder, prev, next);
                 indexgen.generateIndexFile((Character)indexbuilder.
                                                                  elements()[i]);
@@ -104,7 +101,7 @@
         } catch (IOException exc) {
             configuration.standardmessage.error(
                         "doclet.exception_encountered",
-                        exc.toString(), filename);
+                        exc.toString(), filename.getPath());
             throw new DocletAbortException();
         }
     }
@@ -142,7 +139,7 @@
         Object[] unicodeChars = indexbuilder.elements();
         for (int i = 0; i < unicodeChars.length; i++) {
             int j = i + 1;
-            contentTree.addContent(getHyperLink("index-" + j + ".html",
+            contentTree.addContent(getHyperLink(DocPaths.indexN(j),
                     new StringContent(unicodeChars[i].toString())));
             contentTree.addContent(getSpace());
         }
@@ -159,7 +156,7 @@
             return HtmlTree.LI(prevletterLabel);
         }
         else {
-            Content prevLink = getHyperLink("index-" + prev + ".html", "",
+            Content prevLink = getHyperLink(DocPaths.indexN(prev),
                     prevletterLabel);
             return HtmlTree.LI(prevLink);
         }
@@ -176,7 +173,7 @@
             return HtmlTree.LI(nextletterLabel);
         }
         else {
-            Content nextLink = getHyperLink("index-" + next + ".html","",
+            Content nextLink = getHyperLink(DocPaths.indexN(next),
                     nextletterLabel);
             return HtmlTree.LI(nextLink);
         }
--- a/src/share/classes/com/sun/tools/doclets/formats/html/SubWriterHolderWriter.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/SubWriterHolderWriter.java	Fri Nov 02 17:55:34 2012 -0700
@@ -54,18 +54,11 @@
  */
 public abstract class SubWriterHolderWriter extends HtmlDocletWriter {
 
-    public SubWriterHolderWriter(ConfigurationImpl configuration,
-                                 String filename) throws IOException {
+    public SubWriterHolderWriter(ConfigurationImpl configuration, DocPath filename)
+            throws IOException {
         super(configuration, filename);
     }
 
-
-    public SubWriterHolderWriter(ConfigurationImpl configuration,
-                                 String path, String filename, String relpath)
-                                 throws IOException {
-        super(configuration, path, filename, relpath);
-    }
-
     /**
      * Add the summary header.
      *
--- a/src/share/classes/com/sun/tools/doclets/formats/html/TagletWriterImpl.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/TagletWriterImpl.java	Fri Nov 02 17:55:34 2012 -0700
@@ -66,8 +66,10 @@
     public TagletOutput getDocRootOutput() {
         if (htmlWriter.configuration.docrootparent.length() > 0)
             return new TagletOutputImpl(htmlWriter.configuration.docrootparent);
+        else if (htmlWriter.pathToRoot.isEmpty())
+            return new TagletOutputImpl(".");
         else
-            return new TagletOutputImpl(htmlWriter.relativepathNoSlash);
+            return new TagletOutputImpl(htmlWriter.pathToRoot.getPath());
     }
 
     /**
@@ -170,19 +172,24 @@
                 htmlWriter instanceof ClassWriterImpl) {
             //Automatically add link to constant values page for constant fields.
             result = addSeeHeader(result);
-            result += htmlWriter.getHyperLinkString(htmlWriter.relativePath +
-                ConfigurationImpl.CONSTANTS_FILE_NAME
-                + "#" + ((ClassWriterImpl) htmlWriter).getClassDoc().qualifiedName()
-                + "." + ((FieldDoc) holder).name(),
-                htmlWriter.configuration.getText("doclet.Constants_Summary"));
+            DocPath constantsPath =
+                    htmlWriter.pathToRoot.resolve(DocPaths.CONSTANT_VALUES);
+            String whichConstant =
+                    ((ClassWriterImpl) htmlWriter).getClassDoc().qualifiedName() + "." + ((FieldDoc) holder).name();
+            DocLink link = constantsPath.fragment(whichConstant);
+            result += htmlWriter.getHyperLinkString(link,
+                    htmlWriter.configuration.getText("doclet.Constants_Summary"),
+                    false);
         }
         if (holder.isClass() && ((ClassDoc)holder).isSerializable()) {
             //Automatically add link to serialized form page for serializable classes.
             if ((SerializedFormBuilder.serialInclude(holder) &&
                       SerializedFormBuilder.serialInclude(((ClassDoc)holder).containingPackage()))) {
                 result = addSeeHeader(result);
-                result += htmlWriter.getHyperLinkString(htmlWriter.relativePath + "serialized-form.html",
-                        ((ClassDoc)holder).qualifiedName(), htmlWriter.configuration.getText("doclet.Serialized_Form"), false);
+                DocPath serialPath = htmlWriter.pathToRoot.resolve(DocPaths.SERIALIZED_FORM);
+                DocLink link = serialPath.fragment(((ClassDoc)holder).qualifiedName());
+                result += htmlWriter.getHyperLinkString(link,
+                        htmlWriter.configuration.getText("doclet.Serialized_Form"), false);
             }
         }
         return result.equals("") ? null : new TagletOutputImpl(result + "</dd>");
--- a/src/share/classes/com/sun/tools/doclets/formats/html/TreeWriter.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/TreeWriter.java	Fri Nov 02 17:55:34 2012 -0700
@@ -67,7 +67,7 @@
      * @param classtree the tree being built.
      */
     public TreeWriter(ConfigurationImpl configuration,
-            String filename, ClassTree classtree)
+            DocPath filename, ClassTree classtree)
     throws IOException {
         super(configuration, filename, classtree);
         packages = configuration.packages;
@@ -84,7 +84,7 @@
     public static void generate(ConfigurationImpl configuration,
                                 ClassTree classtree) {
         TreeWriter treegen;
-        String filename = "overview-tree.html";
+        DocPath filename = DocPaths.OVERVIEW_TREE;
         try {
             treegen = new TreeWriter(configuration, filename, classtree);
             treegen.generateTreeFile();
@@ -144,9 +144,9 @@
                         (configuration.nodeprecated && Util.isDeprecated(packages[i]))) {
                     continue;
                 }
-                String link = pathString(packages[i], "package-tree.html");
+                DocPath link = pathString(packages[i], DocPaths.PACKAGE_TREE);
                 Content li = HtmlTree.LI(getHyperLink(
-                        link, "", new StringContent(packages[i].name())));
+                        link, new StringContent(packages[i].name())));
                 if (i < packages.length - 1) {
                     li.addContent(", ");
                 }
--- a/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java	Fri Nov 02 17:55:34 2012 -0700
@@ -31,6 +31,9 @@
 import com.sun.javadoc.*;
 import com.sun.tools.doclets.formats.html.ConfigurationImpl;
 import com.sun.tools.doclets.internal.toolkit.*;
+import com.sun.tools.doclets.internal.toolkit.util.DocLink;
+import com.sun.tools.doclets.internal.toolkit.util.DocPath;
+import com.sun.tools.doclets.internal.toolkit.util.DocPaths;
 
 
 /**
@@ -56,25 +59,11 @@
      *
      * @param filename String file name.
      */
-    public HtmlDocWriter(Configuration configuration,
-                         String filename) throws IOException {
-        super(configuration,
-              null, configuration.destDirName + filename,
-              configuration.docencoding);
-        // use File to normalize file separators
+    public HtmlDocWriter(Configuration configuration, DocPath filename)
+            throws IOException {
+        super(configuration, filename);
         configuration.message.notice("doclet.Generating_0",
-            new File(configuration.destDirName, filename));
-    }
-
-    public HtmlDocWriter(Configuration configuration,
-                         String path, String filename) throws IOException {
-        super(configuration,
-              configuration.destDirName + path, filename,
-              configuration.docencoding);
-        // use File to normalize file separators
-        configuration.message.notice("doclet.Generating_0",
-            new File(configuration.destDirName,
-                    ((path.length() > 0)? path + File.separator: "") + filename));
+            filename.resolveAgainst(configuration.destDirName));
     }
 
     /**
@@ -86,77 +75,99 @@
      * Return Html Hyper Link string.
      *
      * @param link       String name of the file.
-     * @param where      Position of the link in the file. Character '#' is not
-     * needed.
      * @param label      Tag for the link.
      * @param strong       Boolean that sets label to strong.
      * @return String    Hyper Link.
      */
-    public String getHyperLinkString(String link, String where,
+    public String getHyperLinkString(DocPath link,
                                String label, boolean strong) {
-        return getHyperLinkString(link, where, label, strong, "", "", "");
+        return getHyperLinkString(link, label, strong, "", "", "");
+    }
+
+    public String getHyperLinkString(DocLink link,
+                               String label, boolean strong) {
+        return getHyperLinkString(link, label, strong, "", "", "");
     }
 
     /**
      * Get Html Hyper Link string.
      *
      * @param link       String name of the file.
-     * @param where      Position of the link in the file. Character '#' is not
-     *                   needed.
      * @param label      Tag for the link.
      * @param strong       Boolean that sets label to strong.
      * @param stylename  String style of text defined in style sheet.
      * @return String    Hyper Link.
      */
-    public String getHyperLinkString(String link, String where,
+    public String getHyperLinkString(DocPath link,
                                String label, boolean strong,
                                String stylename) {
-        return getHyperLinkString(link, where, label, strong, stylename, "", "");
+        return getHyperLinkString(link, label, strong, stylename, "", "");
+    }
+
+    public String getHyperLinkString(DocLink link,
+                               String label, boolean strong,
+                               String stylename) {
+        return getHyperLinkString(link, label, strong, stylename, "", "");
+    }
+
+    /**
+     * Get Html Hyper Link string.
+     *
+     * @param where      Position of the link in the file. Character '#' is not
+     *                   needed.
+     * @param label      Tag for the link.
+     * @return a content tree for the hyper link
+     */
+    public Content getHyperLink(String where,
+                               Content label) {
+        return getHyperLink(DocLink.fragment(where), label, "", "");
     }
 
     /**
      * Get Html Hyper Link string.
      *
      * @param link       String name of the file.
-     * @param where      Position of the link in the file. Character '#' is not
-     *                   needed.
      * @param label      Tag for the link.
      * @return a content tree for the hyper link
      */
-    public Content getHyperLink(String link, String where,
+    public Content getHyperLink(DocPath link,
                                Content label) {
-        return getHyperLink(link, where, label, "", "");
+        return getHyperLink(link, label, "", "");
+    }
+
+    public Content getHyperLink(DocLink link,
+                               Content label) {
+        return getHyperLink(link, label, "", "");
     }
 
     /**
      * Get Html Hyper Link string.
      *
      * @param link       String name of the file.
-     * @param where      Position of the link in the file. Character '#' is not
-     *                   needed.
      * @param label      Tag for the link.
      * @param strong       Boolean that sets label to strong.
      * @param stylename  String style of text defined in style sheet.
-     * @param title      String that describes the link's content for accessibility.
+     * @param title      String that describes the links content for accessibility.
      * @param target     Target frame.
      * @return String    Hyper Link.
      */
-    public String getHyperLinkString(String link, String where,
+    public String getHyperLinkString(DocPath link,
+                               String label, boolean strong,
+                               String stylename, String title, String target) {
+        return getHyperLinkString(new DocLink(link), label, strong,
+                stylename, title, target);
+    }
+
+    public String getHyperLinkString(DocLink link,
                                String label, boolean strong,
                                String stylename, String title, String target) {
         StringBuilder retlink = new StringBuilder();
-        retlink.append("<a href=\"");
-        retlink.append(link);
-        if (where != null && where.length() != 0) {
-            retlink.append("#");
-            retlink.append(where);
-        }
-        retlink.append("\"");
+        retlink.append("<a href=\"").append(link).append('"');
         if (title != null && title.length() != 0) {
-            retlink.append(" title=\"").append(title).append("\"");
+            retlink.append(" title=\"").append(title).append('"');
         }
         if (target != null && target.length() != 0) {
-            retlink.append(" target=\"").append(target).append("\"");
+            retlink.append(" target=\"").append(target).append('"');
         }
         retlink.append(">");
         if (stylename != null && stylename.length() != 0) {
@@ -182,19 +193,19 @@
      * Get Html Hyper Link.
      *
      * @param link       String name of the file.
-     * @param where      Position of the link in the file. Character '#' is not
-     *                   needed.
      * @param label      Tag for the link.
      * @param title      String that describes the link's content for accessibility.
      * @param target     Target frame.
      * @return a content tree for the hyper link.
      */
-    public Content getHyperLink(String link, String where,
+    public Content getHyperLink(DocPath link,
             Content label, String title, String target) {
-        if (where != null && where.length() != 0) {
-            link += "#" + where;
-        }
-        HtmlTree anchor = HtmlTree.A(link, label);
+        return getHyperLink(new DocLink(link), label, title, target);
+    }
+
+    public Content getHyperLink(DocLink link,
+            Content label, String title, String target) {
+        HtmlTree anchor = HtmlTree.A(link.toString(), label);
         if (title != null && title.length() != 0) {
             anchor.addAttr(HtmlAttr.TITLE, title);
         }
@@ -205,25 +216,14 @@
     }
 
     /**
-     * Get a hyperlink to a file.
-     *
-     * @param link String name of the file
-     * @param label Label for the link
-     * @return a content for the hyperlink to the file
-     */
-    public Content getHyperLink(String link, Content label) {
-        return getHyperLink(link, "", label);
-    }
-
-    /**
      * Get link string without positioning in the file.
      *
      * @param link       String name of the file.
      * @param label      Tag for the link.
      * @return Strign    Hyper link.
      */
-    public String getHyperLinkString(String link, String label) {
-        return getHyperLinkString(link, "", label, false);
+    public String getHyperLinkString(DocPath link, String label) {
+        return getHyperLinkString(link, label, false);
     }
 
     /**
--- a/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java	Fri Nov 02 17:55:34 2012 -0700
@@ -47,22 +47,11 @@
 public class HtmlWriter {
 
     /**
-     * Name of the file, to which this writer is writing to.
-     */
-    protected final String htmlFilename;
-
-    /**
      * The window title of this file
      */
     protected String winTitle;
 
     /**
-     * URL file separator string("/").
-     */
-    public static final String fileseparator =
-         DirectoryManager.URL_FILE_SEPARATOR;
-
-    /**
      * The configuration
      */
     protected Configuration configuration;
@@ -160,20 +149,15 @@
      *
      * @param path The directory path to be created for this file
      *             or null if none to be created.
-     * @param filename File Name to which the PrintWriter will
-     *                 do the Output.
-     * @param docencoding Encoding to be used for this file.
      * @exception IOException Exception raised by the FileWriter is passed on
      * to next level.
      * @exception UnsupportedEncodingException Exception raised by the
      * OutputStreamWriter is passed on to next level.
      */
-    public HtmlWriter(Configuration configuration,
-                      String path, String filename, String docencoding)
-                      throws IOException, UnsupportedEncodingException {
-        writer = Util.genWriter(configuration, path, filename, docencoding);
+    public HtmlWriter(Configuration configuration, DocPath path)
+            throws IOException, UnsupportedEncodingException {
+        writer = DocFile.createFileForOutput(configuration, path).openWriter();
         this.configuration = configuration;
-        htmlFilename = filename;
         this.memberDetailsListPrinted = false;
         packageTableHeader = new String[] {
             configuration.getText("doclet.Package"),
--- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/AbstractDoclet.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/AbstractDoclet.java	Fri Nov 02 17:55:34 2012 -0700
@@ -106,7 +106,7 @@
 
     /**
      * Start the generation of files. Call generate methods in the individual
-     * writers, which will in turn genrate the documentation files. Call the
+     * writers, which will in turn generate the documentation files. Call the
      * TreeWriter generation first to ensure the Class Hierarchy is built
      * first and then can be used in the later generation.
      *
@@ -124,17 +124,7 @@
         ClassTree classtree = new ClassTree(configuration, configuration.nodeprecated);
 
         generateClassFiles(root, classtree);
-        if (configuration.sourcepath != null && configuration.sourcepath.length() > 0) {
-            StringTokenizer pathTokens = new StringTokenizer(configuration.sourcepath,
-                String.valueOf(File.pathSeparatorChar));
-            boolean first = true;
-            while(pathTokens.hasMoreTokens()){
-                Util.copyDocFiles(configuration,
-                    pathTokens.nextToken() + File.separator,
-                    DocletConstants.DOC_FILES_DIR_NAME, first);
-                first = false;
-            }
-        }
+        Util.copyDocFiles(configuration, DocPaths.DOC_FILES);
 
         PackageListWriter.generate(configuration);
         generatePackageFiles(classtree);
--- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java	Fri Nov 02 17:55:34 2012 -0700
@@ -408,11 +408,11 @@
                 group.checkPackageGroups(os[1], os[2]);
             } else if (opt.equals("-link")) {
                 String url = os[1];
-                extern.url(url, url, root, false);
+                extern.link(url, url, root, false);
             } else if (opt.equals("-linkoffline")) {
                 String url = os[1];
                 String pkglisturl = os[2];
-                extern.url(url, pkglisturl, root, true);
+                extern.link(url, pkglisturl, root, true);
             }
         }
         if (sourcepath.length() == 0) {
@@ -456,7 +456,7 @@
                 tagletManager.addCustomTag(args[1], tagletpath);
                 continue;
             }
-            String[] tokens = Util.tokenize(args[1],
+            String[] tokens = tokenize(args[1],
                 TagletManager.SIMPLE_TAGLET_OPT_SEPERATOR, 3);
             if (tokens.length == 1) {
                 String tagName = args[1];
@@ -480,6 +480,47 @@
         }
     }
 
+    /**
+     * Given a string, return an array of tokens.  The separator can be escaped
+     * with the '\' character.  The '\' character may also be escaped by the
+     * '\' character.
+     *
+     * @param s         the string to tokenize.
+     * @param separator the separator char.
+     * @param maxTokens the maximum number of tokens returned.  If the
+     *                  max is reached, the remaining part of s is appended
+     *                  to the end of the last token.
+     *
+     * @return an array of tokens.
+     */
+    private String[] tokenize(String s, char separator, int maxTokens) {
+        List<String> tokens = new ArrayList<String>();
+        StringBuilder  token = new StringBuilder ();
+        boolean prevIsEscapeChar = false;
+        for (int i = 0; i < s.length(); i += Character.charCount(i)) {
+            int currentChar = s.codePointAt(i);
+            if (prevIsEscapeChar) {
+                // Case 1:  escaped character
+                token.appendCodePoint(currentChar);
+                prevIsEscapeChar = false;
+            } else if (currentChar == separator && tokens.size() < maxTokens-1) {
+                // Case 2:  separator
+                tokens.add(token.toString());
+                token = new StringBuilder();
+            } else if (currentChar == '\\') {
+                // Case 3:  escape character
+                prevIsEscapeChar = true;
+            } else {
+                // Case 4:  regular character
+                token.appendCodePoint(currentChar);
+            }
+        }
+        if (token.length() > 0) {
+            tokens.add(token.toString());
+        }
+        return tokens.toArray(new String[] {});
+    }
+
     private void addToSet(Set<String> s, String str){
         StringTokenizer st = new StringTokenizer(str, ":");
         String current;
@@ -532,12 +573,12 @@
             String opt = os[0].toLowerCase();
             if (opt.equals("-d")) {
                 String destdirname = addTrailingFileSep(os[1]);
-                File destDir = new File(destdirname);
+                DocFile destDir = DocFile.createFileForDirectory(this, destdirname);
                 if (!destDir.exists()) {
                     //Create the output directory (in case it doesn't exist yet)
                     reporter.printNotice(getText("doclet.dest_dir_create",
                         destdirname));
-                    (new File(destdirname)).mkdirs();
+                    destDir.mkdirs();
                 } else if (!destDir.isDirectory()) {
                     reporter.printError(getText(
                         "doclet.destination_directory_not_directory_0",
@@ -711,7 +752,7 @@
     public InputStream getBuilderXML() throws FileNotFoundException {
         return builderXMLPath == null ?
             Configuration.class.getResourceAsStream(DEFAULT_BUILDER_XML) :
-            new FileInputStream(new File(builderXMLPath));
+            DocFile.createFileForInput(this, builderXMLPath).openInputStream();
     }
 
     /**
--- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/PackageSummaryWriter.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/PackageSummaryWriter.java	Fri Nov 02 17:55:34 2012 -0700
@@ -45,13 +45,6 @@
 public interface PackageSummaryWriter {
 
     /**
-     * Return the name of the output file.
-     *
-     * @return the name of the output file.
-     */
-    public abstract String getOutputFileName();
-
-    /**
      * Get the header for the summary.
      *
      * @param heading Package name.
--- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeBuilder.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeBuilder.java	Fri Nov 02 17:55:34 2012 -0700
@@ -140,12 +140,7 @@
             //Only copy doc files dir if the containing package is not
             //documented AND if we have not documented a class from the same
             //package already. Otherwise, we are making duplicate copies.
-            Util.copyDocFiles(configuration,
-                Util.getPackageSourcePath(configuration,
-                    annotationTypeDoc.containingPackage()) +
-                DirectoryManager.getDirectoryPath(
-                    annotationTypeDoc.containingPackage())
-                    + File.separator, DocletConstants.DOC_FILES_DIR_NAME, true);
+            Util.copyDocFiles(configuration, containingPackage);
             containingPackagesSeen.add(containingPackage.name());
         }
      }
--- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ClassBuilder.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ClassBuilder.java	Fri Nov 02 17:55:34 2012 -0700
@@ -266,11 +266,7 @@
             //Only copy doc files dir if the containing package is not
             //documented AND if we have not documented a class from the same
             //package already. Otherwise, we are making duplicate copies.
-            Util.copyDocFiles(configuration,
-                    Util.getPackageSourcePath(configuration,
-                    classDoc.containingPackage()) +
-                    DirectoryManager.getDirectoryPath(classDoc.containingPackage())
-                    + File.separator, DocletConstants.DOC_FILES_DIR_NAME, true);
+            Util.copyDocFiles(configuration, containingPackage);
             containingPackagesSeen.add(containingPackage.name());
         }
      }
--- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/PackageSummaryBuilder.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/PackageSummaryBuilder.java	Fri Nov 02 17:55:34 2012 -0700
@@ -119,13 +119,7 @@
         packageWriter.addPackageFooter(contentTree);
         packageWriter.printDocument(contentTree);
         packageWriter.close();
-        Util.copyDocFiles(
-                configuration,
-                Util.getPackageSourcePath(configuration, packageDoc),
-                DirectoryManager.getDirectoryPath(packageDoc)
-                        + File.separator
-                        + DocletConstants.DOC_FILES_DIR_NAME,
-                true);
+        Util.copyDocFiles(configuration, packageDoc);
     }
 
     /**
--- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/SerializedFormBuilder.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/SerializedFormBuilder.java	Fri Nov 02 17:55:34 2012 -0700
@@ -474,6 +474,8 @@
         Arrays.sort(tags);
         int tagsLength = tags.length;
         for (int i = 0; i < tagsLength; i++) {
+            if (tags[i].fieldName() == null || tags[i].fieldType() == null) // ignore malformed @serialField tags
+                continue;
             Content fieldsContentTree = fieldWriter.getFieldsContentHeader(
                     (i == tagsLength - 1));
             fieldWriter.addMemberHeader(tags[i].fieldTypeDoc(),
--- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java	Fri Nov 02 17:55:34 2012 -0700
@@ -161,7 +161,7 @@
      * @param message the message retriever to print warnings.
      */
     public TagletManager(boolean nosince, boolean showversion,
-                         boolean showauthor, MessageRetriever message){
+                         boolean showauthor, MessageRetriever message) {
         overridenStandardTags = new HashSet<String>();
         potentiallyConflictingTags = new HashSet<String>();
         standardTags = new HashSet<String>();
@@ -253,47 +253,17 @@
      * @param path the search path string
      * @return the resulting array of directory and JAR file URLs
      */
-    private static URL[] pathToURLs(String path) {
-        StringTokenizer st = new StringTokenizer(path, File.pathSeparator);
-        URL[] urls = new URL[st.countTokens()];
-        int count = 0;
-        while (st.hasMoreTokens()) {
-            URL url = fileToURL(new File(st.nextToken()));
-            if (url != null) {
-                urls[count++] = url;
+    private URL[] pathToURLs(String path) {
+        Set<URL> urls = new LinkedHashSet<URL>();
+        for (String s: path.split(File.pathSeparator)) {
+            if (s.isEmpty()) continue;
+            try {
+                urls.add(new File(s).getAbsoluteFile().toURI().toURL());
+            } catch (MalformedURLException e) {
+                message.error("doclet.MalformedURL", s);
             }
         }
-        urls = Arrays.copyOf(urls, count);
-        return urls;
-    }
-
-    /**
-     * Returns the directory or JAR file URL corresponding to the specified
-     * local file name.
-     *
-     * @param file the File object
-     * @return the resulting directory or JAR file URL, or null if unknown
-     */
-    private static URL fileToURL(File file) {
-        String name;
-        try {
-            name = file.getCanonicalPath();
-        } catch (IOException e) {
-            name = file.getAbsolutePath();
-        }
-        name = name.replace(File.separatorChar, '/');
-        if (!name.startsWith("/")) {
-            name = "/" + name;
-        }
-        // If the file does not exist, then assume that it's a directory
-        if (!file.isFile()) {
-            name = name + "/";
-        }
-        try {
-            return new URL("file", "", name);
-        } catch (MalformedURLException e) {
-            throw new IllegalArgumentException("file");
-        }
+        return urls.toArray(new URL[urls.size()]);
     }
 
 
--- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DirectoryManager.java	Thu Nov 01 14:13:13 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,317 +0,0 @@
-/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.tools.doclets.internal.toolkit.util;
-
-import com.sun.tools.doclets.internal.toolkit.*;
-import com.sun.javadoc.*;
-import java.io.*;
-
-
-/**
- * Handle the directory creations and the path string generations.
- * All static - never instaniated.
- *
- * This code is not part of an API.
- * It is implementation that is subject to change.
- * Do not use it as an API
- *
- * @since 1.2
- * @author Atul M Dambalkar
- */
-public class DirectoryManager {
-
-    /**
-     * The file separator string, "/", used in the formation of the URL path.
-     */
-    public static final String URL_FILE_SEPARATOR = "/";
-
-    /**
-     * Never instaniated.
-     */
-    private DirectoryManager() {
-    }
-
-    /**
-     * Given a PackageDoc, return its URL path string.
-     *
-     * @param pd PackageDoc
-     * @see #getPath(String)
-     */
-    public static String createPathString(PackageDoc pd) {
-        if (pd == null) {
-            return "";
-        }
-        return getPath(pd.name());
-    }
-
-    /**
-     * Given a ClassDoc, return its URL path string.
-     *
-     * @param cd ClassDoc
-     * @see #getPath(String)
-     */
-    public static String createPathString(ClassDoc cd) {
-        if (cd == null) {
-            return "";
-        }
-        PackageDoc pd = cd.containingPackage();
-        return (pd == null)? "": getPath(pd.name());
-    }
-
-    /**
-     * Given a PackageDoc, return the corresponding directory name
-     * with the platform-dependent file separator between subdirectory names.
-     * For example, if name of the package is "java.lang" , then it
-     * returns "java/lang" on Unix and "java\lang" on Windows.
-     * If name of the package contains no dot, then the value
-     * will be returned unchanged.  Because package names cannot
-     * end in a dot, the return value will never end with a slash.
-     * <p>
-     * Also see getPath for the URL separator version of this method
-     * that takes a string instead of a PackageDoc.
-     *
-     * @param  pd    the PackageDoc
-     * @return       the platform-dependent directory path for the package
-     */
-    public static String getDirectoryPath(PackageDoc pd) {
-        return pd == null || pd.name().length() == 0 ? "" : getDirectoryPath(pd.name());
-    }
-
-    /**
-     * Given a package name, return the corresponding directory name
-     * with the platform-dependent file separator between subdirectory names.
-     * For example, if name of the package is "java.lang" , then it
-     * returns "java/lang" on Unix and "java\lang" on Windows.
-     * If name of the package contains no dot, then the value
-     * will be returned unchanged.  Because package names cannot
-     * end in a dot, the return value will never end with a slash.
-     * <p>
-     * Also see getPath for the URL separator version of this method
-     * that takes a string instead of a PackageDoc.
-     *
-     * @param  packageName    the name of the package
-     * @return       the platform-dependent directory path for the package
-     */
-    public static String getDirectoryPath(String packageName) {
-        if (packageName == null || packageName.length() == 0) {
-            return "";
-        }
-        StringBuilder pathstr = new StringBuilder();
-        for (int i = 0; i < packageName.length(); i++) {
-            char ch = packageName.charAt(i);
-            if (ch == '.') {
-                pathstr.append(URL_FILE_SEPARATOR);
-            } else {
-                pathstr.append(ch);
-            }
-        }
-        if (pathstr.length() > 0 && ! pathstr.toString().endsWith(URL_FILE_SEPARATOR)) {
-            pathstr.append(URL_FILE_SEPARATOR);
-        }
-        return pathstr.toString();
-    }
-
-    /**
-     * Given a package name (a string), return the path string,
-     * with the URL separator "/" separating the subdirectory names.
-     * If name of the package contains no dot, then the value
-     * will be returned unchanged.  Because package names cannot
-     * end in a dot, the return value will never end with a slash.
-     * <p>
-     * For example if the string is "com.sun.javadoc" then the URL
-     * path string will be "com/sun/javadoc".
-     *
-     * @param name   the package name as a String
-     * @return       the String URL path
-     */
-    public static String getPath(String name) {
-        if (name == null || name.length() == 0) {
-            return "";
-        }
-        StringBuilder pathstr = new StringBuilder();
-        for (int i = 0; i < name.length(); i++) {
-            char ch = name.charAt(i);
-            if (ch == '.') {
-                pathstr.append(URL_FILE_SEPARATOR);
-            } else {
-                pathstr.append(ch);
-            }
-        }
-        return pathstr.toString();
-    }
-
-    /**
-     * Given two package names as strings, return the relative path
-     * from the package directory corresponding to the first string
-     * to the package directory corresponding to the second string,
-     * with the URL file separator "/" separating subdirectory names.
-     * <p>
-     * For example, if the parameter "from" is "java.lang"
-     * and parameter "to" is "java.applet", return string
-     * "../../java/applet".
-     *
-     * @param from   the package name from which path is calculated
-     * @param to     the package name to which path is calculated
-     * @return       relative path between "from" and "to" with URL
-     *               separators
-     * @see          #getRelativePath(String)
-     * @see          #getPath(String)
-     */
-    public static String getRelativePath(String from, String to) {
-        StringBuilder pathstr = new StringBuilder();
-        pathstr.append(getRelativePath(from));
-        pathstr.append(getPath(to));
-        pathstr.append(URL_FILE_SEPARATOR);
-        return pathstr.toString();
-    }
-
-    /**
-     * Given a package name as a string, return relative path string
-     * from the corresponding package directory to the root of
-     * the documentation, using the URL separator "/" between
-     * subdirectory names.
-     * <p>
-     * For example, if the string "from" is "java.lang",
-     * return "../../"
-     *
-     * @param from    the package
-     * @return        String relative path from "from".
-     * @see           #getRelativePath(String, String)
-     */
-    public static String getRelativePath(PackageDoc from) {
-        return from == null || from.name().length() == 0 ? "" : getRelativePath(from.name());
-    }
-
-    /**
-     * Given a package name as a string, return relative path string
-     * from the corresponding package directory to the root of
-     * the documentation, using the URL separator "/" between
-     * subdirectory names.
-     * <p>
-     * For example, if the string "from" is "java.lang",
-     * return "../../"
-     *
-     * @param from    the package name
-     * @return        String relative path from "from".
-     * @see           #getRelativePath(String, String)
-     */
-    public static String getRelativePath(String from) {
-        if (from == null || from.length() == 0) {
-            return "";
-        }
-        StringBuilder pathstr = new StringBuilder();
-        for (int i = 0; i < from.length(); i++) {
-            char ch = from.charAt(i);
-            if (ch == '.') {
-                pathstr.append(".." + URL_FILE_SEPARATOR);
-            }
-        }
-        pathstr.append(".." + URL_FILE_SEPARATOR);
-        return pathstr.toString();
-    }
-
-    /**
-     * Given a relative or absolute path that might be empty,
-     * convert it to a path that does not end with a
-     * URL separator "/".  Used for converting
-     * HtmlStandardWriter.relativepath when replacing {@docRoot}.
-     *
-     * @param path   the path to convert.  An empty path represents
-     *               the current directory.
-     */
-    public static String getPathNoTrailingSlash(String path) {
-        if ( path.equals("") ) {
-            return ".";
-        }
-        if ( path.equals("/") ) {
-            return "/.";
-        }
-        if ( path.endsWith("/") ) {
-            // Remove trailing slash
-            path = path.substring(0, path.length() -1);
-        }
-        return path;
-    }
-
-    /**
-     * Given a path string create all the directories in the path. For example,
-     * if the path string is "java/applet", the method will create directory
-     * "java" and then "java/applet" if they don't exist. The file separator
-     * string "/" is platform dependent system property.
-     *
-     * @param path Directory path string.
-     */
-    public static void createDirectory(Configuration configuration,
-                                       String path) {
-        if (path == null || path.length() == 0) {
-            return;
-        }
-        File dir = new File(path);
-        if (dir.exists()) {
-            return;
-        } else {
-            if (dir.mkdirs()) {
-                return;
-            } else {
-                configuration.message.error(
-                       "doclet.Unable_to_create_directory_0", path);
-                throw new DocletAbortException();
-            }
-        }
-    }
-
-    /**
-     * Given a package name and a file name, return the full path to that file.
-     * For example, if PackageDoc passed is for "java.lang" and the filename
-     * passed is "package-summary.html", then the string returned is
-     * "java/lang/package-summary.html".
-     *
-     * @param pd         PackageDoc.
-     * @param filename   File name to be appended to the path of the package.
-     */
-    public static String getPathToPackage(PackageDoc pd, String filename) {
-        StringBuilder buf = new StringBuilder();
-        String pathstr = createPathString(pd);
-        if (pathstr.length() > 0) {
-            buf.append(pathstr);
-            buf.append(URL_FILE_SEPARATOR);
-        }
-        buf.append(filename);
-        return buf.toString();
-    }
-
-    /**
-     * Given a class name return the full path to the class file.
-     * For example, if ClassDoc passed is for "java.lang.Object" then the
-     * string returned is "java/lang/Object.html".
-     *
-     * @param cd   ClassDoc.
-     */
-    public static String getPathToClass(ClassDoc cd) {
-        return getPathToPackage(cd.containingPackage(), cd.name() + ".html");
-    }
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFile.java	Fri Nov 02 17:55:34 2012 -0700
@@ -0,0 +1,399 @@
+/*
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.doclets.internal.toolkit.util;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.tools.JavaFileManager.Location;
+import javax.tools.StandardLocation;
+
+import com.sun.tools.doclets.internal.toolkit.Configuration;
+
+/**
+ * Abstraction for handling files, which may be specified directly
+ * (e.g. via a path on the command line) or relative to a Location.
+ *
+ *  <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>
+ *
+ * @since 8
+ */
+public class DocFile {
+
+    /**
+     * The doclet configuration.
+     * Provides access to options such as docencoding, output directory, etc.
+     */
+    private final Configuration configuration;
+
+    /**
+     * The location for this file. Maybe null if the file was created without
+     * a location or path.
+     */
+    private final Location location;
+
+    /**
+     * The path relative to the (output) location. Maybe null if the file was
+     * created without a location or path.
+     */
+    private final DocPath path;
+
+    /**
+     * The file object itself.
+     * This is temporary, until we create different subtypes of DocFile.
+     */
+    private final File file;
+
+    /** Create a DocFile for a directory. */
+    public static DocFile createFileForDirectory(Configuration configuration, String file) {
+        return new DocFile(configuration, new File(file));
+    }
+
+    /** Create a DocFile for a file that will be opened for reading. */
+    public static DocFile createFileForInput(Configuration configuration, String file) {
+        return new DocFile(configuration, new File(file));
+    }
+
+    /** Create a DocFile for a file that will be opened for writing. */
+    public static DocFile createFileForOutput(Configuration configuration, DocPath path) {
+        return new DocFile(configuration, StandardLocation.CLASS_OUTPUT, path);
+    }
+
+    /**
+     * List the directories and files found in subdirectories along the
+     * elements of the given location.
+     * @param configuration the doclet configuration
+     * @param location currently, only {@link StandardLocation#SOURCE_PATH} is supported.
+     * @param path the subdirectory of the directories of the location for which to
+     *  list files
+     */
+    public static Iterable<DocFile> list(Configuration configuration, Location location, DocPath path) {
+        if (location != StandardLocation.SOURCE_PATH)
+            throw new IllegalArgumentException();
+
+        Set<DocFile> files = new LinkedHashSet<DocFile>();
+        for (String s : configuration.sourcepath.split(File.pathSeparator)) {
+            if (s.isEmpty())
+                continue;
+            File f = new File(s);
+            if (f.isDirectory()) {
+                f = new File(f, path.getPath());
+                if (f.exists())
+                    files.add(new DocFile(configuration, f));
+            }
+        }
+        return files;
+    }
+
+    /** Create a DocFile for a given file. */
+    private DocFile(Configuration configuration, File file) {
+        this.configuration = configuration;
+        this.location = null;
+        this.path = null;
+        this.file = file;
+    }
+
+    /** Create a DocFile for a given location and relative path. */
+    private DocFile(Configuration configuration, Location location, DocPath path) {
+        this.configuration = configuration;
+        this.location = location;
+        this.path = path;
+        this.file = path.resolveAgainst(configuration.destDirName);
+    }
+
+    /** Open an input stream for the file. */
+    public InputStream openInputStream() throws FileNotFoundException {
+        return new BufferedInputStream(new FileInputStream(file));
+    }
+
+    /**
+     * Open an output stream for the file.
+     * The file must have been created with a location of
+     * {@link StandardLocation#CLASS_OUTPUT} and a corresponding relative path.
+     */
+    public OutputStream openOutputStream() throws IOException, UnsupportedEncodingException {
+        if (location != StandardLocation.CLASS_OUTPUT)
+            throw new IllegalStateException();
+
+        createDirectoryForFile(file);
+        return new BufferedOutputStream(new FileOutputStream(file));
+    }
+
+    /**
+     * Open an writer for the file, using the encoding (if any) given in the
+     * doclet configuration.
+     * The file must have been created with a location of
+     * {@link StandardLocation#CLASS_OUTPUT} and a corresponding relative path.
+     */
+    public Writer openWriter() throws IOException, UnsupportedEncodingException {
+        if (location != StandardLocation.CLASS_OUTPUT)
+            throw new IllegalStateException();
+
+        createDirectoryForFile(file);
+        FileOutputStream fos = new FileOutputStream(file);
+        if (configuration.docencoding == null) {
+            return new BufferedWriter(new OutputStreamWriter(fos));
+        } else {
+            return new BufferedWriter(new OutputStreamWriter(fos, configuration.docencoding));
+        }
+    }
+
+    /**
+     * Copy the contents of another file directly to this file.
+     */
+    public void copyFile(DocFile fromFile) throws IOException {
+        if (location != StandardLocation.CLASS_OUTPUT)
+            throw new IllegalStateException();
+
+        createDirectoryForFile(file);
+
+        InputStream input = fromFile.openInputStream();
+        OutputStream output = openOutputStream();
+        try {
+            byte[] bytearr = new byte[1024];
+            int len;
+            while ((len = input.read(bytearr)) != -1) {
+                output.write(bytearr, 0, len);
+            }
+        } catch (FileNotFoundException exc) {
+        } catch (SecurityException exc) {
+        } finally {
+            input.close();
+            output.close();
+        }
+    }
+
+    /**
+     * Copy the contents of a resource file to this file.
+     * @param resource the path of the resource, relative to the package of this class
+     * @param overwrite whether or not to overwrite the file if it already exists
+     * @param replaceNewLine if false, the file is copied as a binary file;
+     *     if true, the file is written line by line, using the platform line
+     *     separator
+     */
+    public void copyResource(DocPath resource, boolean overwrite, boolean replaceNewLine) {
+        if (location != StandardLocation.CLASS_OUTPUT)
+            throw new IllegalStateException();
+
+        if (file.exists() && !overwrite)
+            return;
+
+        createDirectoryForFile(file);
+
+        try {
+            InputStream in = Configuration.class.getResourceAsStream(resource.getPath());
+            if (in == null)
+                return;
+
+            OutputStream out = new FileOutputStream(file);
+            try {
+                if (!replaceNewLine) {
+                    byte[] buf = new byte[2048];
+                    int n;
+                    while((n = in.read(buf))>0) out.write(buf,0,n);
+                } else {
+                    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+                    BufferedWriter writer;
+                    if (configuration.docencoding == null) {
+                        writer = new BufferedWriter(new OutputStreamWriter(out));
+                    } else {
+                        writer = new BufferedWriter(new OutputStreamWriter(out,
+                                configuration.docencoding));
+                    }
+                    try {
+                        String line;
+                        while ((line = reader.readLine()) != null) {
+                            writer.write(line);
+                            writer.write(DocletConstants.NL);
+                        }
+                    } finally {
+                        reader.close();
+                        writer.close();
+                    }
+                }
+            } finally {
+                in.close();
+                out.close();
+            }
+        } catch (IOException e) {
+            e.printStackTrace(System.err);
+            throw new DocletAbortException();
+        }
+    }
+
+    /** Return true if the file can be read. */
+    public boolean canRead() {
+        return file.canRead();
+    }
+
+    /** Return true if the file can be written. */
+    public boolean canWrite() {
+        return file.canRead();
+    }
+
+    /** Return true if the file exists. */
+    public boolean exists() {
+        return file.exists();
+    }
+
+    /** Return the base name (last component) of the file name. */
+    public String getName() {
+        return file.getName();
+    }
+
+    /** Return the file system path for this file. */
+    public String getPath() {
+        return file.getPath();
+    }
+
+    /** Return true is file has an absolute path name. */
+    boolean isAbsolute() {
+        return file.isAbsolute();
+    }
+
+    /** Return true is file identifies a directory. */
+    public boolean isDirectory() {
+        return file.isDirectory();
+    }
+
+    /** Return true is file identifies a file. */
+    public boolean isFile() {
+        return file.isFile();
+    }
+
+    /** Return true if this file is the same as another. */
+    public boolean isSameFile(DocFile other) {
+        try {
+            return file.exists()
+                    && file.getCanonicalFile().equals(other.file.getCanonicalFile());
+        } catch (IOException e) {
+            return false;
+        }
+    }
+
+    /** If the file is a directory, list its contents. */
+    public Iterable<DocFile> list() {
+        List<DocFile> files = new ArrayList<DocFile>();
+        for (File f: file.listFiles()) {
+            files.add(new DocFile(configuration, f));
+        }
+        return files;
+    }
+
+    /** Create the file as a directory, including any parent directories. */
+    public boolean mkdirs() {
+        return file.mkdirs();
+    }
+
+    /**
+     * Derive a new file by resolving a relative path against this file.
+     * The new file will inherit the configuration and location of this file
+     * If this file has a path set, the new file will have a corresponding
+     * new path.
+     */
+    public DocFile resolve(DocPath p) {
+        return resolve(p.getPath());
+    }
+
+    /**
+     * Derive a new file by resolving a relative path against this file.
+     * The new file will inherit the configuration and location of this file
+     * If this file has a path set, the new file will have a corresponding
+     * new path.
+     */
+    public DocFile resolve(String p) {
+        if (location == null && path == null) {
+            return new DocFile(configuration, new File(file, p));
+        } else {
+            return new DocFile(configuration, location, path.resolve(p));
+        }
+    }
+
+    /**
+     * Resolve a relative file against the given output location.
+     * @param locn Currently, only SOURCE_OUTPUT is supported.
+     */
+    public DocFile resolveAgainst(StandardLocation locn) {
+        if (locn != StandardLocation.CLASS_OUTPUT)
+            throw new IllegalArgumentException();
+        return new DocFile(configuration,
+                new File(configuration.destDirName, file.getPath()));
+    }
+
+    /**
+     * Given a path string create all the directories in the path. For example,
+     * if the path string is "java/applet", the method will create directory
+     * "java" and then "java/applet" if they don't exist. The file separator
+     * string "/" is platform dependent system property.
+     *
+     * @param path Directory path string.
+     */
+    private void createDirectoryForFile(File file) {
+        File dir = file.getParentFile();
+        if (dir == null || dir.exists() || dir.mkdirs())
+            return;
+
+        configuration.message.error(
+               "doclet.Unable_to_create_directory_0", dir.getPath());
+        throw new DocletAbortException();
+    }
+
+    /** Return a string to identify the contents of this object,
+     * for debugging purposes.
+     */
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("DocFile[");
+        if (location != null)
+            sb.append("locn:").append(location).append(",");
+        if (path != null)
+            sb.append("path:").append(path.getPath()).append(",");
+        sb.append("file:").append(file);
+        sb.append("]");
+        return sb.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocLink.java	Fri Nov 02 17:55:34 2012 -0700
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.doclets.internal.toolkit.util;
+
+/**
+ * Abstraction for simple relative URIs, consisting of a path,
+ * an optional query, and an optional fragment. DocLink objects can
+ * be created by the constructors below or from a DocPath using the
+ * convenience methods, {@link DocPath#fragment fragment} and
+ * {@link DocPath#query query}.
+ *
+ *  <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 DocLink {
+    final String path;
+    final String query;
+    final String fragment;
+
+    /** Create a DocLink representing the URI {@code #fragment}. */
+    public static DocLink fragment(String fragment) {
+        return new DocLink((String) null, (String) null, fragment);
+    }
+
+    /** Create a DocLink representing the URI {@code path}. */
+    public DocLink(DocPath path) {
+        this(path.getPath(), null, null);
+    }
+
+    /**
+     * Create a DocLink representing the URI {@code path?query#fragment}.
+     * query and fragment may be null.
+     */
+    public DocLink(DocPath path, String query, String fragment) {
+        this(path.getPath(), query, fragment);
+    }
+
+    /**
+     * Create a DocLink representing the URI {@code path?query#fragment}.
+     * Any of the component parts may be null.
+     */
+    public DocLink(String path, String query, String fragment) {
+        this.path = path;
+        this.query = query;
+        this.fragment = fragment;
+    }
+
+    /**
+     * Return the link in the form "path?query#fragment", omitting any empty
+     * components.
+     */
+    @Override
+    public String toString() {
+        // common fast path
+        if (path != null && isEmpty(query) && isEmpty(fragment))
+            return path;
+
+        StringBuilder sb = new StringBuilder();
+        if (path != null)
+            sb.append(path);
+        if (!isEmpty(query))
+            sb.append("?").append(query);
+        if (!isEmpty(fragment))
+            sb.append("#").append(fragment);
+        return sb.toString();
+    }
+
+    private static boolean isEmpty(String s) {
+        return (s == null) || s.isEmpty();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocPath.java	Fri Nov 02 17:55:34 2012 -0700
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.doclets.internal.toolkit.util;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.PackageDoc;
+import java.io.File;
+
+/**
+ * Abstraction for immutable relative paths.
+ * Paths always use '/' as a separator, and never begin or end with '/'.
+ *
+ *  <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 DocPath {
+    private final String path;
+
+    /** The empty path. */
+    public static final DocPath empty = new DocPath("");
+
+    /** The empty path. */
+    public static final DocPath parent = new DocPath("..");
+
+    /**
+     * Create a path from a string.
+     */
+    public static DocPath create(String p) {
+        return (p == null) || p.isEmpty() ? empty : new DocPath(p);
+    }
+
+    /**
+     * Return the path for a class.
+     * For example, if the class is java.lang.Object,
+     * the path is java/lang/Object.html.
+     */
+    public static DocPath forClass(ClassDoc cd) {
+        return (cd == null) ? empty :
+                forPackage(cd.containingPackage()).resolve(forName(cd));
+    }
+
+    /**
+     * Return the path for the simple name of the class.
+     * For example, if the class is java.lang.Object,
+     * the path is Object.html.
+     */
+    public static DocPath forName(ClassDoc cd) {
+        return (cd == null) ? empty : new DocPath(cd.name() + ".html");
+    }
+
+    /**
+     * Return the path for the package of a class.
+     * For example, if the class is java.lang.Object,
+     * the path is java/lang.
+     */
+    public static DocPath forPackage(ClassDoc cd) {
+        return (cd == null) ? empty : forPackage(cd.containingPackage());
+    }
+
+    /**
+     * Return the path for a package.
+     * For example, if the package is java.lang,
+     * the path is java/lang.
+     */
+    public static DocPath forPackage(PackageDoc pd) {
+        return (pd == null) ? empty : DocPath.create(pd.name().replace('.', '/'));
+    }
+
+    /**
+     * Return the inverse path for a package.
+     * For example, if the package is java.lang,
+     * the inverse path is ../...
+     */
+    public static DocPath forRoot(PackageDoc pd) {
+        String name = (pd == null) ? "" : pd.name();
+        if (name.isEmpty())
+            return empty;
+        return new DocPath(name.replace('.', '/').replaceAll("[^/]+", ".."));
+    }
+
+    /**
+     * Return the relative path from one package to another.
+     */
+    public static DocPath relativePath(PackageDoc from, PackageDoc to) {
+        return forRoot(from).resolve(forPackage(to));
+    }
+
+    protected DocPath(String p) {
+        path = (p.endsWith("/") ? p.substring(0, p.length() - 1) : p);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean equals(Object other) {
+        return (other instanceof DocPath) && path.equals(((DocPath)other).path);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int hashCode() {
+        return path.hashCode();
+    }
+
+    public DocPath basename() {
+        int sep = path.lastIndexOf("/");
+        return (sep == -1) ? this : new DocPath(path.substring(sep + 1));
+    }
+
+    public DocPath parent() {
+        int sep = path.lastIndexOf("/");
+        return (sep == -1) ? empty : new DocPath(path.substring(0, sep));
+    }
+
+    /**
+     * Return the path formed by appending the specified string to the current path.
+     */
+    public DocPath resolve(String p) {
+        if (p == null || p.isEmpty())
+            return this;
+        if (path.isEmpty())
+            return new DocPath(p);
+        return new DocPath(path + "/" + p);
+    }
+
+    /**
+     * Return the path by appending the specified path to the current path.
+     */
+    public DocPath resolve(DocPath p) {
+        if (p == null || p.isEmpty())
+            return this;
+        if (path.isEmpty())
+            return p;
+        return new DocPath(path + "/" + p.getPath());
+    }
+
+    /**
+     * Get the file created by evaluating the path against a specified directory.
+     */
+    // Temporary: this signature should not use String for dir.
+    // Eventually, this should involve javax.tools.Location.
+    public File resolveAgainst(String dir) {
+        return dir.isEmpty() ? new File(path) : new File(dir, path);
+    }
+
+    /**
+     * Return the inverse path for this path.
+     * For example, if the path is a/b/c, the inverse path is ../../..
+     */
+    public DocPath invert() {
+        return new DocPath(path.replaceAll("[^/]+", ".."));
+    }
+
+    /**
+     * Return true if this path is empty.
+     */
+    public boolean isEmpty() {
+        return path.isEmpty();
+    }
+
+    public DocLink fragment(String fragment) {
+        return new DocLink(path, null, fragment);
+    }
+
+    public DocLink query(String query) {
+        return new DocLink(path, query, null);
+    }
+
+    /**
+     * Return this path as a string.
+     */
+    // This is provided instead of using toString() to help catch
+    // unintended use of toString() in string concatenation sequences.
+    public String getPath() {
+        return path;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocPaths.java	Fri Nov 02 17:55:34 2012 -0700
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.doclets.internal.toolkit.util;
+
+/**
+ * Standard DocPath objects.
+ *
+ *  <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>
+ *
+ * @since 8
+ */
+public class DocPaths {
+
+    /** The name of the file for all classes, using frames. */
+    public static final DocPath ALLCLASSES_FRAME = DocPath.create("allclasses-frame.html");
+
+    /** The name of the file for all classes, without using frames. */
+    public static final DocPath ALLCLASSES_NOFRAME = DocPath.create("allclasses-noframe.html");
+
+    /** The name of the sub-directory for storing class usage info. */
+    public static final DocPath CLASS_USE = DocPath.create("class-use");
+
+    /** The name of the file for constant values. */
+    public static final DocPath CONSTANT_VALUES = DocPath.create("constant-values.html");
+
+    /** The name of the fie for deprecated elements. */
+    public static final DocPath DEPRECATED_LIST = DocPath.create("deprecated-list.html");
+
+    /** The name of the subdirectory for user-provided additional documentation files. */
+    public static final DocPath DOC_FILES = DocPath.create("doc-files");
+
+    /** The name of the file for help info. */
+    public static final DocPath HELP_DOC = DocPath.create("help-doc.html");
+
+    /** The name of the main index file. */
+    public static final DocPath INDEX = DocPath.create("index.html");
+
+    /** The name of the single index file for all classes. */
+    public static final DocPath INDEX_ALL = DocPath.create("index-all.html");
+
+    /** The name of the directory for the split index files. */
+    public static final DocPath INDEX_FILES = DocPath.create("index-files");
+
+    /** Generate the name of one of the files in the split index. */
+    public static final DocPath indexN(int n) {
+        return DocPath.create("index-" + n + ".html");
+    }
+
+    /** The name of the file for the overview frame. */
+    public static final DocPath OVERVIEW_FRAME = DocPath.create("overview-frame.html");
+
+    /** The name of the file for the overview summary. */
+    public static final DocPath OVERVIEW_SUMMARY = DocPath.create("overview-summary.html");
+
+    /** The name of the file for the overview tree. */
+    public static final DocPath OVERVIEW_TREE = DocPath.create("overview-tree.html");
+
+    /** The name of the file for the package frame. */
+    public static final DocPath PACKAGE_FRAME = DocPath.create("package-frame.html");
+
+    /** The name of the file for the package list. */
+    public static final DocPath PACKAGE_LIST = DocPath.create("package-list");
+
+    /** The name of the file for the package summary. */
+    public static final DocPath PACKAGE_SUMMARY = DocPath.create("package-summary.html");
+
+    /** The name of the file for the package tree. */
+    public static final DocPath PACKAGE_TREE = DocPath.create("package-tree.html");
+
+    /** The name of the file for the package usage info. */
+    public static final DocPath PACKAGE_USE = DocPath.create("package-use.html");
+
+    /** The name of the directory in which resources are generated.
+     *  Also the name of the sub-package from which resources are read.
+     */
+    public static final DocPath RESOURCES = DocPath.create("resources");
+
+    /** The name of the file for the serialized form info. */
+    public static final DocPath SERIALIZED_FORM = DocPath.create("serialized-form.html");
+
+    /** The name of the directory in which HTML versions of the source code
+     *  are generated.
+     */
+    public static final DocPath SOURCE_OUTPUT = DocPath.create("src-html");
+
+    /** The name of the default stylesheet. */
+    public static final DocPath STYLESHEET = DocPath.create("stylesheet.css");
+
+}
--- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocletConstants.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocletConstants.java	Fri Nov 02 17:55:34 2012 -0700
@@ -40,6 +40,16 @@
 public class DocletConstants {
 
     /**
+     * The default amount of space between tab stops.
+     */
+    public static final int DEFAULT_TAB_STOP_LENGTH = 8;
+
+    /**
+     * The line separator for the current operating system.
+     */
+    public static final String NL = System.getProperty("line.separator");
+
+    /**
      * The default package name.
      */
     public static final String DEFAULT_PACKAGE_NAME = "&lt;Unnamed&gt;";
@@ -53,34 +63,4 @@
      * The anchor for the default package.
      */
     public static final String UNNAMED_PACKAGE_ANCHOR = "unnamed_package";
-
-    /**
-     * The name of the doc files directory.
-     */
-    public static final String DOC_FILES_DIR_NAME = "doc-files";
-
-    /**
-     * The default amount of space between tab stops.
-     */
-    public static final int DEFAULT_TAB_STOP_LENGTH = 8;
-
-    /**
-     * The name of the directory where we will copy resource files to.
-     */
-    public static final String RESOURE_DIR_NAME = "resources";
-
-    /**
-     * The source output directory name
-     */
-    public static final String SOURCE_OUTPUT_DIR_NAME = "src-html/";
-
-    /**
-     * The name of the package list file.
-     */
-    public static final String PACKAGE_LIST_FILE_NAME = "package-list";
-
-    /**
-     * The line seperator for the current operating system.
-     */
-    public static final String NL = System.getProperty("line.separator");
 }
--- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Extern.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Extern.java	Fri Nov 02 17:55:34 2012 -0700
@@ -30,6 +30,8 @@
 import java.util.HashMap;
 import java.util.Map;
 
+import javax.tools.StandardLocation;
+
 import com.sun.javadoc.*;
 import com.sun.tools.doclets.internal.toolkit.*;
 
@@ -138,21 +140,25 @@
      *
      * @param pkgName The package name.
      * @param relativepath    The relative path.
-     * @param link    The link to convert.
+     * @param filename    The link to convert.
      * @return if external return converted link else return null
      */
-    public String getExternalLink(String pkgName,
-                                  String relativepath, String link) {
+    public DocLink getExternalLink(String pkgName,
+                                  DocPath relativepath, String filename) {
+        return getExternalLink(pkgName, relativepath, filename, null);
+    }
+
+    public DocLink getExternalLink(String pkgName,
+                                  DocPath relativepath, String filename, String memberName) {
         Item fnd = findPackageItem(pkgName);
-        if (fnd != null) {
-            String externlink = fnd.path + link;
-            if (fnd.relative) {  // it's a relative path.
-                return relativepath + externlink;
-            } else {
-                return externlink;
-            }
-        }
-        return null;
+        if (fnd == null)
+            return null;
+
+        DocPath p = fnd.relative ?
+                relativepath.resolve(fnd.path).resolve(filename) :
+                DocPath.create(fnd.path).resolve(filename);
+
+        return new DocLink(p, "is-external=true", memberName);
     }
 
     /**
@@ -163,17 +169,38 @@
      * @param pkglisturl This can be another URL for "package-list" or ordinary
      *                   file.
      * @param reporter   The <code>DocErrorReporter</code> used to report errors.
-     * @param linkoffline True if -linkoffline isused and false if -link is used.
+     * @param linkoffline True if -linkoffline is used and false if -link is used.
      */
-    public boolean url(String url, String pkglisturl,
+    public boolean link(String url, String pkglisturl,
                               DocErrorReporter reporter, boolean linkoffline) {
         this.linkoffline = linkoffline;
-        String errMsg = composeExternPackageList(url, pkglisturl);
-        if (errMsg != null) {
-            reporter.printWarning(errMsg);
+        try {
+            url = adjustEndFileSeparator(url);
+            if (isUrl(pkglisturl)) {
+                readPackageListFromURL(url, toURL(pkglisturl));
+            } else {
+                readPackageListFromFile(url, DocFile.createFileForInput(configuration, pkglisturl));
+            }
+            return true;
+        } catch (Fault f) {
+            reporter.printWarning(f.getMessage());
             return false;
-        } else {
-            return true;
+        }
+    }
+
+    private URL toURL(String url) throws Fault {
+        try {
+            return new URL(url);
+        } catch (MalformedURLException e) {
+            throw new Fault(configuration.getText("doclet.MalformedURL", url), e);
+        }
+    }
+
+    private class Fault extends Exception {
+        private static final long serialVersionUID = 0;
+
+        Fault(String msg, Exception cause) {
+            super(msg, cause);
         }
     }
 
@@ -190,31 +217,10 @@
     }
 
     /**
-     * Adjusts the end file separator if it is missing from the URL or the
-     * directory path and depending upon the URL or file path, fetch or
-     * read the "package-list" file.
-     *
-     * @param urlOrDirPath        URL or the directory path.
-     * @param pkgListUrlOrDirPath URL or directory path for the "package-list" file or the "package-list"
-     * file itself.
-     */
-    private String composeExternPackageList(String urlOrDirPath, String pkgListUrlOrDirPath) {
-        urlOrDirPath = adjustEndFileSeparator(urlOrDirPath);
-        pkgListUrlOrDirPath = adjustEndFileSeparator(pkgListUrlOrDirPath);
-        return isUrl(pkgListUrlOrDirPath) ?
-            fetchURLComposeExternPackageList(urlOrDirPath, pkgListUrlOrDirPath) :
-            readFileComposeExternPackageList(urlOrDirPath, pkgListUrlOrDirPath);
-    }
-
-    /**
      * If the URL or Directory path is missing end file separator, add that.
      */
     private String adjustEndFileSeparator(String url) {
-        String filesep = "/";
-        if (!url.endsWith(filesep)) {
-            url += filesep;
-        }
-        return url;
+        return url.endsWith("/") ? url : url + '/';
     }
 
     /**
@@ -223,17 +229,18 @@
      * @param urlpath        Path to the packages.
      * @param pkglisturlpath URL or the path to the "package-list" file.
      */
-    private String fetchURLComposeExternPackageList(String urlpath,
-                                                   String pkglisturlpath) {
-        String link = pkglisturlpath + "package-list";
+    private void readPackageListFromURL(String urlpath, URL pkglisturlpath)
+            throws Fault {
         try {
-            readPackageList((new URL(link)).openStream(), urlpath, false);
+            URL link = pkglisturlpath.toURI().resolve(DocPaths.PACKAGE_LIST.getPath()).toURL();
+            readPackageList(link.openStream(), urlpath, false);
+        } catch (URISyntaxException exc) {
+            throw new Fault(configuration.getText("doclet.MalformedURL", pkglisturlpath.toString()), exc);
         } catch (MalformedURLException exc) {
-            return configuration.getText("doclet.MalformedURL", link);
+            throw new Fault(configuration.getText("doclet.MalformedURL", pkglisturlpath.toString()), exc);
         } catch (IOException exc) {
-            return configuration.getText("doclet.URL_error", link);
+            throw new Fault(configuration.getText("doclet.URL_error", pkglisturlpath.toString()), exc);
         }
-        return null;
     }
 
     /**
@@ -242,27 +249,24 @@
      * @param path URL or directory path to the packages.
      * @param pkgListPath Path to the local "package-list" file.
      */
-    private String readFileComposeExternPackageList(String path,
-                                                   String pkgListPath) {
-
-        String link = pkgListPath + "package-list";
-        if (! ((new File(pkgListPath)).isAbsolute() || linkoffline)){
-            link = configuration.destDirName + link;
+    private void readPackageListFromFile(String path, DocFile pkgListPath)
+            throws Fault {
+        DocFile file = pkgListPath.resolve(DocPaths.PACKAGE_LIST);
+        if (! (file.isAbsolute() || linkoffline)){
+            file = file.resolveAgainst(StandardLocation.CLASS_OUTPUT);
         }
         try {
-            File file = new File(link);
             if (file.exists() && file.canRead()) {
-                readPackageList(new FileInputStream(file), path,
-                    ! ((new File(path)).isAbsolute() || isUrl(path)));
+                boolean pathIsRelative =
+                        !DocFile.createFileForInput(configuration, path).isAbsolute()
+                        && !isUrl(path);
+                readPackageList(file.openInputStream(), path, pathIsRelative);
             } else {
-                return configuration.getText("doclet.File_error", link);
+                throw new Fault(configuration.getText("doclet.File_error", file.getPath()), null);
             }
-        } catch (FileNotFoundException exc) {
-            return configuration.getText("doclet.File_error", link);
         } catch (IOException exc) {
-            return configuration.getText("doclet.File_error", link);
+           throw new Fault(configuration.getText("doclet.File_error", file.getPath()), exc);
         }
-        return null;
     }
 
     /**
--- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/PackageListWriter.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/PackageListWriter.java	Fri Nov 02 17:55:34 2012 -0700
@@ -52,8 +52,7 @@
      * @param configuration the current configuration of the doclet.
      */
     public PackageListWriter(Configuration configuration) throws IOException {
-        super(Util.genWriter(configuration, configuration.destDirName,
-            DocletConstants.PACKAGE_LIST_FILE_NAME, configuration.docencoding));
+        super(DocFile.createFileForOutput(configuration, DocPaths.PACKAGE_LIST).openWriter());
         this.configuration = configuration;
     }
 
@@ -71,7 +70,7 @@
             packgen.close();
         } catch (IOException exc) {
             configuration.message.error("doclet.exception_encountered",
-                exc.toString(), DocletConstants.PACKAGE_LIST_FILE_NAME);
+                exc.toString(), DocPaths.PACKAGE_LIST);
             throw new DocletAbortException();
         }
     }
--- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/SourcePath.java	Thu Nov 01 14:13:13 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,133 +0,0 @@
-/*
- * Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.doclets.internal.toolkit.util;
-
-import java.io.File;
-
-/**
- * This class is used to represent a source path which can contain only
- * directories no zip files. If a zip file is specified in the command line it
- * will not get reflected in the SourcePath.
- *
- * This code is not part of an API.
- * It is implementation that is subject to change.
- * Do not use it as an API
- *
- * @author Atul M Dambalkar
- */
-public
-    class SourcePath {
-    private final char dirSeparator = File.pathSeparatorChar;
-
-    /**
-     * The original class path string
-     */
-    private String pathstr;
-
-    /**
-     * List of source path entries. Each entry is a directory.
-     */
-    private File[] sourcePath;
-
-
-    /**
-     * Build a source path from the specified path string on the command line.
-     */
-    public SourcePath(String pathstr) {
-        init(pathstr);
-    }
-
-    /**
-     * Build a default source path from the path strings specified by
-     * the properties env.class.path.
-     */
-    public SourcePath() {
-        init(System.getProperty("env.class.path"));
-    }
-
-    /**
-     * Initialize the SourcePath File array, which will contain only the
-     * directory names from the given path string.
-     *
-     * @param pathstr Path String.
-     */
-    private void init(String pathstr) {
-        if (pathstr == null ||  pathstr.length() == 0) {
-            pathstr = ".";
-        }
-
-        int noOfFileSep = 0;
-        int index = 0;
-        this.pathstr = pathstr; // Save original class path string
-
-        // Count the number of path separators
-        while ((index = pathstr.indexOf(dirSeparator, index)) != -1) {
-            noOfFileSep++;
-            index++;
-        }
-        // Build the source path
-        File[] tempPath = new File[noOfFileSep + 1];
-        int tempPathIndex = 0;
-        int len = pathstr.length();
-        int sepPos = 0;
-        for (index = 0; index < len; index = sepPos + 1) {
-            sepPos = pathstr.indexOf(dirSeparator, index);
-            if (sepPos < 0) {
-                sepPos = len;
-            }
-            File file = new File(pathstr.substring(index, sepPos));
-            if (file.isDirectory()) {
-                tempPath[tempPathIndex++] = file;
-            } // if it is really a file, ignore it.
-        }
-        sourcePath = new File[tempPathIndex];
-        System.arraycopy((Object)tempPath, 0, (Object)sourcePath,
-                         0, tempPathIndex);
-    }
-
-    /**
-     * Find the specified directory in the source path.
-     *
-     * @param name Name of the directory to be searched for in the source path.
-     * @return File Return the directory if found else return null.
-     */
-    public File getDirectory(String name) {
-        for (int i = 0; i < sourcePath.length; i++) {
-            File directoryNeeded = new File(sourcePath[i], name);
-            if (directoryNeeded.isDirectory()) {
-                return directoryNeeded;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Return original source path string.
-     */
-    public String toString() {
-        return pathstr;
-    }
-}
--- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java	Fri Nov 02 17:55:34 2012 -0700
@@ -30,6 +30,7 @@
 
 import com.sun.javadoc.*;
 import com.sun.tools.doclets.internal.toolkit.*;
+import javax.tools.StandardLocation;
 
 /**
  * Utilities Class for Doclets.
@@ -52,11 +53,6 @@
     {{"&", "&amp;"}, {"<", "&lt;"}, {">", "&gt;"}};
 
     /**
-     * Name of the resource directory.
-     */
-    public static final String RESOURCESDIR = "resources";
-
-    /**
      * Return array of class members whose documentation is to be generated.
      * If the member is deprecated do not include such a member in the
      * returned array.
@@ -197,32 +193,6 @@
     }
 
     /**
-     * Copy source file to destination file.
-     *
-     * @throws SecurityException
-     * @throws IOException
-     */
-    public static void copyFile(File destfile, File srcfile)
-        throws IOException {
-        byte[] bytearr = new byte[512];
-        int len = 0;
-        FileInputStream input = new FileInputStream(srcfile);
-        File destDir = destfile.getParentFile();
-        destDir.mkdirs();
-        FileOutputStream output = new FileOutputStream(destfile);
-        try {
-            while ((len = input.read(bytearr)) != -1) {
-                output.write(bytearr, 0, len);
-                }
-        } catch (FileNotFoundException exc) {
-        } catch (SecurityException exc) {
-            } finally {
-            input.close();
-            output.close();
-            }
-        }
-
-    /**
      * Copy the given directory contents from the source package directory
      * to the generated documentation directory. For example for a package
      * java.lang this method find out the source location of the package using
@@ -235,45 +205,45 @@
      * @param dir The original directory name to copy from.
      * @param overwrite Overwrite files if true.
      */
-    public static void copyDocFiles(Configuration configuration,
-            String path, String dir, boolean overwrite) {
-        if (checkCopyDocFilesErrors(configuration, path, dir)) {
-            return;
-        }
-        String destname = configuration.docFileDestDirName;
-        File srcdir = new File(path + dir);
-        if (destname.length() > 0 && !destname.endsWith(
-               DirectoryManager.URL_FILE_SEPARATOR)) {
-            destname += DirectoryManager.URL_FILE_SEPARATOR;
-        }
-        String dest = destname + dir;
+    public static void copyDocFiles(Configuration configuration, PackageDoc pd) {
+        copyDocFiles(configuration, DocPath.forPackage(pd).resolve(DocPaths.DOC_FILES));
+    }
+
+    public static void copyDocFiles(Configuration configuration, DocPath dir) {
         try {
-            File destdir = new File(dest);
-            DirectoryManager.createDirectory(configuration, dest);
-            String[] files = srcdir.list();
-            for (int i = 0; i < files.length; i++) {
-                File srcfile = new File(srcdir, files[i]);
-                File destfile = new File(destdir, files[i]);
-                if (srcfile.isFile()) {
-                    if(destfile.exists() && ! overwrite) {
-                        configuration.message.warning((SourcePosition) null,
-                                "doclet.Copy_Overwrite_warning",
-                                srcfile.toString(), destdir.toString());
-                    } else {
-                        configuration.message.notice(
-                            "doclet.Copying_File_0_To_Dir_1",
-                            srcfile.toString(), destdir.toString());
-                        Util.copyFile(destfile, srcfile);
-                    }
-                } else if(srcfile.isDirectory()) {
-                    if(configuration.copydocfilesubdirs
-                        && ! configuration.shouldExcludeDocFileDir(
-                          srcfile.getName())){
-                        copyDocFiles(configuration, path, dir +
-                                    DirectoryManager.URL_FILE_SEPARATOR + srcfile.getName(),
-                                overwrite);
+            boolean first = true;
+            for (DocFile f : DocFile.list(configuration, StandardLocation.SOURCE_PATH, dir)) {
+                if (!f.isDirectory()) {
+                    continue;
+                }
+                DocFile srcdir = f;
+                DocFile destdir = DocFile.createFileForOutput(configuration, dir);
+                if (srcdir.isSameFile(destdir)) {
+                    continue;
+                }
+
+                for (DocFile srcfile: srcdir.list()) {
+                    DocFile destfile = destdir.resolve(srcfile.getName());
+                    if (srcfile.isFile()) {
+                        if (destfile.exists() && !first) {
+                            configuration.message.warning((SourcePosition) null,
+                                    "doclet.Copy_Overwrite_warning",
+                                    srcfile.getPath(), destdir.getPath());
+                        } else {
+                            configuration.message.notice(
+                                    "doclet.Copying_File_0_To_Dir_1",
+                                    srcfile.getPath(), destdir.getPath());
+                            destfile.copyFile(srcfile);
+                        }
+                    } else if (srcfile.isDirectory()) {
+                        if (configuration.copydocfilesubdirs
+                                && !configuration.shouldExcludeDocFileDir(srcfile.getName())) {
+                            copyDocFiles(configuration, dir.resolve(srcfile.getName()));
+                        }
                     }
                 }
+
+                first = false;
             }
         } catch (SecurityException exc) {
             throw new DocletAbortException();
@@ -283,142 +253,6 @@
     }
 
     /**
-     * Given the parameters for copying doc-files, check for errors.
-     *
-     * @param configuration The configuration of the current doclet.
-     * @param path The relative path to the directory to be copied.
-     * @param dirName The original directory name to copy from.
-     */
-    private static boolean checkCopyDocFilesErrors (Configuration configuration,
-            String path, String dirName) {
-        if ((configuration.sourcepath == null || configuration.sourcepath.length() == 0) &&
-               (configuration.destDirName == null || configuration.destDirName.length() == 0)) {
-            //The destination path and source path are definitely equal.
-            return true;
-        }
-        File sourcePath, destPath = new File(configuration.destDirName);
-        StringTokenizer pathTokens = new StringTokenizer(
-            configuration.sourcepath == null ? "" : configuration.sourcepath,
-            File.pathSeparator);
-        //Check if the destination path is equal to the source path.  If yes,
-        //do not copy doc-file directories.
-        while(pathTokens.hasMoreTokens()){
-            sourcePath = new File(pathTokens.nextToken());
-            if(destPath.equals(sourcePath)){
-                return true;
-            }
-        }
-        //Make sure the doc-file being copied exists.
-        File srcdir = new File(path + dirName);
-        if (! srcdir.exists()) {
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Copy a file in the resources directory to the destination
-     * directory (if it is not there already).  If
-     * <code>overwrite</code> is true and the destination file
-     * already exists, overwrite it.
-     *
-     * @param configuration  Holds the destination directory and error message
-     * @param resourcefile   The name of the resource file to copy
-     * @param overwrite      A flag to indicate whether the file in the
-     *                       destination directory will be overwritten if
-     *                       it already exists.
-     */
-    public static void copyResourceFile(Configuration configuration,
-            String resourcefile, boolean overwrite) {
-        String destresourcesdir = configuration.destDirName + RESOURCESDIR;
-        copyFile(configuration, resourcefile, RESOURCESDIR, destresourcesdir,
-                overwrite, false);
-    }
-
-    /**
-     * Copy a file from a source directory to a destination directory
-     * (if it is not there already). If <code>overwrite</code> is true and
-     * the destination file already exists, overwrite it.
-     *
-     * @param configuration Holds the error message
-     * @param file The name of the file to copy
-     * @param source The source directory
-     * @param destination The destination directory where the file needs to be copied
-     * @param overwrite A flag to indicate whether the file in the
-     *                  destination directory will be overwritten if
-     *                  it already exists.
-     * @param replaceNewLine true if the newline needs to be replaced with platform-
-     *                  specific newline.
-     */
-    public static void copyFile(Configuration configuration, String file, String source,
-            String destination, boolean overwrite, boolean replaceNewLine) {
-        DirectoryManager.createDirectory(configuration, destination);
-        File destfile = new File(destination, file);
-        if(destfile.exists() && (! overwrite)) return;
-        try {
-            InputStream in = Configuration.class.getResourceAsStream(
-                    source + DirectoryManager.URL_FILE_SEPARATOR + file);
-            if(in==null) return;
-            OutputStream out = new FileOutputStream(destfile);
-            try {
-                if (!replaceNewLine) {
-                    byte[] buf = new byte[2048];
-                    int n;
-                    while((n = in.read(buf))>0) out.write(buf,0,n);
-                } else {
-                    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
-                    BufferedWriter writer;
-                    if (configuration.docencoding == null) {
-                        writer = new BufferedWriter(new OutputStreamWriter(out));
-                    } else {
-                        writer = new BufferedWriter(new OutputStreamWriter(out,
-                            configuration.docencoding));
-                    }
-                    try {
-                        String line;
-                        while ((line = reader.readLine()) != null) {
-                            writer.write(line);
-                            writer.write(DocletConstants.NL);
-                        }
-                    } finally {
-                        reader.close();
-                        writer.close();
-                    }
-                }
-            } finally {
-                in.close();
-                out.close();
-            }
-        } catch (IOException ie) {
-            ie.printStackTrace(System.err);
-            throw new DocletAbortException();
-        }
-    }
-
-    /**
-     * Given a PackageDoc, return the source path for that package.
-     * @param configuration The Configuration for the current Doclet.
-     * @param pkgDoc The package to seach the path for.
-     * @return A string representing the path to the given package.
-     */
-    public static String getPackageSourcePath(Configuration configuration,
-            PackageDoc pkgDoc){
-        try{
-            String pkgPath = DirectoryManager.getDirectoryPath(pkgDoc);
-            String completePath = new SourcePath(configuration.sourcepath).
-                getDirectory(pkgPath) + DirectoryManager.URL_FILE_SEPARATOR;
-            //Make sure that both paths are using the same separators.
-            completePath = Util.replaceText(completePath, File.separator,
-                    DirectoryManager.URL_FILE_SEPARATOR);
-            pkgPath = Util.replaceText(pkgPath, File.separator,
-                    DirectoryManager.URL_FILE_SEPARATOR);
-            return completePath.substring(0, completePath.lastIndexOf(pkgPath));
-        } catch (Exception e){
-            return "";
-        }
-    }
-
-    /**
      * We want the list of types in alphabetical order.  However, types are not
      * comparable.  We need a comparator for now.
      */
@@ -552,7 +386,7 @@
     }
 
     /**
-     * Given a package, return it's name.
+     * Given a package, return its name.
      * @param packageDoc the package to check.
      * @return the name of the given package.
      */
@@ -562,7 +396,7 @@
     }
 
     /**
-     * Given a package, return it's file name without the extension.
+     * Given a package, return its file name without the extension.
      * @param packageDoc the package to check.
      * @return the file name of the given package.
      */
@@ -572,7 +406,7 @@
     }
 
     /**
-     * Given a string, replace all occurraces of 'newStr' with 'oldStr'.
+     * Given a string, replace all occurrences of 'newStr' with 'oldStr'.
      * @param originalStr the string to modify.
      * @param oldStr the string to replace.
      * @param newStr the string to insert in place of the old string.
@@ -623,40 +457,6 @@
     }
 
     /**
-     * Create the directory path for the file to be generated, construct
-     * FileOutputStream and OutputStreamWriter depending upon docencoding.
-     *
-     * @param path The directory path to be created for this file.
-     * @param filename File Name to which the PrintWriter will do the Output.
-     * @param docencoding Encoding to be used for this file.
-     * @exception IOException Exception raised by the FileWriter is passed on
-     * to next level.
-     * @exception UnsupportedEncodingException Exception raised by the
-     * OutputStreamWriter is passed on to next level.
-     * @return Writer Writer for the file getting generated.
-     * @see java.io.FileOutputStream
-     * @see java.io.OutputStreamWriter
-     */
-    public static Writer genWriter(Configuration configuration,
-            String path, String filename,
-            String docencoding)
-        throws IOException, UnsupportedEncodingException {
-        FileOutputStream fos;
-        if (path != null) {
-            DirectoryManager.createDirectory(configuration, path);
-            fos = new FileOutputStream(((path.length() > 0)?
-                                                  path + File.separator: "") + filename);
-        } else {
-            fos = new FileOutputStream(filename);
-        }
-        if (docencoding == null) {
-            return new BufferedWriter(new OutputStreamWriter(fos));
-        } else {
-            return new BufferedWriter(new OutputStreamWriter(fos, docencoding));
-        }
-    }
-
-    /**
      * Given an annotation, return true if it should be documented and false
      * otherwise.
      *
@@ -676,47 +476,6 @@
     }
 
     /**
-     * Given a string, return an array of tokens.  The separator can be escaped
-     * with the '\' character.  The '\' character may also be escaped by the
-     * '\' character.
-     *
-     * @param s         the string to tokenize.
-     * @param separator the separator char.
-     * @param maxTokens the maxmimum number of tokens returned.  If the
-     *                  max is reached, the remaining part of s is appended
-     *                  to the end of the last token.
-     *
-     * @return an array of tokens.
-     */
-    public static String[] tokenize(String s, char separator, int maxTokens) {
-        List<String> tokens = new ArrayList<String>();
-        StringBuilder  token = new StringBuilder ();
-        boolean prevIsEscapeChar = false;
-        for (int i = 0; i < s.length(); i += Character.charCount(i)) {
-            int currentChar = s.codePointAt(i);
-            if (prevIsEscapeChar) {
-                // Case 1:  escaped character
-                token.appendCodePoint(currentChar);
-                prevIsEscapeChar = false;
-            } else if (currentChar == separator && tokens.size() < maxTokens-1) {
-                // Case 2:  separator
-                tokens.add(token.toString());
-                token = new StringBuilder();
-            } else if (currentChar == '\\') {
-                // Case 3:  escape character
-                prevIsEscapeChar = true;
-            } else {
-                // Case 4:  regular character
-                token.appendCodePoint(currentChar);
-            }
-        }
-        if (token.length() > 0) {
-            tokens.add(token.toString());
-        }
-        return tokens.toArray(new String[] {});
-    }
-
-    /**
      * Return true if this class is linkable and false if we can't link to the
      * desired class.
      * <br>
--- a/src/share/classes/com/sun/tools/javac/code/Attribute.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Attribute.java	Fri Nov 02 17:55:34 2012 -0700
@@ -34,8 +34,6 @@
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.util.*;
 
-import static com.sun.tools.javac.code.TypeTags.*;
-
 /** An annotation value.
  *
  *  <p><b>This is NOT part of any supported API.
--- a/src/share/classes/com/sun/tools/javac/code/Flags.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Flags.java	Fri Nov 02 17:55:34 2012 -0700
@@ -258,6 +258,12 @@
      */
     public static final long DEFAULT = 1L<<43;
 
+    /**
+     * Flag that marks class as auxiliary, ie a non-public class following
+     * the public class in a source file, that could block implicit compilation.
+     */
+    public static final long AUXILIARY = 1L<<43;
+
     /** Modifier masks.
      */
     public static final int
--- a/src/share/classes/com/sun/tools/javac/code/Kinds.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Kinds.java	Fri Nov 02 17:55:34 2012 -0700
@@ -32,7 +32,9 @@
 import com.sun.tools.javac.api.Formattable;
 import com.sun.tools.javac.api.Messages;
 import static com.sun.tools.javac.code.Flags.*;
-import static com.sun.tools.javac.code.TypeTags.*;
+import static com.sun.tools.javac.code.TypeTag.CLASS;
+import static com.sun.tools.javac.code.TypeTag.PACKAGE;
+import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
 
 /** Internal symbol kinds, which distinguish between elements of
  *  different subclasses of Symbol. Symbol kinds are organized so they can be
--- a/src/share/classes/com/sun/tools/javac/code/Lint.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Lint.java	Fri Nov 02 17:55:34 2012 -0700
@@ -129,6 +129,13 @@
      */
     public enum LintCategory {
         /**
+         * Warn when code refers to a auxiliary class that is hidden in a source file (ie source file name is
+         * different from the class name, and the type is not properly nested) and the referring code
+         * is not located in the same source file.
+         */
+        AUXILIARYCLASS("auxiliaryclass"),
+
+        /**
          * Warn about use of unnecessary casts.
          */
         CAST("cast"),
--- a/src/share/classes/com/sun/tools/javac/code/Printer.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Printer.java	Fri Nov 02 17:55:34 2012 -0700
@@ -32,9 +32,12 @@
 import com.sun.tools.javac.code.Type.*;
 import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.util.ListBuffer;
+
 import static com.sun.tools.javac.code.BoundKind.*;
 import static com.sun.tools.javac.code.Flags.*;
-import static com.sun.tools.javac.code.TypeTags.*;
+import static com.sun.tools.javac.code.TypeTag.ARRAY;
+import static com.sun.tools.javac.code.TypeTag.CLASS;
+import static com.sun.tools.javac.code.TypeTag.FORALL;
 
 /**
  * A combined type/symbol visitor for generating non-trivial localized string
--- a/src/share/classes/com/sun/tools/javac/code/Symbol.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Symbol.java	Fri Nov 02 17:55:34 2012 -0700
@@ -42,7 +42,9 @@
 import com.sun.tools.javac.util.Name;
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Kinds.*;
-import static com.sun.tools.javac.code.TypeTags.*;
+import static com.sun.tools.javac.code.TypeTag.CLASS;
+import static com.sun.tools.javac.code.TypeTag.FORALL;
+import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
 
 /** Root class for Java symbols. It contains subclasses
  *  for specific sorts of symbols, such as variables, methods and operators,
@@ -161,7 +163,7 @@
         if (owner.name == null || owner.name.isEmpty()) {
             return location();
         }
-        if (owner.type.tag == CLASS) {
+        if (owner.type.hasTag(CLASS)) {
             Type ownertype = types.asOuterSuper(site, owner);
             if (ownertype != null) return ownertype.tsym;
         }
@@ -256,7 +258,7 @@
     /** A class is an inner class if it it has an enclosing instance class.
      */
     public boolean isInner() {
-        return type.getEnclosingType().tag == CLASS;
+        return type.getEnclosingType().hasTag(CLASS);
     }
 
     /** An inner class has an outer instance if it is not an interface
@@ -269,7 +271,7 @@
      */
     public boolean hasOuterInstance() {
         return
-            type.getEnclosingType().tag == CLASS && (flags() & (INTERFACE | NOOUTERTHIS)) == 0;
+            type.getEnclosingType().hasTag(CLASS) && (flags() & (INTERFACE | NOOUTERTHIS)) == 0;
     }
 
     /** The closest enclosing class of this symbol's declaration.
@@ -277,7 +279,7 @@
     public ClassSymbol enclClass() {
         Symbol c = this;
         while (c != null &&
-               ((c.kind & TYP) == 0 || c.type.tag != CLASS)) {
+               ((c.kind & TYP) == 0 || !c.type.hasTag(CLASS))) {
             c = c.owner;
         }
         return (ClassSymbol)c;
@@ -346,7 +348,7 @@
                 e = e.next();
             }
             Type superType = types.supertype(clazz.type);
-            if (superType.tag != TypeTags.CLASS) return false;
+            if (!superType.hasTag(CLASS)) return false;
             clazz = (ClassSymbol)superType.tsym;
         }
     }
@@ -373,7 +375,7 @@
             for (Symbol sup = clazz;
                  sup != null && sup != this.owner;
                  sup = types.supertype(sup.type).tsym) {
-                while (sup.type.tag == TYPEVAR)
+                while (sup.type.hasTag(TYPEVAR))
                     sup = sup.type.getUpperBound().tsym;
                 if (sup.type.isErroneous())
                     return true; // error recovery
@@ -520,7 +522,7 @@
             if (owner == null) return name;
             if (((owner.kind != ERR)) &&
                 ((owner.kind & (VAR | MTH)) != 0
-                 || (owner.kind == TYP && owner.type.tag == TYPEVAR)
+                 || (owner.kind == TYP && owner.type.hasTag(TYPEVAR))
                  )) return name;
             Name prefix = owner.getQualifiedName();
             if (prefix == null || prefix == prefix.table.names.empty)
@@ -534,7 +536,7 @@
         static public Name formFlatName(Name name, Symbol owner) {
             if (owner == null ||
                 (owner.kind & (VAR | MTH)) != 0
-                || (owner.kind == TYP && owner.type.tag == TYPEVAR)
+                || (owner.kind == TYP && owner.type.hasTag(TYPEVAR))
                 ) return name;
             char sep = owner.kind == TYP ? '$' : '.';
             Name prefix = owner.flatName();
@@ -553,16 +555,16 @@
             if (this == that)
                 return false;
             if (this.type.tag == that.type.tag) {
-                if (this.type.tag == CLASS) {
+                if (this.type.hasTag(CLASS)) {
                     return
                         types.rank(that.type) < types.rank(this.type) ||
                         types.rank(that.type) == types.rank(this.type) &&
                         that.getQualifiedName().compareTo(this.getQualifiedName()) < 0;
-                } else if (this.type.tag == TYPEVAR) {
+                } else if (this.type.hasTag(TYPEVAR)) {
                     return types.isSubtype(this.type, that.type);
                 }
             }
-            return this.type.tag == TYPEVAR;
+            return this.type.hasTag(TYPEVAR);
         }
 
         // For type params; overridden in subclasses.
@@ -572,7 +574,7 @@
 
         public java.util.List<Symbol> getEnclosedElements() {
             List<Symbol> list = List.nil();
-            if (kind == TYP && type.tag == TYPEVAR) {
+            if (kind == TYP && type.hasTag(TYPEVAR)) {
                 return list;
             }
             for (Scope.Entry e = members().elems; e != null; e = e.sibling) {
@@ -591,7 +593,7 @@
         }
 
         public <R, P> R accept(ElementVisitor<R, P> v, P p) {
-            Assert.check(type.tag == TYPEVAR); // else override will be invoked
+            Assert.check(type.hasTag(TYPEVAR)); // else override will be invoked
             return v.visitTypeParameter(this, p);
         }
 
@@ -798,13 +800,13 @@
             if (this == base) {
                 return true;
             } else if ((base.flags() & INTERFACE) != 0) {
-                for (Type t = type; t.tag == CLASS; t = types.supertype(t))
+                for (Type t = type; t.hasTag(CLASS); t = types.supertype(t))
                     for (List<Type> is = types.interfaces(t);
                          is.nonEmpty();
                          is = is.tail)
                         if (is.head.tsym.isSubClass(base, types)) return true;
             } else {
-                for (Type t = type; t.tag == CLASS; t = types.supertype(t))
+                for (Type t = type; t.hasTag(CLASS); t = types.supertype(t))
                     if (t.tsym == base) return true;
             }
             return false;
@@ -1048,7 +1050,7 @@
          */
         public MethodSymbol(long flags, Name name, Type type, Symbol owner) {
             super(MTH, flags, name, type, owner);
-            if (owner.type.tag == TYPEVAR) Assert.error(owner + "." + name);
+            if (owner.type.hasTag(TYPEVAR)) Assert.error(owner + "." + name);
         }
 
         /** Clone this symbol with new owner.
@@ -1074,7 +1076,7 @@
                     ? owner.name.toString()
                     : name.toString();
                 if (type != null) {
-                    if (type.tag == FORALL)
+                    if (type.hasTag(FORALL))
                         s = "<" + ((ForAll)type).getTypeArguments() + ">" + s;
                     s += "(" + type.argtypes((flags() & VARARGS) != 0) + ")";
                 }
--- a/src/share/classes/com/sun/tools/javac/code/Symtab.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Symtab.java	Fri Nov 02 17:55:34 2012 -0700
@@ -37,6 +37,7 @@
 import com.sun.tools.javac.util.List;
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.jvm.ByteCodes.*;
+import static com.sun.tools.javac.code.TypeTag.*;
 
 /** A class that defines all predefined constants and operators
  *  as well as special classes such as java.lang.Object, which need
@@ -64,16 +65,16 @@
 
     /** Builtin types.
      */
-    public final Type byteType = new Type(TypeTags.BYTE, null);
-    public final Type charType = new Type(TypeTags.CHAR, null);
-    public final Type shortType = new Type(TypeTags.SHORT, null);
-    public final Type intType = new Type(TypeTags.INT, null);
-    public final Type longType = new Type(TypeTags.LONG, null);
-    public final Type floatType = new Type(TypeTags.FLOAT, null);
-    public final Type doubleType = new Type(TypeTags.DOUBLE, null);
-    public final Type booleanType = new Type(TypeTags.BOOLEAN, null);
+    public final Type byteType = new Type(BYTE, null);
+    public final Type charType = new Type(CHAR, null);
+    public final Type shortType = new Type(SHORT, null);
+    public final Type intType = new Type(INT, null);
+    public final Type longType = new Type(LONG, null);
+    public final Type floatType = new Type(FLOAT, null);
+    public final Type doubleType = new Type(DOUBLE, null);
+    public final Type booleanType = new Type(BOOLEAN, null);
     public final Type botType = new BottomType();
-    public final JCNoType voidType = new JCNoType(TypeTags.VOID);
+    public final JCNoType voidType = new JCNoType(VOID);
 
     private final Names names;
     private final ClassReader reader;
@@ -126,6 +127,7 @@
     public final Type cloneableType;
     public final Type serializableType;
     public final Type methodHandleType;
+    public final Type methodHandleLookupType;
     public final Type methodTypeType;
     public final Type nativeHeaderType;
     public final Type throwableType;
@@ -157,6 +159,7 @@
     public final Type systemType;
     public final Type autoCloseableType;
     public final Type trustMeType;
+    public final Type lambdaMetafactory;
     public final Type containedByType;
     public final Type containerForType;
     public final Type documentedType;
@@ -177,11 +180,11 @@
 
     /** The predefined type that belongs to a tag.
      */
-    public final Type[] typeOfTag = new Type[TypeTags.TypeTagCount];
+    public final Type[] typeOfTag = new Type[TypeTag.getTypeTagCount()];
 
     /** The name of the class that belongs to a basix type tag.
      */
-    public final Name[] boxedName = new Name[TypeTags.TypeTagCount];
+    public final Name[] boxedName = new Name[TypeTag.getTypeTagCount()];
 
     /** A set containing all operator names.
      */
@@ -202,7 +205,7 @@
 
     public void initType(Type type, ClassSymbol c) {
         type.tsym = c;
-        typeOfTag[type.tag] = type;
+        typeOfTag[type.tag.ordinal()] = type;
     }
 
     public void initType(Type type, String name) {
@@ -214,7 +217,7 @@
 
     public void initType(Type type, String name, String bname) {
         initType(type, name);
-            boxedName[type.tag] = names.fromString("java.lang." + bname);
+            boxedName[type.tag.ordinal()] = names.fromString("java.lang." + bname);
     }
 
     /** The class symbol that owns all predefined symbols.
@@ -324,7 +327,7 @@
     }
 
     public void synthesizeBoxTypeIfMissing(final Type type) {
-        ClassSymbol sym = reader.enterClass(boxedName[type.tag]);
+        ClassSymbol sym = reader.enterClass(boxedName[type.tag.ordinal()]);
         final Completer completer = sym.completer;
         if (completer != null) {
             sym.completer = new Completer() {
@@ -366,7 +369,7 @@
         target = Target.instance(context);
 
         // Create the unknown type
-        unknownType = new Type(TypeTags.UNKNOWN, null) {
+        unknownType = new Type(UNKNOWN, null) {
             @Override
             public <R, P> R accept(TypeVisitor<R, P> v, P p) {
                 return v.visitUnknown(this, p);
@@ -455,6 +458,7 @@
         throwableType = enterClass("java.lang.Throwable");
         serializableType = enterClass("java.io.Serializable");
         methodHandleType = enterClass("java.lang.invoke.MethodHandle");
+        methodHandleLookupType = enterClass("java.lang.invoke.MethodHandles$Lookup");
         methodTypeType = enterClass("java.lang.invoke.MethodType");
         errorType = enterClass("java.lang.Error");
         illegalArgumentExceptionType = enterClass("java.lang.IllegalArgumentException");
@@ -502,10 +506,12 @@
                              autoCloseableType.tsym);
         trustMeType = enterClass("java.lang.SafeVarargs");
         nativeHeaderType = enterClass("javax.tools.annotation.GenerateNativeHeader");
+        lambdaMetafactory = enterClass("java.lang.invoke.LambdaMetafactory");
 
         synthesizeEmptyInterfaceIfMissing(autoCloseableType);
         synthesizeEmptyInterfaceIfMissing(cloneableType);
         synthesizeEmptyInterfaceIfMissing(serializableType);
+        synthesizeEmptyInterfaceIfMissing(lambdaMetafactory);
         synthesizeBoxTypeIfMissing(doubleType);
         synthesizeBoxTypeIfMissing(floatType);
         synthesizeBoxTypeIfMissing(voidType);
--- a/src/share/classes/com/sun/tools/javac/code/Type.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Type.java	Fri Nov 02 17:55:34 2012 -0700
@@ -38,7 +38,7 @@
 import static com.sun.tools.javac.code.BoundKind.*;
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Kinds.*;
-import static com.sun.tools.javac.code.TypeTags.*;
+import static com.sun.tools.javac.code.TypeTag.*;
 
 /** This class represents Java types. The class itself defines the behavior of
  *  the following types:
@@ -66,7 +66,7 @@
  *  This code and its internal interfaces are subject to change or
  *  deletion without notice.</b>
  *
- *  @see TypeTags
+ *  @see TypeTag
  */
 public class Type implements PrimitiveType {
 
@@ -83,15 +83,77 @@
 
     /** The tag of this type.
      *
-     *  @see TypeTags
+     *  @see TypeTag
      */
-    public int tag;
+    protected TypeTag tag;
 
     /** The defining class / interface / package / type variable
      */
     public TypeSymbol tsym;
 
     /**
+     * Checks if the current type tag is equal to the given tag.
+     * @return true if tag is equal to the current type tag.
+     */
+    public boolean hasTag(TypeTag tag) {
+        return this.tag == tag;
+    }
+
+    /**
+     * Returns the current type tag.
+     * @return the value of the current type tag.
+     */
+    public TypeTag getTag() {
+        return tag;
+    }
+
+    public boolean isNumeric() {
+        switch (tag) {
+            case BYTE: case CHAR:
+            case SHORT:
+            case INT: case LONG:
+            case FLOAT: case DOUBLE:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    public boolean isPrimitive() {
+        return (isNumeric() || tag == BOOLEAN);
+    }
+
+    public boolean isPrimitiveOrVoid() {
+        return (isPrimitive() || tag == VOID);
+    }
+
+    public boolean isReference() {
+        switch (tag) {
+        case CLASS:
+        case ARRAY:
+        case TYPEVAR:
+        case WILDCARD:
+        case ERROR:
+            return true;
+        default:
+            return false;
+        }
+    }
+
+    public boolean isNullOrReference() {
+        return (tag == BOT || isReference());
+    }
+
+    public boolean isPartial() {
+        switch(tag) {
+            case ERROR: case UNKNOWN: case UNDETVAR:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /**
      * The constant value of this type, null if this type does not
      * have a constant value attribute. Only primitive types and
      * strings (ClassType) can have a constant value attribute.
@@ -121,7 +183,7 @@
 
     /** Define a type given its tag and type symbol
      */
-    public Type(int tag, TypeSymbol tsym) {
+    public Type(TypeTag tag, TypeSymbol tsym) {
         this.tag = tag;
         this.tsym = tsym;
     }
@@ -162,7 +224,7 @@
      */
     public Type constType(Object constValue) {
         final Object value = constValue;
-        Assert.check(tag <= BOOLEAN);
+        Assert.check(isPrimitive());
         return new Type(tag, tsym) {
                 @Override
                 public Object constValue() {
@@ -352,10 +414,6 @@
         return (tsym.flags() & FINAL) != 0;
     }
 
-    public boolean isPrimitive() {
-        return tag < VOID;
-    }
-
     /**
      * Does this type contain occurrences of type t?
      */
@@ -808,7 +866,7 @@
         }
 
         public int hashCode() {
-            return (ARRAY << 5) + elemtype.hashCode();
+            return (ARRAY.ordinal() << 5) + elemtype.hashCode();
         }
 
         public boolean isVarargs() {
@@ -915,7 +973,7 @@
         }
 
         public int hashCode() {
-            int h = METHOD;
+            int h = METHOD.ordinal();
             for (List<Type> thisargs = this.argtypes;
                  thisargs.tail != null; /*inlined: thisargs.nonEmpty()*/
                  thisargs = thisargs.tail)
@@ -1099,7 +1157,7 @@
 
     public static abstract class DelegatedType extends Type {
         public Type qtype;
-        public DelegatedType(int tag, Type qtype) {
+        public DelegatedType(TypeTag tag, Type qtype) {
             super(tag, qtype.tsym);
             this.qtype = qtype;
         }
@@ -1285,7 +1343,7 @@
     /** Represents VOID or NONE.
      */
     static class JCNoType extends Type implements NoType {
-        public JCNoType(int tag) {
+        public JCNoType(TypeTag tag) {
             super(tag, null);
         }
 
@@ -1307,7 +1365,7 @@
 
     static class BottomType extends Type implements NullType {
         public BottomType() {
-            super(TypeTags.BOT, null);
+            super(BOT, null);
         }
 
         @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/javac/code/TypeTag.java	Fri Nov 02 17:55:34 2012 -0700
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javac.code;
+
+import com.sun.source.tree.Tree.Kind;
+
+import javax.lang.model.type.TypeKind;
+
+/** An interface for type tag values, which distinguish between different
+ *  sorts of types.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public enum TypeTag {
+    /** The tag of the basic type `byte'.
+     */
+    BYTE(1),
+
+    /** The tag of the basic type `char'.
+     */
+    CHAR(2),
+
+    /** The tag of the basic type `short'.
+     */
+    SHORT(3),
+
+    /** The tag of the basic type `int'.
+     */
+    INT(4),
+
+    /** The tag of the basic type `long'.
+     */
+    LONG(5),
+
+    /** The tag of the basic type `float'.
+     */
+    FLOAT(6),
+
+    /** The tag of the basic type `double'.
+     */
+    DOUBLE(7),
+
+    /** The tag of the basic type `boolean'.
+     */
+    BOOLEAN,
+
+    /** The tag of the type `void'.
+     */
+    VOID,
+
+    /** The tag of all class and interface types.
+     */
+    CLASS,
+
+    /** The tag of all array types.
+     */
+    ARRAY,
+
+    /** The tag of all (monomorphic) method types.
+     */
+    METHOD,
+
+    /** The tag of all package "types".
+     */
+    PACKAGE,
+
+    /** The tag of all (source-level) type variables.
+     */
+    TYPEVAR,
+
+    /** The tag of all type arguments.
+     */
+    WILDCARD,
+
+    /** The tag of all polymorphic (method-) types.
+     */
+    FORALL,
+
+    /** The tag of deferred expression types in method context
+     */
+    DEFERRED,
+
+    /** The tag of the bottom type {@code <null>}.
+     */
+    BOT,
+
+    /** The tag of a missing type.
+     */
+    NONE,
+
+    /** The tag of the error type.
+     */
+    ERROR,
+
+    /** The tag of an unknown type
+     */
+    UNKNOWN,
+
+    /** The tag of all instantiatable type variables.
+     */
+    UNDETVAR,
+
+    /** Pseudo-types, these are special tags
+     */
+    UNINITIALIZED_THIS,
+
+    UNINITIALIZED_OBJECT;
+
+    /** This field will only be used for tags related with numeric types for
+     *  optimization reasons.
+     */
+    private int order = 0;
+
+    private TypeTag() {}
+
+    private TypeTag(int order) {
+        this.order = order;
+    }
+
+    private static final int MIN_NUMERIC_TAG_ORDER = 1;
+    private static final int MAX_NUMERIC_TAG_ORDER = 7;
+
+    /** Returns the number of type tags.
+     */
+    public static int getTypeTagCount() {
+        // last two tags are not included in the total as long as they are pseudo-types
+        return (UNDETVAR.ordinal() + 1);
+    }
+
+    public boolean isSubRangeOf(TypeTag range) {
+        return (this == range) || isStrictSubRangeOf(range);
+    }
+
+    public boolean isStrictSubRangeOf(TypeTag range) {
+        if (this.order >= MIN_NUMERIC_TAG_ORDER && this.order <= MAX_NUMERIC_TAG_ORDER &&
+            range.order >= MIN_NUMERIC_TAG_ORDER && this.order <= MAX_NUMERIC_TAG_ORDER) {
+            if (this == range)
+                return false;
+            switch (this) {
+                case BYTE:
+                    return true;
+                case CHAR: case SHORT: case INT:
+                case LONG: case FLOAT:
+                    return this.order < range.order && range.order <= MAX_NUMERIC_TAG_ORDER;
+                default:
+                    return false;
+            }
+        }
+        else
+            return false;
+    }
+
+    public Kind getKindLiteral() {
+        switch (this) {
+        case INT:
+            return Kind.INT_LITERAL;
+        case LONG:
+            return Kind.LONG_LITERAL;
+        case FLOAT:
+            return Kind.FLOAT_LITERAL;
+        case DOUBLE:
+            return Kind.DOUBLE_LITERAL;
+        case BOOLEAN:
+            return Kind.BOOLEAN_LITERAL;
+        case CHAR:
+            return Kind.CHAR_LITERAL;
+        case CLASS:
+            return Kind.STRING_LITERAL;
+        case BOT:
+            return Kind.NULL_LITERAL;
+        default:
+            throw new AssertionError("unknown literal kind " + this);
+        }
+    }
+
+    public TypeKind getPrimitiveTypeKind() {
+        switch (this) {
+        case BOOLEAN:
+            return TypeKind.BOOLEAN;
+        case BYTE:
+            return TypeKind.BYTE;
+        case SHORT:
+            return TypeKind.SHORT;
+        case INT:
+            return TypeKind.INT;
+        case LONG:
+            return TypeKind.LONG;
+        case CHAR:
+            return TypeKind.CHAR;
+        case FLOAT:
+            return TypeKind.FLOAT;
+        case DOUBLE:
+            return TypeKind.DOUBLE;
+        case VOID:
+            return TypeKind.VOID;
+        default:
+            throw new AssertionError("unknown primitive type " + this);
+        }
+    }
+}
--- a/src/share/classes/com/sun/tools/javac/code/TypeTags.java	Thu Nov 01 14:13:13 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.tools.javac.code;
-
-
-/** An interface for type tag values, which distinguish between different
- *  sorts of types.
- *
- *  <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 TypeTags {
-
-    private TypeTags() {} // uninstantiable
-
-    /** The tag of the basic type `byte'.
-     */
-    public static final int BYTE = 1;
-
-    /** The tag of the basic type `char'.
-     */
-    public static final int CHAR = BYTE+1;
-
-    /** The tag of the basic type `short'.
-     */
-    public static final int SHORT = CHAR+1;
-
-    /** The tag of the basic type `int'.
-     */
-    public static final int INT = SHORT+1;
-
-    /** The tag of the basic type `long'.
-     */
-    public static final int LONG = INT+1;
-
-    /** The tag of the basic type `float'.
-     */
-    public static final int FLOAT = LONG+1;
-
-    /** The tag of the basic type `double'.
-     */
-    public static final int DOUBLE = FLOAT+1;
-
-    /** The tag of the basic type `boolean'.
-     */
-    public static final int BOOLEAN = DOUBLE+1;
-
-    /** The tag of the type `void'.
-     */
-    public static final int VOID = BOOLEAN+1;
-
-    /** The tag of all class and interface types.
-     */
-    public static final int CLASS = VOID+1;
-
-    /** The tag of all array types.
-     */
-    public static final int ARRAY = CLASS+1;
-
-    /** The tag of all (monomorphic) method types.
-     */
-    public static final int METHOD = ARRAY+1;
-
-    /** The tag of all package "types".
-     */
-    public static final int PACKAGE = METHOD+1;
-
-    /** The tag of all (source-level) type variables.
-     */
-    public static final int TYPEVAR = PACKAGE+1;
-
-    /** The tag of all type arguments.
-     */
-    public static final int WILDCARD = TYPEVAR+1;
-
-    /** The tag of all polymorphic (method-) types.
-     */
-    public static final int FORALL = WILDCARD+1;
-
-    /** The tag of deferred expression types in method context
-     */
-    public static final int DEFERRED = FORALL+1;
-
-    /** The tag of the bottom type {@code <null>}.
-     */
-    public static final int BOT = DEFERRED+1;
-
-    /** The tag of a missing type.
-     */
-    public static final int NONE = BOT+1;
-
-    /** The tag of the error type.
-     */
-    public static final int ERROR = NONE+1;
-
-    /** The tag of an unknown type
-     */
-    public static final int UNKNOWN = ERROR+1;
-
-    /** The tag of all instantiatable type variables.
-     */
-    public static final int UNDETVAR = UNKNOWN+1;
-
-    /** The number of type tags.
-     */
-    public static final int TypeTagCount = UNDETVAR+1;
-
-    /** The maximum tag of a basic type.
-     */
-    public static final int lastBaseTag = BOOLEAN;
-
-    /** The minimum tag of a partial type
-     */
-    public static final int firstPartialTag = ERROR;
-}
--- a/src/share/classes/com/sun/tools/javac/code/Types.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Fri Nov 02 17:55:34 2012 -0700
@@ -40,7 +40,7 @@
 import static com.sun.tools.javac.code.Scope.*;
 import static com.sun.tools.javac.code.Symbol.*;
 import static com.sun.tools.javac.code.Type.*;
-import static com.sun.tools.javac.code.TypeTags.*;
+import static com.sun.tools.javac.code.TypeTag.*;
 import static com.sun.tools.javac.util.ListBuffer.lb;
 
 /**
@@ -605,8 +605,8 @@
     }
     //where
         private boolean isSubtypeUncheckedInternal(Type t, Type s, Warner warn) {
-            if (t.tag == ARRAY && s.tag == ARRAY) {
-                if (((ArrayType)t).elemtype.tag <= lastBaseTag) {
+            if (t.hasTag(ARRAY) && s.hasTag(ARRAY)) {
+                if (((ArrayType)t).elemtype.isPrimitive()) {
                     return isSameType(elemtype(t), elemtype(s));
                 } else {
                     return isSubtypeUnchecked(elemtype(t), elemtype(s), warn);
@@ -664,7 +664,7 @@
         if (t == s)
             return true;
 
-        if (s.tag >= firstPartialTag)
+        if (s.isPartial())
             return isSuperType(s, t);
 
         if (s.isCompound()) {
@@ -686,25 +686,27 @@
         {
             public Boolean visitType(Type t, Type s) {
                 switch (t.tag) {
-                case BYTE: case CHAR:
-                    return (t.tag == s.tag ||
-                              t.tag + 2 <= s.tag && s.tag <= DOUBLE);
-                case SHORT: case INT: case LONG: case FLOAT: case DOUBLE:
-                    return t.tag <= s.tag && s.tag <= DOUBLE;
-                case BOOLEAN: case VOID:
-                    return t.tag == s.tag;
-                case TYPEVAR:
-                    return isSubtypeNoCapture(t.getUpperBound(), s);
-                case BOT:
-                    return
-                        s.tag == BOT || s.tag == CLASS ||
-                        s.tag == ARRAY || s.tag == TYPEVAR;
-                case WILDCARD: //we shouldn't be here - avoids crash (see 7034495)
-                case NONE:
-                    return false;
-                default:
-                    throw new AssertionError("isSubtype " + t.tag);
-                }
+                 case BYTE:
+                     return (!s.hasTag(CHAR) && t.getTag().isSubRangeOf(s.getTag()));
+                 case CHAR:
+                     return (!s.hasTag(SHORT) && t.getTag().isSubRangeOf(s.getTag()));
+                 case SHORT: case INT: case LONG:
+                 case FLOAT: case DOUBLE:
+                     return t.getTag().isSubRangeOf(s.getTag());
+                 case BOOLEAN: case VOID:
+                     return t.hasTag(s.getTag());
+                 case TYPEVAR:
+                     return isSubtypeNoCapture(t.getUpperBound(), s);
+                 case BOT:
+                     return
+                         s.hasTag(BOT) || s.hasTag(CLASS) ||
+                         s.hasTag(ARRAY) || s.hasTag(TYPEVAR);
+                 case WILDCARD: //we shouldn't be here - avoids crash (see 7034495)
+                 case NONE:
+                     return false;
+                 default:
+                     throw new AssertionError("isSubtype " + t.tag);
+                 }
             }
 
             private Set<TypePair> cache = new HashSet<TypePair>();
@@ -774,7 +776,7 @@
             @Override
             public Boolean visitArrayType(ArrayType t, Type s) {
                 if (s.tag == ARRAY) {
-                    if (t.elemtype.tag <= lastBaseTag)
+                    if (t.elemtype.isPrimitive())
                         return isSameType(t.elemtype, elemtype(s));
                     else
                         return isSubtypeNoCapture(t.elemtype, elemtype(s));
@@ -907,7 +909,7 @@
                 if (t == s)
                     return true;
 
-                if (s.tag >= firstPartialTag)
+                if (s.isPartial())
                     return visit(s, t);
 
                 switch (t.tag) {
@@ -936,7 +938,7 @@
 
             @Override
             public Boolean visitWildcardType(WildcardType t, Type s) {
-                if (s.tag >= firstPartialTag)
+                if (s.isPartial())
                     return visit(s, t);
                 else
                     return false;
@@ -947,7 +949,7 @@
                 if (t == s)
                     return true;
 
-                if (s.tag >= firstPartialTag)
+                if (s.isPartial())
                     return visit(s, t);
 
                 if (s.isSuperBound() && !s.isExtendsBound())
@@ -976,10 +978,10 @@
                 if (t == s)
                     return true;
 
-                if (s.tag >= firstPartialTag)
+                if (s.isPartial())
                     return visit(s, t);
 
-                return s.tag == ARRAY
+                return s.hasTag(ARRAY)
                     && containsTypeEquivalent(t.elemtype, elemtype(s));
             }
 
@@ -1120,7 +1122,7 @@
             }
 
             public Boolean visitType(Type t, Type s) {
-                if (s.tag >= firstPartialTag)
+                if (s.isPartial())
                     return containedBy(s, t);
                 else
                     return isSameType(t, s);
@@ -1142,7 +1144,7 @@
 
             @Override
             public Boolean visitWildcardType(WildcardType t, Type s) {
-                if (s.tag >= firstPartialTag)
+                if (s.isPartial())
                     return containedBy(s, t);
                 else {
 //                    debugContainsType(t, s);
@@ -1232,7 +1234,7 @@
                 switch (t.tag) {
                 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
                 case DOUBLE:
-                    return s.tag <= DOUBLE;
+                    return s.isNumeric();
                 case BOOLEAN:
                     return s.tag == BOOLEAN;
                 case VOID:
@@ -1373,8 +1375,7 @@
                 case CLASS:
                     return isSubtype(t, s);
                 case ARRAY:
-                    if (elemtype(t).tag <= lastBaseTag ||
-                            elemtype(s).tag <= lastBaseTag) {
+                    if (elemtype(t).isPrimitive() || elemtype(s).isPrimitive()) {
                         return elemtype(t).tag == elemtype(s).tag;
                     } else {
                         return visit(elemtype(t), elemtype(s));
@@ -1648,8 +1649,8 @@
      */
     public ArrayType makeArrayType(Type t) {
         if (t.tag == VOID ||
-            t.tag >= PACKAGE) {
-            Assert.error("Type t must not be a a VOID or PACKAGE type, " + t.toString());
+            t.tag == PACKAGE) {
+            Assert.error("Type t must not be a VOID or PACKAGE type, " + t.toString());
         }
         return new ArrayType(t, syms.arrayClass);
     }
@@ -1847,7 +1848,7 @@
     public boolean isAssignable(Type t, Type s, Warner warn) {
         if (t.tag == ERROR)
             return true;
-        if (t.tag <= INT && t.constValue() != null) {
+        if (t.tag.isSubRangeOf(INT) && t.constValue() != null) {
             int value = ((Number)t.constValue()).intValue();
             switch (s.tag) {
             case BYTE:
@@ -1891,11 +1892,11 @@
         // We don't want to erase primitive types and String type as that
         // operation is idempotent. Also, erasing these could result in loss
         // of information such as constant values attached to such types.
-        return (t.tag <= lastBaseTag) || (syms.stringType.tsym == t.tsym);
+        return (t.isPrimitive()) || (syms.stringType.tsym == t.tsym);
     }
 
     private Type erasure(Type t, boolean recurse) {
-        if (t.tag <= lastBaseTag)
+        if (t.isPrimitive())
             return t; /* fast special case */
         else
             return erasure.visit(t, recurse);
@@ -1903,7 +1904,7 @@
     // where
         private SimpleVisitor<Type, Boolean> erasure = new SimpleVisitor<Type, Boolean>() {
             public Type visitType(Type t, Boolean recurse) {
-                if (t.tag <= lastBaseTag)
+                if (t.isPrimitive())
                     return t; /*fast special case*/
                 else
                     return t.map(recurse ? erasureRecFun : erasureFun);
@@ -3314,7 +3315,7 @@
         private static final UnaryVisitor<Integer> hashCode = new UnaryVisitor<Integer>() {
 
             public Integer visitType(Type t, Void ignored) {
-                return t.tag;
+                return t.tag.ordinal();
             }
 
             @Override
@@ -3430,7 +3431,7 @@
      * Return the class that boxes the given primitive.
      */
     public ClassSymbol boxedClass(Type t) {
-        return reader.enterClass(syms.boxedName[t.tag]);
+        return reader.enterClass(syms.boxedName[t.tag.ordinal()]);
     }
 
     /**
--- a/src/share/classes/com/sun/tools/javac/comp/Annotate.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Annotate.java	Fri Nov 02 17:55:34 2012 -0700
@@ -34,6 +34,8 @@
 import com.sun.tools.javac.tree.*;
 import com.sun.tools.javac.tree.JCTree.*;
 
+import static com.sun.tools.javac.code.TypeTag.ARRAY;
+import static com.sun.tools.javac.code.TypeTag.CLASS;
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
 
 /** Enter annotations on symbols.  Annotations accumulate in a queue,
@@ -289,7 +291,7 @@
             }
             return enterAnnotation((JCAnnotation)tree, expected, env);
         }
-        if (expected.tag == TypeTags.ARRAY) { // should really be isArray()
+        if (expected.hasTag(ARRAY)) { // should really be isArray()
             if (!tree.hasTag(NEWARRAY)) {
                 tree = make.at(tree.pos).
                     NewArray(null, List.<JCExpression>nil(), List.of(tree));
@@ -309,7 +311,7 @@
             return new Attribute.
                 Array(expected, buf.toArray(new Attribute[buf.length()]));
         }
-        if (expected.tag == TypeTags.CLASS &&
+        if (expected.hasTag(CLASS) &&
             (expected.tsym.flags() & Flags.ENUM) != 0) {
             attr.attribExpr(tree, env, expected);
             Symbol sym = TreeInfo.symbol(tree);
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Nov 02 17:55:34 2012 -0700
@@ -56,8 +56,8 @@
 import static com.sun.tools.javac.code.Flags.BLOCK;
 import static com.sun.tools.javac.code.Kinds.*;
 import static com.sun.tools.javac.code.Kinds.ERRONEOUS;
-import static com.sun.tools.javac.code.TypeTags.*;
-import static com.sun.tools.javac.code.TypeTags.WILDCARD;
+import static com.sun.tools.javac.code.TypeTag.*;
+import static com.sun.tools.javac.code.TypeTag.WILDCARD;
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
 
 /** This is the main context-dependent analysis phase in GJC. It
@@ -227,14 +227,13 @@
      *  are correct.
      *
      *  @param tree     The tree whose kind and type is checked
-     *  @param owntype  The computed type of the tree
      *  @param ownkind  The computed kind of the tree
      *  @param resultInfo  The expected result of the tree
      */
     Type check(final JCTree tree, final Type found, final int ownkind, final ResultInfo resultInfo) {
         InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext();
         Type owntype = found;
-        if (owntype.tag != ERROR && resultInfo.pt.tag != METHOD && resultInfo.pt.tag != FORALL) {
+        if (!owntype.hasTag(ERROR) && !resultInfo.pt.hasTag(METHOD) && !resultInfo.pt.hasTag(FORALL)) {
             if (inferenceContext.free(found)) {
                 inferenceContext.addFreeTypeListener(List.of(found, resultInfo.pt), new FreeTypeListener() {
                     @Override
@@ -606,7 +605,7 @@
     /** Derived visitor method: attribute an expression tree.
      */
     public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt) {
-        return attribTree(tree, env, new ResultInfo(VAL, pt.tag != ERROR ? pt : Type.noType));
+        return attribTree(tree, env, new ResultInfo(VAL, !pt.hasTag(ERROR) ? pt : Type.noType));
     }
 
     /** Derived visitor method: attribute an expression tree with
@@ -806,7 +805,7 @@
                    boolean checkExtensible) {
         if (t.isErroneous())
             return t;
-        if (t.tag == TYPEVAR && !classExpected && !interfaceExpected) {
+        if (t.hasTag(TYPEVAR) && !classExpected && !interfaceExpected) {
             // check that type variable is already visible
             if (t.getUpperBound() == null) {
                 log.error(tree.pos(), "illegal.forward.ref");
@@ -1208,7 +1207,7 @@
                             }
                         } else {
                             Type pattype = attribExpr(c.pat, switchEnv, seltype);
-                            if (pattype.tag != ERROR) {
+                            if (!pattype.hasTag(ERROR)) {
                                 if (pattype.constValue() == null) {
                                     log.error(c.pat.pos(),
                                               (stringSwitch ? "string.const.req" : "const.expr.req"));
@@ -1379,10 +1378,10 @@
         Type condtype = attribExpr(tree.cond, env, syms.booleanType);
 
         boolean standaloneConditional = !allowPoly ||
-                pt().tag == NONE && pt() != Type.recoveryType ||
+                pt().hasTag(NONE) && pt() != Type.recoveryType ||
                 isBooleanOrNumeric(env, tree);
 
-        if (!standaloneConditional && resultInfo.pt.tag == VOID) {
+        if (!standaloneConditional && resultInfo.pt.hasTag(VOID)) {
             //cannot get here (i.e. it means we are returning from void method - which is already an error)
             result = tree.type = types.createErrorType(resultInfo.pt);
             return;
@@ -1416,7 +1415,8 @@
         @SuppressWarnings("fallthrough")
         private boolean isBooleanOrNumeric(Env<AttrContext> env, JCExpression tree) {
             switch (tree.getTag()) {
-                case LITERAL: return ((JCLiteral)tree).typetag < CLASS;
+                case LITERAL: return ((JCLiteral)tree).typetag.isSubRangeOf(DOUBLE) ||
+                              ((JCLiteral)tree).typetag == BOOLEAN;
                 case LAMBDA: case REFERENCE: return false;
                 case PARENS: return isBooleanOrNumeric(env, ((JCParens)tree).expr);
                 case CONDEXPR:
@@ -1426,7 +1426,7 @@
                 default:
                     Type speculativeType = deferredAttr.attribSpeculative(tree, env, unknownExprInfo).type;
                     speculativeType = types.unboxedTypeOrType(speculativeType);
-                    return speculativeType.tag <= BOOLEAN;
+                    return speculativeType.isPrimitive();
             }
         }
 
@@ -1459,16 +1459,19 @@
                 // If one arm has an integer subrange type (i.e., byte,
                 // short, or char), and the other is an integer constant
                 // that fits into the subrange, return the subrange type.
-                if (thenUnboxed.tag < INT && elseUnboxed.tag == INT &&
+                if (thenUnboxed.getTag().isStrictSubRangeOf(INT) && elseUnboxed.hasTag(INT) &&
                     types.isAssignable(elseUnboxed, thenUnboxed))
                     return thenUnboxed.baseType();
-                if (elseUnboxed.tag < INT && thenUnboxed.tag == INT &&
+                if (elseUnboxed.getTag().isStrictSubRangeOf(INT) && thenUnboxed.hasTag(INT) &&
                     types.isAssignable(thenUnboxed, elseUnboxed))
                     return elseUnboxed.baseType();
 
-                for (int i = BYTE; i < VOID; i++) {
-                    Type candidate = syms.typeOfTag[i];
-                    if (types.isSubtype(thenUnboxed, candidate) &&
+                for (TypeTag tag : TypeTag.values()) {
+                    if (tag.ordinal() >= TypeTag.getTypeTagCount()) break;
+                    Type candidate = syms.typeOfTag[tag.ordinal()];
+                    if (candidate != null &&
+                        candidate.isPrimitive() &&
+                        types.isSubtype(thenUnboxed, candidate) &&
                         types.isSubtype(elseUnboxed, candidate))
                         return candidate;
                 }
@@ -1487,7 +1490,7 @@
             if (types.isSubtype(elsetype, thentype))
                 return thentype.baseType();
 
-            if (!allowBoxing || thentype.tag == VOID || elsetype.tag == VOID) {
+            if (!allowBoxing || thentype.hasTag(VOID) || elsetype.hasTag(VOID)) {
                 log.error(pos, "neither.conditional.subtype",
                           thentype, elsetype);
                 return thentype.baseType();
@@ -1601,12 +1604,12 @@
             // Attribute return expression, if it exists, and check that
             // it conforms to result type of enclosing method.
             if (tree.expr != null) {
-                if (env.info.returnResult.pt.tag == VOID) {
+                if (env.info.returnResult.pt.hasTag(VOID)) {
                     log.error(tree.expr.pos(),
                               "cant.ret.val.from.meth.decl.void");
                 }
                 attribTree(tree.expr, env, env.info.returnResult);
-            } else if (env.info.returnResult.pt.tag != VOID) {
+            } else if (!env.info.returnResult.pt.hasTag(VOID)) {
                 log.error(tree.pos(), "missing.ret.val");
             }
         }
@@ -1671,11 +1674,11 @@
                     }
                 }
 
-                if (site.tag == CLASS) {
+                if (site.hasTag(CLASS)) {
                     Type encl = site.getEnclosingType();
-                    while (encl != null && encl.tag == TYPEVAR)
+                    while (encl != null && encl.hasTag(TYPEVAR))
                         encl = encl.getUpperBound();
-                    if (encl.tag == CLASS) {
+                    if (encl.hasTag(CLASS)) {
                         // we are calling a nested class
 
                         if (tree.meth.hasTag(SELECT)) {
@@ -1740,7 +1743,7 @@
 
             // Compute the result type.
             Type restype = mtype.getReturnType();
-            if (restype.tag == WILDCARD)
+            if (restype.hasTag(WILDCARD))
                 throw new AssertionError(mtype);
 
             Type qualifier = (tree.meth.hasTag(SELECT))
@@ -1870,7 +1873,7 @@
                 }
             }
         } else if (!clazztype.tsym.isInterface() &&
-                   clazztype.getEnclosingType().tag == CLASS) {
+                   clazztype.getEnclosingType().hasTag(CLASS)) {
             // Check for the existence of an apropos outer instance
             rs.resolveImplicitThis(tree.pos(), env, clazztype);
         }
@@ -1880,7 +1883,7 @@
         List<Type> typeargtypes = attribTypes(tree.typeargs, localEnv);
 
         // If we have made no mistakes in the class type...
-        if (clazztype.tag == CLASS) {
+        if (clazztype.hasTag(CLASS)) {
             // Enums may not be instantiated except implicitly
             if (allowEnums &&
                 (clazztype.tsym.flags_field&Flags.ENUM) != 0 &&
@@ -2058,7 +2061,7 @@
                             resultInfo.checkContext.inferenceContext().free(resultInfo.pt) ? Type.noType : pt());
                     Type inferred = deferredAttr.attribSpeculative(tree, env, findDiamondResult).type;
                     if (!inferred.isErroneous() &&
-                        types.isAssignable(inferred, pt().tag == NONE ? syms.objectType : pt(), Warner.noWarnings)) {
+                        types.isAssignable(inferred, pt().hasTag(NONE) ? syms.objectType : pt(), Warner.noWarnings)) {
                         String key = types.isSameType(clazztype, inferred) ?
                             "diamond.redundant.args" :
                             "diamond.redundant.args.1";
@@ -2073,8 +2076,8 @@
             private void checkLambdaCandidate(JCNewClass tree, ClassSymbol csym, Type clazztype) {
                 if (allowLambda &&
                         identifyLambdaCandidate &&
-                        clazztype.tag == CLASS &&
-                        pt().tag != NONE &&
+                        clazztype.hasTag(CLASS) &&
+                        !pt().hasTag(NONE) &&
                         types.isFunctionalInterface(clazztype.tsym)) {
                     Symbol descriptor = types.findDescriptorSymbol(clazztype.tsym);
                     int count = 0;
@@ -2125,10 +2128,10 @@
         } else {
             // we are seeing an untyped aggregate { ... }
             // this is allowed only if the prototype is an array
-            if (pt().tag == ARRAY) {
+            if (pt().hasTag(ARRAY)) {
                 elemtype = types.elemtype(pt());
             } else {
-                if (pt().tag != ERROR) {
+                if (!pt().hasTag(ERROR)) {
                     log.error(tree.pos(), "illegal.initializer.for.type",
                               pt());
                 }
@@ -2152,8 +2155,8 @@
      */
     @Override
     public void visitLambda(final JCLambda that) {
-        if (pt().isErroneous() || (pt().tag == NONE && pt() != Type.recoveryType)) {
-            if (pt().tag == NONE) {
+        if (pt().isErroneous() || (pt().hasTag(NONE) && pt() != Type.recoveryType)) {
+            if (pt().hasTag(NONE)) {
                 //lambda only allowed in assignment or method invocation/cast context
                 log.error(that.pos(), "unexpected.lambda");
             }
@@ -2328,7 +2331,7 @@
             //this amounts at checking that, if a lambda body can complete normally,
             //the descriptor's return type must be void
             if (tree.getBodyKind() == JCLambda.BodyKind.STATEMENT && tree.canCompleteNormally &&
-                    returnType.tag != VOID && returnType != Type.recoveryType) {
+                    !returnType.hasTag(VOID) && returnType != Type.recoveryType) {
                 checkContext.report(tree, diags.fragment("incompatible.ret.type.in.lambda",
                         diags.fragment("missing.ret.val", returnType)));
             }
@@ -2363,8 +2366,8 @@
 
     @Override
     public void visitReference(final JCMemberReference that) {
-        if (pt().isErroneous() || (pt().tag == NONE && pt() != Type.recoveryType)) {
-            if (pt().tag == NONE) {
+        if (pt().isErroneous() || (pt().hasTag(NONE) && pt() != Type.recoveryType)) {
+            if (pt().hasTag(NONE)) {
                 //method reference only allowed in assignment or method invocation/cast context
                 log.error(that.pos(), "unexpected.mref");
             }
@@ -2465,7 +2468,7 @@
 
             ResultInfo checkInfo =
                     resultInfo.dup(newMethodTemplate(
-                        desc.getReturnType().tag == VOID ? Type.noType : desc.getReturnType(),
+                        desc.getReturnType().hasTag(VOID) ? Type.noType : desc.getReturnType(),
                         lookupHelper.argtypes,
                         typeargtypes));
 
@@ -2510,11 +2513,11 @@
 
         Type incompatibleReturnType = resType;
 
-        if (returnType.tag == VOID) {
+        if (returnType.hasTag(VOID)) {
             incompatibleReturnType = null;
         }
 
-        if (returnType.tag != VOID && resType.tag != VOID) {
+        if (!returnType.hasTag(VOID) && !resType.hasTag(VOID)) {
             if (resType.isErroneous() ||
                     new LambdaReturnContext(checkContext).compatible(resType, returnType, Warner.noWarnings)) {
                 incompatibleReturnType = null;
@@ -2711,7 +2714,7 @@
         attribExpr(tree.index, env, syms.intType);
         if (types.isArray(atype))
             owntype = types.elemtype(atype);
-        else if (atype.tag != ERROR)
+        else if (!atype.hasTag(ERROR))
             log.error(tree.pos(), "array.req.but.found", atype);
         if ((pkind() & VAR) == 0) owntype = capture(owntype);
         result = check(tree, owntype, VAR, resultInfo);
@@ -2721,7 +2724,7 @@
         Symbol sym;
 
         // Find symbol
-        if (pt().tag == METHOD || pt().tag == FORALL) {
+        if (pt().hasTag(METHOD) || pt().hasTag(FORALL)) {
             // If we are looking for a method, the prototype `pt' will be a
             // method type with the type of the call's arguments as parameters.
             env.info.pendingResolutionPhase = null;
@@ -2811,9 +2814,9 @@
         // don't allow T.class T[].class, etc
         if (skind == TYP) {
             Type elt = site;
-            while (elt.tag == ARRAY)
+            while (elt.hasTag(ARRAY))
                 elt = ((ArrayType)elt).elemtype;
-            if (elt.tag == TYPEVAR) {
+            if (elt.hasTag(TYPEVAR)) {
                 log.error(tree.pos(), "type.var.cant.be.deref");
                 result = types.createErrorType(tree.type);
                 return;
@@ -2839,8 +2842,8 @@
         boolean varArgs = env.info.lastResolveVarargs();
         tree.sym = sym;
 
-        if (site.tag == TYPEVAR && !isType(sym) && sym.kind != ERR) {
-            while (site.tag == TYPEVAR) site = site.getUpperBound();
+        if (site.hasTag(TYPEVAR) && !isType(sym) && sym.kind != ERR) {
+            while (site.hasTag(TYPEVAR)) site = site.getUpperBound();
             site = capture(site);
         }
 
@@ -2929,14 +2932,14 @@
                                  ResultInfo resultInfo) {
             DiagnosticPosition pos = tree.pos();
             Name name = tree.name;
-            switch (site.tag) {
+            switch (site.getTag()) {
             case PACKAGE:
                 return rs.accessBase(
                     rs.findIdentInPackage(env, site.tsym, name, resultInfo.pkind),
                     pos, location, site, name, true);
             case ARRAY:
             case CLASS:
-                if (resultInfo.pt.tag == METHOD || resultInfo.pt.tag == FORALL) {
+                if (resultInfo.pt.hasTag(METHOD) || resultInfo.pt.hasTag(FORALL)) {
                     return rs.resolveQualifiedMethod(
                         pos, env, location, site, name, resultInfo.pt.getParameterTypes(), resultInfo.pt.getTypeArguments());
                 } else if (name == names._this || name == names._super) {
@@ -3029,7 +3032,7 @@
                      Symbol sym,
                      Env<AttrContext> env,
                      ResultInfo resultInfo) {
-            Type pt = resultInfo.pt.tag == FORALL || resultInfo.pt.tag == METHOD ?
+            Type pt = resultInfo.pt.hasTag(FORALL) || resultInfo.pt.hasTag(METHOD) ?
                     resultInfo.pt.map(deferredAttr.new DeferredTypeMap(AttrMode.SPECULATIVE, sym, env.info.pendingResolutionPhase)) :
                     resultInfo.pt;
 
@@ -3046,7 +3049,8 @@
                 // For types, the computed type equals the symbol's type,
                 // except for two situations:
                 owntype = sym.type;
-                if (owntype.tag == CLASS) {
+                if (owntype.hasTag(CLASS)) {
+                    chk.checkForBadAuxiliaryClassAccess(tree.pos(), env, (ClassSymbol)sym);
                     Type ownOuter = owntype.getEnclosingType();
 
                     // (a) If the symbol's type is parameterized, erase it
@@ -3066,9 +3070,9 @@
                     //
                     // Then the type of the last expression above is
                     // Tree<Point>.Visitor.
-                    else if (ownOuter.tag == CLASS && site != ownOuter) {
+                    else if (ownOuter.hasTag(CLASS) && site != ownOuter) {
                         Type normOuter = site;
-                        if (normOuter.tag == CLASS)
+                        if (normOuter.hasTag(CLASS))
                             normOuter = types.asEnclosingSuper(site, ownOuter.tsym);
                         if (normOuter == null) // perhaps from an import
                             normOuter = types.erasure(ownOuter);
@@ -3087,7 +3091,7 @@
                     resultInfo.pkind == VAR &&
                     v.owner.kind == TYP &&
                     (v.flags() & STATIC) == 0 &&
-                    (site.tag == CLASS || site.tag == TYPEVAR)) {
+                    (site.hasTag(CLASS) || site.hasTag(TYPEVAR))) {
                     Type s = types.asOuterSuper(site, v.owner);
                     if (s != null &&
                         s.isRaw() &&
@@ -3266,7 +3270,7 @@
         // an unchecked warning if its argument types change under erasure.
         if (allowGenerics &&
             (sym.flags() & STATIC) == 0 &&
-            (site.tag == CLASS || site.tag == TYPEVAR)) {
+            (site.hasTag(CLASS) || site.hasTag(TYPEVAR))) {
             Type s = types.asOuterSuper(site, sym.owner);
             if (s != null && s.isRaw() &&
                 !types.isSameTypes(sym.type.getParameterTypes(),
@@ -3312,12 +3316,12 @@
     //where
     /** Return the type of a literal with given type tag.
      */
-    Type litType(int tag) {
-        return (tag == TypeTags.CLASS) ? syms.stringType : syms.typeOfTag[tag];
+    Type litType(TypeTag tag) {
+        return (tag == CLASS) ? syms.stringType : syms.typeOfTag[tag.ordinal()];
     }
 
     public void visitTypeIdent(JCPrimitiveTypeTree tree) {
-        result = check(tree, syms.typeOfTag[tree.typetag], TYP, resultInfo);
+        result = check(tree, syms.typeOfTag[tree.typetag.ordinal()], TYP, resultInfo);
     }
 
     public void visitTypeArray(JCArrayTypeTree tree) {
@@ -3339,7 +3343,7 @@
         // Attribute type parameters
         List<Type> actuals = attribTypes(tree.arguments, env);
 
-        if (clazztype.tag == CLASS) {
+        if (clazztype.hasTag(CLASS)) {
             List<Type> formals = clazztype.tsym.type.getTypeArguments();
             if (actuals.isEmpty()) //diamond
                 actuals = formals;
@@ -3354,7 +3358,7 @@
                 }
                 // Compute the proper generic outer
                 Type clazzOuter = clazztype.getEnclosingType();
-                if (clazzOuter.tag == CLASS) {
+                if (clazzOuter.hasTag(CLASS)) {
                     Type site;
                     JCExpression clazz = TreeInfo.typeIn(tree.clazz);
                     if (clazz.hasTag(IDENT)) {
@@ -3362,8 +3366,8 @@
                     } else if (clazz.hasTag(SELECT)) {
                         site = ((JCFieldAccess) clazz).selected.type;
                     } else throw new AssertionError(""+tree);
-                    if (clazzOuter.tag == CLASS && site != clazzOuter) {
-                        if (site.tag == CLASS)
+                    if (clazzOuter.hasTag(CLASS) && site != clazzOuter) {
+                        if (site.hasTag(CLASS))
                             site = types.asOuterSuper(site, clazzOuter.tsym);
                         if (site == null)
                             site = types.erasure(clazzOuter);
@@ -3419,7 +3423,7 @@
             }
         }
         Type t = check(tree, types.lub(multicatchTypes.toList()), TYP, resultInfo);
-        if (t.tag == CLASS) {
+        if (t.hasTag(CLASS)) {
             List<Type> alternatives =
                 ((all_multicatchTypes == null) ? multicatchTypes : all_multicatchTypes).toList();
             t = new UnionClassType((ClassType) t, alternatives);
@@ -3440,7 +3444,7 @@
             if (b.isErroneous()) {
                 a.bound = b;
             }
-            else if (b.tag == TYPEVAR) {
+            else if (b.hasTag(TYPEVAR)) {
                 // if first bound was a typevar, do not accept further bounds.
                 if (tree.bounds.tail.nonEmpty()) {
                     log.error(tree.bounds.tail.head.pos(),
@@ -3456,7 +3460,7 @@
                     Type i = checkBase(bs.head, bound, env, false, true, false);
                     if (i.isErroneous())
                         a.bound = i;
-                    else if (i.tag == CLASS)
+                    else if (i.hasTag(CLASS))
                         chk.checkNotRepeated(bound.pos(), types.erasure(i), boundSet);
                 }
             }
@@ -3568,7 +3572,7 @@
      *  @param c   The class symbol whose definition will be attributed.
      */
     void attribClass(ClassSymbol c) throws CompletionFailure {
-        if (c.type.tag == ERROR) return;
+        if (c.type.hasTag(ERROR)) return;
 
         // Check for cycles in the inheritance graph, which can arise from
         // ill-formed class files.
@@ -3577,11 +3581,11 @@
         Type st = types.supertype(c.type);
         if ((c.flags_field & Flags.COMPOUND) == 0) {
             // First, attribute superclass.
-            if (st.tag == CLASS)
+            if (st.hasTag(CLASS))
                 attribClass((ClassSymbol)st.tsym);
 
             // Next attribute owner, if it is a class.
-            if (c.owner.kind == TYP && c.owner.type.tag == CLASS)
+            if (c.owner.kind == TYP && c.owner.type.hasTag(CLASS))
                 attribClass((ClassSymbol)c.owner);
         }
 
@@ -3793,7 +3797,7 @@
                         TreeInfo.diagnosticPositionFor(svuid, tree), "improper.SVUID", c);
 
             // check that it is long
-            else if (svuid.type.tag != TypeTags.LONG)
+            else if (!svuid.type.hasTag(LONG))
                 log.warning(LintCategory.SERIAL,
                         TreeInfo.diagnosticPositionFor(svuid, tree), "long.SVUID", c);
 
--- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Fri Nov 02 17:55:34 2012 -0700
@@ -27,6 +27,7 @@
 
 import java.util.*;
 import java.util.Set;
+import javax.tools.JavaFileManager;
 
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.jvm.*;
@@ -48,8 +49,8 @@
 import static com.sun.tools.javac.code.Flags.ANNOTATION;
 import static com.sun.tools.javac.code.Flags.SYNCHRONIZED;
 import static com.sun.tools.javac.code.Kinds.*;
-import static com.sun.tools.javac.code.TypeTags.*;
-import static com.sun.tools.javac.code.TypeTags.WILDCARD;
+import static com.sun.tools.javac.code.TypeTag.*;
+import static com.sun.tools.javac.code.TypeTag.WILDCARD;
 
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
 
@@ -77,6 +78,7 @@
     private boolean suppressAbortOnBadClassFile;
     private boolean enableSunApiLintControl;
     private final TreeInfo treeinfo;
+    private final JavaFileManager fileManager;
 
     // The set of lint options currently in effect. It is initialized
     // from the context, and then is set/reset as needed by Attr as it
@@ -109,6 +111,7 @@
         Options options = Options.instance(context);
         lint = Lint.instance(context);
         treeinfo = TreeInfo.instance(context);
+        fileManager = context.get(JavaFileManager.class);
 
         Source source = Source.instance(context);
         allowGenerics = source.allowGenerics();
@@ -280,7 +283,7 @@
     Type typeTagError(DiagnosticPosition pos, Object required, Object found) {
         // this error used to be raised by the parser,
         // but has been delayed to this point:
-        if (found instanceof Type && ((Type)found).tag == VOID) {
+        if (found instanceof Type && ((Type)found).hasTag(VOID)) {
             log.error(pos, "illegal.start.of.type");
             return syms.errType;
         }
@@ -358,7 +361,7 @@
             for (Scope.Entry e = s.next.lookup(c.name);
                  e.scope != null && e.sym.owner == c.owner;
                  e = e.next()) {
-                if (e.sym.kind == TYP && e.sym.type.tag != TYPEVAR &&
+                if (e.sym.kind == TYP && !e.sym.type.hasTag(TYPEVAR) &&
                     (e.sym.owner.kind & (VAR | MTH)) != 0 &&
                     c.name != names.error) {
                     duplicateError(pos, e.sym);
@@ -527,14 +530,14 @@
                 }
             });
         }
-        if (req.tag == ERROR)
+        if (req.hasTag(ERROR))
             return req;
-        if (req.tag == NONE)
+        if (req.hasTag(NONE))
             return found;
         if (checkContext.compatible(found, req, checkContext.checkWarner(pos, found, req))) {
             return found;
         } else {
-            if (found.tag <= DOUBLE && req.tag <= DOUBLE) {
+            if (found.getTag().isSubRangeOf(DOUBLE) && req.getTag().isSubRangeOf(DOUBLE)) {
                 checkContext.report(pos, diags.fragment("possible.loss.of.precision", found, req));
                 return types.createErrorType(found);
             }
@@ -594,7 +597,7 @@
          *  type variables?
          */
         boolean isTypeVar(Type t) {
-            return t.tag == TYPEVAR || t.tag == ARRAY && isTypeVar(types.elemtype(t));
+            return t.hasTag(TYPEVAR) || t.hasTag(ARRAY) && isTypeVar(types.elemtype(t));
         }
 
     /** Check that a type is within some bounds.
@@ -607,7 +610,7 @@
     private boolean checkExtends(Type a, Type bound) {
          if (a.isUnbound()) {
              return true;
-         } else if (a.tag != WILDCARD) {
+         } else if (!a.hasTag(WILDCARD)) {
              a = types.upperBound(a);
              return types.isSubtype(a, bound);
          } else if (a.isExtendsBound()) {
@@ -623,7 +626,7 @@
      *  @param t             The type to be checked.
      */
     Type checkNonVoid(DiagnosticPosition pos, Type t) {
-        if (t.tag == VOID) {
+        if (t.hasTag(VOID)) {
             log.error(pos, "void.not.allowed.here");
             return types.createErrorType(t);
         } else {
@@ -636,10 +639,10 @@
      *  @param t             The type to be checked.
      */
     Type checkClassType(DiagnosticPosition pos, Type t) {
-        if (t.tag != CLASS && t.tag != ERROR)
+        if (!t.hasTag(CLASS) && !t.hasTag(ERROR))
             return typeTagError(pos,
                                 diags.fragment("type.req.class"),
-                                (t.tag == TYPEVAR)
+                                (t.hasTag(TYPEVAR))
                                 ? diags.fragment("type.parameter", t)
                                 : t);
         else
@@ -650,7 +653,7 @@
      */
     Type checkConstructorRefType(DiagnosticPosition pos, Type t) {
         t = checkClassType(pos, t);
-        if (t.tag == CLASS) {
+        if (t.hasTag(CLASS)) {
             if ((t.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) {
                 log.error(pos, "abstract.cant.be.instantiated");
                 t = types.createErrorType(t);
@@ -672,7 +675,7 @@
         if (noBounds && t.isParameterized()) {
             List<Type> args = t.getTypeArguments();
             while (args.nonEmpty()) {
-                if (args.head.tag == WILDCARD)
+                if (args.head.hasTag(WILDCARD))
                     return typeTagError(pos,
                                         diags.fragment("type.req.exact"),
                                         args.head);
@@ -687,7 +690,7 @@
      *  @param t             The type to be checked.
      */
     Type checkReifiableReferenceType(DiagnosticPosition pos, Type t) {
-        if (t.tag != CLASS && t.tag != ARRAY && t.tag != ERROR) {
+        if (!t.hasTag(CLASS) && !t.hasTag(ARRAY) && !t.hasTag(ERROR)) {
             return typeTagError(pos,
                                 diags.fragment("type.req.class.array"),
                                 t);
@@ -705,18 +708,12 @@
      *  @param t             The type to be checked.
      */
     Type checkRefType(DiagnosticPosition pos, Type t) {
-        switch (t.tag) {
-        case CLASS:
-        case ARRAY:
-        case TYPEVAR:
-        case WILDCARD:
-        case ERROR:
+        if (t.isReference())
             return t;
-        default:
+        else
             return typeTagError(pos,
                                 diags.fragment("type.req.ref"),
                                 t);
-        }
     }
 
     /** Check that each type is a reference type, i.e. a class, interface or array type
@@ -738,19 +735,12 @@
      *  @param t             The type to be checked.
      */
     Type checkNullOrRefType(DiagnosticPosition pos, Type t) {
-        switch (t.tag) {
-        case CLASS:
-        case ARRAY:
-        case TYPEVAR:
-        case WILDCARD:
-        case BOT:
-        case ERROR:
+        if (t.isNullOrReference())
             return t;
-        default:
+        else
             return typeTagError(pos,
                                 diags.fragment("type.req.ref"),
                                 t);
-        }
     }
 
     /** Check that flag set does not contain elements of two conflicting sets. s
@@ -1054,7 +1044,7 @@
             bounds = bounds_buf.toList();
 
             for (Type arg : types.capture(type).getTypeArguments()) {
-                if (arg.tag == TYPEVAR &&
+                if (arg.hasTag(TYPEVAR) &&
                         arg.getUpperBound().isErroneous() &&
                         !bounds.head.isErroneous() &&
                         !isTypeArgErroneous(args.head)) {
@@ -1309,7 +1299,7 @@
 
         @Override
         public void visitTypeApply(JCTypeApply tree) {
-            if (tree.type.tag == CLASS) {
+            if (tree.type.hasTag(CLASS)) {
                 List<JCExpression> args = tree.arguments;
                 List<Type> forms = tree.type.tsym.type.getTypeArguments();
 
@@ -1360,7 +1350,7 @@
 
         @Override
         public void visitSelect(JCFieldAccess tree) {
-            if (tree.type.tag == CLASS) {
+            if (tree.type.hasTag(CLASS)) {
                 visitSelectInternal(tree);
 
                 // Check that this type is either fully parameterized, or
@@ -1409,7 +1399,7 @@
 
         void checkRaw(JCTree tree, Env<AttrContext> env) {
             if (lint.isEnabled(LintCategory.RAW) &&
-                tree.type.tag == CLASS &&
+                tree.type.hasTag(CLASS) &&
                 !TreeInfo.isDiamond(tree) &&
                 !withinAnonConstr(env) &&
                 tree.type.isRaw()) {
@@ -1511,9 +1501,9 @@
      */
     boolean isUnchecked(Type exc) {
         return
-            (exc.tag == TYPEVAR) ? isUnchecked(types.supertype(exc)) :
-            (exc.tag == CLASS) ? isUnchecked((ClassSymbol)exc.tsym) :
-            exc.tag == BOT;
+            (exc.hasTag(TYPEVAR)) ? isUnchecked(types.supertype(exc)) :
+            (exc.hasTag(CLASS)) ? isUnchecked((ClassSymbol)exc.tsym) :
+            exc.hasTag(BOT);
     }
 
     /** Same, but handling completion failures.
@@ -1759,7 +1749,7 @@
             // case, we will have dealt with when examining the supertype classes
             ClassSymbol mc = m.enclClass();
             Type st = types.supertype(origin.type);
-            if (st.tag != CLASS)
+            if (!st.hasTag(CLASS))
                 return true;
             MethodSymbol stimpl = m.implementation((ClassSymbol)st.tsym, types, false);
 
@@ -1782,7 +1772,7 @@
      */
     public void checkCompatibleConcretes(DiagnosticPosition pos, Type site) {
         Type sup = types.supertype(site);
-        if (sup.tag != CLASS) return;
+        if (!sup.hasTag(CLASS)) return;
 
         for (Type t1 = sup;
              t1.tsym.type.isParameterized();
@@ -1803,7 +1793,7 @@
                 if (st1 == s1.type) continue;
 
                 for (Type t2 = sup;
-                     t2.tag == CLASS;
+                     t2.hasTag(CLASS);
                      t2 = types.supertype(t2)) {
                     for (Scope.Entry e2 = t2.tsym.members().lookup(s1.name);
                          e2.scope != null;
@@ -1876,7 +1866,7 @@
 
     /** Compute all the supertypes of t, indexed by type symbol. */
     private void closure(Type t, Map<TypeSymbol,Type> typeMap) {
-        if (t.tag != CLASS) return;
+        if (!t.hasTag(CLASS)) return;
         if (typeMap.put(t.tsym, t) == null) {
             closure(types.supertype(t), typeMap);
             for (Type i : types.interfaces(t))
@@ -1886,7 +1876,7 @@
 
     /** Compute all the supertypes of t, indexed by type symbol (except thise in typesSkip). */
     private void closure(Type t, Map<TypeSymbol,Type> typesSkip, Map<TypeSymbol,Type> typeMap) {
-        if (t.tag != CLASS) return;
+        if (!t.hasTag(CLASS)) return;
         if (typesSkip.get(t.tsym) != null) return;
         if (typeMap.put(t.tsym, t) == null) {
             closure(types.supertype(t), typesSkip, typeMap);
@@ -1916,7 +1906,8 @@
                     Type rt2 = types.subst(st2.getReturnType(), tvars2, tvars1);
                     boolean compat =
                         types.isSameType(rt1, rt2) ||
-                        rt1.tag >= CLASS && rt2.tag >= CLASS &&
+                        !rt1.isPrimitiveOrVoid() &&
+                        !rt2.isPrimitiveOrVoid() &&
                         (types.covariantReturnType(rt1, rt2, Warner.noWarnings) ||
                          types.covariantReturnType(rt2, rt1, Warner.noWarnings)) ||
                          checkCommonOverriderIn(s1,s2,site);
@@ -1961,7 +1952,8 @@
                     Type rt13 = types.subst(st3.getReturnType(), tvars3, tvars1);
                     Type rt23 = types.subst(st3.getReturnType(), tvars3, tvars2);
                     boolean compat =
-                        rt13.tag >= CLASS && rt23.tag >= CLASS &&
+                        !rt13.isPrimitiveOrVoid() &&
+                        !rt23.isPrimitiveOrVoid() &&
                         (types.covariantReturnType(rt13, rt1, Warner.noWarnings) &&
                          types.covariantReturnType(rt23, rt2, Warner.noWarnings));
                     if (compat)
@@ -1984,7 +1976,7 @@
                 log.error(tree.pos(), "enum.no.finalize");
                 return;
             }
-        for (Type t = origin.type; t.tag == CLASS;
+        for (Type t = origin.type; t.hasTag(CLASS);
              t = types.supertype(t)) {
             if (t != origin.type) {
                 checkOverride(tree, t, origin, m);
@@ -2064,7 +2056,7 @@
                 }
                 if (undef == null) {
                     Type st = types.supertype(c.type);
-                    if (st.tag == CLASS)
+                    if (st.hasTag(CLASS))
                         undef = firstUndef(impl, (ClassSymbol)st.tsym);
                 }
                 for (List<Type> l = types.interfaces(c.type);
@@ -2155,7 +2147,7 @@
             } else if (!c.type.isErroneous()) {
                 try {
                     seenClasses = seenClasses.prepend(c);
-                    if (c.type.tag == CLASS) {
+                    if (c.type.hasTag(CLASS)) {
                         if (supertypes.nonEmpty()) {
                             scan(supertypes);
                         }
@@ -2200,13 +2192,13 @@
 
     private void checkNonCyclic1(DiagnosticPosition pos, Type t, List<TypeVar> seen) {
         final TypeVar tv;
-        if  (t.tag == TYPEVAR && (t.tsym.flags() & UNATTRIBUTED) != 0)
+        if  (t.hasTag(TYPEVAR) && (t.tsym.flags() & UNATTRIBUTED) != 0)
             return;
         if (seen.contains(t)) {
             tv = (TypeVar)t;
             tv.bound = types.createErrorType(t);
             log.error(pos, "cyclic.inheritance", t);
-        } else if (t.tag == TYPEVAR) {
+        } else if (t.hasTag(TYPEVAR)) {
             tv = (TypeVar)t;
             seen = seen.prepend(tv);
             for (Type b : types.getBounds(tv))
@@ -2232,14 +2224,14 @@
         } else if (!c.type.isErroneous()) {
             try {
                 c.flags_field |= LOCKED;
-                if (c.type.tag == CLASS) {
+                if (c.type.hasTag(CLASS)) {
                     ClassType clazz = (ClassType)c.type;
                     if (clazz.interfaces_field != null)
                         for (List<Type> l=clazz.interfaces_field; l.nonEmpty(); l=l.tail)
                             complete &= checkNonCyclicInternal(pos, l.head);
                     if (clazz.supertype_field != null) {
                         Type st = clazz.supertype_field;
-                        if (st != null && st.tag == CLASS)
+                        if (st != null && st.hasTag(CLASS))
                             complete &= checkNonCyclicInternal(pos, st);
                     }
                     if (c.owner.kind == TYP)
@@ -2261,7 +2253,7 @@
         for (List<Type> l=types.interfaces(c.type); l.nonEmpty(); l=l.tail)
             l.head = types.createErrorType((ClassSymbol)l.head.tsym, Type.noType);
         Type st = types.supertype(c.type);
-        if (st.tag == CLASS)
+        if (st.hasTag(CLASS))
             ((ClassType)c.type).supertype_field = types.createErrorType((ClassSymbol)st.tsym, Type.noType);
         c.type = types.createErrorType(c, c.type);
         c.flags_field |= ACYCLIC;
@@ -2313,7 +2305,7 @@
     void checkCompatibleSupertypes(DiagnosticPosition pos, Type c) {
         List<Type> supertypes = types.interfaces(c);
         Type supertype = types.supertype(c);
-        if (supertype.tag == CLASS &&
+        if (supertype.hasTag(CLASS) &&
             (supertype.tsym.flags() & ABSTRACT) != 0)
             supertypes = supertypes.prepend(supertype);
         for (List<Type> l = supertypes; l.nonEmpty(); l = l.tail) {
@@ -2542,7 +2534,7 @@
      * @jls 9.6 Annotation Types
      */
     void validateAnnotationMethod(DiagnosticPosition pos, MethodSymbol m) {
-        for (Type sup = syms.annotationType; sup.tag == CLASS; sup = types.supertype(sup)) {
+        for (Type sup = syms.annotationType; sup.hasTag(CLASS); sup = types.supertype(sup)) {
             Scope s = sup.tsym.members();
             for (Scope.Entry e = s.lookup(m.name); e.scope != null; e = e.next()) {
                 if (e.sym.kind == MTH &&
@@ -2855,7 +2847,7 @@
                 { if (s.kind == TYP ||
                       s.kind == VAR ||
                       (s.kind == MTH && !s.isConstructor() &&
-                       s.type.getReturnType().tag != VOID))
+                       !s.type.getReturnType().hasTag(VOID)))
                     return true;
                 }
             else
@@ -3016,12 +3008,12 @@
     }
 
     void checkAnnotationResType(DiagnosticPosition pos, Type type) {
-        switch (type.tag) {
-        case TypeTags.CLASS:
+        switch (type.getTag()) {
+        case CLASS:
             if ((type.tsym.flags() & ANNOTATION) != 0)
                 checkNonCyclicElementsInternal(pos, type.tsym);
             break;
-        case TypeTags.ARRAY:
+        case ARRAY:
             checkAnnotationResType(pos, types.elemtype(type));
             break;
         default:
@@ -3114,7 +3106,7 @@
     void checkDivZero(DiagnosticPosition pos, Symbol operator, Type operand) {
         if (operand.constValue() != null
             && lint.isEnabled(LintCategory.DIVZERO)
-            && operand.tag <= LONG
+            && (operand.getTag().isSubRangeOf(LONG))
             && ((Number) (operand.constValue())).longValue() == 0) {
             int opc = ((OperatorSymbol)operator).opcode;
             if (opc == ByteCodes.idiv || opc == ByteCodes.imod
@@ -3241,6 +3233,19 @@
             return true;
         }
 
+    /** Check that an auxiliary class is not accessed from any other file than its own.
+     */
+    void checkForBadAuxiliaryClassAccess(DiagnosticPosition pos, Env<AttrContext> env, ClassSymbol c) {
+        if (lint.isEnabled(Lint.LintCategory.AUXILIARYCLASS) &&
+            (c.flags() & AUXILIARY) != 0 &&
+            rs.isAccessible(env, c) &&
+            !fileManager.isSameFile(c.sourcefile, env.toplevel.sourcefile))
+        {
+            log.warning(pos, "auxiliary.class.accessed.from.outside.of.its.source.file",
+                        c, c.sourcefile);
+        }
+    }
+
     private class ConversionWarner extends Warner {
         final String uncheckedKey;
         final Type found;
--- a/src/share/classes/com/sun/tools/javac/comp/ConstFold.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/ConstFold.java	Fri Nov 02 17:55:34 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,8 @@
 
 import com.sun.tools.javac.code.Type.*;
 
-import static com.sun.tools.javac.code.TypeTags.*;
+import static com.sun.tools.javac.code.TypeTag.BOOLEAN;
+
 import static com.sun.tools.javac.jvm.ByteCodes.*;
 
 /** Helper class for constant folding, used by the attribution phase.
@@ -176,19 +177,19 @@
                 case imod:
                     return syms.intType.constType(intValue(l) % intValue(r));
                 case iand:
-                    return (left.tag == BOOLEAN
+                    return (left.hasTag(BOOLEAN)
                       ? syms.booleanType : syms.intType)
                       .constType(intValue(l) & intValue(r));
                 case bool_and:
                     return syms.booleanType.constType(b2i((intValue(l) & intValue(r)) != 0));
                 case ior:
-                    return (left.tag == BOOLEAN
+                    return (left.hasTag(BOOLEAN)
                       ? syms.booleanType : syms.intType)
                       .constType(intValue(l) | intValue(r));
                 case bool_or:
                     return syms.booleanType.constType(b2i((intValue(l) | intValue(r)) != 0));
                 case ixor:
-                    return (left.tag == BOOLEAN
+                    return (left.hasTag(BOOLEAN)
                       ? syms.booleanType : syms.intType)
                       .constType(intValue(l) ^ intValue(r));
                 case ishl: case ishll:
@@ -326,7 +327,7 @@
 
     /** Coerce constant type to target type.
      *  @param etype      The source type of the coercion,
-     *                    which is assumed to be a constant type compatble with
+     *                    which is assumed to be a constant type compatible with
      *                    ttype.
      *  @param ttype      The target type of the coercion.
      */
@@ -334,9 +335,9 @@
          // WAS if (etype.baseType() == ttype.baseType())
          if (etype.tsym.type == ttype.tsym.type)
              return etype;
-         if (etype.tag <= DOUBLE) {
+         if (etype.isNumeric()) {
              Object n = etype.constValue();
-             switch (ttype.tag) {
+             switch (ttype.getTag()) {
              case BYTE:
                  return syms.byteType.constType(0 + (byte)intValue(n));
              case CHAR:
--- a/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Fri Nov 02 17:55:34 2012 -0700
@@ -44,7 +44,8 @@
 import java.util.Set;
 import java.util.WeakHashMap;
 
-import static com.sun.tools.javac.code.TypeTags.*;
+import static com.sun.tools.javac.code.TypeTag.DEFERRED;
+import static com.sun.tools.javac.code.TypeTag.NONE;
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
 
 /**
@@ -203,7 +204,7 @@
                         case SPECULATIVE:
                             Assert.check(mode == null ||
                                     (mode == AttrMode.SPECULATIVE &&
-                                    speculativeType(deferredAttrContext.msym, deferredAttrContext.phase).tag == NONE));
+                                    speculativeType(deferredAttrContext.msym, deferredAttrContext.phase).hasTag(NONE)));
                             JCTree speculativeTree = attribSpeculative(tree, env, resultInfo);
                             speculativeCache.put(deferredAttrContext.msym, speculativeTree, deferredAttrContext.phase);
                             return speculativeTree.type;
@@ -442,7 +443,7 @@
 
         @Override
         public Type apply(Type t) {
-            if (t.tag != DEFERRED) {
+            if (!t.hasTag(DEFERRED)) {
                 return t.map(this);
             } else {
                 DeferredType dt = (DeferredType)t;
@@ -479,7 +480,7 @@
         @Override
         protected Type typeOf(DeferredType dt) {
             Type owntype = super.typeOf(dt);
-            return owntype.tag == NONE ?
+            return owntype.hasTag(NONE) ?
                         recover(dt) : owntype;
         }
 
@@ -516,7 +517,7 @@
      */
     @SuppressWarnings("fallthrough")
     List<Type> stuckVars(JCTree tree, ResultInfo resultInfo) {
-        if (resultInfo.pt.tag == NONE || resultInfo.pt.isErroneous()) {
+        if (resultInfo.pt.hasTag(NONE) || resultInfo.pt.isErroneous()) {
             return List.nil();
         } else {
             StuckChecker sc = new StuckChecker(resultInfo);
--- a/src/share/classes/com/sun/tools/javac/comp/Enter.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Enter.java	Fri Nov 02 17:55:34 2012 -0700
@@ -49,7 +49,7 @@
  *  the symbol table. The pass consists of two phases, organized as
  *  follows:
  *
- *  <p>In the first phase, all class symbols are intered into their
+ *  <p>In the first phase, all class symbols are entered into their
  *  enclosing scope, descending recursively down the tree for classes
  *  which are members of other classes. The class symbols are given a
  *  MemberEnter object as completer.
--- a/src/share/classes/com/sun/tools/javac/comp/Flow.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Flow.java	Fri Nov 02 17:55:34 2012 -0700
@@ -40,7 +40,8 @@
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Flags.BLOCK;
 import static com.sun.tools.javac.code.Kinds.*;
-import static com.sun.tools.javac.code.TypeTags.*;
+import static com.sun.tools.javac.code.TypeTag.BOOLEAN;
+import static com.sun.tools.javac.code.TypeTag.VOID;
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
 
 /** This pass implements dataflow analysis for Java programs though
@@ -473,7 +474,7 @@
                 alive = true;
                 scanStat(tree.body);
 
-                if (alive && tree.sym.type.getReturnType().tag != VOID)
+                if (alive && !tree.sym.type.getReturnType().hasTag(VOID))
                     log.error(TreeInfo.diagEndPos(tree.body), "missing.ret.stmt");
 
                 List<PendingExit> exits = pendingExits.toList();
@@ -1976,8 +1977,8 @@
             Bits uninitsBeforeElse = uninitsWhenFalse;
             inits = initsWhenTrue;
             uninits = uninitsWhenTrue;
-            if (tree.truepart.type.tag == BOOLEAN &&
-                tree.falsepart.type.tag == BOOLEAN) {
+            if (tree.truepart.type.hasTag(BOOLEAN) &&
+                tree.falsepart.type.hasTag(BOOLEAN)) {
                 // if b and c are boolean valued, then
                 // v is (un)assigned after a?b:c when true iff
                 //    v is (un)assigned after b when true and
--- a/src/share/classes/com/sun/tools/javac/comp/Infer.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java	Fri Nov 02 17:55:34 2012 -0700
@@ -42,7 +42,7 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import static com.sun.tools.javac.code.TypeTags.*;
+import static com.sun.tools.javac.code.TypeTag.*;
 
 /** Helper class for type parameter inference, used by the attribution phase.
  *
@@ -145,7 +145,7 @@
     private Filter<Type> boundFilter = new Filter<Type>() {
         @Override
         public boolean accepts(Type t) {
-            return !t.isErroneous() && t.tag != BOT;
+            return !t.isErroneous() && !t.hasTag(BOT);
         }
     };
 
@@ -163,7 +163,7 @@
             else {
                 that.inst = types.lub(lobounds);
             }
-            if (that.inst == null || that.inst.tag == ERROR)
+            if (that.inst == null || that.inst.hasTag(ERROR))
                     throw inferenceException
                         .setMessage("no.unique.minimal.instance.exists",
                                     that.qtype, lobounds);
@@ -189,13 +189,13 @@
             Attr.ResultInfo resultInfo,
             Warner warn) throws InferenceException {
         Type to = resultInfo.pt;
-        if (to.tag == NONE || resultInfo.checkContext.inferenceContext().free(resultInfo.pt)) {
-            to = mtype.getReturnType().tag <= VOID ?
+        if (to.hasTag(NONE) || resultInfo.checkContext.inferenceContext().free(resultInfo.pt)) {
+            to = mtype.getReturnType().isPrimitiveOrVoid() ?
                     mtype.getReturnType() : syms.objectType;
         }
         Type qtype1 = inferenceContext.asFree(mtype.getReturnType(), types);
         if (!types.isSubtype(qtype1,
-                qtype1.tag == UNDETVAR ? types.boxedTypeOrType(to) : to)) {
+                qtype1.hasTag(UNDETVAR) ? types.boxedTypeOrType(to) : to)) {
             throw inferenceException
                     .setMessage("infer.no.conforming.instance.exists",
                     inferenceContext.restvars(), mtype.getReturnType(), to);
@@ -515,7 +515,7 @@
             //for remaining uninferred type-vars in the functional interface type,
             //simply replace the wildcards with its bound
             for (Type t : formalInterface.getTypeArguments()) {
-                if (actualTypeargs.head.tag == WILDCARD) {
+                if (actualTypeargs.head.hasTag(WILDCARD)) {
                     WildcardType wt = (WildcardType)actualTypeargs.head;
                     typeargs.append(wt.type);
                 } else {
@@ -592,7 +592,7 @@
 
             public Type apply(Type t) {
                 t = types.erasure(super.apply(t));
-                if (t.tag == BOT)
+                if (t.hasTag(BOT))
                     // nulls type as the marker type Null (which has no instances)
                     // infer as java.lang.Void for now
                     t = types.boxedClass(syms.voidType).type;
@@ -614,7 +614,7 @@
         }
 
         public Type apply(Type t) {
-            if (t.tag == TYPEVAR) return new UndetVar((TypeVar)t, types, includeBounds);
+            if (t.hasTag(TYPEVAR)) return new UndetVar((TypeVar)t, types, includeBounds);
             else return t.map(this);
         }
     };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Fri Nov 02 17:55:34 2012 -0700
@@ -0,0 +1,1398 @@
+/*
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.javac.comp;
+
+import com.sun.tools.javac.tree.*;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.*;
+import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
+import com.sun.tools.javac.tree.TreeMaker;
+import com.sun.tools.javac.tree.TreeScanner;
+import com.sun.tools.javac.tree.TreeTranslator;
+import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.code.Kinds;
+import com.sun.tools.javac.code.Symbol;
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.code.Symbol.DynamicMethodSymbol;
+import com.sun.tools.javac.code.Symbol.MethodSymbol;
+import com.sun.tools.javac.code.Symbol.VarSymbol;
+import com.sun.tools.javac.code.Symtab;
+import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.code.Type.ClassType;
+import com.sun.tools.javac.code.Type.MethodType;
+import com.sun.tools.javac.code.Types;
+import com.sun.tools.javac.comp.LambdaToMethod.LambdaAnalyzer.*;
+import com.sun.tools.javac.jvm.*;
+import com.sun.tools.javac.util.*;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
+import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import static com.sun.tools.javac.comp.LambdaToMethod.LambdaSymbolKind.*;
+import static com.sun.tools.javac.code.Flags.*;
+import static com.sun.tools.javac.code.Kinds.*;
+import static com.sun.tools.javac.code.TypeTag.BOT;
+import static com.sun.tools.javac.code.TypeTag.NONE;
+import static com.sun.tools.javac.code.TypeTag.VOID;
+import static com.sun.tools.javac.tree.JCTree.Tag.*;
+
+/**
+ * This pass desugars lambda expressions into static methods
+ *
+ *  <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 LambdaToMethod extends TreeTranslator {
+
+    private Names names;
+    private Symtab syms;
+    private Resolve rs;
+    private TreeMaker make;
+    private Types types;
+    private TransTypes transTypes;
+    private Env<AttrContext> attrEnv;
+
+    /** the analyzer scanner */
+    private LambdaAnalyzer analyzer;
+
+    /** map from lambda trees to translation contexts */
+    private Map<JCTree, TranslationContext<?>> contextMap;
+
+    /** current translation context (visitor argument) */
+    private TranslationContext<?> context;
+
+    /** list of translated methods
+     **/
+    private ListBuffer<JCTree> translatedMethodList;
+
+    // <editor-fold defaultstate="collapsed" desc="Instantiating">
+    private static final Context.Key<LambdaToMethod> unlambdaKey =
+            new Context.Key<LambdaToMethod>();
+
+    public static LambdaToMethod instance(Context context) {
+        LambdaToMethod instance = context.get(unlambdaKey);
+        if (instance == null) {
+            instance = new LambdaToMethod(context);
+        }
+        return instance;
+    }
+
+    private LambdaToMethod(Context context) {
+        names = Names.instance(context);
+        syms = Symtab.instance(context);
+        rs = Resolve.instance(context);
+        make = TreeMaker.instance(context);
+        types = Types.instance(context);
+        transTypes = TransTypes.instance(context);
+        this.analyzer = makeAnalyzer();
+    }
+
+    private LambdaAnalyzer makeAnalyzer() {
+        return new LambdaAnalyzer();
+    }
+    // </editor-fold>
+
+    // <editor-fold defaultstate="collapsed" desc="translate methods">
+    @Override
+    public <T extends JCTree> T translate(T tree) {
+        TranslationContext<?> newContext = contextMap.get(tree);
+        return translate(tree, newContext != null ? newContext : context);
+    }
+
+    public <T extends JCTree> T translate(T tree, TranslationContext<?> newContext) {
+        TranslationContext<?> prevContext = context;
+        try {
+            context = newContext;
+            return super.translate(tree);
+        }
+        finally {
+            context = prevContext;
+        }
+    }
+
+    public <T extends JCTree> List<T> translate(List<T> trees, TranslationContext<?> newContext) {
+        ListBuffer<T> buf = ListBuffer.lb();
+        for (T tree : trees) {
+            buf.append(translate(tree, newContext));
+        }
+        return buf.toList();
+    }
+
+    public JCTree translateTopLevelClass(Env<AttrContext> env, JCTree cdef, TreeMaker make) {
+        this.make = make;
+        this.attrEnv = env;
+        this.context = null;
+        this.contextMap = new HashMap<JCTree, TranslationContext<?>>();
+        return translate(cdef);
+    }
+    // </editor-fold>
+
+    // <editor-fold defaultstate="collapsed" desc="visitor methods">
+    /**
+     * Visit a class.
+     * Maintain the translatedMethodList across nested classes.
+     * Append the translatedMethodList to the class after it is translated.
+     * @param tree
+     */
+    @Override
+    public void visitClassDef(JCClassDecl tree) {
+        if (tree.sym.owner.kind == PCK) {
+            //analyze class
+            analyzer.analyzeClass(tree);
+        }
+        ListBuffer<JCTree> prevTranslated = translatedMethodList;
+        try {
+            translatedMethodList = ListBuffer.lb();
+            super.visitClassDef(tree);
+            //add all translated instance methods here
+            tree.defs = tree.defs.appendList(translatedMethodList.toList());
+            for (JCTree lambda : translatedMethodList) {
+                tree.sym.members().enter(((JCMethodDecl)lambda).sym);
+            }
+            result = tree;
+        } finally {
+            translatedMethodList = prevTranslated;
+        }
+    }
+
+    /**
+     * Translate a lambda into a method to be inserted into the class.
+     * Then replace the lambda site with an invokedynamic call of to lambda
+     * meta-factory, which will use the lambda method.
+     * @param tree
+     */
+    @Override
+    public void visitLambda(JCLambda tree) {
+        LambdaTranslationContext localContext = (LambdaTranslationContext)context;
+        MethodSymbol sym = (MethodSymbol)localContext.translatedSym;
+        MethodType lambdaType = (MethodType) sym.type;
+
+        //create the method declaration hoisting the lambda body
+        JCMethodDecl lambdaDecl = make.MethodDef(make.Modifiers(sym.flags_field),
+                sym.name,
+                make.QualIdent(lambdaType.getReturnType().tsym),
+                List.<JCTypeParameter>nil(),
+                localContext.syntheticParams,
+                lambdaType.getThrownTypes() == null ?
+                    List.<JCExpression>nil() :
+                    make.Types(lambdaType.getThrownTypes()),
+                null,
+                null);
+        lambdaDecl.sym = sym;
+        lambdaDecl.type = lambdaType;
+
+        //translate lambda body
+        //As the lambda body is translated, all references to lambda locals,
+        //captured variables, enclosing members are adjusted accordingly
+        //to refer to the static method parameters (rather than i.e. acessing to
+        //captured members directly).
+        lambdaDecl.body = translate(makeLambdaBody(tree, lambdaDecl));
+
+        //Add the method to the list of methods to be added to this class.
+        translatedMethodList = translatedMethodList.prepend(lambdaDecl);
+
+        //now that we have generated a method for the lambda expression,
+        //we can translate the lambda into a method reference pointing to the newly
+        //created method.
+        //
+        //Note that we need to adjust the method handle so that it will match the
+        //signature of the SAM descriptor - this means that the method reference
+        //should be added the following synthetic arguments:
+        //
+        // * the "this" argument if it is an instance method
+        // * enclosing locals captured by the lambda expression
+
+        ListBuffer<JCExpression> syntheticInits = ListBuffer.lb();
+
+        if (!sym.isStatic()) {
+            syntheticInits.append(makeThis(
+                    sym.owner.asType(),
+                    localContext.owner.enclClass()));
+        }
+
+        //add captured locals
+        for (Symbol fv : localContext.getSymbolMap(CAPTURED_VAR).keySet()) {
+            if (fv != localContext.self) {
+                JCTree captured_local = make.Ident(fv).setType(fv.type);
+                syntheticInits.append((JCExpression) captured_local);
+            }
+        }
+
+        //then, determine the arguments to the indy call
+        List<JCExpression> indy_args = translate(syntheticInits.toList(), localContext.prev);
+
+        //build a sam instance using an indy call to the meta-factory
+        int refKind = referenceKind(sym);
+
+        //convert to an invokedynamic call
+        result = makeMetaFactoryIndyCall(tree, tree.targetType, refKind, sym, indy_args);
+    }
+
+    private JCIdent makeThis(Type type, Symbol owner) {
+        VarSymbol _this = new VarSymbol(PARAMETER | FINAL | SYNTHETIC,
+                names._this,
+                type,
+                owner);
+        return make.Ident(_this);
+    }
+
+    /**
+     * Translate a method reference into an invokedynamic call to the
+     * meta-factory.
+     * @param tree
+     */
+    @Override
+    public void visitReference(JCMemberReference tree) {
+        ReferenceTranslationContext localContext = (ReferenceTranslationContext)context;
+
+        //first determine the method symbol to be used to generate the sam instance
+        //this is either the method reference symbol, or the bridged reference symbol
+        Symbol refSym = localContext.needsBridge() ?
+            localContext.bridgeSym :
+            tree.sym;
+
+        //build the bridge method, if needed
+        if (localContext.needsBridge()) {
+            bridgeMemberReference(tree, localContext);
+        }
+
+        //the qualifying expression is treated as a special captured arg
+        JCExpression init;
+        switch(tree.kind) {
+
+            case IMPLICIT_INNER:    /** Inner # new */
+            case SUPER:             /** super # instMethod */
+                init = makeThis(
+                    localContext.owner.owner.asType(),
+                    localContext.owner);
+                break;
+
+            case BOUND:             /** Expr # instMethod */
+                init = tree.getQualifierExpression();
+                break;
+
+            case STATIC_EVAL:       /** Expr # staticMethod */
+            case UNBOUND:           /** Type # instMethod */
+            case STATIC:            /** Type # staticMethod */
+            case TOPLEVEL:          /** Top level # new */
+                init = null;
+                break;
+
+            default:
+                throw new InternalError("Should not have an invalid kind");
+        }
+
+        List<JCExpression> indy_args = init==null? List.<JCExpression>nil() : translate(List.of(init), localContext.prev);
+
+
+        //build a sam instance using an indy call to the meta-factory
+        result = makeMetaFactoryIndyCall(tree, tree.targetType, localContext.referenceKind(), refSym, indy_args);
+
+        //if we had a static reference with non-static qualifier, add a let
+        //expression to force the evaluation of the qualifier expr
+        if (tree.hasKind(ReferenceKind.STATIC_EVAL)) {
+            VarSymbol rec = new VarSymbol(0, names.fromString("rec$"), tree.getQualifierExpression().type, localContext.owner);
+            JCVariableDecl recDef = make.VarDef(rec, tree.getQualifierExpression());
+            result = make.LetExpr(recDef, result).setType(tree.type);
+        }
+    }
+
+    /**
+     * Translate identifiers within a lambda to the mapped identifier
+     * @param tree
+     */
+    @Override
+    public void visitIdent(JCIdent tree) {
+        if (context == null || !analyzer.lambdaIdentSymbolFilter(tree.sym)) {
+            super.visitIdent(tree);
+        } else {
+            LambdaTranslationContext lambdaContext = (LambdaTranslationContext) context;
+            if (lambdaContext.getSymbolMap(PARAM).containsKey(tree.sym)) {
+                Symbol translatedSym = lambdaContext.getSymbolMap(PARAM).get(tree.sym);
+                result = make.Ident(translatedSym).setType(tree.type);
+            } else if (lambdaContext.getSymbolMap(LOCAL_VAR).containsKey(tree.sym)) {
+                Symbol translatedSym = lambdaContext.getSymbolMap(LOCAL_VAR).get(tree.sym);
+                result = make.Ident(translatedSym).setType(tree.type);
+            } else if (lambdaContext.getSymbolMap(CAPTURED_VAR).containsKey(tree.sym)) {
+                Symbol translatedSym = lambdaContext.getSymbolMap(CAPTURED_VAR).get(tree.sym);
+                result = make.Ident(translatedSym).setType(tree.type);
+            } else {
+                if (tree.sym.owner.kind == Kinds.TYP) {
+                    for (Map.Entry<Symbol, Symbol> encl_entry : lambdaContext.getSymbolMap(CAPTURED_THIS).entrySet()) {
+                        if (tree.sym.isMemberOf((ClassSymbol) encl_entry.getKey(), types)) {
+                            JCExpression enclRef = make.Ident(encl_entry.getValue());
+                            result = tree.sym.name == names._this
+                                    ? enclRef.setType(tree.type)
+                                    : make.Select(enclRef, tree.sym).setType(tree.type);
+                            result = tree;
+                            return;
+                        }
+                    }
+                }
+                //access to untranslated symbols (i.e. compile-time constants,
+                //members defined inside the lambda body, etc.) )
+                super.visitIdent(tree);
+            }
+        }
+    }
+
+    @Override
+    public void visitVarDef(JCVariableDecl tree) {
+        LambdaTranslationContext lambdaContext = (LambdaTranslationContext)context;
+        if (context != null && lambdaContext.getSymbolMap(LOCAL_VAR).containsKey(tree.sym)) {
+            JCExpression init = translate(tree.init);
+            result = make.VarDef((VarSymbol)lambdaContext.getSymbolMap(LOCAL_VAR).get(tree.sym), init);
+        } else {
+            super.visitVarDef(tree);
+        }
+    }
+
+    // </editor-fold>
+
+    // <editor-fold defaultstate="collapsed" desc="Translation helper methods">
+
+    private JCBlock makeLambdaBody(JCLambda tree, JCMethodDecl lambdaMethodDecl) {
+        return tree.getBodyKind() == JCLambda.BodyKind.EXPRESSION ?
+                makeLambdaExpressionBody((JCExpression)tree.body, lambdaMethodDecl) :
+                makeLambdaStatementBody((JCBlock)tree.body, lambdaMethodDecl, tree.canCompleteNormally);
+    }
+
+    private JCBlock makeLambdaExpressionBody(JCExpression expr, JCMethodDecl lambdaMethodDecl) {
+        Type restype = lambdaMethodDecl.type.getReturnType();
+        boolean isLambda_void = expr.type.hasTag(VOID);
+        boolean isTarget_void = restype.hasTag(VOID);
+        boolean isTarget_Void = types.isSameType(restype, types.boxedClass(syms.voidType).type);
+        if (isTarget_void) {
+            //target is void:
+            // BODY;
+            JCStatement stat = make.Exec(expr);
+            return make.Block(0, List.<JCStatement>of(stat));
+        } else if (isLambda_void && isTarget_Void) {
+            //void to Void conversion:
+            // BODY; return null;
+            ListBuffer<JCStatement> stats = ListBuffer.lb();
+            stats.append(make.Exec(expr));
+            stats.append(make.Return(make.Literal(BOT, null).setType(syms.botType)));
+            return make.Block(0, stats.toList());
+        } else {
+            //non-void to non-void conversion:
+            // return (TYPE)BODY;
+            JCExpression retExpr = transTypes.coerce(attrEnv, expr, restype);
+            return make.Block(0, List.<JCStatement>of(make.Return(retExpr)));
+        }
+    }
+
+    private JCBlock makeLambdaStatementBody(JCBlock block, final JCMethodDecl lambdaMethodDecl, boolean completeNormally) {
+        final Type restype = lambdaMethodDecl.type.getReturnType();
+        final boolean isTarget_void = restype.hasTag(VOID);
+        boolean isTarget_Void = types.isSameType(restype, types.boxedClass(syms.voidType).type);
+
+        class LambdaBodyTranslator extends TreeTranslator {
+
+            @Override
+            public void visitClassDef(JCClassDecl tree) {
+                //do NOT recurse on any inner classes
+                result = tree;
+            }
+
+            @Override
+            public void visitLambda(JCLambda tree) {
+                //do NOT recurse on any nested lambdas
+                result = tree;
+            }
+
+            @Override
+            public void visitReturn(JCReturn tree) {
+                boolean isLambda_void = tree.expr == null;
+                if (isTarget_void && !isLambda_void) {
+                    //Void to void conversion:
+                    // { TYPE $loc = RET-EXPR; return; }
+                    VarSymbol loc = makeSyntheticVar(0, names.fromString("$loc"), tree.expr.type, lambdaMethodDecl.sym);
+                    JCVariableDecl varDef = make.VarDef(loc, tree.expr);
+                    result = make.Block(0, List.<JCStatement>of(varDef, make.Return(null)));
+                } else if (!isTarget_void || !isLambda_void) {
+                    //non-void to non-void conversion:
+                    // return (TYPE)RET-EXPR;
+                    tree.expr = transTypes.coerce(attrEnv, tree.expr, restype);
+                    result = tree;
+                } else {
+                    result = tree;
+                }
+
+            }
+        }
+
+        JCBlock trans_block = new LambdaBodyTranslator().translate(block);
+        if (completeNormally && isTarget_Void) {
+            //there's no return statement and the lambda (possibly inferred)
+            //return type is java.lang.Void; emit a synthetic return statement
+            trans_block.stats = trans_block.stats.append(make.Return(make.Literal(BOT, null).setType(syms.botType)));
+        }
+        return trans_block;
+    }
+
+    /**
+     * Create new synthetic method with given flags, name, type, owner
+     */
+    private MethodSymbol makeSyntheticMethod(long flags, Name name, Type type, Symbol owner) {
+        return new MethodSymbol(flags | SYNTHETIC, name, type, owner);
+    }
+
+    /**
+     * Create new synthetic variable with given flags, name, type, owner
+     */
+    private VarSymbol makeSyntheticVar(long flags, String name, Type type, Symbol owner) {
+        return makeSyntheticVar(flags, names.fromString(name), type, owner);
+    }
+
+    /**
+     * Create new synthetic variable with given flags, name, type, owner
+     */
+    private VarSymbol makeSyntheticVar(long flags, Name name, Type type, Symbol owner) {
+        return new VarSymbol(flags | SYNTHETIC, name, type, owner);
+    }
+
+    /**
+     * Set varargsElement field on a given tree (must be either a new class tree
+     * or a method call tree)
+     */
+    private void setVarargsIfNeeded(JCTree tree, Type varargsElement) {
+        if (varargsElement != null) {
+            switch (tree.getTag()) {
+                case APPLY: ((JCMethodInvocation)tree).varargsElement = varargsElement; break;
+                case NEWCLASS: ((JCNewClass)tree).varargsElement = varargsElement; break;
+                default: throw new AssertionError();
+            }
+        }
+    }
+
+    /**
+     * Convert method/constructor arguments by inserting appropriate cast
+     * as required by type-erasure - this is needed when bridging a lambda/method
+     * reference, as the bridged signature might require downcast to be compatible
+     * with the generated signature.
+     */
+    private List<JCExpression> convertArgs(Symbol meth, List<JCExpression> args, Type varargsElement) {
+       Assert.check(meth.kind == Kinds.MTH);
+       List<Type> formals = types.erasure(meth.type).getParameterTypes();
+       if (varargsElement != null) {
+           Assert.check((meth.flags() & VARARGS) != 0);
+       }
+       return transTypes.translateArgs(args, formals, varargsElement, attrEnv);
+    }
+
+    // </editor-fold>
+
+    private MethodSymbol makeSamDescriptor(Type targetType) {
+        return (MethodSymbol)types.findDescriptorSymbol(targetType.tsym);
+    }
+
+    private Type makeFunctionalDescriptorType(Type targetType, MethodSymbol samDescriptor, boolean erased) {
+        Type descType = types.memberType(targetType, samDescriptor);
+        return erased ? types.erasure(descType) : descType;
+    }
+
+    private Type makeFunctionalDescriptorType(Type targetType, boolean erased) {
+        return makeFunctionalDescriptorType(targetType, makeSamDescriptor(targetType), erased);
+    }
+
+    /**
+     * Generate an adapter method "bridge" for a method reference which cannot
+     * be used directly.
+     */
+    private class MemberReferenceBridger {
+
+        private final JCMemberReference tree;
+        private final ReferenceTranslationContext localContext;
+        private final ListBuffer<JCExpression> args = ListBuffer.lb();
+        private final ListBuffer<JCVariableDecl> params = ListBuffer.lb();
+
+        MemberReferenceBridger(JCMemberReference tree, ReferenceTranslationContext localContext) {
+            this.tree = tree;
+            this.localContext = localContext;
+        }
+
+        /**
+         * Generate the bridge
+         */
+        JCMethodDecl bridge() {
+            int prevPos = make.pos;
+            try {
+                make.at(tree);
+                Type samDesc = localContext.bridgedRefSig();
+                List<Type> samPTypes = samDesc.getParameterTypes();
+
+                //an extra argument is prepended to the signature of the bridge in case
+                //the member reference is an instance method reference (in which case
+                //the receiver expression is passed to the bridge itself).
+                Type recType = null;
+                switch (tree.kind) {
+                    case IMPLICIT_INNER:
+                        recType = tree.sym.owner.type.getEnclosingType();
+                        break;
+                    case BOUND:
+                        recType = tree.getQualifierExpression().type;
+                        break;
+                    case UNBOUND:
+                        recType = samPTypes.head;
+                        samPTypes = samPTypes.tail;
+                        break;
+                }
+
+                //generate the parameter list for the bridged member reference - the
+                //bridge signature will match the signature of the target sam descriptor
+
+                VarSymbol rcvr = (recType == null)
+                        ? null
+                        : addParameter("rec$", recType, false);
+
+                List<Type> refPTypes = tree.sym.type.getParameterTypes();
+                int refSize = refPTypes.size();
+                int samSize = samPTypes.size();
+                int last = localContext.needsVarArgsConversion() ? refSize - 1 : refSize;   // Last parameter to copy from referenced method
+
+                List<Type> l = refPTypes;
+                // Use parameter types of the referenced method, excluding final var args
+                for (int i = 0; l.nonEmpty() && i < last; ++i) {
+                    addParameter("x$" + i, l.head, true);
+                    l = l.tail;
+                }
+                // Flatten out the var args
+                for (int i = last; i < samSize; ++i) {
+                    addParameter("xva$" + i, tree.varargsElement, true);
+                }
+
+                //generate the bridge method declaration
+                JCMethodDecl bridgeDecl = make.MethodDef(make.Modifiers(localContext.bridgeSym.flags()),
+                        localContext.bridgeSym.name,
+                        make.QualIdent(samDesc.getReturnType().tsym),
+                        List.<JCTypeParameter>nil(),
+                        params.toList(),
+                        tree.sym.type.getThrownTypes() == null
+                        ? List.<JCExpression>nil()
+                        : make.Types(tree.sym.type.getThrownTypes()),
+                        null,
+                        null);
+                bridgeDecl.sym = (MethodSymbol) localContext.bridgeSym;
+                bridgeDecl.type = localContext.bridgeSym.type = types.createMethodTypeWithParameters(samDesc, TreeInfo.types(params.toList()));
+
+                //bridge method body generation - this can be either a method call or a
+                //new instance creation expression, depending on the member reference kind
+                JCExpression bridgeExpr = (tree.getMode() == ReferenceMode.INVOKE)
+                        ? bridgeExpressionInvoke(rcvr)
+                        : bridgeExpressionNew();
+
+                //the body is either a return expression containing a method call,
+                //or the method call itself, depending on whether the return type of
+                //the bridge is non-void/void.
+                bridgeDecl.body = makeLambdaExpressionBody(bridgeExpr, bridgeDecl);
+
+                return bridgeDecl;
+            } finally {
+                make.at(prevPos);
+            }
+        }
+
+        /**
+         * determine the receiver of the bridged method call - the receiver can
+         * be either the synthetic receiver parameter or a type qualifier; the
+         * original qualifier expression is never used here, as it might refer
+         * to symbols not available in the static context of the bridge
+         */
+        private JCExpression bridgeExpressionInvoke(VarSymbol rcvr) {
+            JCExpression qualifier =
+                    tree.sym.isStatic() ?
+                        make.Type(tree.sym.owner.type) :
+                        (rcvr != null) ?
+                            make.Ident(rcvr) :
+                            tree.getQualifierExpression();
+
+            //create the qualifier expression
+            JCFieldAccess select = make.Select(qualifier, tree.sym.name);
+            select.sym = tree.sym;
+            select.type = tree.sym.erasure(types);
+
+            //create the method call expression
+            JCExpression apply = make.Apply(List.<JCExpression>nil(), select,
+                    convertArgs(tree.sym, args.toList(), tree.varargsElement)).setType(tree.sym.erasure(types).getReturnType());
+
+            apply = transTypes.coerce(apply, localContext.generatedRefSig().getReturnType());
+            setVarargsIfNeeded(apply, tree.varargsElement);
+            return apply;
+        }
+
+        /**
+         * the enclosing expression is either 'null' (no enclosing type) or set
+         * to the first bridge synthetic parameter
+         */
+        private JCExpression bridgeExpressionNew() {
+            JCExpression encl = null;
+            switch (tree.kind) {
+                case UNBOUND:
+                case IMPLICIT_INNER:
+                    encl = make.Ident(params.first());
+            }
+
+            //create the instance creation expression
+            JCNewClass newClass = make.NewClass(encl,
+                    List.<JCExpression>nil(),
+                    make.Type(tree.getQualifierExpression().type),
+                    convertArgs(tree.sym, args.toList(), tree.varargsElement),
+                    null);
+            newClass.constructor = tree.sym;
+            newClass.constructorType = tree.sym.erasure(types);
+            newClass.type = tree.getQualifierExpression().type;
+            setVarargsIfNeeded(newClass, tree.varargsElement);
+            return newClass;
+        }
+
+        private VarSymbol addParameter(String name, Type p, boolean genArg) {
+            VarSymbol vsym = new VarSymbol(0, names.fromString(name), p, localContext.bridgeSym);
+            params.append(make.VarDef(vsym, null));
+            if (genArg) {
+                args.append(make.Ident(vsym));
+            }
+            return vsym;
+        }
+    }
+
+    /**
+     * Bridges a member reference - this is needed when:
+     * * Var args in the referenced method need to be flattened away
+     * * super is used
+     */
+    private void bridgeMemberReference(JCMemberReference tree, ReferenceTranslationContext localContext) {
+        JCMethodDecl bridgeDecl = (new MemberReferenceBridger(tree, localContext).bridge());
+        translatedMethodList = translatedMethodList.prepend(bridgeDecl);
+    }
+
+    /**
+     * Generate an indy method call to the meta factory
+     */
+    private JCExpression makeMetaFactoryIndyCall(JCExpression tree, Type targetType, int refKind, Symbol refSym, List<JCExpression> indy_args) {
+        //determine the static bsm args
+        Type mtype = makeFunctionalDescriptorType(targetType, true);
+        List<Object> staticArgs = List.<Object>of(
+                new Pool.MethodHandle(ClassFile.REF_invokeInterface, types.findDescriptorSymbol(targetType.tsym)),
+                new Pool.MethodHandle(refKind, refSym),
+                new MethodType(mtype.getParameterTypes(),
+                        mtype.getReturnType(),
+                        mtype.getThrownTypes(),
+                        syms.methodClass));
+
+        //computed indy arg types
+        ListBuffer<Type> indy_args_types = ListBuffer.lb();
+        for (JCExpression arg : indy_args) {
+            indy_args_types.append(arg.type);
+        }
+
+        //finally, compute the type of the indy call
+        MethodType indyType = new MethodType(indy_args_types.toList(),
+                tree.type,
+                List.<Type>nil(),
+                syms.methodClass);
+
+        return makeIndyCall(tree, syms.lambdaMetafactory, names.metaFactory, staticArgs, indyType, indy_args);
+    }
+
+    /**
+     * Generate an indy method call with given name, type and static bootstrap
+     * arguments types
+     */
+    private JCExpression makeIndyCall(DiagnosticPosition pos, Type site, Name bsmName, List<Object> staticArgs, MethodType indyType, List<JCExpression> indyArgs) {
+        int prevPos = make.pos;
+        try {
+            make.at(pos);
+            List<Type> bsm_staticArgs = List.of(syms.methodHandleLookupType,
+                    syms.stringType,
+                    syms.methodTypeType).appendList(bsmStaticArgToTypes(staticArgs));
+
+            Symbol bsm = rs.resolveInternalMethod(pos, attrEnv, site,
+                    bsmName, bsm_staticArgs, List.<Type>nil());
+
+            DynamicMethodSymbol dynSym =
+                    new DynamicMethodSymbol(names.lambda,
+                                            syms.noSymbol,
+                                            bsm.isStatic() ? ClassFile.REF_invokeStatic : ClassFile.REF_invokeVirtual,
+                                            (MethodSymbol)bsm,
+                                            indyType,
+                                            staticArgs.toArray());
+
+            JCFieldAccess qualifier = make.Select(make.QualIdent(site.tsym), bsmName);
+            qualifier.sym = dynSym;
+            qualifier.type = indyType.getReturnType();
+
+            JCMethodInvocation proxyCall = make.Apply(List.<JCExpression>nil(), qualifier, indyArgs);
+            proxyCall.type = indyType.getReturnType();
+            return proxyCall;
+        } finally {
+            make.at(prevPos);
+        }
+    }
+    //where
+    private List<Type> bsmStaticArgToTypes(List<Object> args) {
+        ListBuffer<Type> argtypes = ListBuffer.lb();
+        for (Object arg : args) {
+            argtypes.append(bsmStaticArgToType(arg));
+        }
+        return argtypes.toList();
+    }
+
+    private Type bsmStaticArgToType(Object arg) {
+        Assert.checkNonNull(arg);
+        if (arg instanceof ClassSymbol) {
+            return syms.classType;
+        } else if (arg instanceof Integer) {
+            return syms.intType;
+        } else if (arg instanceof Long) {
+            return syms.longType;
+        } else if (arg instanceof Float) {
+            return syms.floatType;
+        } else if (arg instanceof Double) {
+            return syms.doubleType;
+        } else if (arg instanceof String) {
+            return syms.stringType;
+        } else if (arg instanceof Pool.MethodHandle) {
+            return syms.methodHandleType;
+        } else if (arg instanceof MethodType) {
+            return syms.methodTypeType;
+        } else {
+            Assert.error("bad static arg " + arg.getClass());
+            return null;
+        }
+    }
+
+    /**
+     * Get the opcode associated with this method reference
+     */
+    private int referenceKind(Symbol refSym) {
+        if (refSym.isConstructor()) {
+            return ClassFile.REF_newInvokeSpecial;
+        } else {
+            if (refSym.isStatic()) {
+                return ClassFile.REF_invokeStatic;
+            } else if (refSym.enclClass().isInterface()) {
+                return ClassFile.REF_invokeInterface;
+            } else {
+                return ClassFile.REF_invokeVirtual;
+            }
+        }
+    }
+    // </editor-fold>
+
+    // <editor-fold defaultstate="collapsed" desc="Lambda/reference analyzer">\
+    /**
+     * This visitor collects information about translation of a lambda expression.
+     * More specifically, it keeps track of the enclosing contexts and captured locals
+     * accessed by the lambda being translated (as well as other useful info).
+     */
+    class LambdaAnalyzer extends TreeScanner {
+
+        /** the frame stack - used to reconstruct translation info about enclosing scopes */
+        private List<Frame> frameStack;
+
+        /**
+         * keep the count of lambda expression (used to generate unambiguous
+         * names)
+         */
+        private int lambdaCount = 0;
+
+        private void analyzeClass(JCClassDecl tree) {
+            frameStack = List.nil();
+            scan(tree);
+        }
+
+        @Override
+        public void visitBlock(JCBlock tree) {
+            List<Frame> prevStack = frameStack;
+            try {
+                if (frameStack.nonEmpty() && frameStack.head.tree.hasTag(CLASSDEF)) {
+                    frameStack = frameStack.prepend(new Frame(tree));
+                }
+                super.visitBlock(tree);
+            }
+            finally {
+                frameStack = prevStack;
+            }
+        }
+
+        @Override
+        public void visitClassDef(JCClassDecl tree) {
+            List<Frame> prevStack = frameStack;
+            try {
+                if (frameStack.nonEmpty() && enclosingLambda() != null) {
+                    tree.sym.owner = owner();
+                    LambdaTranslationContext lambdaContext = (LambdaTranslationContext)contextMap.get(enclosingLambda());
+                    Type encl = lambdaContext.enclosingType();
+                    if (encl.hasTag(NONE)) {
+                        //if the translated lambda body occurs in a static context,
+                        //any class declaration within it must be made static
+                        tree.sym.flags_field |= STATIC;
+                        ((ClassType)tree.sym.type).setEnclosingType(Type.noType);
+                    } else {
+                        //if the translated lambda body is in an instance context
+                        //the enclosing type of any class declaration within it
+                        //must be updated to point to the new enclosing type (if any)
+                        ((ClassType)tree.sym.type).setEnclosingType(encl);
+                    }
+                }
+                frameStack = frameStack.prepend(new Frame(tree));
+                super.visitClassDef(tree);
+            }
+            finally {
+                frameStack = prevStack;
+            }
+            if (frameStack.nonEmpty() && enclosingLambda() != null) {
+                // Any class defined within a lambda is an implicit 'this' reference
+                // because its constructor will reference the enclosing class
+                ((LambdaTranslationContext) context()).addSymbol(tree.sym.type.getEnclosingType().tsym, CAPTURED_THIS);
+            }
+        }
+
+        @Override
+        public void visitIdent(JCIdent tree) {
+            if (context() == null || !lambdaIdentSymbolFilter(tree.sym)) {
+                super.visitIdent(tree);
+            } else {
+                if (tree.sym.kind == VAR &&
+                        tree.sym.owner.kind == MTH &&
+                        tree.type.constValue() == null) {
+                    TranslationContext<?> localContext = context();
+                    while (localContext != null) {
+                        if (localContext.tree.getTag() == LAMBDA) {
+                            JCTree block = capturedDecl(localContext.depth, tree.sym);
+                            if (block == null) break;
+                            ((LambdaTranslationContext)localContext).addSymbol(tree.sym, CAPTURED_VAR);
+                        }
+                        localContext = localContext.prev;
+                    }
+                } else if (tree.sym.owner.kind == TYP) {
+                    TranslationContext<?> localContext = context();
+                    while (localContext != null) {
+                        if (localContext.tree.hasTag(LAMBDA)) {
+                            JCTree block = capturedDecl(localContext.depth, tree.sym);
+                            if (block == null) break;
+                            switch (block.getTag()) {
+                                case CLASSDEF:
+                                    JCClassDecl cdecl = (JCClassDecl)block;
+                                    ((LambdaTranslationContext)localContext).addSymbol(cdecl.sym, CAPTURED_THIS);
+                                    break;
+                                default:
+                                    Assert.error("bad block kind");
+                            }
+                        }
+                        localContext = localContext.prev;
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void visitLambda(JCLambda tree) {
+            List<Frame> prevStack = frameStack;
+            try {
+                LambdaTranslationContext context = (LambdaTranslationContext)makeLambdaContext(tree);
+                frameStack = frameStack.prepend(new Frame(tree));
+                for (JCVariableDecl param : tree.params) {
+                    context.addSymbol(param.sym, PARAM);
+                    frameStack.head.addLocal(param.sym);
+                }
+                contextMap.put(tree, context);
+                scan(tree.body);
+                context.complete();
+            }
+            finally {
+                frameStack = prevStack;
+            }
+        }
+
+        @Override
+        public void visitMethodDef(JCMethodDecl tree) {
+            List<Frame> prevStack = frameStack;
+            try {
+                frameStack = frameStack.prepend(new Frame(tree));
+                super.visitMethodDef(tree);
+            }
+            finally {
+                frameStack = prevStack;
+            }
+        }
+
+        @Override
+        public void visitNewClass(JCNewClass tree) {
+            if (lambdaNewClassFilter(context(), tree)) {
+                ((LambdaTranslationContext) context()).addSymbol(tree.type.getEnclosingType().tsym, CAPTURED_THIS);
+            }
+            super.visitNewClass(tree);
+        }
+
+        @Override
+        public void visitReference(JCMemberReference tree) {
+            scan(tree.getQualifierExpression());
+            contextMap.put(tree, makeReferenceContext(tree));
+        }
+
+        @Override
+        public void visitSelect(JCFieldAccess tree) {
+            if (context() != null && lambdaSelectSymbolFilter(tree.sym)) {
+                TranslationContext<?> localContext = context();
+                while (localContext != null) {
+                    if (localContext.tree.hasTag(LAMBDA)) {
+                        JCClassDecl clazz = (JCClassDecl)capturedDecl(localContext.depth, tree.sym);
+                        if (clazz == null) break;
+                        ((LambdaTranslationContext)localContext).addSymbol(clazz.sym, CAPTURED_THIS);
+                    }
+                    localContext = localContext.prev;
+                }
+                scan(tree.selected);
+            } else {
+                super.visitSelect(tree);
+            }
+        }
+
+        @Override
+        public void visitVarDef(JCVariableDecl tree) {
+            if (frameStack.head.tree.hasTag(LAMBDA)) {
+                ((LambdaTranslationContext)context()).addSymbol(tree.sym, LOCAL_VAR);
+            }
+            List<Frame> prevStack = frameStack;
+            try {
+                if (tree.sym.owner.kind == MTH) {
+                    frameStack.head.addLocal(tree.sym);
+                }
+                frameStack = frameStack.prepend(new Frame(tree));
+                super.visitVarDef(tree);
+            }
+            finally {
+                frameStack = prevStack;
+            }
+        }
+
+        private Name lambdaName() {
+            return names.lambda.append(names.fromString("$" + lambdaCount++));
+        }
+
+        /**
+         * Return a valid owner given the current declaration stack
+         * (required to skip synthetic lambda symbols)
+         */
+        private Symbol owner() {
+            List<Frame> frameStack2 = frameStack;
+            while (frameStack2.nonEmpty()) {
+                switch (frameStack2.head.tree.getTag()) {
+                    case VARDEF:
+                        if (((JCVariableDecl)frameStack2.head.tree).sym.isLocal()) {
+                            frameStack2 = frameStack2.tail;
+                            break;
+                        }
+                        JCClassDecl cdecl = (JCClassDecl)frameStack2.tail.head.tree;
+                        return makeSyntheticMethod(((JCVariableDecl)frameStack2.head.tree).sym.flags() & STATIC, names.empty, null, cdecl.sym);
+                    case BLOCK:
+                        JCClassDecl cdecl2 = (JCClassDecl)frameStack2.tail.head.tree;
+                        return makeSyntheticMethod(((JCBlock)frameStack2.head.tree).flags & STATIC | Flags.BLOCK, names.empty, null, cdecl2.sym);
+                    case CLASSDEF:
+                        return ((JCClassDecl)frameStack2.head.tree).sym;
+                    case METHODDEF:
+                        return ((JCMethodDecl)frameStack2.head.tree).sym;
+                    case LAMBDA:
+                        return ((LambdaTranslationContext)contextMap.get(frameStack2.head.tree)).translatedSym;
+                    default:
+                        frameStack2 = frameStack2.tail;
+                }
+            }
+            Assert.error();
+            return null;
+        }
+
+        private JCTree enclosingLambda() {
+            List<Frame> frameStack2 = frameStack;
+            while (frameStack2.nonEmpty()) {
+                switch (frameStack2.head.tree.getTag()) {
+                    case CLASSDEF:
+                    case METHODDEF:
+                        return null;
+                    case LAMBDA:
+                        return frameStack2.head.tree;
+                    default:
+                        frameStack2 = frameStack2.tail;
+                }
+            }
+            Assert.error();
+            return null;
+        }
+
+        /**
+         * Return the declaration corresponding to a symbol in the enclosing
+         * scope; the depth parameter is used to filter out symbols defined
+         * in nested scopes (which do not need to undergo capture).
+         */
+        private JCTree capturedDecl(int depth, Symbol sym) {
+            int currentDepth = frameStack.size() - 1;
+            for (Frame block : frameStack) {
+                switch (block.tree.getTag()) {
+                    case CLASSDEF:
+                        ClassSymbol clazz = ((JCClassDecl)block.tree).sym;
+                        if (sym.isMemberOf(clazz, types)) {
+                            return currentDepth > depth ? null : block.tree;
+                        }
+                        break;
+                    case VARDEF:
+                        if (((JCVariableDecl)block.tree).sym == sym &&
+                                sym.owner.kind == MTH) { //only locals are captured
+                            return currentDepth > depth ? null : block.tree;
+                        }
+                        break;
+                    case BLOCK:
+                    case METHODDEF:
+                    case LAMBDA:
+                        if (block.locals != null && block.locals.contains(sym)) {
+                            return currentDepth > depth ? null : block.tree;
+                        }
+                        break;
+                    default:
+                        Assert.error("bad decl kind " + block.tree.getTag());
+                }
+                currentDepth--;
+            }
+            return null;
+        }
+
+        private TranslationContext<?> context() {
+            for (Frame frame : frameStack) {
+                TranslationContext<?> context = contextMap.get(frame.tree);
+                if (context != null) {
+                    return context;
+                }
+            }
+            return null;
+        }
+
+        /**
+         *  This is used to filter out those identifiers that needs to be adjusted
+         *  when translating away lambda expressions
+         */
+        private boolean lambdaIdentSymbolFilter(Symbol sym) {
+            return (sym.kind == VAR || sym.kind == MTH)
+                    && !sym.isStatic()
+                    && sym.name != names.init;
+        }
+
+        private boolean lambdaSelectSymbolFilter(Symbol sym) {
+            return (sym.kind == VAR || sym.kind == MTH) &&
+                        !sym.isStatic() &&
+                        (sym.name == names._this ||
+                        sym.name == names._super);
+        }
+
+        /**
+         * This is used to filter out those new class expressions that need to
+         * be qualified with an enclosing tree
+         */
+        private boolean lambdaNewClassFilter(TranslationContext<?> context, JCNewClass tree) {
+            if (context != null
+                    && tree.encl == null
+                    && tree.def == null
+                    && tree.type.getEnclosingType().hasTag(NONE)) {
+                Type encl = tree.type.getEnclosingType();
+                Type current = context.owner.enclClass().type;
+                while (current.hasTag(NONE)) {
+                    if (current.tsym.isSubClass(encl.tsym, types)) {
+                        return true;
+                    }
+                    current = current.getEnclosingType();
+                }
+                return false;
+            } else {
+                return false;
+            }
+        }
+
+        private TranslationContext<JCLambda> makeLambdaContext(JCLambda tree) {
+            return new LambdaTranslationContext(tree);
+        }
+
+        private TranslationContext<JCMemberReference> makeReferenceContext(JCMemberReference tree) {
+            return new ReferenceTranslationContext(tree);
+        }
+
+        private class Frame {
+            final JCTree tree;
+            List<Symbol> locals;
+
+            public Frame(JCTree tree) {
+                this.tree = tree;
+            }
+
+            void addLocal(Symbol sym) {
+                if (locals == null) {
+                    locals = List.nil();
+                }
+                locals = locals.prepend(sym);
+            }
+        }
+
+        /**
+         * This class is used to store important information regarding translation of
+         * lambda expression/method references (see subclasses).
+         */
+        private abstract class TranslationContext<T extends JCTree> {
+
+            /** the underlying (untranslated) tree */
+            T tree;
+
+            /** points to the adjusted enclosing scope in which this lambda/mref expression occurs */
+            Symbol owner;
+
+            /** the depth of this lambda expression in the frame stack */
+            int depth;
+
+            /** the enclosing translation context (set for nested lambdas/mref) */
+            TranslationContext<?> prev;
+
+            TranslationContext(T tree) {
+                this.tree = tree;
+                this.owner = owner();
+                this.depth = frameStack.size() - 1;
+                this.prev = context();
+            }
+        }
+
+        /**
+         * This class retains all the useful information about a lambda expression;
+         * the contents of this class are filled by the LambdaAnalyzer visitor,
+         * and the used by the main translation routines in order to adjust references
+         * to captured locals/members, etc.
+         */
+        private class LambdaTranslationContext extends TranslationContext<JCLambda> {
+
+            /** variable in the enclosing context to which this lambda is assigned */
+            Symbol self;
+
+            /** map from original to translated lambda parameters */
+            Map<Symbol, Symbol> lambdaParams = new LinkedHashMap<Symbol, Symbol>();
+
+            /** map from original to translated lambda locals */
+            Map<Symbol, Symbol> lambdaLocals = new LinkedHashMap<Symbol, Symbol>();
+
+            /** map from variables in enclosing scope to translated synthetic parameters */
+            Map<Symbol, Symbol> capturedLocals  = new LinkedHashMap<Symbol, Symbol>();
+
+            /** map from class symbols to translated synthetic parameters (for captured member access) */
+            Map<Symbol, Symbol> capturedThis = new LinkedHashMap<Symbol, Symbol>();
+
+            /** the synthetic symbol for the method hoisting the translated lambda */
+            Symbol translatedSym;
+
+            List<JCVariableDecl> syntheticParams;
+
+            LambdaTranslationContext(JCLambda tree) {
+                super(tree);
+                Frame frame = frameStack.head;
+                if (frame.tree.hasTag(VARDEF)) {
+                    self = ((JCVariableDecl)frame.tree).sym;
+                }
+                this.translatedSym = makeSyntheticMethod(0, lambdaName(), null, owner.enclClass());
+            }
+
+            /**
+             * Translate a symbol of a given kind into something suitable for the
+             * synthetic lambda body
+             */
+            Symbol translate(String name, Symbol sym, LambdaSymbolKind skind) {
+                if (skind == CAPTURED_THIS) {
+                    return sym;  // self represented
+                } else {
+                    return makeSyntheticVar(FINAL, name, types.erasure(sym.type), translatedSym);
+                }
+            }
+
+            void addSymbol(Symbol sym, LambdaSymbolKind skind) {
+                Map<Symbol, Symbol> transMap = null;
+                String preferredName;
+                switch (skind) {
+                    case CAPTURED_THIS:
+                        transMap = capturedThis;
+                        preferredName = "encl$" + capturedThis.size();
+                        break;
+                    case CAPTURED_VAR:
+                        transMap = capturedLocals;
+                        preferredName = "cap$" + capturedLocals.size();
+                        break;
+                    case LOCAL_VAR:
+                        transMap = lambdaLocals;
+                        preferredName = sym.name.toString();
+                        break;
+                    case PARAM:
+                        transMap = lambdaParams;
+                        preferredName = sym.name.toString();
+                        break;
+                    default: throw new AssertionError();
+                }
+                if (!transMap.containsKey(sym)) {
+                    transMap.put(sym, translate(preferredName, sym, skind));
+                }
+            }
+
+            Map<Symbol, Symbol> getSymbolMap(LambdaSymbolKind... skinds) {
+                LinkedHashMap<Symbol, Symbol> translationMap = new LinkedHashMap<Symbol, Symbol>();
+                for (LambdaSymbolKind skind : skinds) {
+                    switch (skind) {
+                        case CAPTURED_THIS:
+                            translationMap.putAll(capturedThis);
+                            break;
+                        case CAPTURED_VAR:
+                            translationMap.putAll(capturedLocals);
+                            break;
+                        case LOCAL_VAR:
+                            translationMap.putAll(lambdaLocals);
+                            break;
+                        case PARAM:
+                            translationMap.putAll(lambdaParams);
+                            break;
+                        default: throw new AssertionError();
+                    }
+                }
+                return translationMap;
+            }
+
+            /**
+             * The translatedSym is not complete/accurate until the analysis is
+             * finished.  Once the analysis is finished, the translatedSym is
+             * "completed" -- updated with type information, access modifiers,
+             * and full parameter list.
+             */
+            void complete() {
+                if (syntheticParams != null) {
+                    return;
+                }
+                boolean inInterface = translatedSym.owner.isInterface();
+                boolean thisReferenced = !getSymbolMap(CAPTURED_THIS).isEmpty();
+                boolean needInstance = thisReferenced || inInterface;
+
+                // If instance access isn't needed, make it static
+                // Interface methods much be public default methods, otherwise make it private
+                translatedSym.flags_field = SYNTHETIC | (needInstance? 0 : STATIC) | (inInterface? PUBLIC | DEFAULT : PRIVATE);
+
+                //compute synthetic params
+                ListBuffer<JCVariableDecl> params = ListBuffer.lb();
+
+                // The signature of the method is augmented with the following
+                // synthetic parameters:
+                //
+                // 1) reference to enclosing contexts captured by the lambda expression
+                // 2) enclosing locals captured by the lambda expression
+                for (Symbol thisSym : getSymbolMap(CAPTURED_VAR, PARAM).values()) {
+                    params.append(make.VarDef((VarSymbol) thisSym, null));
+                }
+
+                syntheticParams = params.toList();
+
+                //prepend synthetic args to translated lambda method signature
+                translatedSym.type = (MethodType) types.createMethodTypeWithParameters(
+                        (MethodType) generatedLambdaSig(),
+                        TreeInfo.types(syntheticParams));
+            }
+
+            Type enclosingType() {
+                //local inner classes defined inside a lambda are always non-static
+                return owner.enclClass().type;
+            }
+
+            Type generatedLambdaSig() {
+                return types.erasure(types.findDescriptorType(tree.targetType));
+            }
+        }
+
+        /**
+         * This class retains all the useful information about a method reference;
+         * the contents of this class are filled by the LambdaAnalyzer visitor,
+         * and the used by the main translation routines in order to adjust method
+         * references (i.e. in case a bridge is needed)
+         */
+        private class ReferenceTranslationContext extends TranslationContext<JCMemberReference> {
+
+            final boolean isSuper;
+            final Symbol bridgeSym;
+
+            ReferenceTranslationContext(JCMemberReference tree) {
+                super(tree);
+                this.isSuper = tree.hasKind(ReferenceKind.SUPER);
+                this.bridgeSym = needsBridge()
+                        ? makeSyntheticMethod(isSuper ? 0 : STATIC,
+                                              lambdaName().append(names.fromString("$bridge")), null,
+                                              owner.enclClass())
+                        : null;
+            }
+
+            /**
+             * Get the opcode associated with this method reference
+             */
+            int referenceKind() {
+                return LambdaToMethod.this.referenceKind(needsBridge() ? bridgeSym : tree.sym);
+            }
+
+            boolean needsVarArgsConversion() {
+                return tree.varargsElement != null;
+            }
+
+            /**
+             * @return Is this an array operation like clone()
+             */
+            boolean isArrayOp() {
+                return tree.sym.owner == syms.arrayClass;
+            }
+
+            /**
+             * Does this reference needs a bridge (i.e. var args need to be
+             * expanded or "super" is used)
+             */
+            final boolean needsBridge() {
+                return isSuper || needsVarArgsConversion() || isArrayOp();
+            }
+
+            Type generatedRefSig() {
+                return types.erasure(tree.sym.type);
+            }
+
+            Type bridgedRefSig() {
+                return types.erasure(types.findDescriptorSymbol(tree.targetType.tsym).type);
+            }
+        }
+    }
+    // </editor-fold>
+
+    enum LambdaSymbolKind {
+        CAPTURED_VAR,
+        CAPTURED_THIS,
+        LOCAL_VAR,
+        PARAM;
+    }
+}
--- a/src/share/classes/com/sun/tools/javac/comp/Lower.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Lower.java	Fri Nov 02 17:55:34 2012 -0700
@@ -45,7 +45,7 @@
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Flags.BLOCK;
 import static com.sun.tools.javac.code.Kinds.*;
-import static com.sun.tools.javac.code.TypeTags.*;
+import static com.sun.tools.javac.code.TypeTag.*;
 import static com.sun.tools.javac.jvm.ByteCodes.*;
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
 
@@ -485,7 +485,7 @@
      *  @param value      The literal's value.
      */
     JCExpression makeLit(Type type, Object value) {
-        return make.Literal(type.tag, value).setType(type.constType(value));
+        return make.Literal(type.getTag(), value).setType(type.constType(value));
     }
 
     /** Make an attributed tree representing null.
@@ -549,7 +549,7 @@
      *  reference type..
      */
     JCExpression makeString(JCExpression tree) {
-        if (tree.type.tag >= CLASS) {
+        if (!tree.type.isPrimitiveOrVoid()) {
             return tree;
         } else {
             Symbol valueOfSym = lookupMethod(tree.pos(),
@@ -1405,7 +1405,7 @@
     Name outerThisName(Type type, Symbol owner) {
         Type t = type.getEnclosingType();
         int nestingLevel = 0;
-        while (t.tag == CLASS) {
+        while (t.hasTag(CLASS)) {
             t = t.getEnclosingType();
             nestingLevel++;
         }
@@ -1529,7 +1529,7 @@
             new VarSymbol(SYNTHETIC | FINAL,
                           makeSyntheticName(names.fromString("twrVar" +
                                            depth), twrVars),
-                          (resource.type.tag == TypeTags.BOT) ?
+                          (resource.type.hasTag(BOT)) ?
                           syms.autoCloseableType : resource.type,
                           currentMethodSym);
             twrVars.enter(syntheticTwrVar);
@@ -1992,7 +1992,7 @@
     }
 
     private JCExpression classOfType(Type type, DiagnosticPosition pos) {
-        switch (type.tag) {
+        switch (type.getTag()) {
         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
         case DOUBLE: case BOOLEAN: case VOID:
             // replace with <BoxedClass>.TYPE
@@ -2761,7 +2761,7 @@
     }
 //where
         private JCTree convert(JCTree tree, Type pt) {
-            if (tree.type == pt || tree.type.tag == TypeTags.BOT)
+            if (tree.type == pt || tree.type.hasTag(BOT))
                 return tree;
             JCTree result = make_at(tree.pos()).TypeCast(make.Type(pt), (JCExpression)tree);
             result.type = (tree.type.constValue() != null) ? cfolder.coerce(tree.type, pt)
@@ -2934,7 +2934,7 @@
             return tree;
         if (havePrimitive) {
             Type unboxedTarget = types.unboxedType(type);
-            if (unboxedTarget.tag != NONE) {
+            if (!unboxedTarget.hasTag(NONE)) {
                 if (!types.isSubtype(tree.type, unboxedTarget)) //e.g. Character c = 89;
                     tree.type = unboxedTarget.constType(tree.type.constValue());
                 return (T)boxPrimitive((JCExpression)tree, type);
@@ -2974,7 +2974,7 @@
     /** Unbox an object to a primitive value. */
     JCExpression unbox(JCExpression tree, Type primitive) {
         Type unboxedType = types.unboxedType(tree.type);
-        if (unboxedType.tag == NONE) {
+        if (unboxedType.hasTag(NONE)) {
             unboxedType = primitive;
             if (!unboxedType.isPrimitive())
                 throw new AssertionError(unboxedType);
@@ -3292,7 +3292,7 @@
                 iteratorTarget = types.erasure(iterableType.getTypeArguments().head);
             Type eType = tree.expr.type;
             tree.expr.type = types.erasure(eType);
-            if (eType.tag == TYPEVAR && eType.getUpperBound().isCompound())
+            if (eType.hasTag(TYPEVAR) && eType.getUpperBound().isCompound())
                 tree.expr = make.TypeCast(types.erasure(iterableType), tree.expr);
             Symbol iterator = lookupMethod(tree.expr.pos(),
                                            names.iterator,
--- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Fri Nov 02 17:55:34 2012 -0700
@@ -42,7 +42,9 @@
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Flags.ANNOTATION;
 import static com.sun.tools.javac.code.Kinds.*;
-import static com.sun.tools.javac.code.TypeTags.*;
+import static com.sun.tools.javac.code.TypeTag.CLASS;
+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;
@@ -370,7 +372,7 @@
         ListBuffer<Type> thrownbuf = new ListBuffer<Type>();
         for (List<JCExpression> l = thrown; l.nonEmpty(); l = l.tail) {
             Type exc = attr.attribType(l.head, env);
-            if (exc.tag != TYPEVAR)
+            if (!exc.hasTag(TYPEVAR))
                 exc = chk.checkClassType(l.head.pos(), exc);
             thrownbuf.append(exc);
         }
@@ -921,7 +923,7 @@
             }
             for (JCExpression iface : interfaceTrees) {
                 Type i = attr.attribBase(iface, baseEnv, false, true, true);
-                if (i.tag == CLASS) {
+                if (i.hasTag(CLASS)) {
                     interfaces.append(i);
                     if (all_interfaces != null) all_interfaces.append(i);
                     chk.checkNotRepeated(iface.pos(), types.erasure(i), interfaceSet);
@@ -1006,7 +1008,7 @@
                     new VarSymbol(FINAL | HASINIT, names._this, c.type, c);
                 thisSym.pos = Position.FIRSTPOS;
                 env.info.scope.enter(thisSym);
-                if (ct.supertype_field.tag == CLASS) {
+                if (ct.supertype_field.hasTag(CLASS)) {
                     VarSymbol superSym =
                         new VarSymbol(FINAL | HASINIT, names._super,
                                       ct.supertype_field, c);
@@ -1020,11 +1022,13 @@
             // name as a top-level package.
             if (checkClash &&
                 c.owner.kind == PCK && c.owner != syms.unnamedPackage &&
-                reader.packageExists(c.fullname))
-                {
-                    log.error(tree.pos, "clash.with.pkg.of.same.name", Kinds.kindName(sym), c);
-                }
-
+                reader.packageExists(c.fullname)) {
+                log.error(tree.pos, "clash.with.pkg.of.same.name", Kinds.kindName(sym), c);
+            }
+            if (c.owner.kind == PCK && (c.flags_field & PUBLIC) == 0 &&
+                !env.toplevel.sourcefile.isNameCompatible(c.name.toString(),JavaFileObject.Kind.SOURCE)) {
+                c.flags_field |= AUXILIARY;
+            }
         } catch (CompletionFailure ex) {
             chk.completionError(tree.pos(), ex);
         } finally {
@@ -1094,7 +1098,7 @@
     }
 
     Type modelMissingTypes(Type t, final JCExpression tree, final boolean interfaceExpected) {
-        if (t.tag != ERROR)
+        if (!t.hasTag(ERROR))
             return t;
 
         return new ErrorType(((ErrorType) t).getOriginalType(), t.tsym) {
@@ -1139,7 +1143,7 @@
 
         @Override
         public void visitIdent(JCIdent tree) {
-            if (tree.type.tag != ERROR) {
+            if (!tree.type.hasTag(ERROR)) {
                 result = tree.type;
             } else {
                 result = synthesizeClass(tree.name, syms.unnamedPackage).type;
@@ -1148,7 +1152,7 @@
 
         @Override
         public void visitSelect(JCFieldAccess tree) {
-            if (tree.type.tag != ERROR) {
+            if (!tree.type.hasTag(ERROR)) {
                 result = tree.type;
             } else {
                 Type selectedType;
@@ -1166,7 +1170,7 @@
 
         @Override
         public void visitTypeApply(JCTypeApply tree) {
-            if (tree.type.tag != ERROR) {
+            if (!tree.type.hasTag(ERROR)) {
                 result = tree.type;
             } else {
                 ClassType clazzType = (ClassType) visit(tree.clazz);
--- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Fri Nov 02 17:55:34 2012 -0700
@@ -59,7 +59,7 @@
 import static com.sun.tools.javac.code.Flags.BLOCK;
 import static com.sun.tools.javac.code.Kinds.*;
 import static com.sun.tools.javac.code.Kinds.ERRONEOUS;
-import static com.sun.tools.javac.code.TypeTags.*;
+import static com.sun.tools.javac.code.TypeTag.*;
 import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
 
@@ -228,7 +228,7 @@
 
     JCDiagnostic getVerboseApplicableCandidateDiag(int pos, Symbol sym, Type inst) {
         JCDiagnostic subDiag = null;
-        if (sym.type.tag == FORALL) {
+        if (sym.type.hasTag(FORALL)) {
             subDiag = diags.fragment("partial.inst.sig", inst);
         }
 
@@ -331,7 +331,7 @@
     }
 
     boolean isAccessible(Env<AttrContext> env, Type t, boolean checkInner) {
-        return (t.tag == ARRAY)
+        return (t.hasTag(ARRAY))
             ? isAccessible(env, types.elemtype(t))
             : isAccessible(env, t.tsym, checkInner);
     }
@@ -467,10 +467,10 @@
         // need to inferred.
         List<Type> tvars = List.nil();
         if (typeargtypes == null) typeargtypes = List.nil();
-        if (mt.tag != FORALL && typeargtypes.nonEmpty()) {
+        if (!mt.hasTag(FORALL) && typeargtypes.nonEmpty()) {
             // This is not a polymorphic method, but typeargs are supplied
             // which is fine, see JLS 15.12.2.1
-        } else if (mt.tag == FORALL && typeargtypes.nonEmpty()) {
+        } else if (mt.hasTag(FORALL) && typeargtypes.nonEmpty()) {
             ForAll pmt = (ForAll) mt;
             if (typeargtypes.length() != pmt.tvars.length())
                 throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args
@@ -487,7 +487,7 @@
                 actuals = actuals.tail;
             }
             mt = types.subst(pmt.qtype, pmt.tvars, typeargtypes);
-        } else if (mt.tag == FORALL) {
+        } else if (mt.hasTag(FORALL)) {
             ForAll pmt = (ForAll) mt;
             List<Type> tvars1 = types.newInstances(pmt.tvars);
             tvars = tvars.appendList(tvars1);
@@ -499,7 +499,7 @@
         for (List<Type> l = argtypes;
              l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded;
              l = l.tail) {
-            if (l.head.tag == FORALL) instNeeded = true;
+            if (l.head.hasTag(FORALL)) instNeeded = true;
         }
 
         if (instNeeded)
@@ -807,7 +807,7 @@
 
         @Override
         protected Type check(DiagnosticPosition pos, Type found) {
-            if (found.tag == DEFERRED) {
+            if (found.hasTag(DEFERRED)) {
                 DeferredType dt = (DeferredType)found;
                 return dt.check(this);
             } else {
@@ -875,7 +875,7 @@
                      Type site,
                      Name name,
                      TypeSymbol c) {
-        while (c.type.tag == TYPEVAR)
+        while (c.type.hasTag(TYPEVAR))
             c = c.type.getUpperBound().tsym;
         Symbol bestSoFar = varNotFound;
         Symbol sym;
@@ -888,7 +888,7 @@
             e = e.next();
         }
         Type st = types.supertype(c.type);
-        if (st != null && (st.tag == CLASS || st.tag == TYPEVAR)) {
+        if (st != null && (st.hasTag(CLASS) || st.hasTag(TYPEVAR))) {
             sym = findField(env, site, name, st.tsym);
             if (sym.kind < bestSoFar.kind) bestSoFar = sym;
         }
@@ -1184,7 +1184,7 @@
                     lastFormal2 : formals2.head;
 
             //is this a structural actual argument?
-            boolean isStructuralPoly = actual.tag == DEFERRED &&
+            boolean isStructuralPoly = actual.hasTag(DEFERRED) &&
                     (((DeferredType)actual).tree.hasTag(LAMBDA) ||
                     ((DeferredType)actual).tree.hasTag(REFERENCE));
 
@@ -1301,7 +1301,7 @@
         Type rt1 = mt1.getReturnType();
         Type rt2 = mt2.getReturnType();
 
-        if (mt1.tag == FORALL && mt2.tag == FORALL) {
+        if (mt1.hasTag(FORALL) && mt2.hasTag(FORALL)) {
             //if both are generic methods, adjust return type ahead of subtyping check
             rt1 = types.subst(rt1, mt1.getTypeArguments(), mt2.getTypeArguments());
         }
@@ -1448,11 +1448,11 @@
                     }
 
                     TypeSymbol symbolFor(Type t) {
-                        if (t.tag != CLASS &&
-                                t.tag != TYPEVAR) {
+                        if (!t.hasTag(CLASS) &&
+                                !t.hasTag(TYPEVAR)) {
                             return null;
                         }
-                        while (t.tag == TYPEVAR)
+                        while (t.hasTag(TYPEVAR))
                             t = t.getUpperBound();
                         if (seen.contains(t.tsym)) {
                             //degenerate case in which we have a circular
@@ -1610,7 +1610,7 @@
             e = e.next();
         }
         Type st = types.supertype(c.type);
-        if (st != null && st.tag == CLASS) {
+        if (st != null && st.hasTag(CLASS)) {
             sym = findMemberType(env, site, name, st.tsym);
             if (sym.kind < bestSoFar.kind) bestSoFar = sym;
         }
@@ -1660,7 +1660,7 @@
                  e = e.next()) {
                 if (e.sym.kind == TYP) {
                     if (staticOnly &&
-                        e.sym.type.tag == TYPEVAR &&
+                        e.sym.type.hasTag(TYPEVAR) &&
                         e.sym.owner.kind == TYP) return new StaticError(e.sym);
                     return e.sym;
                 }
@@ -1669,8 +1669,8 @@
             sym = findMemberType(env1, env1.enclClass.sym.type, name,
                                  env1.enclClass.sym);
             if (staticOnly && sym.kind == TYP &&
-                sym.type.tag == CLASS &&
-                sym.type.getEnclosingType().tag == CLASS &&
+                sym.type.hasTag(CLASS) &&
+                sym.type.getEnclosingType().hasTag(CLASS) &&
                 env1.enclClass.sym.type.isParameterized() &&
                 sym.type.getEnclosingType().isParameterized())
                 return new StaticError(sym);
@@ -1906,7 +1906,7 @@
                     //method symbol that can be used for lookups in the speculative cache,
                     //causing problems in Attr.checkId()
                     for (Type t : argtypes) {
-                        if (t.tag == DEFERRED) {
+                        if (t.hasTag(DEFERRED)) {
                             DeferredType dt = (DeferredType)t;
                             dt.speculativeCache.dupAllTo(msym, accessedSym);
                         }
@@ -1955,7 +1955,7 @@
     }
 
     public void printscopes(Type t) {
-        while (t.tag == CLASS) {
+        while (t.hasTag(CLASS)) {
             printscopes(t.tsym.members());
             t = types.supertype(t);
         }
@@ -2259,7 +2259,7 @@
             //- System.out.println(" e " + e.sym);
             if (sym.kind == MTH &&
                 (sym.flags_field & SYNTHETIC) == 0) {
-                    List<Type> oldParams = e.sym.type.tag == FORALL ?
+                    List<Type> oldParams = e.sym.type.hasTag(FORALL) ?
                             ((ForAll)sym.type).tvars :
                             List.<Type>nil();
                     Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams),
@@ -2565,7 +2565,7 @@
                 findMethod(env, site, name, argtypes, typeargtypes,
                         phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name));
             return sym.kind != MTH ||
-                          site.getEnclosingType().tag == NONE ||
+                          site.getEnclosingType().hasTag(NONE) ||
                           hasEnclosingInstance(env, site) ?
                           sym : new InvalidSymbolError(Kinds.MISSING_ENCL, sym, null) {
                     @Override
@@ -2578,7 +2578,7 @@
 
         @Override
         ReferenceKind referenceKind(Symbol sym) {
-            return site.getEnclosingType().tag == NONE ?
+            return site.getEnclosingType().hasTag(NONE) ?
                     ReferenceKind.TOPLEVEL : ReferenceKind.IMPLICIT_INNER;
         }
     }
@@ -2847,7 +2847,7 @@
         } else {
             ListBuffer<Object> diagArgs = ListBuffer.lb();
             for (Type t : argtypes) {
-                if (t.tag == DEFERRED) {
+                if (t.hasTag(DEFERRED)) {
                     diagArgs.append(((DeferredAttr.DeferredType)t).tree);
                 } else {
                     diagArgs.append(t);
@@ -3222,7 +3222,7 @@
                 Name name,
                 List<Type> argtypes,
                 List<Type> typeargtypes) {
-            if (sym.owner.type.tag == ERROR)
+            if (sym.owner.type.hasTag(ERROR))
                 return null;
 
             if (sym.name == names.init && sym.owner != site.tsym) {
@@ -3267,7 +3267,7 @@
                 Name name,
                 List<Type> argtypes,
                 List<Type> typeargtypes) {
-            Symbol errSym = ((sym.kind == TYP && sym.type.tag == CLASS)
+            Symbol errSym = ((sym.kind == TYP && sym.type.hasTag(CLASS))
                 ? types.erasure(sym.type).tsym
                 : sym);
             return diags.create(dkind, log.currentSource(), pos,
--- a/src/share/classes/com/sun/tools/javac/comp/TransTypes.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/TransTypes.java	Fri Nov 02 17:55:34 2012 -0700
@@ -37,7 +37,9 @@
 
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Kinds.*;
-import static com.sun.tools.javac.code.TypeTags.*;
+import static com.sun.tools.javac.code.TypeTag.CLASS;
+import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
+import static com.sun.tools.javac.code.TypeTag.VOID;
 
 /** This pass translates Generic Java to conventional Java.
  *
@@ -118,6 +120,16 @@
      *  @param tree    The expression tree.
      *  @param target  The target type.
      */
+    public JCExpression coerce(Env<AttrContext> env, JCExpression tree, Type target) {
+        Env<AttrContext> prevEnv = this.env;
+        try {
+            this.env = env;
+            return coerce(tree, target);
+        }
+        finally {
+            this.env = prevEnv;
+        }
+    }
     JCExpression coerce(JCExpression tree, Type target) {
         Type btarget = target.baseType();
         if (tree.type.isPrimitive() == target.isPrimitive()) {
@@ -155,7 +167,7 @@
      */
     JCExpression retype(JCExpression tree, Type erasedType, Type target) {
 //      System.err.println("retype " + tree + " to " + erasedType);//DEBUG
-        if (erasedType.tag > lastBaseTag) {
+        if (!erasedType.isPrimitive()) {
             if (target != null && target.isPrimitive())
                 target = erasure(tree.type);
             tree.type = erasedType;
@@ -194,6 +206,20 @@
         return _args;
     }
 
+    public <T extends JCTree> List<T> translateArgs(List<T> _args,
+                                           List<Type> parameters,
+                                           Type varargsElement,
+                                           Env<AttrContext> localEnv) {
+        Env<AttrContext> prevEnv = env;
+        try {
+            env = localEnv;
+            return translateArgs(_args, parameters, varargsElement);
+        }
+        finally {
+            env = prevEnv;
+        }
+    }
+
     /** Add a bridge definition and enter corresponding method symbol in
      *  local scope of origin.
      *
@@ -245,7 +271,7 @@
                            make.Select(receiver, impl).setType(calltype),
                            translateArgs(make.Idents(md.params), origErasure.getParameterTypes(), null))
                 .setType(calltype);
-            JCStatement stat = (origErasure.getReturnType().tag == VOID)
+            JCStatement stat = (origErasure.getReturnType().hasTag(VOID))
                 ? make.Exec(call)
                 : make.Return(coerce(call, bridgeType.getReturnType()));
             md.body = make.Block(0, List.of(stat));
@@ -400,7 +426,7 @@
      */
     void addBridges(DiagnosticPosition pos, ClassSymbol origin, ListBuffer<JCTree> bridges) {
         Type st = types.supertype(origin.type);
-        while (st.tag == CLASS) {
+        while (st.hasTag(CLASS)) {
 //          if (isSpecialization(st))
             addBridges(pos, st.tsym, origin, bridges);
             st = types.supertype(st);
@@ -449,9 +475,9 @@
         result = tree;
     }
 
-    JCMethodDecl currentMethod = null;
+    JCTree currentMethod = null;
     public void visitMethodDef(JCMethodDecl tree) {
-        JCMethodDecl previousMethod = currentMethod;
+        JCTree previousMethod = currentMethod;
         try {
             currentMethod = tree;
             tree.restype = translate(tree.restype, null);
@@ -517,6 +543,22 @@
         result = tree;
     }
 
+    public void visitLambda(JCLambda tree) {
+        JCTree prevMethod = currentMethod;
+        try {
+            currentMethod = null;
+            tree.params = translate(tree.params);
+            tree.body = translate(tree.body, null);
+            //save non-erased target
+            tree.targetType = tree.type;
+            tree.type = erasure(tree.type);
+            result = tree;
+        }
+        finally {
+            currentMethod = prevMethod;
+        }
+    }
+
     public void visitSwitch(JCSwitch tree) {
         Type selsuper = types.supertype(tree.selector.type);
         boolean enumSwitch = selsuper != null &&
@@ -568,7 +610,7 @@
     }
 
     public void visitReturn(JCReturn tree) {
-        tree.expr = translate(tree.expr, currentMethod.sym.erasure(types).getReturnType());
+        tree.expr = translate(tree.expr, currentMethod != null ? types.erasure(currentMethod.type).getReturnType() : null);
         result = tree;
     }
 
@@ -599,6 +641,7 @@
             Assert.check(tree.args.length() == argtypes.length());
         tree.args = translateArgs(tree.args, argtypes, tree.varargsElement);
 
+        tree.type = types.erasure(tree.type);
         // Insert casts of method invocation results as needed.
         result = retype(tree, mt.getReturnType(), pt);
     }
@@ -612,6 +655,8 @@
         tree.args = translateArgs(
             tree.args, tree.constructor.erasure(types).getParameterTypes(), tree.varargsElement);
         tree.def = translate(tree.def, null);
+        if (tree.constructorType != null)
+            tree.constructorType = erasure(tree.constructorType);
         tree.type = erasure(tree.type);
         result = tree;
     }
@@ -629,16 +674,6 @@
         result = tree;
     }
 
-    @Override
-    public void visitLambda(JCLambda tree) {
-        Assert.error("Translation of lambda expression not supported yet");
-    }
-
-    @Override
-    public void visitReference(JCMemberReference tree) {
-        Assert.error("Translation of method reference not supported yet");
-    }
-
     public void visitParens(JCParens tree) {
         tree.expr = translate(tree.expr, pt);
         tree.type = erasure(tree.type);
@@ -701,7 +736,7 @@
         Type et = tree.sym.erasure(types);
 
         // Map type variables to their bounds.
-        if (tree.sym.kind == TYP && tree.sym.type.tag == TYPEVAR) {
+        if (tree.sym.kind == TYP && tree.sym.type.hasTag(TYPEVAR)) {
             result = make.at(tree.pos).Type(et);
         } else
         // Map constants expressions to themselves.
@@ -720,7 +755,7 @@
 
     public void visitSelect(JCFieldAccess tree) {
         Type t = tree.selected.type;
-        while (t.tag == TYPEVAR)
+        while (t.hasTag(TYPEVAR))
             t = t.getUpperBound();
         if (t.isCompound()) {
             if ((tree.sym.flags() & IPROXY) != 0) {
@@ -747,6 +782,14 @@
         }
     }
 
+    public void visitReference(JCMemberReference tree) {
+        tree.expr = translate(tree.expr, null);
+        //save non-erased target
+        tree.targetType = tree.type;
+        tree.type = erasure(tree.type);
+        result = tree;
+    }
+
     public void visitTypeArray(JCArrayTypeTree tree) {
         tree.elemtype = translate(tree.elemtype, null);
         tree.type = erasure(tree.type);
@@ -844,7 +887,7 @@
                        translateArgs(make.Idents(md.params),
                                      implErasure.getParameterTypes(), null))
             .setType(calltype);
-        JCStatement stat = (member.getReturnType().tag == VOID)
+        JCStatement stat = (member.getReturnType().hasTag(VOID))
             ? make.Exec(call)
             : make.Return(coerce(call, member.erasure(types).getReturnType()));
         md.body = make.Block(0, List.of(stat));
@@ -862,7 +905,7 @@
         Type st = types.supertype(c.type);
 
         // process superclass before derived
-        if (st.tag == CLASS)
+        if (st.hasTag(CLASS))
             translateClass((ClassSymbol)st.tsym);
 
         Env<AttrContext> myEnv = enter.typeEnvs.remove(c);
--- a/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Fri Nov 02 17:55:34 2012 -0700
@@ -90,7 +90,7 @@
         EnumSet.of(JavaFileObject.Kind.SOURCE, JavaFileObject.Kind.CLASS);
 
     protected boolean mmappedIO;
-    protected boolean ignoreSymbolFile;
+    protected boolean symbolFileEnabled;
 
     protected enum SortFiles implements Comparator<File> {
         FORWARD {
@@ -142,7 +142,7 @@
             zipFileIndexCache = ZipFileIndexCache.getSharedInstance();
 
         mmappedIO = options.isSet("mmappedIO");
-        ignoreSymbolFile = options.isSet("ignore.symbol.file");
+        symbolFileEnabled = !options.isSet("ignore.symbol.file");
 
         String sf = options.get("sortFiles");
         if (sf != null) {
@@ -150,6 +150,13 @@
         }
     }
 
+    /**
+     * Set whether or not to use ct.sym as an alternate to rt.jar.
+     */
+    public void setSymbolFileEnabled(boolean b) {
+        symbolFileEnabled = b;
+    }
+
     @Override
     public boolean isDefaultBootClassPath() {
         return locations.isDefaultBootClassPath();
@@ -466,7 +473,7 @@
      */
     private Archive openArchive(File zipFileName, boolean useOptimizedZip) throws IOException {
         File origZipFileName = zipFileName;
-        if (!ignoreSymbolFile && locations.isDefaultBootClassPathRtJar(zipFileName)) {
+        if (symbolFileEnabled && locations.isDefaultBootClassPathRtJar(zipFileName)) {
             File file = zipFileName.getParentFile().getParentFile(); // ${java.home}
             if (new File(file.getName()).equals(new File("jre")))
                 file = file.getParentFile();
--- a/src/share/classes/com/sun/tools/javac/file/Locations.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/file/Locations.java	Fri Nov 02 17:55:34 2012 -0700
@@ -420,14 +420,10 @@
             if (!options.contains(option))
                 return false;
             searchPath = value == null ? null :
-                    Collections.unmodifiableCollection(computePath(value));
+                    Collections.unmodifiableCollection(createPath().addFiles(value));
             return true;
         }
 
-        protected Path computePath(String value) {
-            return new Path().addFiles(value);
-        }
-
         @Override
         Collection<File> getLocation() {
             return searchPath;
@@ -439,10 +435,18 @@
             if (files == null) {
                 p = computePath(null);
             } else {
-                p = new Path().addFiles(files);
+                p = createPath().addFiles(files);
             }
             searchPath = Collections.unmodifiableCollection(p);
         }
+
+        protected Path computePath(String value) {
+            return createPath().addFiles(value);
+        }
+
+        protected Path createPath() {
+            return new Path();
+        }
     }
 
     /**
@@ -477,11 +481,15 @@
             // Default to current working directory.
             if (cp == null) cp = ".";
 
+            return createPath().addFiles(cp);
+        }
+
+        @Override
+        protected Path createPath() {
             return new Path()
-                .expandJarClassPaths(true)        // Only search user jars for Class-Paths
-                .emptyPathDefault(new File("."))  // Empty path elt ==> current directory
-                .addFiles(cp);
-            }
+                .expandJarClassPaths(true)         // Only search user jars for Class-Paths
+                .emptyPathDefault(new File("."));  // Empty path elt ==> current directory
+        }
 
         private void lazy() {
             if (searchPath == null)
@@ -591,7 +599,6 @@
             String extdirsOpt = optionValues.get(EXTDIRS);
             String xbootclasspathPrependOpt = optionValues.get(XBOOTCLASSPATH_PREPEND);
             String xbootclasspathAppendOpt = optionValues.get(XBOOTCLASSPATH_APPEND);
-
             path.addFiles(xbootclasspathPrependOpt);
 
             if (endorseddirsOpt != null)
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Fri Nov 02 17:55:34 2012 -0700
@@ -55,7 +55,7 @@
 
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Kinds.*;
-import static com.sun.tools.javac.code.TypeTags.*;
+import static com.sun.tools.javac.code.TypeTag.CLASS;
 import static com.sun.tools.javac.jvm.ClassFile.*;
 import static com.sun.tools.javac.jvm.ClassFile.Version.*;
 
@@ -1018,6 +1018,15 @@
                     ClassSymbol c = (ClassSymbol) sym;
                     Name n = readName(nextChar());
                     c.sourcefile = new SourceFileObject(n, c.flatname);
+                    // If the class is a toplevel class, originating from a Java source file,
+                    // but the class name does not match the file name, then it is
+                    // an auxiliary class.
+                    String sn = n.toString();
+                    if (c.owner.kind == Kinds.PCK &&
+                        sn.endsWith(".java") &&
+                        !sn.equals(c.name.toString()+".java")) {
+                        c.flags_field |= AUXILIARY;
+                    }
                 }
             },
 
@@ -1870,7 +1879,7 @@
      *  `typevars'.
      */
     protected void enterTypevars(Type t) {
-        if (t.getEnclosingType() != null && t.getEnclosingType().tag == CLASS)
+        if (t.getEnclosingType() != null && t.getEnclosingType().hasTag(CLASS))
             enterTypevars(t.getEnclosingType());
         for (List<Type> xs = t.getTypeArguments(); xs.nonEmpty(); xs = xs.tail)
             typevars.enter(xs.head.tsym);
@@ -1895,7 +1904,7 @@
 
         // prepare type variable table
         typevars = typevars.dup(currentOwner);
-        if (ct.getEnclosingType().tag == CLASS)
+        if (ct.getEnclosingType().hasTag(CLASS))
             enterTypevars(ct.getEnclosingType());
 
         // read flags, or skip if this is an inner class
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Fri Nov 02 17:55:34 2012 -0700
@@ -45,7 +45,7 @@
 import static com.sun.tools.javac.code.BoundKind.*;
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Kinds.*;
-import static com.sun.tools.javac.code.TypeTags.*;
+import static com.sun.tools.javac.code.TypeTag.*;
 import static com.sun.tools.javac.jvm.UninitializedType.*;
 import static com.sun.tools.javac.main.Option.*;
 import static javax.tools.StandardLocation.CLASS_OUTPUT;
@@ -274,7 +274,7 @@
     /** Assemble signature of given type in string buffer.
      */
     void assembleSig(Type type) {
-        switch (type.tag) {
+        switch (type.getTag()) {
         case BYTE:
             sigbuf.appendByte('B');
             break;
@@ -361,13 +361,13 @@
             assembleSig(types.erasure(((UninitializedType)type).qtype));
             break;
         default:
-            throw new AssertionError("typeSig " + type.tag);
+            throw new AssertionError("typeSig " + type.getTag());
         }
     }
 
     boolean hasTypeVar(List<Type> l) {
         while (l.nonEmpty()) {
-            if (l.head.tag == TypeTags.TYPEVAR) return true;
+            if (l.head.hasTag(TYPEVAR)) return true;
             l = l.tail;
         }
         return false;
@@ -439,9 +439,9 @@
      *  external representation.
      */
     public Name xClassName(Type t) {
-        if (t.tag == CLASS) {
+        if (t.hasTag(CLASS)) {
             return names.fromUtf(externalize(t.tsym.flatName()));
-        } else if (t.tag == ARRAY) {
+        } else if (t.hasTag(ARRAY)) {
             return typeSig(types.erasure(t));
         } else {
             throw new AssertionError("xClassName");
@@ -521,7 +521,7 @@
                 ClassSymbol c = (ClassSymbol)value;
                 if (c.owner.kind == TYP) pool.put(c.owner);
                 poolbuf.appendByte(CONSTANT_Class);
-                if (c.type.tag == ARRAY) {
+                if (c.type.hasTag(ARRAY)) {
                     poolbuf.appendChar(pool.put(typeSig(c.type)));
                 } else {
                     poolbuf.appendChar(pool.put(names.fromUtf(externalize(c.flatname))));
@@ -555,7 +555,7 @@
                 poolbuf.appendChar(pool.put(typeSig(mtype)));
             } else if (value instanceof Type) {
                 Type type = (Type)value;
-                if (type.tag == CLASS) enterInner((ClassSymbol)type.tsym);
+                if (type.hasTag(CLASS)) enterInner((ClassSymbol)type.tsym);
                 poolbuf.appendByte(CONSTANT_Class);
                 poolbuf.appendChar(pool.put(xClassName(type)));
             } else if (value instanceof Pool.MethodHandle) {
@@ -815,7 +815,7 @@
     class AttributeWriter implements Attribute.Visitor {
         public void visitConstant(Attribute.Constant _value) {
             Object value = _value.value;
-            switch (_value.type.tag) {
+            switch (_value.type.getTag()) {
             case BYTE:
                 databuf.appendByte('B');
                 break;
@@ -901,7 +901,7 @@
             System.err.println("error: " + c + ": " + ex.getMessage());
             throw ex;
         }
-        if (c.type.tag != CLASS) return; // arrays
+        if (!c.type.hasTag(CLASS)) return; // arrays
         if (pool != null && // pool might be null if called from xClassName
             c.owner.enclClass() != null &&
             (innerClasses == null || !innerClasses.contains(c))) {
@@ -1207,7 +1207,7 @@
                 if (debugstackmap) System.out.print("empty");
                 databuf.appendByte(0);
             }
-            else switch(t.tag) {
+            else switch(t.getTag()) {
             case BYTE:
             case CHAR:
             case SHORT:
@@ -1430,7 +1430,7 @@
         }
 
         static boolean isInt(Type t) {
-            return (t.tag < TypeTags.INT || t.tag == TypeTags.BOOLEAN);
+            return (t.getTag().isStrictSubRangeOf(INT)  || t.hasTag(BOOLEAN));
         }
 
         static boolean isSameType(Type t1, Type t2, Types types) {
@@ -1439,15 +1439,15 @@
 
             if (isInt(t1) && isInt(t2)) { return true; }
 
-            if (t1.tag == UNINITIALIZED_THIS) {
-                return t2.tag == UNINITIALIZED_THIS;
-            } else if (t1.tag == UNINITIALIZED_OBJECT) {
-                if (t2.tag == UNINITIALIZED_OBJECT) {
+            if (t1.hasTag(UNINITIALIZED_THIS)) {
+                return t2.hasTag(UNINITIALIZED_THIS);
+            } else if (t1.hasTag(UNINITIALIZED_OBJECT)) {
+                if (t2.hasTag(UNINITIALIZED_OBJECT)) {
                     return ((UninitializedType)t1).offset == ((UninitializedType)t2).offset;
                 } else {
                     return false;
                 }
-            } else if (t2.tag == UNINITIALIZED_THIS || t2.tag == UNINITIALIZED_OBJECT) {
+            } else if (t2.hasTag(UNINITIALIZED_THIS) || t2.hasTag(UNINITIALIZED_OBJECT)) {
                 return false;
             }
 
@@ -1554,7 +1554,7 @@
         databuf.appendChar(flags);
 
         databuf.appendChar(pool.put(c));
-        databuf.appendChar(supertype.tag == CLASS ? pool.put(supertype.tsym) : 0);
+        databuf.appendChar(supertype.hasTag(CLASS) ? pool.put(supertype.tsym) : 0);
         databuf.appendChar(interfaces.length());
         for (List<Type> l = interfaces; l.nonEmpty(); l = l.tail)
             databuf.appendChar(pool.put(l.head.tsym));
--- a/src/share/classes/com/sun/tools/javac/jvm/Code.java	Thu Nov 01 14:13:13 2012 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/Code.java	Fri Nov 02 17:55:34 2012 -0700
@@ -30,7 +30,8 @@
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 
-import static com.sun.tools.javac.code.TypeTags.*;
+import static com.sun.tools.javac.code.TypeTag.BOT;
+import static com.sun.tools.javac.code.TypeTag.INT;
 import static com.sun.tools.javac.jvm.ByteCodes.*;
 import static com.sun.tools.javac.jvm.UninitializedType.*;
 import static com.sun.tools.javac.jvm.ClassWriter.StackMapTableFrame;
@@ -224,7 +225,7 @@
      *  JVM architecture).
      */
     public static int typecode(Type type) {
-        switch (type.tag) {
+        switch (type.getTag()) {
         case BYTE: return BYTEcode;
         case SHORT: return SHORTcode;
         case CHAR: return CHARcode;
@@ -242,7 +243,7 @@
         case UNINITIALIZED_THIS:
         case UNINITIALIZED_OBJECT:
             return OBJECTcode;
-        default: throw new AssertionError("typecode " + type.tag);
+        default: throw new AssertionError("typecode " + type.getTag());
         }
     }
 
@@ -281,7 +282,7 @@
     /** Given a type, return its code for allocating arrays of that type.
      */
     public static int arraycode(Type type) {
-        switch (type.tag) {
+        switch (type.getTag()) {
         case BYTE: return 8;
         case BOOLEAN: return 4;
         case SHORT: return 9;
@@ -477,7 +478,7 @@
             state.pop(1);
             //sometimes 'null type' is treated as a one-dimensional array type
             //see Gen.visitLiteral - we should handle this case accordingly
-            Type stackType = a.tag == BOT ?
+            Type stackType = a.hasTag(BOT) ?
                 syms.objectType :
                 types.erasure(types.elemtype(a));
             state.push(stackType); }
@@ -1656,13 +1657,13 @@
 
         void push(Type t) {
             if (debugCode) System.err.println("   pushing " + t);
-            switch (t.tag) {
-            case TypeTags.VOID:
+            switch (t.getTag()) {
+            case VOID:
                 return;
-            case TypeTags.BYTE:
-            case TypeTags.CHAR:
-            case TypeTags.SHORT:
-            case TypeTags.BOOLEAN:
+            case BYTE:
+            case CHAR:
+            case SHORT:
+            case BOOLEAN:
                 t = syms.intType;
                 break;
             default:
@@ -1722,7 +1723,7 @@
          *  of its current type. */
         void forceStackTop(Type t) {
             if (!alive) return;
-            switch (t.tag) {
+            switch (t.getTag()) {
             case CLASS:
             case ARRAY:
                 int width = width(t);
@@ -1824,7 +1825,7 @@
         }
     }
 
-    static Type jsrReturnValue = new Type(TypeTags.INT, null);
+    static Type jsrReturnValue = new Type(INT, null);
 
 
 /* ********************************************************