src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java
changeset 47846 4e78aba768f0
parent 47427 251676148c62
child 47847 7640bc1eb94f
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java	Thu Nov 16 20:25:45 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java	Thu Nov 16 15:01:45 2017 -0800
@@ -25,9 +25,11 @@
 
 package jdk.javadoc.internal.doclets.formats.html;
 
+import jdk.javadoc.internal.doclets.formats.html.markup.Table;
+import jdk.javadoc.internal.doclets.formats.html.markup.TableHeader;
+
+import java.util.ArrayList;
 import java.util.Collections;
-import java.util.EnumSet;
-import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -43,7 +45,7 @@
 
 import com.sun.source.doctree.DocTree;
 import jdk.javadoc.doclet.DocletEnvironment.ModuleMode;
-import jdk.javadoc.internal.doclets.formats.html.markup.HtmlAttr;
+import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
 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.HtmlTag;
@@ -55,7 +57,6 @@
 import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
 import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
 import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
-import jdk.javadoc.internal.doclets.toolkit.util.ModulePackageTypes;
 
 /**
  * Class to generate file for each module contents in the right-hand frame. This will list all the
@@ -157,12 +158,6 @@
     private final Map<TypeElement, Content> providesTrees
             = new TreeMap<>(utils.makeAllClassesComparator());
 
-    private int packageTypesOr = 0;
-
-    protected Set<ModulePackageTypes> modulePackageTypes = EnumSet.noneOf(ModulePackageTypes.class);
-
-    protected Map<String, Integer> typeMap = new LinkedHashMap<>();
-
     /**
      * The HTML tree for main tag.
      */
@@ -208,7 +203,7 @@
             bodyTree.addContent(htmlTree);
         }
         HtmlTree div = new HtmlTree(HtmlTag.DIV);
-        div.addStyle(HtmlStyle.header);
+        div.setStyle(HtmlStyle.header);
         Content annotationContent = new HtmlTree(HtmlTag.P);
         addAnnotationInfo(mdle, annotationContent);
         div.addContent(annotationContent);
@@ -234,7 +229,7 @@
     @Override
     public Content getContentHeader() {
         HtmlTree div = new HtmlTree(HtmlTag.DIV);
-        div.addStyle(HtmlStyle.contentContainer);
+        div.setStyle(HtmlStyle.contentContainer);
         return div;
     }
 
@@ -244,7 +239,7 @@
     @Override
     public Content getSummaryHeader() {
         HtmlTree li = new HtmlTree(HtmlTag.LI);
-        li.addStyle(HtmlStyle.blockList);
+        li.setStyle(HtmlStyle.blockList);
         return li;
     }
 
@@ -465,21 +460,7 @@
     }
 
     /**
-     * Get a table.
-     *
-     * @param text the table caption
-     * @param tableSummary the summary for the table
-     * @param tableStyle the table style
-     * @param tableHeader the table header
-     * @return a content object
-     */
-    Content getTable(String text, String tableSummary, HtmlStyle tableStyle,
-            TableHeader tableHeader) {
-        return getTable(getTableCaption(new RawHtml(text)), tableSummary, tableStyle, tableHeader);
-    }
-
-    /**
-     * Get a table.
+     * Get a table, with two columns.
      *
      * @param caption the table caption
      * @param tableSummary the summary for the table
@@ -487,13 +468,32 @@
      * @param tableHeader the table header
      * @return a content object
      */
