changeset 47923:4a28dc8a86c2

8190821: Introduce a new Links builder class Reviewed-by: bpatel, ksrini
author jjg
date Thu, 16 Nov 2017 15:16:21 -0800
parents 0e38db7cf1cc
children 6a9bb4f77d50
files src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractExecutableMemberWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractIndexWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractMemberWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeFieldWriterImpl.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeOptionalMemberWriterImpl.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeWriterImpl.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstantsSummaryWriterImpl.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstructorWriterImpl.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DeprecatedListWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/EnumConstantWriterImpl.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FieldWriterImpl.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HelpWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/LinkFactoryImpl.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MethodWriterImpl.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleFrameWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleIndexFrameWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModulePackageIndexFrameWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/NestedClassWriterImpl.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageIndexFrameWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageTreeWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageUseWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PropertyWriterImpl.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SingleIndexWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SplitIndexWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TreeWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlDocWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Links.java
diffstat 36 files changed, 569 insertions(+), 436 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractExecutableMemberWriter.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractExecutableMemberWriter.java	Thu Nov 16 15:16:21 2017 -0800
@@ -358,6 +358,6 @@
             }
         }
         buf.append(")");
-        return foundTypeVariable ? writer.getName(buf.toString()) : null;
+        return foundTypeVariable ? configuration.links.getName(buf.toString()) : null;
     }
 }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractIndexWriter.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractIndexWriter.java	Thu Nov 16 15:16:21 2017 -0800
@@ -222,6 +222,7 @@
      *
      * @param mdle the module to be documented
      * @param dlTree the content tree to which the description will be added