-    Content getTable(Content caption, String tableSummary, HtmlStyle tableStyle,
+    private Table getTable2(Content caption, String tableSummary, HtmlStyle tableStyle,
             TableHeader tableHeader) {
-        Content table = (configuration.isOutputHtml5())
-                ? HtmlTree.TABLE(tableStyle, caption)
-                : HtmlTree.TABLE(tableStyle, tableSummary, caption);
-        table.addContent(tableHeader.toContent());
-        return table;
+        return new Table(configuration.htmlVersion, tableStyle)
+                .setSummary(tableSummary)
+                .setCaption(caption)
+                .setHeader(tableHeader)
+                .setColumnStyles(HtmlStyle.colFirst, HtmlStyle.colLast);
+    }
+
+    /**
+     * Get a table, with three columns, with the second column being the defining column.
+     *
+     * @param caption the table caption
+     * @param tableSummary the summary for the table
+     * @param tableStyle the table style
+     * @param tableHeader the table header
+     * @return a content object
+     */
+    private Table getTable3(Content caption, String tableSummary, HtmlStyle tableStyle,
+            TableHeader tableHeader) {
+        return new Table(configuration.htmlVersion, tableStyle)
+                .setSummary(tableSummary)
+                .setCaption(caption)
+                .setHeader(tableHeader)
+                .setRowScopeColumn(1)
+                .setColumnStyles(HtmlStyle.colFirst, HtmlStyle.colSecond, HtmlStyle.colLast);
     }
 
     /**
@@ -506,33 +506,31 @@
                     new TableHeader(contents.modifierLabel, contents.moduleLabel,
                             contents.descriptionLabel);
             HtmlTree li = new HtmlTree(HtmlTag.LI);
-            li.addStyle(HtmlStyle.blockList);
+            li.setStyle(HtmlStyle.blockList);
             addSummaryHeader(HtmlConstants.START_OF_MODULES_SUMMARY, SectionName.MODULES,
                     contents.navModules, li);
             if (display(requires)) {
-                String text = configuration.getText("doclet.Requires_Summary");
-                String tableSummary = configuration.getText("doclet.Member_Table_Summary",
+                String text = resources.getText("doclet.Requires_Summary");
+                String tableSummary = resources.getText("doclet.Member_Table_Summary",
                         text,
-                        configuration.getText("doclet.modules"));
-                Content table = getTable(text, tableSummary, HtmlStyle.requiresSummary,
-                        requiresTableHeader);
-                Content tbody = new HtmlTree(HtmlTag.TBODY);
-                addModulesList(requires, tbody);
-                table.addContent(tbody);
-                li.addContent(table);
+                        resources.getText("doclet.modules"));
+                Content caption = getTableCaption(new StringContent(text));
+                Table table = getTable3(caption, tableSummary, HtmlStyle.requiresSummary,
+                            requiresTableHeader);
+                addModulesList(requires, table);
+                li.addContent(table.toContent());
             }
             // Display indirect modules table in both "api" and "all" mode.
             if (display(indirectModules)) {
-                String amrText = configuration.getText("doclet.Indirect_Requires_Summary");
-                String amrTableSummary = configuration.getText("doclet.Member_Table_Summary",
+                String amrText = resources.getText("doclet.Indirect_Requires_Summary");
+                String amrTableSummary = resources.getText("doclet.Member_Table_Summary",
                         amrText,
                         configuration.getText("doclet.modules"));
-                Content amrTable = getTable(amrText, amrTableSummary, HtmlStyle.requiresSummary,
-                        requiresTableHeader);
-                Content amrTbody = new HtmlTree(HtmlTag.TBODY);
-                addModulesList(indirectModules, amrTbody);
-                amrTable.addContent(amrTbody);
-                li.addContent(amrTable);
+                Content amrCaption = getTableCaption(new StringContent(amrText));
+                Table amrTable = getTable3(amrCaption, amrTableSummary, HtmlStyle.requiresSummary,
+                            requiresTableHeader);
+                addModulesList(indirectModules, amrTable);
+                li.addContent(amrTable.toContent());
             }
             HtmlTree ul = HtmlTree.UL(HtmlStyle.blockList, li);
             summaryContentTree.addContent(ul);
@@ -545,21 +543,13 @@
      * @param mdleMap map of modules and modifiers
      * @param tbody the content tree to which the list will be added
      */
-    public void addModulesList(Map<ModuleElement, Content> mdleMap, Content tbody) {
-        boolean altColor = true;
+    private void addModulesList(Map<ModuleElement, Content> mdleMap, Table table) {
         for (ModuleElement m : mdleMap.keySet()) {
-            Content tdModifiers = HtmlTree.TD(HtmlStyle.colFirst, mdleMap.get(m));
-            Content moduleLinkContent = getModuleLink(m, new StringContent(m.getQualifiedName()));
-            Content thModule = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colSecond, moduleLinkContent);
-            HtmlTree tdSummary = new HtmlTree(HtmlTag.TD);
-            tdSummary.addStyle(HtmlStyle.colLast);
-            addSummaryComment(m, tdSummary);
-            HtmlTree tr = HtmlTree.TR(tdModifiers);
-            tr.addContent(thModule);
-            tr.addContent(tdSummary);
-            tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
-            tbody.addContent(tr);
-            altColor = !altColor;
+            Content modifiers = mdleMap.get(m);
+            Content moduleLink = getModuleLink(m, new StringContent(m.getQualifiedName()));
+            Content moduleSummary = new ContentBuilder();
+            addSummaryComment(m, moduleSummary);
+            table.addRow(modifiers, moduleLink, moduleSummary);
         }
     }
 
@@ -568,42 +558,38 @@
         if (display(exportedPackages) || display(openedPackages) || display(concealedPackages)
                 || display(indirectPackages) || display(indirectOpenPackages)) {
             HtmlTree li = new HtmlTree(HtmlTag.LI);
-            li.addStyle(HtmlStyle.blockList);
+            li.setStyle(HtmlStyle.blockList);
             addSummaryHeader(HtmlConstants.START_OF_PACKAGES_SUMMARY, SectionName.PACKAGES,
                     contents.navPackages, li);
-            String tableSummary = configuration.getText("doclet.Member_Table_Summary",
-                    configuration.getText("doclet.Packages_Summary"),
-                    configuration.getText("doclet.packages"));
             if (display(exportedPackages) || display(openedPackages) || display(concealedPackages)) {
+                String tableSummary = resources.getText("doclet.Member_Table_Summary",
+                        resources.getText("doclet.Packages_Summary"),
+                        resources.getText("doclet.packages"));
                 addPackageSummary(tableSummary, li);
             }
             TableHeader indirectPackagesHeader =
                     new TableHeader(contents.fromLabel, contents.packagesLabel);
             if (display(indirectPackages)) {
-                String aepText = configuration.getText("doclet.Indirect_Exports_Summary");
-                String aepTableSummary = configuration.getText("doclet.Indirect_Packages_Table_Summary",
+                String aepText = resources.getText("doclet.Indirect_Exports_Summary");
+                String aepTableSummary = resources.getText("doclet.Indirect_Packages_Table_Summary",
                         aepText,
-                        configuration.getText("doclet.modules"),
-                        configuration.getText("doclet.packages"));
-                Content aepTable = getTable(aepText, aepTableSummary, HtmlStyle.packagesSummary,
-                        indirectPackagesHeader);
-                Content aepTbody = new HtmlTree(HtmlTag.TBODY);
-                addIndirectPackages(aepTbody, indirectPackages);
-                aepTable.addContent(aepTbody);
-                li.addContent(aepTable);
+                        resources.getText("doclet.modules"),
+                        resources.getText("doclet.packages"));
+                Table aepTable = getTable2(new StringContent(aepText), aepTableSummary,
+                        HtmlStyle.packagesSummary, indirectPackagesHeader);
+                addIndirectPackages(aepTable, indirectPackages);
+                li.addContent(aepTable.toContent());
             }
             if (display(indirectOpenPackages)) {
-                String aopText = configuration.getText("doclet.Indirect_Opens_Summary");
-                String aopTableSummary = configuration.getText("doclet.Indirect_Packages_Table_Summary",
+                String aopText = resources.getText("doclet.Indirect_Opens_Summary");
+                String aopTableSummary = resources.getText("doclet.Indirect_Packages_Table_Summary",
                         aopText,
-                        configuration.getText("doclet.modules"),
-                        configuration.getText("doclet.packages"));
-                Content aopTable = getTable(aopText, aopTableSummary, HtmlStyle.packagesSummary,
-                        indirectPackagesHeader);
-                Content aopTbody = new HtmlTree(HtmlTag.TBODY);
-                addIndirectPackages(aopTbody, indirectOpenPackages);
-                aopTable.addContent(aopTbody);
-                li.addContent(aopTable);
+                        resources.getText("doclet.modules"),
+                        resources.getText("doclet.packages"));
+                Table aopTable = getTable2(new StringContent(aopText), aopTableSummary,
+                        HtmlStyle.packagesSummary, indirectPackagesHeader);
+                addIndirectPackages(aopTable, indirectOpenPackages);
+                li.addContent(aopTable.toContent());
             }
             HtmlTree ul = HtmlTree.UL(HtmlStyle.blockList, li);
             summaryContentTree.addContent(ul);
@@ -617,79 +603,31 @@
      * @param li
      */
     public void addPackageSummary(String tableSummary, HtmlTree li) {
-        Content caption;
-        Content tbody = getPackageTableRows();
-        if (showTabs()) {
-            caption = getTableCaption();
-            generateTableTabTypesScript(typeMap, modulePackageTypes, "packages");
-        } else {
-            ModulePackageTypes type = modulePackageTypes.iterator().next();
-            caption = getTableCaption(configuration.getContent(type.tableTabs().resourceKey()));
-        }
-        TableHeader header = (configuration.docEnv.getModuleMode() == ModuleMode.ALL)
-                ? new TableHeader(contents.packageLabel, contents.moduleLabel, contents.descriptionLabel)
-                : new TableHeader(contents.packageLabel, contents.descriptionLabel);
-        Content table = getTable(caption, tableSummary, HtmlStyle.packagesSummary, header);
-        table.addContent(tbody);
-        li.addContent(table);
-    }
-
-    /**
-     * Returns true if the table tabs needs to be displayed.
-     *
-     * @return true if the tabs should be displayed
-     */
-    public boolean showTabs() {
-        int value;
-        for (ModulePackageTypes type : EnumSet.allOf(ModulePackageTypes.class)) {
-            value = type.tableTabs().value();
-            if ((value & packageTypesOr) == value) {
-                modulePackageTypes.add(type);
-            }
-        }
-        boolean showTabs = modulePackageTypes.size() > 1;
-        if (showTabs) {
-            modulePackageTypes.add(ModulePackageTypes.ALL);
-        }
-        return showTabs;
-    }
+        Table table = new Table(configuration.htmlVersion, HtmlStyle.packagesSummary)
+                .setSummary(tableSummary)
+                .setDefaultTab(resources.getText("doclet.All_Packages"))
+                .addTab(resources.getText("doclet.Exported_Packages_Summary"),
+                        e -> exportedPackages.containsKey((PackageElement) e))
+                .addTab(resources.getText("doclet.Opened_Packages_Summary"),
+                        e -> openedPackages.containsKey((PackageElement) e))
+                .addTab(resources.getText("doclet.Concealed_Packages_Summary"),
+                        e -> concealedPackages.contains((PackageElement) e))
+                .setTabScript(i -> String.format("showPkgs(%d);", i))
+                .setTabScriptVariable("packages");
 
-    /**
-     * Get the summary table caption.
-     *
-     * @return the caption for the summary table
-     */
-    public Content getTableCaption() {
-        Content tabbedCaption = new HtmlTree(HtmlTag.CAPTION);
-        for (ModulePackageTypes type : modulePackageTypes) {
-            Content captionSpan;
-            Content span;
-            if (type.tableTabs().isDefaultTab()) {
-                captionSpan = HtmlTree.SPAN(configuration.getContent(type.tableTabs().resourceKey()));
-                span = HtmlTree.SPAN(type.tableTabs().tabId(),
-                        HtmlStyle.activeTableTab, captionSpan);
-            } else {
-                captionSpan = HtmlTree.SPAN(getPackageTypeLinks(type));
-                span = HtmlTree.SPAN(type.tableTabs().tabId(),
-                        HtmlStyle.tableTab, captionSpan);
-            }
-            Content tabSpan = HtmlTree.SPAN(HtmlStyle.tabEnd, Contents.SPACE);
-            span.addContent(tabSpan);
-            tabbedCaption.addContent(span);
+        if (configuration.docEnv.getModuleMode() == ModuleMode.API) {
+            table.setHeader(new TableHeader(contents.packageLabel, contents.descriptionLabel))
+                    .setColumnStyles(HtmlStyle.colFirst, HtmlStyle.colLast);
+        } else {
+            table.setHeader(new TableHeader(contents.packageLabel, contents.moduleLabel, contents.descriptionLabel))
+                    .setColumnStyles(HtmlStyle.colFirst, HtmlStyle.colSecond, HtmlStyle.colLast);
         }
-        return tabbedCaption;
-    }
 
-    /**
-     * Get the package type links for the table caption.
-     *
-     * @param packageType the package type to be displayed as link
-     * @return the content tree for the package type link
-     */
-    public Content getPackageTypeLinks(ModulePackageTypes packageType) {
-        String jsShow = "javascript:showPkgs(" + packageType.tableTabs().value() + ");";
-        HtmlTree link = HtmlTree.A(jsShow, configuration.getContent(packageType.tableTabs().resourceKey()));
-        return link;
+        addPackageTableRows(table);
+        li.addContent(table.toContent());
+        if (table.needsScript()) {
+            script.addContent(new RawHtml(table.getScript()));
+        }
     }
 
     /**
@@ -697,109 +635,70 @@
      *
      * @return a content object
      */
-    public Content getPackageTableRows() {
-        Content tbody = new HtmlTree(HtmlTag.TBODY);
-        boolean altColor = true;
-        int counter = 0;
-        counter = addPackageTableRows(tbody, counter, ModulePackageTypes.EXPORTED, exportedPackages);
-        counter = addPackageTableRows(tbody, counter, ModulePackageTypes.OPENED, openedPackages);
+    private void addPackageTableRows(Table table) {
+        addPackageTableRows(table, exportedPackages);
+        addPackageTableRows(table, openedPackages);
         // Show concealed packages only in "all" mode.
         if (moduleMode == ModuleMode.ALL) {
             for (PackageElement pkg : concealedPackages) {
                 Content pkgLinkContent = getPackageLink(pkg, new StringContent(utils.getPackageName(pkg)));
-                Content thPackage = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst, pkgLinkContent);
-                HtmlTree tdModules = new HtmlTree(HtmlTag.TD);
-                tdModules.addStyle(HtmlStyle.colSecond);
-                tdModules.addContent(configuration.getText("doclet.None"));
-                HtmlTree tdSummary = new HtmlTree(HtmlTag.TD);
-                tdSummary.addStyle(HtmlStyle.colLast);
-                addSummaryComment(pkg, tdSummary);
-                HtmlTree tr = HtmlTree.TR(thPackage);
-                tr.addContent(tdModules);
-                tr.addContent(tdSummary);
-                tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
-                int pkgType = ModulePackageTypes.CONCEALED.tableTabs().value();
-                packageTypesOr = packageTypesOr | pkgType;
-                String tableId = "i" + counter;
-                counter++;
-                typeMap.put(tableId, pkgType);
-                tr.addAttr(HtmlAttr.ID, tableId);
-                tbody.addContent(tr);
-                altColor = !altColor;
+                Content noModules = new StringContent(resources.getText("doclet.None"));
+                Content summary = new ContentBuilder();
+                addSummaryComment(pkg, summary);
+                table.addRow(pkg, pkgLinkContent, noModules, summary);
             }
         }
-        return tbody;
     }
 
-    public int addPackageTableRows(Content tbody, int counter, ModulePackageTypes pType,
-            Map<PackageElement,SortedSet<ModuleElement>> ap) {
-        boolean altColor = true;
+    private void addPackageTableRows(Table table, Map<PackageElement,SortedSet<ModuleElement>> ap) {
         for (Map.Entry<PackageElement, SortedSet<ModuleElement>> entry : ap.entrySet()) {
+            List<Content> row = new ArrayList<>();
             PackageElement pkg = entry.getKey();
             SortedSet<ModuleElement> mdleList = entry.getValue();
             Content pkgLinkContent = getPackageLink(pkg, new StringContent(utils.getPackageName(pkg)));
-            Content thPackage = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst, pkgLinkContent);
-            HtmlTree tr = HtmlTree.TR(thPackage);
+            row.add(pkgLinkContent);
+
             if (moduleMode == ModuleMode.ALL) {
-                HtmlTree tdModules = new HtmlTree(HtmlTag.TD);
-                tdModules.addStyle(HtmlStyle.colSecond);
+                Content modules = new ContentBuilder();
                 if (!mdleList.isEmpty()) {
-                    int sep = 0;
                     for (ModuleElement m : mdleList) {
-                        if (sep > 0) {
-                            tdModules.addContent(new HtmlTree(HtmlTag.BR));
+                        if (!modules.isEmpty()) {
+                            modules.addContent(new HtmlTree(HtmlTag.BR));
                         }
-                        tdModules.addContent(getModuleLink(m, new StringContent(m.getQualifiedName())));
-                        sep++;
+                        modules.addContent(getModuleLink(m, new StringContent(m.getQualifiedName())));
                     }
                 } else {
-                    tdModules.addContent(configuration.getText("doclet.All_Modules"));
+                    Content allModules = new StringContent(resources.getText("doclet.All_Modules"));
+                    modules.addContent(allModules);
                 }
-                tr.addContent(tdModules);
+                row.add(modules);
             }
-            HtmlTree tdSummary = new HtmlTree(HtmlTag.TD);
-            tdSummary.addStyle(HtmlStyle.colLast);
-            addSummaryComment(pkg, tdSummary);
-            tr.addContent(tdSummary);
-            tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
-            int pkgType = pType.tableTabs().value();
-            packageTypesOr = packageTypesOr | pkgType;
-            String tableId = "i" + counter;
-            counter++;
-            typeMap.put(tableId, pkgType);
-            tr.addAttr(HtmlAttr.ID, tableId);
-            tbody.addContent(tr);
-            altColor = !altColor;
+            Content summary = new ContentBuilder();
+            addSummaryComment(pkg, summary);
+            row.add(summary);
+            table.addRow(pkg, row);
         }
-        return counter;
     }
 
     /**
      * Add the indirect packages for the module being documented.
      *
-     * @param tbody the content tree to which the table will be added
+     * @param table the table to which the content rows will be added
      * @param ip indirect packages to be added
      */
-    public void addIndirectPackages(Content tbody, Map<ModuleElement, SortedSet<PackageElement>> ip) {
-        boolean altColor = true;
+    public void addIndirectPackages(Table table, Map<ModuleElement, SortedSet<PackageElement>> ip) {
         for (Map.Entry<ModuleElement, SortedSet<PackageElement>> entry : ip.entrySet()) {
             ModuleElement m = entry.getKey();
             SortedSet<PackageElement> pkgList = entry.getValue();
             Content moduleLinkContent = getModuleLink(m, new StringContent(m.getQualifiedName()));
-            Content thModule = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst, moduleLinkContent);
-            HtmlTree tdPackages = new HtmlTree(HtmlTag.TD);
-            tdPackages.addStyle(HtmlStyle.colLast);
+            Content packages = new ContentBuilder();
             String sep = "";
             for (PackageElement pkg : pkgList) {
-                tdPackages.addContent(sep);
-                tdPackages.addContent(getPackageLink(pkg, new StringContent(utils.getPackageName(pkg))));
+                packages.addContent(sep);
+                packages.addContent(getPackageLink(pkg, new StringContent(utils.getPackageName(pkg))));
                 sep = " ";
             }
-            HtmlTree tr = HtmlTree.TR(thModule);
-            tr.addContent(tdPackages);
-            tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
-            tbody.addContent(tr);
-            altColor = !altColor;
+            table.addRow(moduleLinkContent, packages);
         }
     }
 
@@ -814,7 +713,7 @@
 
         if (haveProvides || haveUses) {
             HtmlTree li = new HtmlTree(HtmlTag.LI);
-            li.addStyle(HtmlStyle.blockList);
+            li.setStyle(HtmlStyle.blockList);
             addSummaryHeader(HtmlConstants.START_OF_SERVICES_SUMMARY, SectionName.SERVICES,
                     contents.navServices, li);
             TableHeader usesProvidesTableHeader =
@@ -822,27 +721,25 @@
             if (haveProvides) {
                 String label = resources.getText("doclet.Provides_Summary");
                 String tableSummary = resources.getText("doclet.Member_Table_Summary",
-                        label, resources.getText("doclet.types"));
-                Content table = getTable(label, tableSummary, HtmlStyle.providesSummary,
+                        label,
+                        resources.getText("doclet.types"));
+                Table table = getTable2(new StringContent(label), tableSummary, HtmlStyle.providesSummary,
                         usesProvidesTableHeader);
-                Content tbody = new HtmlTree(HtmlTag.TBODY);
-                addProvidesList(tbody);
-                if (!tbody.isEmpty()) {
-                    table.addContent(tbody);
-                    li.addContent(table);
+                addProvidesList(table);
+                if (!table.isEmpty()) {
+                    li.addContent(table.toContent());
                 }
             }
             if (haveUses){
                 String label = resources.getText("doclet.Uses_Summary");
                 String tableSummary = resources.getText("doclet.Member_Table_Summary",
-                        label, resources.getText("doclet.types"));
-                Content table = getTable(label, tableSummary, HtmlStyle.usesSummary,
+                        label,
+                        resources.getText("doclet.types"));
+                Table table = getTable2(new StringContent(label), tableSummary, HtmlStyle.usesSummary,
                         usesProvidesTableHeader);
-                Content tbody = new HtmlTree(HtmlTag.TBODY);
-                addUsesList(tbody);
-                if (!tbody.isEmpty()) {
-                    table.addContent(tbody);
-                    li.addContent(table);
+                addUsesList(table);
+                if (!table.isEmpty()) {
+                    li.addContent(table.toContent());
                 }
             }
             HtmlTree ul = HtmlTree.UL(HtmlStyle.blockList, li);
@@ -853,44 +750,34 @@
     /**
      * Add the uses list for the module.
      *
-     * @param tbody the content tree to which the directive will be added
+     * @param table the table to which the services used will be added
      */
-    public void addUsesList(Content tbody) {
-        boolean altColor = true;
+    public void addUsesList(Table table) {
         Content typeLinkContent;
-        Content thType;
-        HtmlTree tdSummary;
         Content description;
         for (TypeElement t : uses) {
             if (!displayServiceDirective(t, usesTrees)) {
                 continue;
             }
             typeLinkContent = getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.PACKAGE, t));
-            thType = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst, typeLinkContent);
-            tdSummary = new HtmlTree(HtmlTag.TD);
-            tdSummary.addStyle(HtmlStyle.colLast);
+            Content summary = new ContentBuilder();
             if (display(usesTrees)) {
                 description = usesTrees.get(t);
                 if (description != null) {
-                    tdSummary.addContent(description);
+                    summary.addContent(description);
                 }
             }
-            addSummaryComment(t, tdSummary);
-            HtmlTree tr = HtmlTree.TR(thType);
-            tr.addContent(tdSummary);
-            tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
-            tbody.addContent(tr);
-            altColor = !altColor;
+            addSummaryComment(t, summary);
+            table.addRow(typeLinkContent, summary);
         }
     }
 
     /**
      * Add the provides list for the module.
      *
-     * @param tbody the content tree to which the directive will be added
+     * @param table the table to which the services provided will be added
      */
-    public void addProvidesList(Content tbody) {
-        boolean altColor = true;
+    public void addProvidesList(Table table) {
         SortedSet<TypeElement> implSet;
         Content description;
         for (Map.Entry<TypeElement, SortedSet<TypeElement>> entry : provides.entrySet()) {
@@ -900,36 +787,30 @@
             }
             implSet = entry.getValue();
             Content srvLinkContent = getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.PACKAGE, srv));
-            HtmlTree thType = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst, srvLinkContent);
-            HtmlTree tdDesc = new HtmlTree(HtmlTag.TD);
-            tdDesc.addStyle(HtmlStyle.colLast);
+            Content desc = new ContentBuilder();
             if (display(providesTrees)) {
                 description = providesTrees.get(srv);
                 if (description != null) {
-                    tdDesc.addContent(description);
+                    desc.addContent(description);
                 }
             }
-            addSummaryComment(srv, tdDesc);
+            addSummaryComment(srv, desc);
             // Only display the implementation details in the "all" mode.
             if (moduleMode == ModuleMode.ALL && !implSet.isEmpty()) {
-                tdDesc.addContent(new HtmlTree(HtmlTag.BR));
-                tdDesc.addContent("(");
+                desc.addContent(new HtmlTree(HtmlTag.BR));
+                desc.addContent("(");
                 HtmlTree implSpan = HtmlTree.SPAN(HtmlStyle.implementationLabel, contents.implementation);
-                tdDesc.addContent(implSpan);
-                tdDesc.addContent(Contents.SPACE);
+                desc.addContent(implSpan);
+                desc.addContent(Contents.SPACE);
                 String sep = "";
                 for (TypeElement impl : implSet) {
-                    tdDesc.addContent(sep);
-                    tdDesc.addContent(getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.PACKAGE, impl)));
+                    desc.addContent(sep);
+                    desc.addContent(getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.PACKAGE, impl)));
                     sep = ", ";
                 }
-                tdDesc.addContent(")");
+                desc.addContent(")");
             }