+     * @param si the search index item
      */
     protected void addDescription(ModuleElement mdle, Content dlTree, SearchIndexItem si) {
         String moduleName = utils.getFullyQualifiedName(mdle);
@@ -316,7 +317,7 @@
             name = name + utils.flatSignature(ee);
             si.setLabel(name);
             if (!((utils.signature(ee)).equals(utils.flatSignature(ee)))) {
-                si.setUrl(getName(getAnchor(ee)));
+                si.setUrl(links.getName(getAnchor(ee)));
             }
 
         }  else {
@@ -420,7 +421,7 @@
      * @return a content tree for the marker anchor
      */
     public Content getMarkerAnchorForIndex(String anchorNameForIndex) {
-        return getMarkerAnchor(getNameForIndex(anchorNameForIndex), null);
+        return links.createAnchor(getNameForIndex(anchorNameForIndex), null);
     }
 
     /**
@@ -430,7 +431,7 @@
      * @return a valid HTML name string.
      */
     public String getNameForIndex(String unicode) {
-        return "I:" + getName(unicode);
+        return "I:" + links.getName(unicode);
     }
 
     /**
@@ -452,6 +453,13 @@
     }
 
     /**
+     * Creates a search index file.
+     *
+     * @param searchIndexFile   the file to be generated
+     * @param searchIndexZip    the zip file to be generated
+     * @param searchIndexJS     the file for the JavaScript to be generated
+     * @param searchIndex       the search index items
+     * @param varName           the variable name to write in the JavaScript file
      * @throws DocFileIOException if there is a problem creating the search index file
      */
     protected void createSearchIndexFile(DocPath searchIndexFile, DocPath searchIndexZip,
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractMemberWriter.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractMemberWriter.java	Thu Nov 16 15:16:21 2017 -0800
@@ -44,6 +44,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.Content;
 import jdk.javadoc.internal.doclets.toolkit.MemberSummaryWriter;
@@ -74,6 +75,7 @@
     protected final SubWriterHolderWriter writer;
     protected final Contents contents;
     protected final Resources resources;
+    protected final Links links;
 
     protected final TypeElement typeElement;
     public final boolean nodepr;
@@ -88,6 +90,7 @@
         this.utils = configuration.utils;
         this.contents = configuration.contents;
         this.resources = configuration.resources;
+        this.links = configuration.links;
     }
 
     public AbstractMemberWriter(SubWriterHolderWriter writer) {
@@ -519,6 +522,7 @@
      * @param member the member being documented
      * @param firstSentenceTags the first sentence tags to be added to the summary
      */
+    @Override
     public void addMemberSummary(TypeElement tElement, Element member,
             List<? extends DocTree> firstSentenceTags) {
         if (tElement != typeElement) {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeFieldWriterImpl.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeFieldWriterImpl.java	Thu Nov 16 15:16:21 2017 -0800
@@ -39,6 +39,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.AnnotationTypeFieldWriter;
 import jdk.javadoc.internal.doclets.toolkit.Content;
@@ -108,7 +109,7 @@
     public void addAnnotationDetailsTreeHeader(TypeElement typeElement,
             Content memberDetailsTree) {
         if (!writer.printedAnnotationFieldHeading) {
-            memberDetailsTree.addContent(writer.getMarkerAnchor(
+            memberDetailsTree.addContent(links.createAnchor(
                     SectionName.ANNOTATION_TYPE_FIELD_DETAIL));
             Content heading = HtmlTree.HEADING(HtmlConstants.DETAILS_HEADING,
                     contents.fieldDetailsLabel);
@@ -122,8 +123,7 @@
      */
     public Content getAnnotationDocTreeHeader(Element member,
             Content annotationDetailsTree) {
-        annotationDetailsTree.addContent(
-                writer.getMarkerAnchor(name(member)));
+        annotationDetailsTree.addContent(links.createAnchor(name(member)));
         Content annotationDocTree = writer.getMemberTreeHeader();
         Content heading = new HtmlTree(HtmlConstants.MEMBER_HEADING);
         heading.addContent(name(member));
@@ -232,26 +232,30 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public void addSummaryAnchor(TypeElement typeElement, Content memberTree) {
-        memberTree.addContent(writer.getMarkerAnchor(
+        memberTree.addContent(links.createAnchor(
                 SectionName.ANNOTATION_TYPE_FIELD_SUMMARY));
     }
 
     /**
      * {@inheritDoc}
      */
+    @Override
     public void addInheritedSummaryAnchor(TypeElement typeElement, Content inheritedTree) {
     }
 
     /**
      * {@inheritDoc}
      */
+    @Override
     public void addInheritedSummaryLabel(TypeElement typeElement, Content inheritedTree) {
     }
 
     /**
      * {@inheritDoc}
      */
+    @Override
     protected void addSummaryLink(LinkInfoImpl.Kind context, TypeElement typeElement, Element member,
             Content tdSummary) {
         Content memberLink = HtmlTree.SPAN(HtmlStyle.memberNameLink,
@@ -288,7 +292,7 @@
      */
     protected Content getNavSummaryLink(TypeElement typeElement, boolean link) {
         if (link) {
-            return writer.getHyperLink(
+            return Links.createLink(
                     SectionName.ANNOTATION_TYPE_FIELD_SUMMARY,
                     contents.navField);
         } else {
@@ -301,7 +305,7 @@
      */
     protected void addNavDetailLink(boolean link, Content liNav) {
         if (link) {
-            liNav.addContent(writer.getHyperLink(
+            liNav.addContent(Links.createLink(
                     SectionName.ANNOTATION_TYPE_FIELD_DETAIL,
                     contents.navField));
         } else {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeOptionalMemberWriterImpl.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeOptionalMemberWriterImpl.java	Thu Nov 16 15:16:21 2017 -0800
@@ -35,6 +35,7 @@
 
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.AnnotationTypeOptionalMemberWriter;
 import jdk.javadoc.internal.doclets.toolkit.Content;
@@ -148,7 +149,7 @@
      */
     @Override
     public void addSummaryAnchor(TypeElement typeElement, Content memberTree) {
-        memberTree.addContent(writer.getMarkerAnchor(
+        memberTree.addContent(links.createAnchor(
                 SectionName.ANNOTATION_TYPE_OPTIONAL_ELEMENT_SUMMARY));
     }
 
@@ -158,7 +159,7 @@
     @Override
     protected Content getNavSummaryLink(TypeElement typeElement, boolean link) {
         if (link) {
-            return writer.getHyperLink(
+            return Links.createLink(
                     SectionName.ANNOTATION_TYPE_OPTIONAL_ELEMENT_SUMMARY,
                     contents.navAnnotationTypeOptionalMember);
         } else {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java	Thu Nov 16 15:16:21 2017 -0800
@@ -40,6 +40,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.AnnotationTypeRequiredMemberWriter;
 import jdk.javadoc.internal.doclets.toolkit.Content;
@@ -110,7 +111,7 @@
     public void addAnnotationDetailsTreeHeader(TypeElement te,
             Content memberDetailsTree) {
         if (!writer.printedAnnotationHeading) {
-            memberDetailsTree.addContent(writer.getMarkerAnchor(
+            memberDetailsTree.addContent(links.createAnchor(
                     SectionName.ANNOTATION_TYPE_ELEMENT_DETAIL));
             Content heading = HtmlTree.HEADING(HtmlConstants.DETAILS_HEADING,
                     contents.annotationTypeDetailsLabel);
@@ -122,11 +123,11 @@
     /**
      * {@inheritDoc}
      */
-    public Content getAnnotationDocTreeHeader(Element member,
-            Content annotationDetailsTree) {
+    @Override
+    public Content getAnnotationDocTreeHeader(Element member, Content annotationDetailsTree) {
         String simpleName = name(member);
-        annotationDetailsTree.addContent(writer.getMarkerAnchor(simpleName +
-                utils.signature((ExecutableElement) member)));
+        annotationDetailsTree.addContent(links.createAnchor(
+                simpleName + utils.signature((ExecutableElement) member)));
         Content annotationDocTree = writer.getMemberTreeHeader();
         Content heading = new HtmlTree(HtmlConstants.MEMBER_HEADING);
         heading.addContent(simpleName);
@@ -252,7 +253,7 @@
      * {@inheritDoc}
      */
     public void addSummaryAnchor(TypeElement typeElement, Content memberTree) {
-        memberTree.addContent(writer.getMarkerAnchor(
+        memberTree.addContent(links.createAnchor(
                 SectionName.ANNOTATION_TYPE_REQUIRED_ELEMENT_SUMMARY));
     }
 
@@ -307,7 +308,7 @@
      */
     protected Content getNavSummaryLink(TypeElement typeElement, boolean link) {
         if (link) {
-            return writer.getHyperLink(
+            return Links.createLink(
                     SectionName.ANNOTATION_TYPE_REQUIRED_ELEMENT_SUMMARY,
                     contents.navAnnotationTypeRequiredMember);
         } else {
@@ -320,7 +321,7 @@
      */
     protected void addNavDetailLink(boolean link, Content liNav) {
         if (link) {
-            liNav.addContent(writer.getHyperLink(
+            liNav.addContent(Links.createLink(
                     SectionName.ANNOTATION_TYPE_ELEMENT_DETAIL,
                     contents.navAnnotationTypeMember));
         } else {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeWriterImpl.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeWriterImpl.java	Thu Nov 16 15:16:21 2017 -0800
@@ -37,6 +37,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.AnnotationTypeWriter;
 import jdk.javadoc.internal.doclets.toolkit.Content;
@@ -108,7 +109,7 @@
      */
     @Override
     protected Content getNavLinkPackage() {
-        Content linkContent = getHyperLink(DocPaths.PACKAGE_SUMMARY,
+        Content linkContent = Links.createLink(DocPaths.PACKAGE_SUMMARY,
                 contents.packageLabel);
         Content li = HtmlTree.LI(linkContent);
         return li;
@@ -132,7 +133,7 @@
      */
     @Override
     protected Content getNavLinkClassUse() {
-        Content linkContent = getHyperLink(DocPaths.CLASS_USE.resolve(filename), contents.useLabel);
+        Content linkContent = Links.createLink(DocPaths.CLASS_USE.resolve(filename), contents.useLabel);
         Content li = HtmlTree.LI(linkContent);
         return li;
     }
@@ -346,7 +347,7 @@
      */
     @Override
     protected Content getNavLinkTree() {
-        Content treeLinkContent = getHyperLink(DocPaths.PACKAGE_TREE,
+        Content treeLinkContent = Links.createLink(DocPaths.PACKAGE_TREE,
                 contents.treeLabel, "", "");
         Content li = HtmlTree.LI(treeLinkContent);
         return li;
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java	Thu Nov 16 15:16:21 2017 -0800
@@ -47,6 +47,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.Content;
 import jdk.javadoc.internal.doclets.toolkit.util.ClassTree;
@@ -348,7 +349,7 @@
         HtmlTree ul = new HtmlTree(HtmlTag.UL);
         ul.setStyle(HtmlStyle.blockList);
         for (PackageElement pkg : pkgSet) {
-            Content markerAnchor = getMarkerAnchor(getPackageAnchorName(pkg));
+            Content markerAnchor = links.createAnchor(getPackageAnchorName(pkg));
             HtmlTree htmlTree = (configuration.allowTag(HtmlTag.SECTION))
                     ? HtmlTree.SECTION(markerAnchor)
                     : HtmlTree.LI(HtmlStyle.blockList, markerAnchor);
@@ -377,7 +378,7 @@
      */
     protected void addPackageUse(PackageElement pkg, Table table) {
         Content pkgLink =
-                getHyperLink(getPackageAnchorName(pkg), new StringContent(utils.getPackageName(pkg)));
+                links.createLink(getPackageAnchorName(pkg), new StringContent(utils.getPackageName(pkg)));
         Content summary = new ContentBuilder();
         addSummaryComment(pkg, summary);
         table.addRow(pkgLink, summary);
@@ -514,7 +515,7 @@
      */
     protected Content getNavLinkPackage() {
         Content linkContent =
-                getHyperLink(DocPath.parent.resolve(DocPaths.PACKAGE_SUMMARY), contents.packageLabel);
+                Links.createLink(DocPath.parent.resolve(DocPaths.PACKAGE_SUMMARY), contents.packageLabel);
         Content li = HtmlTree.LI(linkContent);
         return li;
     }
@@ -549,8 +550,8 @@
      */
     protected Content getNavLinkTree() {
         Content linkContent = utils.isEnclosingPackageIncluded(typeElement)
-                ? getHyperLink(DocPath.parent.resolve(DocPaths.PACKAGE_TREE), contents.treeLabel)
-                : getHyperLink(pathToRoot.resolve(DocPaths.OVERVIEW_TREE), contents.treeLabel);
+                ? Links.createLink(DocPath.parent.resolve(DocPaths.PACKAGE_TREE), contents.treeLabel)
+                : Links.createLink(pathToRoot.resolve(DocPaths.OVERVIEW_TREE), contents.treeLabel);
         Content li = HtmlTree.LI(linkContent);
         return li;
     }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java	Thu Nov 16 15:16:21 2017 -0800
@@ -40,6 +40,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.ClassWriter;
 import jdk.javadoc.internal.doclets.toolkit.Content;
@@ -119,7 +120,7 @@
      */
     @Override
     protected Content getNavLinkPackage() {
-        Content linkContent = getHyperLink(DocPaths.PACKAGE_SUMMARY,
+        Content linkContent = Links.createLink(DocPaths.PACKAGE_SUMMARY,
                 contents.packageLabel);
         Content li = HtmlTree.LI(linkContent);
         return li;
@@ -143,7 +144,7 @@
      */
     @Override
     protected Content getNavLinkClassUse() {
-        Content linkContent = getHyperLink(DocPaths.CLASS_USE.resolve(filename), contents.useLabel);
+        Content linkContent = Links.createLink(DocPaths.CLASS_USE.resolve(filename), contents.useLabel);
         Content li = HtmlTree.LI(linkContent);
         return li;
     }
@@ -659,7 +660,7 @@
      */
     @Override
     protected Content getNavLinkTree() {
-        Content treeLinkContent = getHyperLink(DocPaths.PACKAGE_TREE,
+        Content treeLinkContent = Links.createLink(DocPaths.PACKAGE_TREE,
                 contents.treeLabel, "", "");
         Content li = HtmlTree.LI(treeLinkContent);
         return li;
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstantsSummaryWriterImpl.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstantsSummaryWriterImpl.java	Thu Nov 16 15:16:21 2017 -0800
@@ -40,6 +40,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.ConstantsSummaryWriter;
 import jdk.javadoc.internal.doclets.toolkit.Content;
@@ -134,14 +135,13 @@
         //add link to summary
         Content link;
         if (pkg.isUnnamed()) {
-            link = getHyperLink(getDocLink(
-                    SectionName.UNNAMED_PACKAGE_ANCHOR),
+            link = Links.createLink(SectionName.UNNAMED_PACKAGE_ANCHOR,
                     contents.defaultPackageLabel, "", "");
         } else {
             String parsedPackageName = utils.parsePackageName(pkg);
             Content packageNameContent = getPackageLabel(parsedPackageName);
             packageNameContent.addContent(".*");
-            link = getHyperLink(DocLink.fragment(parsedPackageName),
+            link = Links.createLink(DocLink.fragment(parsedPackageName),
                     packageNameContent, "", "");
             PackageElement abbrevPkg = configuration.workArounds.getAbbreviatedPackageElement(pkg);
             printedPackageHeaders.add(abbrevPkg);
@@ -193,12 +193,11 @@
             summariesTree.addContent(summaryTree);
         }
         if (pkg.isUnnamed()) {
-            summariesTree.addContent(getMarkerAnchor(
-                    SectionName.UNNAMED_PACKAGE_ANCHOR));
+            summariesTree.addContent(links.createAnchor(SectionName.UNNAMED_PACKAGE_ANCHOR));
             pkgNameContent = contents.defaultPackageLabel;
         } else {
             String parsedPackageName = utils.parsePackageName(pkg);
-            summariesTree.addContent(getMarkerAnchor(parsedPackageName));
+            summariesTree.addContent(links.createAnchor(parsedPackageName));
             pkgNameContent = getPackageLabel(parsedPackageName);
         }
         Content headingContent = new StringContent(".*");
@@ -277,8 +276,8 @@
      * @return the type column of the constant table row
      */
     private Content getTypeColumn(VariableElement member) {
-        Content anchor = getMarkerAnchor(currentTypeElement.getQualifiedName() +
-                "." + member.getSimpleName());
+        Content anchor = links.createAnchor(
+                currentTypeElement.getQualifiedName() + "." + member.getSimpleName());
         Content typeContent = new ContentBuilder();
         typeContent.addContent(anchor);
         Content code = new HtmlTree(HtmlTag.CODE);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstructorWriterImpl.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstructorWriterImpl.java	Thu Nov 16 15:16:21 2017 -0800
@@ -38,6 +38,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.ConstructorWriter;
 import jdk.javadoc.internal.doclets.toolkit.Content;
@@ -119,7 +120,7 @@
             Content memberDetailsTree) {
         memberDetailsTree.addContent(HtmlConstants.START_OF_CONSTRUCTOR_DETAILS);
         Content constructorDetailsTree = writer.getMemberTreeHeader();
-        constructorDetailsTree.addContent(writer.getMarkerAnchor(
+        constructorDetailsTree.addContent(links.createAnchor(
                 SectionName.CONSTRUCTOR_DETAIL));
         Content heading = HtmlTree.HEADING(HtmlConstants.DETAILS_HEADING,
                 contents.constructorDetailsLabel);
@@ -135,10 +136,9 @@
             Content constructorDetailsTree) {
         String erasureAnchor;
         if ((erasureAnchor = getErasureAnchor(constructor)) != null) {
-            constructorDetailsTree.addContent(writer.getMarkerAnchor((erasureAnchor)));
+            constructorDetailsTree.addContent(links.createAnchor((erasureAnchor)));
         }
-        constructorDetailsTree.addContent(
-                writer.getMarkerAnchor(writer.getAnchor(constructor)));
+        constructorDetailsTree.addContent(links.createAnchor(writer.getAnchor(constructor)));
         Content constructorDocTree = writer.getMemberTreeHeader();
         Content heading = new HtmlTree(HtmlConstants.MEMBER_HEADING);
         heading.addContent(name(constructor));
@@ -277,8 +277,7 @@
      */
     @Override
     public void addSummaryAnchor(TypeElement typeElement, Content memberTree) {
-        memberTree.addContent(writer.getMarkerAnchor(
-                SectionName.CONSTRUCTOR_SUMMARY));
+        memberTree.addContent(links.createAnchor(SectionName.CONSTRUCTOR_SUMMARY));
     }
 
     /**
@@ -301,7 +300,7 @@
     @Override
     protected Content getNavSummaryLink(TypeElement typeElement, boolean link) {
         if (link) {
-            return writer.getHyperLink(SectionName.CONSTRUCTOR_SUMMARY,
+            return Links.createLink(SectionName.CONSTRUCTOR_SUMMARY,
                     contents.navConstructor);
         } else {
             return contents.navConstructor;
@@ -314,7 +313,7 @@
     @Override
     protected void addNavDetailLink(boolean link, Content liNav) {
         if (link) {
-            liNav.addContent(writer.getHyperLink(
+            liNav.addContent(Links.createLink(
                     SectionName.CONSTRUCTOR_DETAIL,
                     contents.navConstructor));
         } else {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DeprecatedListWriter.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DeprecatedListWriter.java	Thu Nov 16 15:16:21 2017 -0800
@@ -325,7 +325,7 @@
     private void addIndexLink(DeprecatedAPIListBuilder builder,
             DeprElementKind kind, Content contentTree) {
         if (builder.hasDocumentation(kind)) {
-            Content li = HtmlTree.LI(getHyperLink(getAnchorName(kind),
+            Content li = HtmlTree.LI(links.createLink(getAnchorName(kind),
                     contents.getContent(getHeadingKey(kind))));
             contentTree.addContent(li);
         }
@@ -362,7 +362,7 @@
      */
     private void addAnchor(DeprecatedAPIListBuilder builder, DeprElementKind kind, Content htmlTree) {
         if (builder.hasDocumentation(kind)) {
-            htmlTree.addContent(getMarkerAnchor(getAnchorName(kind)));
+            htmlTree.addContent(links.createAnchor(getAnchorName(kind)));
         }
     }
 
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/EnumConstantWriterImpl.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/EnumConstantWriterImpl.java	Thu Nov 16 15:16:21 2017 -0800
@@ -37,6 +37,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.Content;
 import jdk.javadoc.internal.doclets.toolkit.EnumConstantWriter;
@@ -92,7 +93,7 @@
             Content memberDetailsTree) {
         memberDetailsTree.addContent(HtmlConstants.START_OF_ENUM_CONSTANT_DETAILS);
         Content enumConstantsDetailsTree = writer.getMemberTreeHeader();
-        enumConstantsDetailsTree.addContent(writer.getMarkerAnchor(
+        enumConstantsDetailsTree.addContent(links.createAnchor(
                 SectionName.ENUM_CONSTANT_DETAIL));
         Content heading = HtmlTree.HEADING(HtmlConstants.DETAILS_HEADING,
                 contents.enumConstantDetailLabel);
@@ -106,8 +107,7 @@
     @Override
     public Content getEnumConstantsTreeHeader(VariableElement enumConstant,
             Content enumConstantsDetailsTree) {
-        enumConstantsDetailsTree.addContent(
-                writer.getMarkerAnchor(name(enumConstant)));
+        enumConstantsDetailsTree.addContent(links.createAnchor(name(enumConstant)));
         Content enumConstantsTree = writer.getMemberTreeHeader();
         Content heading = new HtmlTree(HtmlConstants.MEMBER_HEADING);
         heading.addContent(name(enumConstant));
@@ -221,8 +221,7 @@
      */
     @Override
     public void addSummaryAnchor(TypeElement typeElement, Content memberTree) {
-        memberTree.addContent(writer.getMarkerAnchor(
-                SectionName.ENUM_CONSTANT_SUMMARY));
+        memberTree.addContent(links.createAnchor(SectionName.ENUM_CONSTANT_SUMMARY));
     }
 
     /**
@@ -282,10 +281,10 @@
     protected Content getNavSummaryLink(TypeElement typeElement, boolean link) {
         if (link) {
             if (typeElement == null) {
-                return writer.getHyperLink(SectionName.ENUM_CONSTANT_SUMMARY,
+                return Links.createLink(SectionName.ENUM_CONSTANT_SUMMARY,
                         contents.navEnum);
             } else {
-                return writer.getHyperLink(
+                return links.createLink(
                         SectionName.ENUM_CONSTANTS_INHERITANCE,
                         configuration.getClassName(typeElement), contents.navEnum);
             }
@@ -300,7 +299,7 @@
     @Override
     protected void addNavDetailLink(boolean link, Content liNav) {
         if (link) {
-            liNav.addContent(writer.getHyperLink(
+            liNav.addContent(Links.createLink(
                     SectionName.ENUM_CONSTANT_DETAIL,
                     contents.navEnum));
         } else {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FieldWriterImpl.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FieldWriterImpl.java	Thu Nov 16 15:16:21 2017 -0800
@@ -39,6 +39,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.Content;
 import jdk.javadoc.internal.doclets.toolkit.FieldWriter;
@@ -95,7 +96,7 @@
     public Content getFieldDetailsTreeHeader(TypeElement typeElement, Content memberDetailsTree) {
         memberDetailsTree.addContent(HtmlConstants.START_OF_FIELD_DETAILS);
         Content fieldDetailsTree = writer.getMemberTreeHeader();
-        fieldDetailsTree.addContent(writer.getMarkerAnchor(
+        fieldDetailsTree.addContent(links.createAnchor(
                 SectionName.FIELD_DETAIL));
         Content heading = HtmlTree.HEADING(HtmlConstants.DETAILS_HEADING,
                 contents.fieldDetailsLabel);
@@ -108,7 +109,7 @@
      */
     @Override
     public Content getFieldDocTreeHeader(VariableElement field, Content fieldDetailsTree) {
-        fieldDetailsTree.addContent(writer.getMarkerAnchor(name(field)));
+        fieldDetailsTree.addContent(links.createAnchor(name(field)));
         Content fieldTree = writer.getMemberTreeHeader();
         Content heading = new HtmlTree(HtmlConstants.MEMBER_HEADING);
         heading.addContent(name(field));
@@ -226,7 +227,7 @@
      */
     @Override
     public void addSummaryAnchor(TypeElement typeElement, Content memberTree) {
-        memberTree.addContent(writer.getMarkerAnchor(
+        memberTree.addContent(links.createAnchor(
                 SectionName.FIELD_SUMMARY));
     }
 
@@ -235,7 +236,7 @@
      */
     @Override
     public void addInheritedSummaryAnchor(TypeElement typeElement, Content inheritedTree) {
-        inheritedTree.addContent(writer.getMarkerAnchor(
+        inheritedTree.addContent(links.createAnchor(
                 SectionName.FIELDS_INHERITANCE, configuration.getClassName(typeElement)));
     }
 
@@ -309,11 +310,11 @@
     protected Content getNavSummaryLink(TypeElement typeElement, boolean link) {
         if (link) {
             if (typeElement == null) {
-                return writer.getHyperLink(
+                return Links.createLink(
                         SectionName.FIELD_SUMMARY,
                         contents.navField);
             } else {
-                return writer.getHyperLink(
+                return links.createLink(
                         SectionName.FIELDS_INHERITANCE,
                         configuration.getClassName(typeElement), contents.navField);
             }
@@ -328,7 +329,7 @@
     @Override
     protected void addNavDetailLink(boolean link, Content liNav) {
         if (link) {
-            liNav.addContent(writer.getHyperLink(
+            liNav.addContent(Links.createLink(
                     SectionName.FIELD_DETAIL,
                     contents.navField));
         } else {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HelpWriter.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HelpWriter.java	Thu Nov 16 15:16:21 2017 -0800
@@ -29,6 +29,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.Content;
 import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
@@ -132,7 +133,7 @@
                     ? HtmlTree.SECTION(overviewHeading)
                     : HtmlTree.LI(HtmlStyle.blockList, overviewHeading);
             Content line3 = contents.getContent("doclet.Help_line_3",
-                    getHyperLink(DocPaths.overviewSummary(configuration.frames),
+                    Links.createLink(DocPaths.overviewSummary(configuration.frames),
                     configuration.getText("doclet.Overview")));
             Content overviewPara = HtmlTree.P(line3);
             htmlTree.addContent(overviewPara);
@@ -282,7 +283,7 @@
                     ? HtmlTree.SECTION(treeHead)
                     : HtmlTree.LI(HtmlStyle.blockList, treeHead);
             Content line17 = contents.getContent("doclet.Help_line_17_with_tree_link",
-                    getHyperLink(DocPaths.OVERVIEW_TREE,
+                    Links.createLink(DocPaths.OVERVIEW_TREE,
                     configuration.getText("doclet.Class_Hierarchy")),
                     HtmlTree.CODE(new StringContent("java.lang.Object")));
             Content treePara = HtmlTree.P(line17);
@@ -307,7 +308,7 @@
                     ? HtmlTree.SECTION(dHead)
                     : HtmlTree.LI(HtmlStyle.blockList, dHead);
             Content line20 = contents.getContent("doclet.Help_line_20_with_deprecated_api_link",
-                    getHyperLink(DocPaths.DEPRECATED_LIST,
+                    Links.createLink(DocPaths.DEPRECATED_LIST,
                     configuration.getText("doclet.Deprecated_API")));
             Content dPara = HtmlTree.P(line20);
             htmlTree.addContent(dPara);
@@ -320,10 +321,10 @@
         if (configuration.createindex) {
             Content indexlink;
             if (configuration.splitindex) {
-                indexlink = getHyperLink(DocPaths.INDEX_FILES.resolve(DocPaths.indexN(1)),
+                indexlink = Links.createLink(DocPaths.INDEX_FILES.resolve(DocPaths.indexN(1)),
                         configuration.getText("doclet.Index"));
             } else {
-                indexlink = getHyperLink(DocPaths.INDEX_ALL,
+                indexlink = Links.createLink(DocPaths.INDEX_ALL,
                         configuration.getText("doclet.Index"));
             }
             Content indexHead = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING,
@@ -377,7 +378,7 @@
                 ? HtmlTree.SECTION(allclassesHead)
                 : HtmlTree.LI(HtmlStyle.blockList, allclassesHead);
         Content line27 = contents.getContent("doclet.Help_line_27",
-                getHyperLink(DocPaths.AllClasses(configuration.frames),
+                Links.createLink(DocPaths.AllClasses(configuration.frames),
                 resources.getText("doclet.All_Classes")));
         Content allclassesPara = HtmlTree.P(line27);
         htmlTree.addContent(allclassesPara);
@@ -405,7 +406,7 @@
                 ? HtmlTree.SECTION(constHead)
                 : HtmlTree.LI(HtmlStyle.blockList, constHead);
         Content line29 = contents.getContent("doclet.Help_line_29",
-                getHyperLink(DocPaths.CONSTANT_VALUES,
+                Links.createLink(DocPaths.CONSTANT_VALUES,
                 resources.getText("doclet.Constants_Summary")));
         Content constPara = HtmlTree.P(line29);
         htmlTree.addContent(constPara);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java	Thu Nov 16 15:16:21 2017 -0800
@@ -44,6 +44,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlVersion;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
 import jdk.javadoc.internal.doclets.toolkit.Content;
 import jdk.javadoc.internal.doclets.toolkit.DocletException;
@@ -239,9 +240,11 @@
 
     protected Set<Character> tagSearchIndexKeys;
 
-    protected Contents contents;
+    protected final Contents contents;
 
-    protected Messages messages;
+    protected final Messages messages;
+
+    protected Links links;
 
     /**
      * Creates an object to hold the configuration for a doclet.
@@ -353,6 +356,7 @@
         setTopFile(docEnv);
         workArounds.initDocLint(doclintOpts.values(), tagletManager.getCustomTagNames(),
                 Utils.toLowerCase(htmlVersion.name()));
+        links = new Links(htmlVersion);
         return true;
     }
 
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java	Thu Nov 16 15:16:21 2017 -0800
@@ -77,6 +77,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.RawHtml;
 import jdk.javadoc.internal.doclets.formats.html.markup.Script;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
@@ -154,6 +155,8 @@
 
     protected final Resources resources;
 
+    protected final Links links;
+
     /**
      * To check whether annotation heading is printed or not.
      */
@@ -196,6 +199,7 @@
         this.contents = configuration.contents;
         this.messages = configuration.messages;
         this.resources = configuration.resources;
+        this.links = configuration.links;
         this.utils = configuration.utils;
         this.path = path;
         this.pathToRoot = path.parent().invert();
@@ -366,7 +370,7 @@
      */
     public Content getTargetPackageLink(PackageElement pkg, String target,
             Content label) {
-        return getHyperLink(pathString(pkg, DocPaths.PACKAGE_SUMMARY), label, "", target);
+        return Links.createLink(pathString(pkg, DocPaths.PACKAGE_SUMMARY), label, "", target);
     }
 
     /**
@@ -380,7 +384,7 @@
      */
     public Content getTargetModulePackageLink(PackageElement pkg, String target,
             Content label, ModuleElement mdle) {
-        return getHyperLink(pathString(pkg, DocPaths.PACKAGE_SUMMARY),
+        return Links.createLink(pathString(pkg, DocPaths.PACKAGE_SUMMARY),
                 label, "", target);
     }
 
@@ -393,7 +397,7 @@
      * @return a content for the target module link
      */
     public Content getTargetModuleLink(String target, Content label, ModuleElement mdle) {
-        return getHyperLink(pathToRoot.resolve(
+        return Links.createLink(pathToRoot.resolve(
                 DocPaths.moduleSummary(mdle)), label, "", target);
     }
 
@@ -500,28 +504,28 @@
                 fixedNavDiv.addContent(HtmlConstants.START_OF_TOP_NAVBAR);
                 navDiv.setStyle(HtmlStyle.topNav);
                 allClassesId += "navbar_top";
-                Content a = getMarkerAnchor(SectionName.NAVBAR_TOP);
+                Content a = links.createAnchor(SectionName.NAVBAR_TOP);
                 //WCAG - Hyperlinks should contain text or an image with alt text - for AT tools
                 navDiv.addContent(a);
-                Content skipLinkContent = HtmlTree.DIV(HtmlStyle.skipNav, getHyperLink(
-                    getDocLink(SectionName.SKIP_NAVBAR_TOP), skipNavLinks,
-                    skipNavLinks.toString(), ""));
+                Content skipLinkContent = HtmlTree.DIV(HtmlStyle.skipNav,
+                        Links.createLink(SectionName.SKIP_NAVBAR_TOP, skipNavLinks,
+                        skipNavLinks.toString(), ""));
                 navDiv.addContent(skipLinkContent);
             } else {
                 tree.addContent(HtmlConstants.START_OF_BOTTOM_NAVBAR);
                 navDiv.setStyle(HtmlStyle.bottomNav);
                 allClassesId += "navbar_bottom";
-                Content a = getMarkerAnchor(SectionName.NAVBAR_BOTTOM);
+                Content a = links.createAnchor(SectionName.NAVBAR_BOTTOM);
                 navDiv.addContent(a);
-                Content skipLinkContent = HtmlTree.DIV(HtmlStyle.skipNav, getHyperLink(
-                    getDocLink(SectionName.SKIP_NAVBAR_BOTTOM), skipNavLinks,
-                    skipNavLinks.toString(), ""));
+                Content skipLinkContent = HtmlTree.DIV(HtmlStyle.skipNav,
+                        Links.createLink(SectionName.SKIP_NAVBAR_BOTTOM, skipNavLinks,
+                        skipNavLinks.toString(), ""));
                 navDiv.addContent(skipLinkContent);
             }
             if (header) {
-                navDiv.addContent(getMarkerAnchor(SectionName.NAVBAR_TOP_FIRSTROW));
+                navDiv.addContent(links.createAnchor(SectionName.NAVBAR_TOP_FIRSTROW));
             } else {
-                navDiv.addContent(getMarkerAnchor(SectionName.NAVBAR_BOTTOM_FIRSTROW));
+                navDiv.addContent(links.createAnchor(SectionName.NAVBAR_BOTTOM_FIRSTROW));
             }
             HtmlTree navList = new HtmlTree(HtmlTag.UL);
             navList.setStyle(HtmlStyle.navList);
@@ -592,7 +596,7 @@
             subDiv.addContent(getAllClassesLinkScript(allClassesId));
             addSummaryDetailLinks(subDiv);
             if (header) {
-                subDiv.addContent(getMarkerAnchor(SectionName.SKIP_NAVBAR_TOP));
+                subDiv.addContent(links.createAnchor(SectionName.SKIP_NAVBAR_TOP));
                 fixedNavDiv.addContent(subDiv);
                 fixedNavDiv.addContent(HtmlConstants.END_OF_TOP_NAVBAR);
                 tree.addContent(fixedNavDiv);
@@ -604,7 +608,7 @@
                         + "//-->\n");
                 tree.addContent(script.asContent());
             } else {
-                subDiv.addContent(getMarkerAnchor(SectionName.SKIP_NAVBAR_BOTTOM));
+                subDiv.addContent(links.createAnchor(SectionName.SKIP_NAVBAR_BOTTOM));
                 tree.addContent(subDiv);
                 tree.addContent(HtmlConstants.END_OF_BOTTOM_NAVBAR);
             }
@@ -646,7 +650,7 @@
      * @return a content tree for the link
      */
     protected Content getNavLinkContents() {
-        Content linkContent = getHyperLink(pathToRoot.resolve(DocPaths.overviewSummary(configuration.frames)),
+        Content linkContent = Links.createLink(pathToRoot.resolve(DocPaths.overviewSummary(configuration.frames)),
                 contents.overviewLabel, "", "");
         Content li = HtmlTree.LI(linkContent);
         return li;
@@ -715,7 +719,7 @@
     public Content getNavLinkPrevious(DocPath prev) {
         Content li;
         if (prev != null) {
-            li = HtmlTree.LI(getHyperLink(prev, contents.prevLabel, "", ""));
+            li = HtmlTree.LI(Links.createLink(prev, contents.prevLabel, "", ""));
         }
         else
             li = HtmlTree.LI(contents.prevLabel);
@@ -732,7 +736,7 @@
     public Content getNavLinkNext(DocPath next) {
         Content li;
         if (next != null) {
-            li = HtmlTree.LI(getHyperLink(next, contents.nextLabel, "", ""));
+            li = HtmlTree.LI(Links.createLink(next, contents.nextLabel, "", ""));
         }
         else
             li = HtmlTree.LI(contents.nextLabel);
@@ -747,7 +751,7 @@
      */
     protected Content getNavShowLists(DocPath link) {
         DocLink dl = new DocLink(link, path.getPath(), null);
-        Content framesContent = getHyperLink(dl, contents.framesLabel, "", "_top");
+        Content framesContent = Links.createLink(dl, contents.framesLabel, "", "_top");
         Content li = HtmlTree.LI(framesContent);
         return li;
     }
@@ -768,7 +772,7 @@
      * @return a content tree for the link
      */
     protected Content getNavHideLists(DocPath link) {
-        Content noFramesContent = getHyperLink(link, contents.noFramesLabel, "", "_top");
+        Content noFramesContent = Links.createLink(link, contents.noFramesLabel, "", "_top");
         Content li = HtmlTree.LI(noFramesContent);
         return li;
     }
@@ -786,7 +790,7 @@
         DocPath docPath = packages.size() == 1 && configuration.getSpecifiedTypeElements().isEmpty()
                 ? pathString(packages.get(0), DocPaths.PACKAGE_TREE)
                 : pathToRoot.resolve(DocPaths.OVERVIEW_TREE);
-        return HtmlTree.LI(getHyperLink(docPath, contents.treeLabel, "", ""));
+        return HtmlTree.LI(Links.createLink(docPath, contents.treeLabel, "", ""));
     }
 
     /**
@@ -796,7 +800,7 @@
      * @return a content tree for the link
      */
     protected Content getNavLinkMainTree(String label) {
-        Content mainTreeContent = getHyperLink(pathToRoot.resolve(DocPaths.OVERVIEW_TREE),
+        Content mainTreeContent = Links.createLink(pathToRoot.resolve(DocPaths.OVERVIEW_TREE),
                 new StringContent(label));
         Content li = HtmlTree.LI(mainTreeContent);
         return li;
@@ -818,7 +822,7 @@
      * @return a content tree for the link
      */
     protected Content getNavLinkDeprecated() {
-        Content linkContent = getHyperLink(pathToRoot.resolve(DocPaths.DEPRECATED_LIST),
+        Content linkContent = Links.createLink(pathToRoot.resolve(DocPaths.DEPRECATED_LIST),
                 contents.deprecatedLabel, "", "");
         Content li = HtmlTree.LI(linkContent);
         return li;
@@ -832,7 +836,7 @@
      * @return a content tree for the link
      */
     protected Content getNavLinkClassIndex() {
-        Content allClassesContent = getHyperLink(pathToRoot.resolve(
+        Content allClassesContent = Links.createLink(pathToRoot.resolve(
                 DocPaths.AllClasses(configuration.frames)),
                 contents.allClassesLabel, "", "");
         Content li = HtmlTree.LI(allClassesContent);
@@ -845,7 +849,7 @@
      * @return a content tree for the link
      */
     protected Content getNavLinkIndex() {
-        Content linkContent = getHyperLink(pathToRoot.resolve(
+        Content linkContent = Links.createLink(pathToRoot.resolve(
                 (configuration.splitindex
                     ? DocPaths.INDEX_FILES.resolve(DocPaths.indexN(1))
                     : DocPaths.INDEX_ALL)),
@@ -870,7 +874,7 @@
             DocFile file = DocFile.createFileForInput(configuration, helpfile);
             helpfilenm = DocPath.create(file.getName());
         }
-        Content linkContent = getHyperLink(pathToRoot.resolve(helpfilenm),
+        Content linkContent = Links.createLink(pathToRoot.resolve(helpfilenm),
                 contents.helpLabel, "", "");
         Content li = HtmlTree.LI(linkContent);
         return li;
@@ -903,51 +907,6 @@
     }
 
     /**
-     * Get the marker anchor which will be added to the documentation tree.
-     *
-     * @param anchorName the anchor name attribute
-     * @return a content tree for the marker anchor
-     */
-    public Content getMarkerAnchor(String anchorName) {
-        return getMarkerAnchor(getName(anchorName), null);
-    }
-
-    /**
-     * Get the marker anchor which will be added to the documentation tree.
-     *
-     * @param sectionName the section name anchor attribute for page
-     * @return a content tree for the marker anchor
-     */
-    public Content getMarkerAnchor(SectionName sectionName) {
-        return getMarkerAnchor(sectionName.getName(), null);
-    }
-
-    /**
-     * Get the marker anchor which will be added to the documentation tree.
-     *
-     * @param sectionName the section name anchor attribute for page
-     * @param anchorName the anchor name combined with section name attribute for the page
-     * @return a content tree for the marker anchor
-     */
-    public Content getMarkerAnchor(SectionName sectionName, String anchorName) {
-        return getMarkerAnchor(sectionName.getName() + getName(anchorName), null);
-    }
-
-    /**
-     * Get the marker anchor which will be added to the documentation tree.
-     *
-     * @param anchorName the anchor name or id attribute
-     * @param anchorContent the content that should be added to the anchor
-     * @return a content tree for the marker anchor
-     */
-    public Content getMarkerAnchor(String anchorName, Content anchorContent) {
-        if (anchorContent == null)
-            anchorContent = new Comment(" ");
-        Content markerAnchor = HtmlTree.A(configuration.htmlVersion, anchorName, anchorContent);
-        return markerAnchor;
-    }
-
-    /**
      * Returns a packagename content.
      *
      * @param packageElement the package to check
@@ -1039,12 +998,12 @@
             }
         }
         if (included || packageElement == null) {
-            return getHyperLink(pathString(packageElement, DocPaths.PACKAGE_SUMMARY),
+            return Links.createLink(pathString(packageElement, DocPaths.PACKAGE_SUMMARY),
                     label);
         } else {
             DocLink crossPkgLink = getCrossPackageLink(utils.getPackageName(packageElement));
             if (crossPkgLink != null) {
-                return getHyperLink(crossPkgLink, label);
+                return Links.createLink(crossPkgLink, label);
             } else {
                 return label;
             }
@@ -1061,7 +1020,7 @@
     public Content getModuleLink(ModuleElement mdle, Content label) {
         boolean included = utils.isIncluded(mdle);
         return (included)
-                ? getHyperLink(pathToRoot.resolve(DocPaths.moduleSummary(mdle)), label, "", "")
+                ? Links.createLink(pathToRoot.resolve(DocPaths.moduleSummary(mdle)), label, "", "")
                 : label;
     }
 
@@ -1091,7 +1050,7 @@
         DocPath href = pathToRoot
                 .resolve(DocPaths.SOURCE_OUTPUT)
                 .resolve(DocPath.forClass(utils, te));
-        Content linkContent = getHyperLink(href
+        Content linkContent = Links.createLink(href
                 .fragment(SourceToHTMLConverter.getAnchorName(utils, typeElement)), label, "", "");
         htmltree.addContent(linkContent);
     }
@@ -1156,7 +1115,7 @@
                 */
                 DocLink link = configuration.extern.getExternalLink(packageName, pathToRoot,
                                 className + ".html", refMemName);
-                return getHyperLink(link,
+                return Links.createLink(link,
                     (label == null) || label.isEmpty() ? defaultLabel : label,
                     strong, style,
                     configuration.getText("doclet.Href_Class_Or_Interface_Title", packageName),
@@ -1340,12 +1299,12 @@
             ExecutableElement ee = (ExecutableElement)element;
             return getLink(new LinkInfoImpl(configuration, context, typeElement)
                 .label(label)
-                .where(getName(getAnchor(ee, isProperty)))
+                .where(links.getName(getAnchor(ee, isProperty)))
                 .strong(strong));
         } else if (utils.isVariableElement(element) || utils.isTypeElement(element)) {
             return getLink(new LinkInfoImpl(configuration, context, typeElement)
                 .label(label)
-                .where(getName(element.getSimpleName().toString()))
+                .where(links.getName(element.getSimpleName().toString()))
                 .strong(strong));
         } else {
             return label;
@@ -1371,10 +1330,10 @@
             ExecutableElement emd = (ExecutableElement) element;
             return getLink(new LinkInfoImpl(configuration, context, typeElement)
                 .label(label)
-                .where(getName(getAnchor(emd))));
+                .where(links.getName(getAnchor(emd))));
         } else if (utils.isVariableElement(element) || utils.isTypeElement(element)) {
             return getLink(new LinkInfoImpl(configuration, context, typeElement)
-                .label(label).where(getName(element.getSimpleName().toString())));
+                .label(label).where(links.getName(element.getSimpleName().toString())));
         } else {
             return label;
         }
@@ -1445,7 +1404,7 @@
                 DocLink packageCrossLink = getCrossPackageLink(refClassName);
                 if (packageCrossLink != null) {
                     // Package cross link found
-                    return getHyperLink(packageCrossLink,
+                    return Links.createLink(packageCrossLink,
                         (label.isEmpty() ? text : label));
                 } else if ((classCrossLink = getCrossClassLink(refClassName,
                         refMemName, label, false, "", !isLinkPlain)) != null) {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/LinkFactoryImpl.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/LinkFactoryImpl.java	Thu Nov 16 15:16:21 2017 -0800
@@ -33,6 +33,7 @@
 import javax.lang.model.type.TypeMirror;
 
 import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
 import jdk.javadoc.internal.doclets.toolkit.Content;
 import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
@@ -92,11 +93,13 @@
                 DocPath filename = getPath(classLinkInfo);
                 if (linkInfo.linkToSelf ||
                                 !(DocPath.forName(utils, typeElement)).equals(m_writer.filename)) {
-                        link.addContent(m_writer.getHyperLink(
+                        link.addContent(Links.createLink(
                                 filename.fragment(classLinkInfo.where),
-                            label,
-                            classLinkInfo.isStrong, classLinkInfo.styleName,
-                            title, classLinkInfo.target));
+                                label,
+                                classLinkInfo.isStrong,
+                                classLinkInfo.styleName,
+                                title,
+                                classLinkInfo.target));
                         if (noLabel && !classLinkInfo.excludeTypeParameterLinks) {
                             link.addContent(getTypeParameterLinks(linkInfo));
                         }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MethodWriterImpl.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MethodWriterImpl.java	Thu Nov 16 15:16:21 2017 -0800
@@ -40,6 +40,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.Content;
 import jdk.javadoc.internal.doclets.toolkit.MemberSummaryWriter;
@@ -108,8 +109,7 @@
     public Content getMethodDetailsTreeHeader(TypeElement typeElement, Content memberDetailsTree) {
         memberDetailsTree.addContent(HtmlConstants.START_OF_METHOD_DETAILS);
         Content methodDetailsTree = writer.getMemberTreeHeader();
-        methodDetailsTree.addContent(writer.getMarkerAnchor(
-                SectionName.METHOD_DETAIL));
+        methodDetailsTree.addContent(links.createAnchor(SectionName.METHOD_DETAIL));
         Content heading = HtmlTree.HEADING(HtmlConstants.DETAILS_HEADING,
                 contents.methodDetailLabel);
         methodDetailsTree.addContent(heading);
@@ -123,10 +123,9 @@
     public Content getMethodDocTreeHeader(ExecutableElement method, Content methodDetailsTree) {
         String erasureAnchor;
         if ((erasureAnchor = getErasureAnchor(method)) != null) {
-            methodDetailsTree.addContent(writer.getMarkerAnchor((erasureAnchor)));
+            methodDetailsTree.addContent(links.createAnchor((erasureAnchor)));
         }
-        methodDetailsTree.addContent(
-                writer.getMarkerAnchor(writer.getAnchor(method)));
+        methodDetailsTree.addContent(links.createAnchor(writer.getAnchor(method)));
         Content methodDocTree = writer.getMemberTreeHeader();
         Content heading = new HtmlTree(HtmlConstants.MEMBER_HEADING);
         heading.addContent(name(method));
@@ -280,8 +279,7 @@
      */
     @Override
     public void addSummaryAnchor(TypeElement typeElement, Content memberTree) {
-        memberTree.addContent(writer.getMarkerAnchor(
-                SectionName.METHOD_SUMMARY));
+        memberTree.addContent(links.createAnchor(SectionName.METHOD_SUMMARY));
     }
 
     /**
@@ -289,7 +287,7 @@
      */
     @Override
     public void addInheritedSummaryAnchor(TypeElement typeElement, Content inheritedTree) {
-        inheritedTree.addContent(writer.getMarkerAnchor(
+        inheritedTree.addContent(links.createAnchor(
                 SectionName.METHODS_INHERITANCE, configuration.getClassName(typeElement)));
     }
 
@@ -365,7 +363,7 @@
             Content methlink = writer.getLink(
                     new LinkInfoImpl(writer.configuration, LinkInfoImpl.Kind.MEMBER,
                     holder)
-                    .where(writer.getName(writer.getAnchor(method))).label(method.getSimpleName()));
+                    .where(writer.links.getName(writer.getAnchor(method))).label(method.getSimpleName()));
             Content codeMethLink = HtmlTree.CODE(methlink);
             Content dd = HtmlTree.DD(codeMethLink);
             dd.addContent(Contents.SPACE);
@@ -435,11 +433,11 @@
     protected Content getNavSummaryLink(TypeElement typeElement, boolean link) {
         if (link) {
             if (typeElement == null) {
-                return writer.getHyperLink(
+                return Links.createLink(
                         SectionName.METHOD_SUMMARY,
                         contents.navMethod);
             } else {
-                return writer.getHyperLink(
+                return links.createLink(
                         SectionName.METHODS_INHERITANCE,
                         configuration.getClassName(typeElement), contents.navMethod);
             }
@@ -454,7 +452,7 @@
     @Override
     protected void addNavDetailLink(boolean link, Content liNav) {
         if (link) {
-            liNav.addContent(writer.getHyperLink(
+            liNav.addContent(Links.createLink(
                     SectionName.METHOD_DETAIL, contents.navMethod));
         } else {
             liNav.addContent(contents.navMethod);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleFrameWriter.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleFrameWriter.java	Thu Nov 16 15:16:21 2017 -0800
@@ -36,6 +36,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.Content;
 import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
@@ -100,7 +101,7 @@
                 ? HtmlTree.MAIN()
                 : body;
         Content heading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, HtmlStyle.bar,
-                mdlgen.getHyperLink(DocPaths.moduleSummary(moduleElement), mdlLabel, "", "classFrame"));
+                Links.createLink(DocPaths.moduleSummary(moduleElement), mdlLabel, "", "classFrame"));
         htmlTree.addContent(heading);
         HtmlTree div = new HtmlTree(HtmlTag.DIV);
         div.setStyle(HtmlStyle.indexContainer);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleIndexFrameWriter.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleIndexFrameWriter.java	Thu Nov 16 15:16:21 2017 -0800
@@ -35,6 +35,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.RawHtml;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.Content;
@@ -138,7 +139,7 @@
      * @param ul the Content object to which the all classes link should be added
      */
     protected void addAllClassesLink(Content ul) {
-        Content linkContent = getHyperLink(DocPaths.ALLCLASSES_FRAME,
+        Content linkContent = Links.createLink(DocPaths.ALLCLASSES_FRAME,
                 contents.allClassesLabel, "", "packageFrame");
         Content li = HtmlTree.LI(linkContent);
         ul.addContent(li);
@@ -151,7 +152,7 @@
      * @param ul the Content object to which the all packages link should be added
      */
     protected void addAllPackagesLink(Content ul) {
-        Content linkContent = getHyperLink(DocPaths.OVERVIEW_FRAME,
+        Content linkContent = Links.createLink(DocPaths.OVERVIEW_FRAME,
                 contents.allPackagesLabel, "", "packageListFrame");
         Content li = HtmlTree.LI(linkContent);
         ul.addContent(li);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModulePackageIndexFrameWriter.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModulePackageIndexFrameWriter.java	Thu Nov 16 15:16:21 2017 -0800
@@ -37,6 +37,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.RawHtml;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.Content;
@@ -142,12 +143,12 @@
         Content pkgLabel;
         if (!pkg.isUnnamed()) {
             pkgLabel = getPackageLabel(utils.getPackageName(pkg));
-            packageLinkContent = getHyperLink(pathString(pkg,
+            packageLinkContent = Links.createLink(pathString(pkg,
                      DocPaths.PACKAGE_FRAME), pkgLabel, "",
                     "packageFrame");
         } else {
             pkgLabel = new StringContent("<unnamed package>");
-            packageLinkContent = getHyperLink(DocPaths.PACKAGE_FRAME,
+            packageLinkContent = Links.createLink(DocPaths.PACKAGE_FRAME,
                     pkgLabel, "", "packageFrame");
         }
         Content li = HtmlTree.LI(packageLinkContent);
@@ -188,7 +189,7 @@
      * @param ul the Content object to which the all classes link should be added
      */
     protected void addAllClassesLink(Content ul) {
-        Content linkContent = getHyperLink(DocPaths.ALLCLASSES_FRAME,
+        Content linkContent = Links.createLink(DocPaths.ALLCLASSES_FRAME,
                 contents.allClassesLabel, "", "packageFrame");
         Content li = HtmlTree.LI(linkContent);
         ul.addContent(li);
@@ -201,7 +202,7 @@
      * @param ul the Content object to which the all packages link should be added
      */
     protected void addAllPackagesLink(Content ul) {
-        Content linkContent = getHyperLink(DocPaths.OVERVIEW_FRAME,
+        Content linkContent = Links.createLink(DocPaths.OVERVIEW_FRAME,
                 contents.allPackagesLabel, "", "packageListFrame");
         Content li = HtmlTree.LI(linkContent);
         ul.addContent(li);
@@ -214,7 +215,7 @@
      * @param ul the Content object to which the all modules link should be added
      */
     protected void addAllModulesLink(Content ul) {
-        Content linkContent = getHyperLink(DocPaths.MODULE_OVERVIEW_FRAME,
+        Content linkContent = Links.createLink(DocPaths.MODULE_OVERVIEW_FRAME,
                 contents.allModulesLabel, "", "packageListFrame");
         Content li = HtmlTree.LI(linkContent);
         ul.addContent(li);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java	Thu Nov 16 15:16:21 2017 -0800
@@ -50,6 +50,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.RawHtml;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.Content;
@@ -455,7 +456,7 @@
     public void addSummaryHeader(Content startMarker, SectionName markerAnchor, Content heading,
             Content htmltree) {
         htmltree.addContent(startMarker);
-        htmltree.addContent(getMarkerAnchor(markerAnchor));
+        htmltree.addContent(links.createAnchor(markerAnchor));
         htmltree.addContent(HtmlTree.HEADING(HtmlTag.H3, heading));
     }
 
@@ -846,7 +847,7 @@
             Content tree = configuration.allowTag(HtmlTag.SECTION) ? HtmlTree.SECTION() : moduleContentTree;
             addDeprecationInfo(tree);
             tree.addContent(HtmlConstants.START_OF_MODULE_DESCRIPTION);
-            tree.addContent(getMarkerAnchor(SectionName.MODULE_DESCRIPTION));
+            tree.addContent(links.createAnchor(SectionName.MODULE_DESCRIPTION));
             addInlineComment(mdle, tree);
             if (configuration.allowTag(HtmlTag.SECTION)) {
                 moduleContentTree.addContent(tree);
@@ -890,20 +891,20 @@
         Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li);
         Content liNav = new HtmlTree(HtmlTag.LI);
         liNav.addContent(!utils.getFullBody(mdle).isEmpty() && !configuration.nocomment
-                ? getHyperLink(SectionName.MODULE_DESCRIPTION, contents.navModuleDescription)
+                ? Links.createLink(SectionName.MODULE_DESCRIPTION, contents.navModuleDescription)
                 : contents.navModuleDescription);
         addNavGap(liNav);
         liNav.addContent((display(requires) || display(indirectModules))
-                ? getHyperLink(SectionName.MODULES, contents.navModules)
+                ? Links.createLink(SectionName.MODULES, contents.navModules)
                 : contents.navModules);
         addNavGap(liNav);
         liNav.addContent((display(exportedPackages) || display(openedPackages) || display(concealedPackages)
                 || display(indirectPackages) || display(indirectOpenPackages))
-                ? getHyperLink(SectionName.PACKAGES, contents.navPackages)
+                ? Links.createLink(SectionName.PACKAGES, contents.navPackages)
                 : contents.navPackages);
         addNavGap(liNav);
         liNav.addContent((displayServices(uses, usesTrees) || displayServices(provides.keySet(), providesTrees))
-                ? getHyperLink(SectionName.SERVICES, contents.navServices)
+                ? Links.createLink(SectionName.SERVICES, contents.navServices)
                 : contents.navServices);
         ulNav.addContent(liNav);
         return ulNav;
@@ -995,7 +996,7 @@
         if (prevModule == null) {
             li = HtmlTree.LI(contents.prevModuleLabel);
         } else {
-            li = HtmlTree.LI(getHyperLink(pathToRoot.resolve(DocPaths.moduleSummary(
+            li = HtmlTree.LI(Links.createLink(pathToRoot.resolve(DocPaths.moduleSummary(
                     prevModule)), contents.prevModuleLabel, "", ""));
         }
         return li;
@@ -1012,7 +1013,7 @@
         if (nextModule == null) {
             li = HtmlTree.LI(contents.nextModuleLabel);
         } else {
-            li = HtmlTree.LI(getHyperLink(pathToRoot.resolve(DocPaths.moduleSummary(
+            li = HtmlTree.LI(Links.createLink(pathToRoot.resolve(DocPaths.moduleSummary(
                     nextModule)), contents.nextModuleLabel, "", ""));
         }
         return li;
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/NestedClassWriterImpl.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/NestedClassWriterImpl.java	Thu Nov 16 15:16:21 2017 -0800
@@ -37,6 +37,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.Content;
 import jdk.javadoc.internal.doclets.toolkit.MemberSummaryWriter;
@@ -129,7 +130,7 @@
      */
     @Override
     public void addSummaryAnchor(TypeElement typeElement, Content memberTree) {
-        memberTree.addContent(writer.getMarkerAnchor(
+        memberTree.addContent(links.createAnchor(
                 SectionName.NESTED_CLASS_SUMMARY));
     }
 
@@ -138,7 +139,7 @@
      */
     @Override
     public void addInheritedSummaryAnchor(TypeElement typeElement, Content inheritedTree) {
-        inheritedTree.addContent(writer.getMarkerAnchor(
+        inheritedTree.addContent(links.createAnchor(
                 SectionName.NESTED_CLASSES_INHERITANCE,
                 utils.getFullyQualifiedName(typeElement)));
     }
@@ -212,11 +213,11 @@
     protected Content getNavSummaryLink(TypeElement typeElement, boolean link) {
         if (link) {
             if (typeElement == null) {
-                return writer.getHyperLink(
+                return Links.createLink(
                         SectionName.NESTED_CLASS_SUMMARY,
                         contents.navNested);
             } else {
-                return writer.getHyperLink(
+                return links.createLink(
                         SectionName.NESTED_CLASSES_INHERITANCE,
                         utils.getFullyQualifiedName(typeElement), contents.navNested);
             }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageIndexFrameWriter.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageIndexFrameWriter.java	Thu Nov 16 15:16:21 2017 -0800
@@ -33,6 +33,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.RawHtml;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.Content;
@@ -109,11 +110,11 @@
         Content packageLabel;
         if (pe.isUnnamed()) {
             packageLabel = new StringContent("<unnamed package>");
-            packageLinkContent = getHyperLink(DocPaths.PACKAGE_FRAME,
+            packageLinkContent = Links.createLink(DocPaths.PACKAGE_FRAME,
                     packageLabel, "", "packageFrame");
         } else {
             packageLabel = getPackageLabel(pe.getQualifiedName());
-            packageLinkContent = getHyperLink(pathString(pe,
+            packageLinkContent = Links.createLink(pathString(pe,
                      DocPaths.PACKAGE_FRAME), packageLabel, "",
                     "packageFrame");
         }
@@ -152,7 +153,7 @@
      */
     @Override
     protected void addAllClassesLink(Content ul) {
-        Content linkContent = getHyperLink(DocPaths.ALLCLASSES_FRAME,
+        Content linkContent = Links.createLink(DocPaths.ALLCLASSES_FRAME,
                 contents.allClassesLabel, "", "packageFrame");
         Content li = HtmlTree.LI(linkContent);
         ul.addContent(li);
@@ -166,7 +167,7 @@
      */
     @Override
     protected void addAllModulesLink(Content ul) {
-        Content linkContent = getHyperLink(DocPaths.MODULE_OVERVIEW_FRAME,
+        Content linkContent = Links.createLink(DocPaths.MODULE_OVERVIEW_FRAME,
                 contents.allModulesLabel, "", "packageListFrame");
         Content li = HtmlTree.LI(linkContent);
         ul.addContent(li);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageTreeWriter.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageTreeWriter.java	Thu Nov 16 15:16:21 2017 -0800
@@ -31,6 +31,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.toolkit.Content;
 import jdk.javadoc.internal.doclets.toolkit.util.ClassTree;
 import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
@@ -231,7 +232,7 @@
      */
     @Override
     protected Content getNavLinkPackage() {
-        Content linkContent = getHyperLink(DocPaths.PACKAGE_SUMMARY,
+        Content linkContent = Links.createLink(DocPaths.PACKAGE_SUMMARY,
                 contents.packageLabel);
         Content li = HtmlTree.LI(linkContent);
         return li;
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageUseWriter.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageUseWriter.java	Thu Nov 16 15:16:21 2017 -0800
@@ -38,6 +38,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.Content;
 import jdk.javadoc.internal.doclets.toolkit.util.ClassUseMapper;
@@ -178,7 +179,7 @@
                 .setColumnStyles(HtmlStyle.colFirst, HtmlStyle.colLast);
         for (String pkgname: usingPackageToUsedClasses.keySet()) {
             PackageElement pkg = utils.elementUtils.getPackageElement(pkgname);
-            Content packageLink = getHyperLink(utils.getPackageName(pkg),
+            Content packageLink = links.createLink(utils.getPackageName(pkg),
                     new StringContent(utils.getPackageName(pkg)));
             Content summary = new ContentBuilder();
             if (pkg != null && !pkg.isUnnamed()) {
@@ -205,7 +206,7 @@
             HtmlTree li = new HtmlTree(HtmlTag.LI);
             li.setStyle(HtmlStyle.blockList);
             if (usingPackage != null) {
-                li.addContent(getMarkerAnchor(utils.getPackageName(usingPackage)));
+                li.addContent(links.createAnchor(utils.getPackageName(usingPackage)));
             }
             String tableSummary = resources.getText("doclet.Use_Table_Summary",
                                                         resources.getText("doclet.classes"));
@@ -222,7 +223,7 @@
                 DocPath dp = pathString(te,
                         DocPaths.CLASS_USE.resolve(DocPath.forName(utils, te)));
                 Content stringContent = new StringContent(utils.getSimpleName(te));
-                Content typeContent = getHyperLink(dp.fragment(getPackageAnchorName(usingPackage)),
+                Content typeContent = Links.createLink(dp.fragment(getPackageAnchorName(usingPackage)),
                         stringContent);
                 Content summary = new ContentBuilder();
                 addIndexComment(te, summary);
@@ -287,7 +288,7 @@
      */
     @Override
     protected Content getNavLinkPackage() {
-        Content linkContent = getHyperLink(DocPaths.PACKAGE_SUMMARY,
+        Content linkContent = Links.createLink(DocPaths.PACKAGE_SUMMARY,
                 contents.packageLabel);
         Content li = HtmlTree.LI(linkContent);
         return li;
@@ -311,7 +312,7 @@
      */
     @Override
     protected Content getNavLinkTree() {
-        Content linkContent = getHyperLink(DocPaths.PACKAGE_TREE,
+        Content linkContent = Links.createLink(DocPaths.PACKAGE_TREE,
                 contents.treeLabel);
         Content li = HtmlTree.LI(linkContent);
         return li;
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java	Thu Nov 16 15:16:21 2017 -0800
@@ -40,6 +40,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.Content;
 import jdk.javadoc.internal.doclets.toolkit.PackageSummaryWriter;
@@ -320,7 +321,7 @@
     public void addPackageDescription(Content packageContentTree) {
         if (!utils.getBody(packageElement).isEmpty()) {
             Content tree = configuration.allowTag(HtmlTag.SECTION) ? sectionTree : packageContentTree;
-            tree.addContent(getMarkerAnchor(SectionName.PACKAGE_DESCRIPTION));
+            tree.addContent(links.createAnchor(SectionName.PACKAGE_DESCRIPTION));
             addDeprecationInfo(tree);
             addInlineComment(packageElement, tree);
         }
@@ -384,7 +385,7 @@
      */
     @Override
     protected Content getNavLinkClassUse() {
-        Content useLink = getHyperLink(DocPaths.PACKAGE_USE,
+        Content useLink = Links.createLink(DocPaths.PACKAGE_USE,
                 contents.useLabel, "", "");
         Content li = HtmlTree.LI(useLink);
         return li;
@@ -402,7 +403,7 @@
             li = HtmlTree.LI(contents.prevPackageLabel);
         } else {
             DocPath p = DocPath.relativePath(packageElement, prev);
-            li = HtmlTree.LI(getHyperLink(p.resolve(DocPaths.PACKAGE_SUMMARY),
+            li = HtmlTree.LI(Links.createLink(p.resolve(DocPaths.PACKAGE_SUMMARY),
                 contents.prevPackageLabel, "", ""));
         }
         return li;
@@ -420,7 +421,7 @@
             li = HtmlTree.LI(contents.nextPackageLabel);
         } else {
             DocPath p = DocPath.relativePath(packageElement, next);
-            li = HtmlTree.LI(getHyperLink(p.resolve(DocPaths.PACKAGE_SUMMARY),
+            li = HtmlTree.LI(Links.createLink(p.resolve(DocPaths.PACKAGE_SUMMARY),
                 contents.nextPackageLabel, "", ""));
         }
         return li;
@@ -434,7 +435,7 @@
      */
     @Override
     protected Content getNavLinkTree() {
-        Content useLink = getHyperLink(DocPaths.PACKAGE_TREE,
+        Content useLink = Links.createLink(DocPaths.PACKAGE_TREE,
                 contents.treeLabel, "", "");
         Content li = HtmlTree.LI(useLink);
         return li;
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PropertyWriterImpl.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PropertyWriterImpl.java	Thu Nov 16 15:16:21 2017 -0800
@@ -37,6 +37,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.Content;
 import jdk.javadoc.internal.doclets.toolkit.MemberSummaryWriter;
@@ -90,8 +91,7 @@
             Content memberDetailsTree) {
         memberDetailsTree.addContent(HtmlConstants.START_OF_PROPERTY_DETAILS);
         Content propertyDetailsTree = writer.getMemberTreeHeader();
-        propertyDetailsTree.addContent(writer.getMarkerAnchor(
-                SectionName.PROPERTY_DETAIL));
+        propertyDetailsTree.addContent(links.createAnchor(SectionName.PROPERTY_DETAIL));
         Content heading = HtmlTree.HEADING(HtmlConstants.DETAILS_HEADING,
                 contents.propertyDetailsLabel);
         propertyDetailsTree.addContent(heading);
@@ -104,8 +104,7 @@
     @Override
     public Content getPropertyDocTreeHeader(ExecutableElement property,
             Content propertyDetailsTree) {
-        propertyDetailsTree.addContent(
-                writer.getMarkerAnchor(name(property)));
+        propertyDetailsTree.addContent(links.createAnchor(name(property)));
         Content propertyDocTree = writer.getMemberTreeHeader();
         Content heading = new HtmlTree(HtmlConstants.MEMBER_HEADING);
         heading.addContent(utils.getPropertyLabel(name(property)));
@@ -243,8 +242,7 @@
      */
     @Override
     public void addSummaryAnchor(TypeElement typeElement, Content memberTree) {
-        memberTree.addContent(writer.getMarkerAnchor(
-                SectionName.PROPERTY_SUMMARY));
+        memberTree.addContent(links.createAnchor(SectionName.PROPERTY_SUMMARY));
     }
 
     /**
@@ -252,7 +250,7 @@
      */
     @Override
     public void addInheritedSummaryAnchor(TypeElement typeElement, Content inheritedTree) {
-        inheritedTree.addContent(writer.getMarkerAnchor(
+        inheritedTree.addContent(links.createAnchor(
                 SectionName.PROPERTIES_INHERITANCE,
                 configuration.getClassName(typeElement)));
     }
@@ -334,13 +332,13 @@
     protected Content getNavSummaryLink(TypeElement typeElement, boolean link) {
         if (link) {
             if (typeElement == null) {
-                return writer.getHyperLink(
-                SectionName.PROPERTY_SUMMARY,
-                contents.navProperty);
+                return Links.createLink(
+                        SectionName.PROPERTY_SUMMARY,
+                        contents.navProperty);
             } else {
-                return writer.getHyperLink(
-                SectionName.PROPERTIES_INHERITANCE,
-                configuration.getClassName(typeElement), contents.navProperty);
+                return links.createLink(
+                        SectionName.PROPERTIES_INHERITANCE,
+                        configuration.getClassName(typeElement), contents.navProperty);
             }
         } else {
             return contents.navProperty;
@@ -353,7 +351,7 @@
     @Override
     protected void addNavDetailLink(boolean link, Content liNav) {
         if (link) {
-            liNav.addContent(writer.getHyperLink(
+            liNav.addContent(Links.createLink(
                     SectionName.PROPERTY_DETAIL,
                     contents.navProperty));
         } else {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java	Thu Nov 16 15:16:21 2017 -0800
@@ -168,7 +168,7 @@
                 ? getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.DEFAULT, typeElement)
                         .label(configuration.getClassName(typeElement)))
                 : new StringContent(utils.getFullyQualifiedName(typeElement));
-        Content li = HtmlTree.LI(HtmlStyle.blockList, getMarkerAnchor(
+        Content li = HtmlTree.LI(HtmlStyle.blockList, links.createAnchor(
                 utils.getFullyQualifiedName(typeElement)));
         Content superClassLink = typeElement.getSuperclass() != null
                 ? getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.SERIALIZED_FORM,
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SingleIndexWriter.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SingleIndexWriter.java	Thu Nov 16 15:16:21 2017 -0800
@@ -141,7 +141,7 @@
         for (Object ch : elements) {
             String unicode = ch.toString();
             contentTree.addContent(
-                    getHyperLink(getNameForIndex(unicode),
+                    links.createLink(getNameForIndex(unicode),
                             new StringContent(unicode)));
             contentTree.addContent(Contents.SPACE);
         }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SplitIndexWriter.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SplitIndexWriter.java	Thu Nov 16 15:16:21 2017 -0800
@@ -35,6 +35,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.Content;
 import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
@@ -176,7 +177,7 @@
     protected void addLinksForIndexes(Content contentTree) {
         for (int i = 0; i < indexElements.size(); i++) {
             int j = i + 1;
-            contentTree.addContent(getHyperLink(DocPaths.indexN(j),
+            contentTree.addContent(Links.createLink(DocPaths.indexN(j),
                     new StringContent(indexElements.get(i).toString())));
             contentTree.addContent(Contents.SPACE);
         }
@@ -194,7 +195,7 @@
             return HtmlTree.LI(prevletterLabel);
         }
         else {
-            Content prevLink = getHyperLink(DocPaths.indexN(prev),
+            Content prevLink = Links.createLink(DocPaths.indexN(prev),
                     prevletterLabel);
             return HtmlTree.LI(prevLink);
         }
@@ -212,7 +213,7 @@
             return HtmlTree.LI(nextletterLabel);
         }
         else {
-            Content nextLink = getHyperLink(DocPaths.indexN(next),
+            Content nextLink = Links.createLink(DocPaths.indexN(next),
                     nextletterLabel);
             return HtmlTree.LI(nextLink);
         }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java	Thu Nov 16 15:16:21 2017 -0800
@@ -40,6 +40,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.RawHtml;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
@@ -105,7 +106,7 @@
         }
         String desc = ch.getText(itt.getDescription());
 
-        String anchorName = htmlWriter.getName(tagText);
+        String anchorName = configuration.links.getName(tagText);
         Content result = HtmlTree.A_ID(HtmlStyle.searchTagResult, anchorName, new StringContent(tagText));
         if (configuration.createindex && !tagText.isEmpty()) {
             SearchIndexItem si = new SearchIndexItem();
@@ -287,7 +288,7 @@
                     ((ClassWriterImpl) htmlWriter).getTypeElement().getQualifiedName() + "." +
                     utils.getSimpleName(holder);
             DocLink link = constantsPath.fragment(whichConstant);
-            body.addContent(htmlWriter.getHyperLink(link,
+            body.addContent(Links.createLink(link,
                     new StringContent(configuration.getText("doclet.Constants_Summary"))));
         }
         if (utils.isClass(holder) && utils.isSerializable((TypeElement)holder)) {
@@ -297,7 +298,7 @@
                 appendSeparatorIfNotEmpty(body);
                 DocPath serialPath = htmlWriter.pathToRoot.resolve(DocPaths.SERIALIZED_FORM);
                 DocLink link = serialPath.fragment(utils.getFullyQualifiedName(holder));
-                body.addContent(htmlWriter.getHyperLink(link,
+                body.addContent(Links.createLink(link,
                         new StringContent(configuration.getText("doclet.Serialized_Form"))));
             }
         }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TreeWriter.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TreeWriter.java	Thu Nov 16 15:16:21 2017 -0800
@@ -33,6 +33,7 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.Content;
 import jdk.javadoc.internal.doclets.toolkit.util.ClassTree;
@@ -161,7 +162,7 @@
                     continue;
                 }
                 DocPath link = pathString(pkg, DocPaths.PACKAGE_TREE);
-                Content li = HtmlTree.LI(getHyperLink(link,
+                Content li = HtmlTree.LI(Links.createLink(link,
                         new StringContent(utils.getPackageName(pkg))));
                 if (i < packages.size() - 1) {
                     li.addContent(", ");
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlDocWriter.java	Thu Nov 16 15:13:44 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlDocWriter.java	Thu Nov 16 15:16:21 2017 -0800
@@ -30,7 +30,6 @@
 import javax.lang.model.element.TypeElement;
 
 import jdk.javadoc.internal.doclets.formats.html.HtmlConfiguration;
-import jdk.javadoc.internal.doclets.formats.html.SectionName;
 import jdk.javadoc.internal.doclets.toolkit.Content;
 import jdk.javadoc.internal.doclets.toolkit.Messages;
 import jdk.javadoc.internal.doclets.toolkit.util.DocFile;
@@ -69,213 +68,6 @@
             DocFile.createFileForOutput(configuration, filename).getPath());
     }
 
-    public Content getHyperLink(DocPath link, String label) {
-        return getHyperLink(link, new StringContent(label), false, "", "", "");
-    }
-
-    /**
-     * Get Html Hyper Link Content.
-     *
-     * @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(getDocLink(where), label, "", "");
-    }
-
-    /**
-     * Get Html Hyper Link Content.
-     *
-     * @param sectionName      The section name to which the link will be created.
-     * @param label            Tag for the link.
-     * @return a content tree for the hyper link
-     */
-    public Content getHyperLink(SectionName sectionName,
-                               Content label) {
-        return getHyperLink(getDocLink(sectionName), label, "", "");
-    }
-
-    /**
-     * Get Html Hyper Link Content.
-     *
-     * @param sectionName      The section name combined with where to which the link
-     *                         will be created.
-     * @param where            The fragment combined with sectionName to which the link
-     *                         will be created.
-     * @param label            Tag for the link.
-     * @return a content tree for the hyper link
-     */
-    public Content getHyperLink(SectionName sectionName, String where,
-                               Content label) {
-        return getHyperLink(getDocLink(sectionName, where), label, "", "");
-    }
-
-    /**
-     * Get the link.
-     *
-     * @param where      Position of the link in the file.
-     * @return a DocLink object for the hyper link
-     */
-    public DocLink getDocLink(String where) {
-        return DocLink.fragment(getName(where));
-    }
-
-    /**
-     * Get the link.
-     *
-     * @param sectionName      The section name to which the link will be created.
-     * @return a DocLink object for the hyper link
-     */
-    public DocLink getDocLink(SectionName sectionName) {
-        return DocLink.fragment(sectionName.getName());
-    }
-
-    /**
-     * Get the link.
-     *
-     * @param sectionName      The section name combined with where to which the link
-     *                         will be created.
-     * @param where            The fragment combined with sectionName to which the link
-     *                         will be created.
-     * @return a DocLink object for the hyper link
-     */
-    public DocLink getDocLink(SectionName sectionName, String where) {
-        return DocLink.fragment(sectionName.getName() + getName(where));
-    }
-
-    /**
-     * Convert the name to a valid HTML name.
-     *
-     * @param name the name that needs to be converted to valid HTML name.
-     * @return a valid HTML name string.
-     */
-    public String getName(String name) {
-        /* The HTML 4 spec at http://www.w3.org/TR/html4/types.html#h-6.2 mentions
-         * that the name/id should begin with a letter followed by other valid characters.
-         * The HTML 5 spec (draft) is more permissive on names/ids where the only restriction
-         * is that it should be at least one character long and should not contain spaces.
-         * The spec draft is @ http://www.w3.org/html/wg/drafts/html/master/dom.html#the-id-attribute.
-         *
-         * For HTML 4, we need to check for non-characters at the beginning of the name and
-         * substitute it accordingly, "_" and "$" can appear at the beginning of a member name.
-         * The method substitutes "$" with "Z:Z:D" and will prefix "_" with "Z:Z".
-         */
-
-        if (configuration.isOutputHtml5()) {
-            return name.replaceAll(" +", "");
-        }
-
-        StringBuilder sb = new StringBuilder();
-        for (int i = 0; i < name.length(); i++) {
-            char ch = name.charAt(i);
-            switch (ch) {
-                case '(':
-                case ')':
-                case '<':
-                case '>':
-                case ',':
-                    sb.append('-');
-                    break;
-                case ' ':
-                case '[':
-                    break;
-                case ']':
-                    sb.append(":A");
-                    break;
-                // Any appearance of $ needs to be substituted with ":D" and not with hyphen
-                // since a field name "P$$ and a method P(), both valid member names, can end
-                // up as "P--". A member name beginning with $ needs to be substituted with
-                // "Z:Z:D".
-                case '$':
-                    if (i == 0)
-                        sb.append("Z:Z");
-                    sb.append(":D");
-                    break;
-                // A member name beginning with _ needs to be prefixed with "Z:Z" since valid anchor
-                // names can only begin with a letter.
-                case '_':
-                    if (i == 0)
-                        sb.append("Z:Z");
-                    sb.append(ch);
-                    break;
-                default:
-                    sb.append(ch);
-            }
-        }
-        return sb.toString();
-    }
-
-    /**
-     * Get Html hyperlink.
-     *
-     * @param link       path of the file.
-     * @param label      Tag for the link.
-     * @return a content tree for the hyper link
-     */
-    public Content getHyperLink(DocPath link, Content label) {
-        return getHyperLink(link, label, "", "");
-    }
-
-    public Content getHyperLink(DocLink link, Content label) {
-        return getHyperLink(link, label, "", "");
-    }
-
-    public Content getHyperLink(DocPath link,
-                               Content label, boolean strong,
-                               String stylename, String title, String target) {
-        return getHyperLink(new DocLink(link), label, strong,
-                stylename, title, target);
-    }
-
-    public Content getHyperLink(DocLink link,
-                               Content label, boolean strong,
-                               String stylename, String title, String target) {
-        Content body = label;
-        if (strong) {
-            body = HtmlTree.SPAN(HtmlStyle.typeNameLink, body);
-        }
-        if (stylename != null && stylename.length() != 0) {
-            HtmlTree t = new HtmlTree(HtmlTag.FONT, body);
-            t.addAttr(HtmlAttr.CLASS, stylename);
-            body = t;
-        }
-        HtmlTree l = HtmlTree.A(link.toString(), body);
-        if (title != null && title.length() != 0) {
-            l.addAttr(HtmlAttr.TITLE, title);
-        }
-        if (target != null && target.length() != 0) {
-            l.addAttr(HtmlAttr.TARGET, target);
-        }
-        return l;
-    }
-
-    /**
-     * Get Html Hyper Link.
-     *
-     * @param link       String name of the file.
-     * @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(DocPath link, Content label, String title, String target) {
-        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);
-        }
-        if (target != null && target.length() != 0) {
-            anchor.addAttr(HtmlAttr.TARGET, target);
-        }
-        return anchor;
-    }
-
     public Content getModuleFramesHyperLink(ModuleElement mdle, Content label, String target) {
         DocLink mdlLink = new DocLink(DocPaths.moduleFrame(mdle));
         DocLink mtFrameLink = new DocLink(DocPaths.moduleTypeFrame(mdle));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Links.java	Thu Nov 16 15:16:21 2017 -0800
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 1997, 2017, 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 jdk.javadoc.internal.doclets.formats.html.markup;
+
+import jdk.javadoc.internal.doclets.formats.html.SectionName;
+import jdk.javadoc.internal.doclets.toolkit.Content;
+import jdk.javadoc.internal.doclets.toolkit.util.DocLink;
+import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
+
+/**
+ * Factory for HTML A elements, both links (with a {@code href} attribute)
+ * and anchors (with an {@code id} or {@code name} attribute).
+ *
+ * Most methods in this class are static factory methods.
+ * The exceptions are those methods that directly or indirectly depend on the HTML version
+ * being used, when determining valid HTML names (ids),
+ * and those methods that generate anchors.
+ *
+ *  <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 Links {
+
+    private final HtmlVersion version;
+
+    /**
+     * Creates a {@code Links} object for a specific HTML version.
+     * The version is used by the {@link #getName(String) getName} method
+     * to help determine valid HTML names (ids), and to determine whether
+     * to use an {@code id} or {@code name} attribute when creating anchors.
+     *
+     * @param version the HTML version
+     */
+    public Links(HtmlVersion version) {
+        this.version = version;
+    }
+
+    /**
+     * Creates an anchor of the form {@code <a id="name"><!-- --></a>}.
+     * In HTML4, a {@code name} attribute will be generated instead of an {@code id} attribute.
+     *
+     * @param name the value for the {@code id} or {@code name} attribute
+     * @return a content tree for the anchor
+     */
+    public Content createAnchor(String name) {
+        return createAnchor(getName(name), null);
+    }
+
+    /**
+     * Creates an anchor of the form {@code <a id="sectionName"><!-- --></a>}.
+     * In HTML4, a {@code name} attribute will be generated instead of an {@code id} attribute.
+     *
+     * @param sectionName the value for the {@code id} or {@code name} attribute
+     * @return a content tree for the anchor
+     */
+    public Content createAnchor(SectionName sectionName) {
+        return createAnchor(sectionName.getName(), null);
+    }
+
+    /**
+     * Creates an anchor of the form {@code <a id="sectionNameName"><!-- --></a>}.
+     * In HTML4, a {@code name} attribute will be generated instead of an {@code id} attribute.
+     *
+     * @param sectionName the first part of the value for the {@code id} or {@code name} attribute
+     * @param name the second part of the value for the {@code id} or {@code name} attribute
+     * @return a content tree for the anchor
+     */
+    public Content createAnchor(SectionName sectionName, String name) {
+        return createAnchor(sectionName.getName() + getName(name), null);
+    }
+
+    /**
+     * Creates an anchor of the form {@code <a id="anchorName">content</a>}.
+     * In HTML4, a {@code name} attribute will be generated instead of an {@code id} attribute.
+     *
+     * @param name the value for the {@code id} or {@code name} attribute
+     * @param content the content that should be added to the anchor,
+     *              or null, to use an empty comment
+     * @return a content tree for the marker anchor
+     */
+    public Content createAnchor(String name, Content content) {
+        return HtmlTree.A(version, name, (content == null ? EMPTY_COMMENT : content));
+    }
+
+    private static final Content EMPTY_COMMENT = new Comment(" ");
+
+    /**
+     * Creates a link of the form {@code <a href="#where">label</a>}.
+     *
+     * @param where      the position of the link in the file
+     * @param label      the content for the link
+     * @return a content tree for the link
+     */
+    public Content createLink(String where, Content label) {
+        DocLink l = DocLink.fragment(getName(where));
+        return Links.createLink(l, label, "", "");
+    }
+
+    /**
+     * Creates a link of the form {@code <a href="#sectionName">label</a>}.
+     *
+     * @param sectionName   the section name to which the link will be created
+     * @param label         the content for the link
+     * @return a content tree for the link
+     */
+    public static Content createLink(SectionName sectionName, Content label) {
+        DocLink l =  DocLink.fragment(sectionName.getName());
+        return Links.createLink(l, label, "", "");
+    }
+
+    /**
+     * Creates a link of the form {@code <a href="#sectionNameWhere">label</a>}.
+     *
+     * @param sectionName   the section name combined with where to which the link
+     *                      will be created
+     * @param where         the fragment combined with sectionName to which the link
+     *                      will be created
+     * @param label         the content for the link
+     * @return a content tree for the link
+     */
+    public Content createLink(SectionName sectionName, String where, Content label) {
+        DocLink l =  DocLink.fragment(sectionName.getName() + getName(where));
+        return Links.createLink(l, label, "", "");
+    }
+
+    /**
+     * Creates a link of the form {@code <a href="#stylename" title="title" target="target">label</a>}.
+     *
+     * @param sectionName   the section name to which the link will be created
+     * @param label     the content for the link
+     * @param title     the title for the link
+     * @param target    the target for the link, or null
+     * @return a content tree for the link
+     */
+    public static Content createLink(SectionName sectionName, Content label, String title, String target) {
+        DocLink l = DocLink.fragment(sectionName.getName());
+        return createLink(l, label, title, target);
+    }
+
+    /**
+     * Creates a link of the form {@code <a href="path">label</a>}.
+     *
+     * @param path   the path for the link
+     * @param label  the content for the link
+     * @return a content tree for the link
+     */
+    public static Content createLink(DocPath path, String label) {
+        return Links.createLink(path, new StringContent(label), false, "", "", "");
+    }
+
+    /**
+     * Creates a link of the form {@code <a href="path">label</a>}.
+     *
+     * @param path   the path for the link
+     * @param label  the content for the link
+     * @return a content tree for the link
+     */
+    public static Content createLink(DocPath path, Content label) {
+        return Links.createLink(path, label, "", "");
+    }
+
+    /**
+     * Creates a link of the form {@code <a href="path" title="title" target="target">label</a>}.
+     * If {@code strong} is set, the label will be wrapped in
+     *      {@code <span style="typeNameLink">...</span>}.
+     *
+     * @param path      the path for the link
+     * @param label     the content for the link
+     * @param strong    whether to wrap the {@code label} in a SPAN element
+     * @param stylename (deprecated)
+     * @param title     the title for the link
+     * @param target    the target for the link, or null
+     * @return a content tree for the link
+     */
+    public static Content createLink(DocPath path, Content label, boolean strong, String stylename,
+            String title, String target) {
+        return createLink(new DocLink(path), label, strong, stylename, title, target);
+    }
+
+    /**
+     * Creates a link of the form {@code <a href="path" title="title" target="target">label</a>}.
+     *
+     * @param path      the path for the link
+     * @param label     the content for the link
+     * @param title     the title for the link
+     * @param target    the target for the link, or null
+     * @return a content tree for the link
+     */
+    public static Content createLink(DocPath path, Content label, String title, String target) {
+        return Links.createLink(new DocLink(path), label, title, target);
+    }
+
+    /**
+     * Creates a link of the form {@code <a href="link">label</a>}.
+     *
+     * @param link      the details for the link
+     * @param label     the content for the link
+     * @return a content tree for the link
+     */
+    public static Content createLink(DocLink link, Content label) {
+        return Links.createLink(link, label, "", "");
+    }
+
+    /**
+     * Creates a link of the form {@code <a href="path" title="title" target="target">label</a>}.
+     *
+     * @param link      the details for the link
+     * @param label     the content for the link
+     * @param title     the title for the link
+     * @param target    the target for the link, or null
+     * @return a content tree for the link
+     */
+    public static Content createLink(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);
+        }
+        if (target != null && target.length() != 0) {
+            anchor.addAttr(HtmlAttr.TARGET, target);
+        }
+        return anchor;
+    }
+
+    /**
+     * Creates a link of the form {@code <a href="link" title="title" target="target">label</a>}.
+     * If {@code strong} is set, the label will be wrapped in
+     *      {@code <span style="typeNameLink">...</span>}.
+     *
+     * @param link      the details for the link
+     * @param label     the content for the link
+     * @param strong    whether to wrap the {@code label} in a SPAN element
+     * @param stylename (deprecated)
+     * @param title     the title for the link
+     * @param target    the target for the link, or null
+     * @return a content tree for the link
+     */
+    public static Content createLink(DocLink link, Content label, boolean strong, String stylename,
+            String title, String target) {
+        Content body = label;
+        if (strong) {
+            body = HtmlTree.SPAN(HtmlStyle.typeNameLink, body);
+        }
+        if (stylename != null && stylename.length() != 0) {
+            HtmlTree t = new HtmlTree(HtmlTag.FONT, body);
+            t.addAttr(HtmlAttr.CLASS, stylename);
+            body = t;
+        }
+        HtmlTree l = HtmlTree.A(link.toString(), body);
+        if (title != null && title.length() != 0) {
+            l.addAttr(HtmlAttr.TITLE, title);
+        }
+        if (target != null && target.length() != 0) {
+            l.addAttr(HtmlAttr.TARGET, target);
+        }
+        return l;
+    }
+
+
+    /**
+     * Converts a name to a valid HTML name (id).
+     * This depends on the HTML version specified when the {@code Links} object was created.
+     *
+     * @param name the string that needs to be converted to a valid HTML name
+     * @return a valid HTML name
+     */
+    public String getName(String name) {
+        /* The HTML 4 spec at http://www.w3.org/TR/html4/types.html#h-6.2 mentions
+         * that the name/id should begin with a letter followed by other valid characters.
+         * The HTML 5 spec (draft) is more permissive on names/ids where the only restriction
+         * is that it should be at least one character long and should not contain spaces.
+         * The spec draft is @ http://www.w3.org/html/wg/drafts/html/master/dom.html#the-id-attribute.
+         *
+         * For HTML 4, we need to check for non-characters at the beginning of the name and
+         * substitute it accordingly, "_" and "$" can appear at the beginning of a member name.
+         * The method substitutes "$" with "Z:Z:D" and will prefix "_" with "Z:Z".
+         */
+
+        if (version == HtmlVersion.HTML5) {
+            return name.replaceAll(" +", "");
+        }
+
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < name.length(); i++) {
+            char ch = name.charAt(i);
+            switch (ch) {
+                case '(':
+                case ')':
+                case '<':
+                case '>':
+                case ',':
+                    sb.append('-');
+                    break;
+                case ' ':
+                case '[':
+                    break;
+                case ']':
+                    sb.append(":A");
+                    break;
+                // Any appearance of $ needs to be substituted with ":D" and not with hyphen
+                // since a field name "P$$ and a method P(), both valid member names, can end
+                // up as "P--". A member name beginning with $ needs to be substituted with
+                // "Z:Z:D".
+                case '$':
+                    if (i == 0)
+                        sb.append("Z:Z");
+                    sb.append(":D");
+                    break;
+                // A member name beginning with _ needs to be prefixed with "Z:Z" since valid anchor
+                // names can only begin with a letter.
+                case '_':
+                    if (i == 0)
+                        sb.append("Z:Z");
+                    sb.append(ch);
+                    break;
+                default:
+                    sb.append(ch);
+            }
+        }
+        return sb.toString();
+    }
+
+}