-            HtmlTree tr = HtmlTree.TR(thType);
-            tr.addContent(tdDesc);
-            tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
-            tbody.addContent(tr);
-            altColor = !altColor;
+            table.addRow(srvLinkContent, desc);
         }
     }
 
@@ -943,7 +824,7 @@
         if (utils.isDeprecated(mdle)) {
             CommentHelper ch = utils.getCommentHelper(mdle);
             HtmlTree deprDiv = new HtmlTree(HtmlTag.DIV);
-            deprDiv.addStyle(HtmlStyle.deprecationBlock);
+            deprDiv.setStyle(HtmlStyle.deprecationBlock);
             Content deprPhrase = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(mdle));
             deprDiv.addContent(deprPhrase);
             if (!deprs.isEmpty()) {
@@ -1078,7 +959,7 @@
         if (utils.isDeprecated(pkg)) {
             deprs = utils.getDeprecatedTrees(pkg);
             HtmlTree deprDiv = new HtmlTree(HtmlTag.DIV);
-            deprDiv.addStyle(HtmlStyle.deprecationBlock);
+            deprDiv.setStyle(HtmlStyle.deprecationBlock);
             Content deprPhrase = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(pkg));
             deprDiv.addContent(deprPhrase);
             if (!deprs.isEmpty()) {