/* gnu.classpath.tools.doclets.htmldoclet.HtmlDoclet
   Copyright (C) 2004 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
 
GNU Classpath 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 for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */

package gnu.classpath.tools.doclets.htmldoclet;

import gnu.classpath.tools.IOToolkit;

import gnu.classpath.tools.doclets.AbstractDoclet;
import gnu.classpath.tools.doclets.DocletConfigurationException;
import gnu.classpath.tools.doclets.DocletOption;
import gnu.classpath.tools.doclets.DocletOptionFile;
import gnu.classpath.tools.doclets.DocletOptionFlag;
import gnu.classpath.tools.doclets.DocletOptionString;
import gnu.classpath.tools.doclets.PackageGroup;
import gnu.classpath.tools.doclets.TagletPrinter;
import gnu.classpath.tools.doclets.InlineTagRenderer;

import gnu.classpath.tools.doclets.xmldoclet.HtmlRepairer;

import gnu.classpath.tools.taglets.GnuExtendedTaglet;
import gnu.classpath.tools.taglets.TagletContext;

import gnu.classpath.tools.java2xhtml.Java2xhtml;

import gnu.classpath.tools.StringToolkit;

import com.sun.javadoc.*;
import com.sun.tools.doclets.Taglet;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringWriter;

import java.net.MalformedURLException;

import java.nio.charset.Charset;

import java.text.DateFormat;
import java.text.MessageFormat;

import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.SortedSet;
import java.util.TimeZone;
import java.util.TreeSet;

public class HtmlDoclet
   extends AbstractDoclet
   implements InlineTagRenderer
{
   private static String filenameExtension = ".html";

   /**
    *  Contains ExternalDocSet.
    */
   private List externalDocSets = new LinkedList();

   /**
    *  Contains String->ExternalDocSet.
    */
   private Map packageNameToDocSet = new HashMap();

   /**
    *  Cache for version string from resource /version.properties
    */
   private String docletVersion;

   /**
    *  For now, do not output a help page.
    */
   private static final boolean outputHelpPage = false;

   /**
    *  Stores the output encoding (either the one specified using
    *  -charset, or the platform default encoding).
    */
   private String outputCharset;

   private void printNavBar(HtmlPage output, String currentPage, ClassDoc currentClass)
   {
         output.beginDiv(CssClass.NAVBAR_TOP);

         boolean overviewLevel
            = ("overview".equals(currentPage)
               || "full-tree".equals(currentPage)
               || "index".equals(currentPage)
               || "split-index".equals(currentPage)
               || "serialized".equals(currentPage)
               || "deprecated".equals(currentPage)
               || "about".equals(currentPage)
               );

         if (!isSinglePackage()) {
            if ("overview".equals(currentPage)) {
               output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
               output.print("Overview");
               output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
            }
            else {
               output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
               output.beginAnchor(output.getPathToRoot() + "/overview-summary" + filenameExtension);
               output.print("Overview");
               output.endAnchor();
               output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
            }
            
            output.print(" ");
         }

         if (!overviewLevel || isSinglePackage()) {
            if ("package".equals(currentPage)) {
               output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
               output.print("Package");
               output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
            }
            else {
               output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
               String packageHref;
               if (isSinglePackage()) {
                  packageHref = output.getPathToRoot() + "/" + getPackageURL(getSinglePackage()) + "package-summary" + filenameExtension;
               }
               else {
                  packageHref = "package-summary" + filenameExtension;
               }
               output.beginAnchor(packageHref);
               output.print("Package");
               output.endAnchor();
               output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
            }
         }
         else {
            output.beginSpan(CssClass.NAVBAR_ITEM_DISABLED);
            output.print("Package");
            output.endSpan(CssClass.NAVBAR_ITEM_DISABLED);
         }

         if (optionUse.getValue() || optionLinkSource.getValue()) {
            output.print(" ");

            if (null != currentClass) {
               if ("class".equals(currentPage)) {
                  output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
                  output.print("Class");
                  output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
               }
               else {
                  output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
                  output.beginAnchor(currentClass.name() + filenameExtension);
                  output.print("Class");
                  output.endAnchor();
                  output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
               }
            }
            else {
               output.beginSpan(CssClass.NAVBAR_ITEM_DISABLED);
               output.print("Class");
               output.endSpan(CssClass.NAVBAR_ITEM_DISABLED);
            }

            if (optionUse.getValue()) {
               output.print(" ");

               if (null != currentClass) {
                  if ("uses".equals(currentPage)) {
                     output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
                     output.print("Use");
                     output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
                  }
                  else {
                     output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
                     output.beginAnchor(currentClass.name() + "-uses" + filenameExtension);
                     output.print("Use");
                     output.endAnchor();
                     output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
                  }
               }
               else {
                  output.beginSpan(CssClass.NAVBAR_ITEM_DISABLED);
                  output.print("Use");
                  output.endSpan(CssClass.NAVBAR_ITEM_DISABLED);
               }
            }

            if (optionLinkSource.getValue()) {
               output.print(" ");

               
               if ("source".equals(currentPage)) {
                  output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
                  output.print("Source");
                  output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
               }
               else {

                  if (null != currentClass) {
                     
                     output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
                     String targetClassName = currentClass.name();
                     String targetAnchor = "";
                     if (null != currentClass.containingClass()) {
                        targetClassName = getOuterClassDoc(currentClass).name();
                        targetAnchor = "#line." + currentClass.position().line();
                     }
                     output.beginAnchor(targetClassName + "-source" + filenameExtension + targetAnchor);
                     output.print("Source");
                     output.endAnchor();
                     output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
                  }
                  else {
                     output.beginSpan(CssClass.NAVBAR_ITEM_DISABLED);
                     output.print("Source");
                     output.endSpan(CssClass.NAVBAR_ITEM_DISABLED);
                  }
               }
            }
         }


         if (!optionNoTree.getValue()) {
            output.print(" ");

            if ("full-tree".equals(currentPage) 
                || "package-tree".equals(currentPage)) {
               output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
               output.print("Tree");
               output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
            }
            else {
               output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
               String treeHref;
               if (isSinglePackage() && overviewLevel) {
                  treeHref = getPackageURL(getSinglePackage()) + "tree" + filenameExtension;
               }
               else {
                  treeHref = "tree" + filenameExtension;
               }

               output.beginAnchor(treeHref);
               output.print("Tree");
               output.endAnchor();
               output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
            }
         }

         output.print(" ");

         String indexName;
         if (optionSplitIndex.getValue()) {
            indexName = "alphaindex-1";
         }
         else {
            indexName = "alphaindex";
         }

         if ("index".equals(currentPage) || "split-index".equals(currentPage)) {
            output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
            output.print("Index");
            output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
         }
         else {
            output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
            output.beginAnchor(output.getPathToRoot() + "/" + indexName + filenameExtension);
            output.print("Index");
            output.endAnchor();
            output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
         }

         if (!optionNoDeprecatedList.getValue()) {
            output.print(" ");

            if ("deprecated".equals(currentPage)) {
               output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
               output.print("Deprecated");
               output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
            }
            else {
               output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
               output.beginAnchor(output.getPathToRoot() + "/deprecated" + filenameExtension);
               output.print("Deprecated");
               output.endAnchor();
               output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
            }
         }

         if (outputHelpPage) {
            if (!optionNoHelp.getValue()) {
               output.print(" ");
               
               if ("help".equals(currentPage)) {
                  output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
                  output.print("Help");
                  output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
               }
               else {
                  output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
                  output.beginAnchor(output.getPathToRoot() + "/help" + filenameExtension);
                  output.print("Help");
                  output.endAnchor();
                  output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
               }
            }
         }

         output.print(" ");

         if ("about".equals(currentPage)) {
            output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
            output.print("About");
            output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
         }
         else {
            output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
            output.beginAnchor(output.getPathToRoot() + "/about" + filenameExtension);
            output.print("About");
            output.endAnchor();
            output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
         }

         output.endDiv(CssClass.NAVBAR_TOP);
   }

   private void printNavBarTopRow(HtmlPage output, String currentPage, ClassDoc currentClass)
   {
      output.beginRow();
      output.beginCell(CssClass.NAVBAR_TOP);
      printNavBar(output, currentPage, currentClass);
      output.endCell();
      if (null != optionHeader.getValue()) {
         output.beginCell(CssClass.NAVBAR_TOP_HEADER);
         output.print(replaceDocRoot(output, optionHeader.getValue()));
         output.endCell();
      }
      output.endRow();
   }

   private void printNavBarTopNaviCell(HtmlPage output)
   {
      output.beginCell(CssClass.NAVBAR_TOP_NAVI);
      output.beginAnchor(output.getPathToRoot() + "/index" + filenameExtension, "Show in a frameset", "_top");
      output.print("Frames");
      output.endAnchor();
      output.print(" | ");

      output.beginAnchor(output.getFile().getName(), "Show without frames", "_top");
      output.print("No Frames");
      output.endAnchor();
      output.print(" ");

      output.endCell();
   }

   private void printNavBarTop(HtmlPage output, String currentPage)
   {
      printNavBarTop(output, currentPage, null, null, null);
   }

   private void printNavBarTop(HtmlPage output, String currentPage, 
                               ClassDoc currentClass, Object prev, Object next)
   {
      if (!optionNoNavBar.getValue()) {
         output.beginTable(CssClass.NAVBAR_TOP);
         printNavBarTopRow(output, currentPage, currentClass);
         output.beginRow();
         if ("class".equals(currentPage)) {
            output.beginCell(CssClass.NAVBAR_TOP_NAVI);
            ClassDoc prevClass = (ClassDoc)prev;
            ClassDoc nextClass = (ClassDoc)next;
            if (null != prevClass) {
               output.anchor(getClassDocURL(output, prevClass), "Prev Class");
            }
            else {
               output.print("Prev Class");
            }
            output.print(" | ");
            if (null != nextClass) {
               output.anchor(getClassDocURL(output, nextClass), "Next Class");
            }
            else {
               output.print("Next Class");
            }
            output.endCell();
         }
         else if ("split-index".equals(currentPage)) {
            output.beginCell(CssClass.NAVBAR_TOP_NAVI);
            Integer prevLetter = (Integer)prev;
            Integer nextLetter = (Integer)next;
            if (null != prevLetter) {
               output.anchor("alphaindex-" + prevLetter + filenameExtension, "Prev Letter");
            }
            else {
               output.print("Prev Letter");
            }
            output.print(" | ");
            if (null != nextLetter) {
               output.anchor("alphaindex-" + nextLetter + filenameExtension, "Next Letter");
            }
            else {
               output.print("Next Letter");
            }
            output.endCell();
         }
         else {
            output.beginCell(CssClass.NAVBAR_TOP_NAVI);
            output.endCell();
         }

         printNavBarTopNaviCell(output);
         output.endRow();

         if ("class".equals(currentPage)) {
            output.beginRow();

            output.beginCell(CssClass.NAVBAR_TOP_NAVI);
            output.print("Summary: ");
            
            if (currentClass.innerClasses().length > 0) {
               output.anchor("#summary-inner", "Nested");               
            }
            else {
               output.print("Nested");
            }

            output.print(" | ");
            
            if (currentClass.fields().length > 0) {
               output.anchor("#summary-fields", "Field");
            }
            else {
               output.print("Field");
            }

            output.print(" | ");
            
            if (currentClass.methods().length > 0) {
               output.anchor("#summary-methods", "Method");
            }
            else {
               output.print("Method");
            }

            output.print(" | ");
            
            if (currentClass.constructors().length > 0) {
               output.anchor("#summary-constructors", "Constr");
            }
            else {
               output.print("Constr");
            }

            output.endCell();

            output.beginCell(CssClass.NAVBAR_TOP_NAVI);
            output.print("Detail: ");
            
            if (currentClass.innerClasses().length > 0) {
               output.anchor("#detail-inner", "Nested");               
            }
            else {
               output.print("Nested");
            }

            output.print(" | ");
            
            if (currentClass.fields().length > 0) {
               output.anchor("#detail-fields", "Field");
            }
            else {
               output.print("Field");
            }

            output.print(" | ");
            
            if (currentClass.methods().length > 0) {
               output.anchor("#detail-methods", "Method");
            }
            else {
               output.print("Method");
            }

            output.print(" | ");
            
            if (currentClass.constructors().length > 0) {
               output.anchor("#detail-constructors", "Constr");
            }
            else {
               output.print("Constr");
            }

            output.endCell();
            output.endRow();
         }
         output.endTable();
      }
   }

   private void printNavBarTopPackage(HtmlPage output, String currentPage, 
                                      PackageDoc prevPackage, PackageDoc nextPackage)
   {
      if (!optionNoNavBar.getValue()) {
         output.beginTable(CssClass.NAVBAR_TOP);
         printNavBarTopRow(output, currentPage, null);

         output.beginRow();
         output.beginCell(CssClass.NAVBAR_TOP_NAVI);
         if (null != prevPackage) {
            output.anchor(output.getPathToRoot() + "/" + getPackageURL(prevPackage) + "package-summary" + filenameExtension, "Prev Package");
         }
         else {
            output.print("Prev Package");
         }
         output.print(" | ");
         if (null != nextPackage) {
            output.anchor(output.getPathToRoot() + "/" + getPackageURL(nextPackage) + "package-summary" + filenameExtension, "Next Package");
         }
         else {
            output.print("Next Package");
         }
         output.endCell();

         printNavBarTopNaviCell(output);
         output.endRow();

         output.endTable();
      }
   }

   private void printNavBarBottom(HtmlPage output, String currentPage)
   {
      printNavBarBottom(output, currentPage, null);
   }

   private void printNavBarBottom(HtmlPage output, String currentPage, ClassDoc currentClass)
   {
      if ("class".equals(currentPage)) {
         String boilerplate = null;
         Tag[] boilerplateTags = getOuterClassDoc(currentClass).tags("@boilerplate");
         if (boilerplateTags.length > 0) {
            boilerplate = boilerplateTags[0].text();
         }
         if (null != boilerplate) {
            output.hr();
            output.beginDiv(CssClass.CLASS_BOILERPLATE);
            output.print(boilerplate);
            output.endDiv(CssClass.CLASS_BOILERPLATE);
            output.hr();
         }
      }

      if (!optionNoNavBar.getValue()) {
         output.beginDiv(CssClass.NAVBAR_BOTTOM_SPACER);
         output.print(" ");
         output.endDiv(CssClass.NAVBAR_BOTTOM_SPACER);
         output.beginTable(CssClass.NAVBAR_BOTTOM);
         output.beginRow();
         output.beginCell();
         printNavBar(output, currentPage, currentClass);
         output.endCell();
         if (null != optionFooter.getValue()) {
            output.beginCell();
            output.print(replaceDocRoot(output, optionFooter.getValue()));
            output.endCell();
         }
         output.endRow();
         output.endTable();
      }

      if (null != optionBottom.getValue()) {
         output.hr();
         output.print(replaceDocRoot(output, optionBottom.getValue()));
      }
   }

   private void printPackagePageClasses(HtmlPage output, ClassDoc[] classDocs, String header)
   {
      if (classDocs.length > 0) {
         output.beginDiv(CssClass.TABLE_CONTAINER);
         output.beginTable(CssClass.PACKAGE_SUMMARY, new String[] { "border", "width" }, new String[] { "1", "100%" });
         output.rowDiv(CssClass.TABLE_HEADER, header);

         for (int i=0; i<classDocs.length; ++i) {
            ClassDoc classDoc = classDocs[i];
            if (classDoc.isIncluded()) {
               output.beginRow();
            
               output.beginCell(CssClass.PACKAGE_SUMMARY_LEFT);
               printType(output, classDoc);
               output.endCell();

               output.beginCell(CssClass.PACKAGE_SUMMARY_RIGHT);
               printTags(output, classDoc, classDoc.firstSentenceTags(), true);
               output.endCell();
               output.endRow();
            }
         }
         output.endTable();
         output.endDiv(CssClass.TABLE_CONTAINER);
         output.print("\n");
      }
   }

   private void printPackagesListFile()
      throws IOException
   {
      PrintWriter out
         = new PrintWriter(new OutputStreamWriter(new FileOutputStream(new File(getTargetDirectory(),
                                                                                "package-list")),
                                                  "UTF-8"));

      PackageDoc[] packages = getRootDoc().specifiedPackages();
      for (int i=0; i<packages.length; ++i) {
         String packageName = packages[i].name();
         if (packageName.length() > 0) {
            out.println(packageName);
         }
      }

      out.close();
   }

   private void printPackagePage(File packageDir, String pathToRoot, 
                                 PackageDoc packageDoc, 
                                 PackageDoc prevPackageDoc, 
                                 PackageDoc nextPackageDoc)
      throws IOException
   {
      HtmlPage output = newHtmlPage(new File(packageDir, "package-summary" + filenameExtension),
                                    pathToRoot);

      Set keywords = new LinkedHashSet();
      keywords.add(packageDoc.name() + " packages");

      output.beginPage(getPageTitle(packageDoc.name()), getOutputCharset(),
                       keywords, getStylesheets());
      output.beginBody(CssClass.BODY_CONTENT_PACKAGE);
      printNavBarTopPackage(output, "package", prevPackageDoc, nextPackageDoc);

      output.beginDiv(CssClass.PACKAGE_TITLE);
      output.print("Package ");
      if (packageDoc.name().length() > 0) {
         output.print(packageDoc.name());
      }
      else {
         output.print("&lt;Unnamed&gt;");
      }
      output.endDiv(CssClass.PACKAGE_TITLE);

      output.beginDiv(CssClass.PACKAGE_DESCRIPTION_TOP);
      printTags(output, packageDoc, packageDoc.firstSentenceTags(), true);
      output.endDiv(CssClass.PACKAGE_DESCRIPTION_TOP);
      
      printPackagePageClasses(output, packageDoc.interfaces(), 
                              "Interface Summary");
      printPackagePageClasses(output, packageDoc.ordinaryClasses(), 
                              "Class Summary");
      printPackagePageClasses(output, packageDoc.exceptions(), 
                              "Exception Summary");
      printPackagePageClasses(output, packageDoc.errors(), 
                              "Error Summary");

      output.anchorName("description");
      output.beginDiv(CssClass.PACKAGE_DESCRIPTION_FULL);
      printTags(output, packageDoc, packageDoc.inlineTags(), false);
      output.endDiv(CssClass.PACKAGE_DESCRIPTION_FULL);

      printNavBarBottom(output, "package");
      output.endBody();
      output.endPage();
      output.close();
   }

   static class TreeNode
      implements Comparable
   {
      ClassDoc classDoc;
      SortedSet children = new TreeSet();

      TreeNode(ClassDoc classDoc) {
         TreeNode.this.classDoc = classDoc;
      }
      
      public boolean equals(Object other)
      {
         return classDoc.equals(((TreeNode)other).classDoc);
      }

      public int compareTo(Object other)
      {
         return classDoc.compareTo(((TreeNode)other).classDoc);
      }

      public int hashCode()
      {
         return classDoc.hashCode();
      }
   }

   private TreeNode addClassTreeNode(Map treeMap, ClassDoc classDoc)
   {
      TreeNode node = (TreeNode)treeMap.get(classDoc.qualifiedName());
      if (null == node) {
         node = new TreeNode(classDoc);
         treeMap.put(classDoc.qualifiedName(), node);

         ClassDoc superClassDoc = (ClassDoc)classDoc.superclass();
         if (null != superClassDoc) {
            TreeNode parentNode = addClassTreeNode(treeMap, superClassDoc);
            parentNode.children.add(node);
         }
      }
      return node;
   }

   private TreeNode addInterfaceTreeNode(Map treeMap, ClassDoc classDoc)
   {
      TreeNode node = (TreeNode)treeMap.get(classDoc.qualifiedName());
      if (null == node) {
         node = new TreeNode(classDoc);
         treeMap.put(classDoc.qualifiedName(), node);

         ClassDoc[] superInterfaces = classDoc.interfaces();
         if (null != superInterfaces && superInterfaces.length > 0) {
            for (int i=0; i<superInterfaces.length; ++i) {
               TreeNode parentNode = addInterfaceTreeNode(treeMap, superInterfaces[i]);
               parentNode.children.add(node);
            }
         }
         else {
            TreeNode rootNode = (TreeNode)treeMap.get("<root>");
            if (null == rootNode) {
               rootNode = new TreeNode(null);
               treeMap.put("<root>", rootNode);
            }
            rootNode.children.add(node);
         }
      }
      return node;
   }

   private void printPackageTreeRec(HtmlPage output, TreeNode node, TreeNode parentNode)
   {
      output.beginElement("li", "class", "node");
      output.beginElement("div");
      if (node.classDoc.isIncluded()) {
         String packageName = node.classDoc.containingPackage().name();
         if (packageName.length() > 0) {
            output.print(packageName);
            output.print(".");
         }
         output.beginSpan(CssClass.TREE_LINK);
         printType(output, node.classDoc);
         output.endSpan(CssClass.TREE_LINK);
      }
      else {
         output.print(possiblyQualifiedName(node.classDoc));
      }
      ClassDoc[] interfaces = node.classDoc.interfaces();
      ClassDoc parentClassDoc = null;
      if (null != parentNode) {
         parentClassDoc = parentNode.classDoc;
      }
      if (interfaces.length > 0 
          && !(interfaces.length == 1 && interfaces[0].equals(parentClassDoc))) {
         if (node.classDoc.isInterface()) {
            output.print(" (also implements ");
         }
         else {
            output.print(" (implements ");
         }

         boolean firstItem = true;
         for (int i=0; i<interfaces.length; ++i) {
            ClassDoc implemented = interfaces[i];
            if (!implemented.equals(parentClassDoc)) {
               if (!firstItem) {
                  output.print(", ");
               }
               firstItem = false;
               if (implemented.isIncluded()) {
                  output.print(implemented.containingPackage().name());
                  output.print(".");
                  printType(output, implemented);
               }
               else {
                  output.print(possiblyQualifiedName(implemented));
               }
            }
         }
         output.print(")");
      }

      output.endElement("div");
      output.endElement("li");
      if (!node.children.isEmpty()) {
         output.beginElement("li", "class", "level");
         output.beginElement("ul");
         Iterator it = node.children.iterator();
         while (it.hasNext()) {
            TreeNode child = (TreeNode)it.next();
            printPackageTreeRec(output, child, node);
         }
         output.endElement("ul");
         output.endElement("li");
      }
   }

   private void printClassTree(HtmlPage output, ClassDoc[] classDocs)
   {      
      Map classTreeMap = new HashMap();

      for (int i=0; i<classDocs.length; ++i) {
         ClassDoc classDoc = classDocs[i];
         if (!classDoc.isInterface()) {
            addClassTreeNode(classTreeMap, classDoc);
         }
      }

      TreeNode root = (TreeNode)classTreeMap.get("java.lang.Object");
      if (null != root) {
         output.div(CssClass.PACKAGE_TREE_SECTION_TITLE, "Class Hierarchy");
         output.beginDiv(CssClass.PACKAGE_TREE);
         printPackageTreeRec(output, root, null);
         output.endDiv(CssClass.PACKAGE_TREE);
      }
   }

   private void printInterfaceTree(HtmlPage output, ClassDoc[] classDocs)
   {
      Map interfaceTreeMap = new HashMap();

      for (int i=0; i<classDocs.length; ++i) {
         ClassDoc classDoc = classDocs[i];
         if (classDoc.isInterface()) {
            addInterfaceTreeNode(interfaceTreeMap, classDoc);
         }
      }

      TreeNode interfaceRoot = (TreeNode)interfaceTreeMap.get("<root>");
      if (null != interfaceRoot) {
         Iterator it = interfaceRoot.children.iterator();
         if (it.hasNext()) {
            output.div(CssClass.PACKAGE_TREE_SECTION_TITLE, "Interface Hierarchy");
            output.beginDiv(CssClass.PACKAGE_TREE);
            while (it.hasNext()) {
               TreeNode node = (TreeNode)it.next();
               printPackageTreeRec(output, node, null);
            }
            output.endDiv(CssClass.PACKAGE_TREE);
         }
      }

   }

   private void printPackageTreePage(File packageDir, String pathToRoot, PackageDoc packageDoc)
      throws IOException
   {
      HtmlPage output = newHtmlPage(new File(packageDir,
                                             "tree" + filenameExtension),
                                    pathToRoot);
      output.beginPage(getPageTitle(packageDoc.name() + " Hierarchy"), 
                       getOutputCharset(),
                       getStylesheets());
      output.beginBody(CssClass.BODY_CONTENT_PACKAGE_TREE);
      printNavBarTop(output, "package-tree");

      output.div(CssClass.PACKAGE_TREE_TITLE, "Hierarchy for Package " + packageDoc.name());

      ClassDoc[] classDocs = packageDoc.allClasses();
      printClassTree(output, classDocs);
      printInterfaceTree(output, classDocs);

      printNavBarBottom(output, "package-tree");
      output.endBody();
      output.endPage();
      output.close();
   }

   private void printFullTreePage()
      throws IOException
   {
      HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
                                             "tree" + filenameExtension),
                                    ".");
      output.beginPage(getPageTitle("Hierarchy"), 
                       getOutputCharset(),
                       getStylesheets());
      output.beginBody(CssClass.BODY_CONTENT_FULL_TREE);
      printNavBarTop(output, "full-tree");

      output.div(CssClass.PACKAGE_TREE_TITLE, "Hierarchy for All Packages");

      output.beginDiv(CssClass.FULL_TREE_PACKAGELIST);
      output.div(CssClass.FULL_TREE_PACKAGELIST_HEADER, "Package Hierarchies:");
      output.beginDiv(CssClass.FULL_TREE_PACKAGELIST_ITEM);
      Set allPackages = getAllPackages();
      Iterator it = allPackages.iterator();
      while (it.hasNext()) {
         PackageDoc packageDoc = (PackageDoc)it.next();
         output.beginAnchor(getPackageURL(packageDoc) + "tree" + filenameExtension);
         output.print(packageDoc.name());
         output.endAnchor();
         if (it.hasNext()) {
            output.print(", ");
         }
      }
      output.endDiv(CssClass.FULL_TREE_PACKAGELIST_ITEM);
      output.endDiv(CssClass.FULL_TREE_PACKAGELIST);

      ClassDoc[] classDocs = getRootDoc().classes();
      printClassTree(output, classDocs);
      printInterfaceTree(output, classDocs);

      printNavBarBottom(output, "full-tree");
      output.endBody();
      output.endPage();
      output.close();
   }

   private void printIndexEntry(HtmlPage output, Doc entry)
   {
      output.beginDiv(CssClass.INDEX_ENTRY);
      output.beginDiv(CssClass.INDEX_ENTRY_KEY);
      String anchor = null;
      String description = null;
      if (entry instanceof PackageDoc) {
         output.beginAnchor(getPackageURL((PackageDoc)entry) + "package-summary" + filenameExtension);
         output.print(entry.name());
         output.endAnchor();
         output.print(" - package");
      }
      else if (entry instanceof ClassDoc) {
         ClassDoc classDoc = (ClassDoc)entry;
         output.beginAnchor(getClassURL(classDoc));
         output.print(entry.name() + getTypeParameters(classDoc));
         output.endAnchor();
         output.print(" - ");
         if (entry.isInterface()) {
            output.print("interface ");
         }
         else if (entry.isException()) {
            output.print("exception ");
         }
         else if (entry.isError()) {
            output.print("error ");
         }
         else {
            output.print("class ");
         }
         String packageName = classDoc.containingPackage().name();
         if (packageName.length() > 0) {
            output.print(packageName);
            output.print(".");
         }
         printType(output, classDoc);
      }
      else {
         ProgramElementDoc memberDoc = (ProgramElementDoc)entry;
         output.beginAnchor(getMemberDocURL(output, memberDoc));
         output.print(entry.name());
         if (memberDoc instanceof ExecutableMemberDoc) {
            output.print(((ExecutableMemberDoc)memberDoc).signature());
         }
         output.endAnchor();
         output.print(" - ");

         if (memberDoc.isStatic()) {
            output.print("static ");
         }

         if (entry.isConstructor()) {
            output.print("constructor for class ");
         }
         else if (entry.isMethod()) {
            output.print("method in class ");
         }
         else if (entry.isField()) {
            output.print("field in class ");
         }
         ClassDoc containingClass = memberDoc.containingClass();
         String packageName = containingClass.containingPackage().name();
         if (packageName.length() > 0) {
            output.print(packageName);
            output.print(".");
         }
         printType(output, containingClass);
      }
      output.endDiv(CssClass.INDEX_ENTRY_KEY);
      output.beginDiv(CssClass.INDEX_ENTRY_DESCRIPTION);
      printTags(output, entry, entry.firstSentenceTags(), true);
      output.endDiv(CssClass.INDEX_ENTRY_DESCRIPTION);
      output.endDiv(CssClass.INDEX_ENTRY);
   }

   private void printFrameSetPage()
      throws IOException
   {
      HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
                                             "index" + filenameExtension),
                                    ".",
                                    HtmlPage.DOCTYPE_FRAMESET);
      
      String title = getWindowTitle();
      output.beginPage(title, getOutputCharset(), getStylesheets());
      output.beginElement("frameset", "cols", "20%,80%");

      String contentURL;
      if (isSinglePackage()) {
         output.atomicElement("frame", 
                              new String[] { "src", "name" }, 
                              new String[] { getPackageURL(getSinglePackage()) + "classes" + filenameExtension, "classes" });
         contentURL = getPackageURL(getSinglePackage()) + "package-summary.html";
      }
      else {
         output.beginElement("frameset", "rows", "25%,75%");
         output.atomicElement("frame", 
                              new String[] { "src", "name" }, 
                              new String[] { "all-packages" + filenameExtension, "packages" });
         output.atomicElement("frame", 
                              new String[] { "src", "name" }, 
                              new String[] { "all-classes" + filenameExtension, "classes" });
         output.endElement("frameset");
         contentURL = "overview-summary" + filenameExtension;
      }
      output.atomicElement("frame", 
                           new String[] { "src", "name" }, 
                           new String[] { contentURL, "content" });
      output.endElement("frameset");
      output.endPage();
      output.close();
   }

   private void printPackagesMenuPage()
      throws IOException
   {
      HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
                                             "all-packages" + filenameExtension),
                                    ".");
      output.beginPage(getPageTitle("Package Menu"), getOutputCharset(), getStylesheets());
      output.beginBody(CssClass.BODY_MENU_PACKAGES, false);

      output.beginSpan(CssClass.PACKAGE_MENU_ENTRY);
      output.beginAnchor("all-classes" + filenameExtension,
                         null,
                         "classes");
      output.print("All Classes");
      output.endAnchor();
      output.endSpan(CssClass.PACKAGE_MENU_ENTRY);

      output.div(CssClass.PACKAGE_MENU_TITLE, "Packages");

      output.beginDiv(CssClass.PACKAGE_MENU_LIST);

      Set packageDocs = getAllPackages();
      Iterator it = packageDocs.iterator();
      while (it.hasNext()) {
         PackageDoc packageDoc = (PackageDoc)it.next();
         output.beginSpan(CssClass.PACKAGE_MENU_ENTRY);
         output.beginAnchor(getPackageURL(packageDoc) + "classes" + filenameExtension,
                            null,
                            "classes");
         if (packageDoc.name().length() > 0) {
            output.print(packageDoc.name());
         }
         else {
            output.print("&lt;unnamed package&gt;");
         }
         output.endAnchor();
         output.endSpan(CssClass.PACKAGE_MENU_ENTRY);
         output.br();
      }

      output.endDiv(CssClass.PACKAGE_MENU_LIST);
      output.endBody();
      output.endPage();
      output.close();
   }

   private void printClassMenuEntry(HtmlPage output, ClassDoc classDoc)
   {
      CssClass entryClass;
      if (classDoc.isInterface()) {
         entryClass = CssClass.CLASS_MENU_ENTRY_INTERFACE;        
      }
      else {
         entryClass = CssClass.CLASS_MENU_ENTRY_CLASS;
      }
      output.beginSpan(entryClass);
      output.beginAnchor(getClassDocURL(output, classDoc),
                         classDoc.qualifiedTypeName(),
                         "content");
      output.print(classDoc.name());
      output.endAnchor();
      output.endSpan(entryClass);
      output.br();
   }

   private void printClassMenuSection(HtmlPage output, Collection classDocs, String header)
   {
      if (!classDocs.isEmpty()) {
         output.div(CssClass.CLASS_MENU_SUBTITLE, header);
         Iterator it = classDocs.iterator();
         while (it.hasNext()) {
            ClassDoc classDoc = (ClassDoc)it.next();
            printClassMenuEntry(output, classDoc);
         }
      }
   }

   private void printClassMenuList(HtmlPage output, ClassDoc[] classDocs, boolean categorized)
   {
      output.beginDiv(CssClass.CLASS_MENU_LIST);

      if (categorized) {
         Set classes = new TreeSet();
         Set interfaces = new TreeSet();
         Set exceptions = new TreeSet();
         Set errors = new TreeSet();

         for (int i=0; i<classDocs.length; ++i) {
            ClassDoc classDoc = classDocs[i];
            if (classDoc.isInterface()) {
               interfaces.add(classDoc);
            }
            else if (classDoc.isException()) {
               exceptions.add(classDoc);
            }
            else if (classDoc.isError()) {
               errors.add(classDoc);
            }
            else {
               classes.add(classDoc);
            }
         }
         printClassMenuSection(output, interfaces, "Interfaces");
         printClassMenuSection(output, classes, "Classes");
         printClassMenuSection(output, exceptions, "Exceptions");
         printClassMenuSection(output, errors, "Errors");
      }
      else {
         for (int i=0; i<classDocs.length; ++i) {
            ClassDoc classDoc = classDocs[i];
            if (classDoc.isIncluded()) {
               printClassMenuEntry(output, classDoc);
            }
         }
      }

      output.endDiv(CssClass.CLASS_MENU_LIST);
   }

   private void printAllClassesMenuPage()
      throws IOException
   {
      HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
                                             "all-classes" + filenameExtension),
                                    ".");
      output.beginPage(getPageTitle("Class Menu"), getOutputCharset(), getStylesheets());
      output.beginBody(CssClass.BODY_MENU_CLASSES, false);

      output.div(CssClass.CLASS_MENU_TITLE, "All Classes");

      printClassMenuList(output, getRootDoc().classes(), false);

      output.endBody();
      output.endPage();
      output.close();
   }

   private void printPackageClassesMenuPage(File packageDir, String pathToRoot, PackageDoc packageDoc)
      throws IOException
   {
      HtmlPage output = newHtmlPage(new File(packageDir,
                                             "classes" + filenameExtension),
                                    pathToRoot);

      output.beginPage(getPageTitle(packageDoc.name() + " Class Menu"), 
                       getOutputCharset(), getStylesheets());
      output.beginBody(CssClass.BODY_MENU_CLASSES, false);

      output.beginDiv(CssClass.CLASS_MENU_TITLE);
      output.beginAnchor("package-summary" + filenameExtension, "", "content");
      if (packageDoc.name().length() > 0) {
         output.print(packageDoc.name());
      }
      else {
         output.print("&lt;Unnamed&gt;");
      }
      output.endAnchor();
      output.endDiv(CssClass.CLASS_MENU_TITLE);

      printClassMenuList(output, packageDoc.allClasses(), true);

      output.endBody();
      output.endPage();
      output.close();
   }

   private void printSplitIndex()
      throws IOException
   {
      Map categorizedIndex = getCategorizedIndex();
      Iterator it = categorizedIndex.keySet().iterator();
      int n = 1;
      int count = categorizedIndex.size();
      while (it.hasNext()) {
         Character c = (Character)it.next();
         List classList = (List)categorizedIndex.get(c);
         printIndexPage(n++, count, c, classList);
      }
   }

   private void printIndexPage()
      throws IOException
   {
      printIndexPage(0, 0, null, null);
   }

   private void printIndexPage(int index, int maxIndex, Character letter, List classList)
      throws IOException
   {
      String pageName = "alphaindex";
      if (null != letter) {
         pageName += "-" + index;
      }
      HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
                                             pageName + filenameExtension),
                                    ".");
      output.beginPage(getPageTitle("Alphabetical Index"), 
                       getOutputCharset(),
                       getStylesheets());
      output.beginBody(CssClass.BODY_CONTENT_INDEX);
      if (null == letter) {
         printNavBarTop(output, "index");
      }
      else {
         printNavBarTop(output, "split-index", null,
                        (index > 1) ? new Integer(index - 1) : null, 
                        (index < maxIndex) ? new Integer(index + 1) : null);
      }

      {
         String title;
         if (null == letter) {
            title = "Alphabetical Index";
         }
         else {
            title = "Alphabetical Index: " + letter;
         }
         output.div(CssClass.INDEX_TITLE, title);

         if (null != letter || getCategorizedIndex().keySet().size() > 1) {
            output.beginDiv(CssClass.INDEX_LETTERS);

            Iterator it = getCategorizedIndex().keySet().iterator();
            int n = 1;
            while (it.hasNext()) {
               Character c = (Character)it.next();
               output.beginSpan(CssClass.INDEX_LETTER);
               if (letter != null) {
                  output.beginAnchor("alphaindex-" + n + filenameExtension);
               }
               else {
                  output.beginAnchor("#" + c);
               }
               output.print(c.toString());
               output.endAnchor();
               output.endSpan(CssClass.INDEX_LETTER);     
               output.beginSpan(CssClass.INDEX_LETTER_SPACER);
               output.print(" ");
               output.endSpan(CssClass.INDEX_LETTER_SPACER);
               ++n;
            }
         }

         output.endDiv(CssClass.INDEX_LETTERS);
      }

      if (null != letter) {
         printIndexCategory(output, letter, classList);
      }
      else {
         Map categorizedIndex = getCategorizedIndex();
         Iterator categoryIt = categorizedIndex.keySet().iterator();

         while (categoryIt.hasNext()) {
            letter = (Character)categoryIt.next();
            classList = (List)categorizedIndex.get(letter);
            output.anchorName(letter.toString());
            printIndexCategory(output, letter, classList);
         }
      }

      printNavBarBottom(output, "index");
      output.endBody();
      output.endPage();
      output.close();
   }

   private void printIndexCategory(HtmlPage output, Character letter, List classList)
   {
      Iterator it = classList.iterator();

      output.div(CssClass.INDEX_CATEGORY_HEADER, letter.toString());
      output.beginDiv(CssClass.INDEX_CATEGORY);
      while (it.hasNext()) {
         Doc entry = (Doc)it.next();
         printIndexEntry(output, entry);
      }
      output.endDiv(CssClass.INDEX_CATEGORY);
   }

   private void printDeprecationSummary(HtmlPage output, List docs, String header)
   {
      if (!docs.isEmpty()) {
         output.beginDiv(CssClass.TABLE_CONTAINER);
         output.beginTable(CssClass.DEPRECATION_SUMMARY, new String[] { "border", "width" }, new String[] { "1", "100%" });
         output.rowDiv(CssClass.TABLE_HEADER, header);

         Iterator it = docs.iterator();
         while (it.hasNext()) {
            Doc doc = (Doc)it.next();
            output.beginRow();
            
            output.beginCell(CssClass.DEPRECATION_SUMMARY_LEFT);
            if (doc instanceof Type) {
               printType(output, (Type)doc);
            }
            else {
               ProgramElementDoc memberDoc = (ProgramElementDoc)doc;
               output.beginAnchor(getMemberDocURL(output, memberDoc));
               output.print(memberDoc.containingClass().qualifiedName());
               output.print(".");
               output.print(memberDoc.name());
               if (memberDoc instanceof ExecutableMemberDoc) {
                  output.print(((ExecutableMemberDoc)memberDoc).flatSignature());
               }
               output.endAnchor();
            }
            output.beginDiv(CssClass.DEPRECATION_SUMMARY_DESCRIPTION);
            printTags(output, doc, doc.tags("deprecated")[0].firstSentenceTags(), true);
            output.endDiv(CssClass.DEPRECATION_SUMMARY_DESCRIPTION);

            output.endCell();

            output.endRow();
         }
         output.endTable();
         output.endDiv(CssClass.TABLE_CONTAINER);
         output.print("\n");
      }
   }


   private void printSerializationPage()
      throws IOException
   {
      HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
                                             "serialized-form" + filenameExtension),
                                    ".");
      output.beginPage(getPageTitle("Serialized Form"), 
                       getOutputCharset(),
                       getStylesheets());
      output.beginBody(CssClass.BODY_CONTENT_DEPRECATED);
      printNavBarTop(output, "serialized");

      output.div(CssClass.SERIALIZED_TITLE, "Serialized Form");

      Iterator it = getAllPackages().iterator();

      while (it.hasNext()) {

         PackageDoc packageDoc = (PackageDoc)it.next();

         List serializableClasses = new LinkedList();
         ClassDoc[] classes = packageDoc.allClasses();
         for (int i=0; i<classes.length; ++i) {
            ClassDoc classDoc = classes[i];
            if (classDoc.isSerializable() || classDoc.isExternalizable()) {
               serializableClasses.add(classDoc);
            }
         }

         if (!serializableClasses.isEmpty()) {
            output.div(CssClass.SERIALIZED_PACKAGE_HEADER, "Package " + packageDoc.name());

            Iterator cit = serializableClasses.iterator();
            while (cit.hasNext()) {
               ClassDoc classDoc = (ClassDoc)cit.next();

               output.anchorName(classDoc.qualifiedTypeName());

               output.beginDiv(CssClass.SERIALIZED_CLASS_HEADER);
               output.print("Class ");
               printType(output, classDoc, true);
               output.print(" extends ");
               printType(output, classDoc.superclass());
               output.print(" implements Serializable");
               output.endDiv(CssClass.SERIALIZED_CLASS_HEADER);

               FieldDoc serialVersionUidField = findField(classDoc, "serialVersionUID");
               if (null != serialVersionUidField
                   && serialVersionUidField.isFinal()
                   && serialVersionUidField.isStatic()
                   && serialVersionUidField.type().typeName().equals("long")) {

                  String fieldValue = serialVersionUidField.constantValueExpression();
                  if (null != fieldValue) {
                     output.beginDiv(CssClass.SERIALIZED_SVUID_OUTER);
                     output.span(CssClass.SERIALIZED_SVUID_HEADER, "serialVersionUID: ");
                     output.span(CssClass.SERIALIZED_SVUID_VALUE, fieldValue);
                     output.endDiv(CssClass.SERIALIZED_SVUID_OUTER);
                  }
               }
               printMemberDetails(output, 
                                  classDoc.serializationMethods(), 
                                  "Serialization Methods",
                                  true, null);
               printMemberDetails(output, 
                                  classDoc.serializableFields(), 
                                  "Serialized Fields",
                                  true, null);
            }
         }
      }

      printNavBarBottom(output, "serialized");

      output.endBody();
      output.endPage();
      output.close();
   }


   private void printDeprecationPage()
      throws IOException
   {
      HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
                                             "deprecated" + filenameExtension),
                                    ".");
      output.beginPage(getPageTitle("Deprecated API"), 
                       getOutputCharset(),
                       getStylesheets());
      output.beginBody(CssClass.BODY_CONTENT_DEPRECATED);
      printNavBarTop(output, "deprecated");

      output.div(CssClass.DEPRECATION_TITLE, "Deprecated API");

      List deprecatedInterfaces = new LinkedList();
      List deprecatedExceptions = new LinkedList();
      List deprecatedErrors = new LinkedList();
      List deprecatedClasses = new LinkedList();
      List deprecatedFields = new LinkedList();
      List deprecatedMethods = new LinkedList();
      List deprecatedConstructors = new LinkedList();

      ClassDoc[] classDocs = getRootDoc().classes();
      for (int i=0; i<classDocs.length; ++i) {
         ClassDoc classDoc = classDocs[i];
         {
            Tag[] deprecatedTags = classDoc.tags("deprecated");
            if (null != deprecatedTags && deprecatedTags.length > 0) {
               if (classDoc.isInterface()) {
                  deprecatedInterfaces.add(classDoc);
               }
               else if (classDoc.isException()) {
                  deprecatedExceptions.add(classDoc);
               }
               else if (classDoc.isError()) {
                  deprecatedErrors.add(classDoc);
               }
               else {
                  deprecatedClasses.add(classDoc);
               }
            }
         }
         ConstructorDoc[] constructors = classDoc.constructors();
         for (int j=0; j<constructors.length; ++j) {
            Tag[] deprecatedTags = constructors[j].tags("deprecated");
            if (null != deprecatedTags && deprecatedTags.length > 0) {
               deprecatedConstructors.add(constructors[j]);
            }
         }
         MethodDoc[] methods = classDoc.methods();
         for (int j=0; j<methods.length; ++j) {
            Tag[] deprecatedTags = methods[j].tags("deprecated");
            if (null != deprecatedTags && deprecatedTags.length > 0) {
               deprecatedMethods.add(methods[j]);
            }
         }
         FieldDoc[] fields = classDoc.fields();
         for (int j=0; j<fields.length; ++j) {
            Tag[] deprecatedTags = fields[j].tags("deprecated");
            if (null != deprecatedTags && deprecatedTags.length > 0) {
               deprecatedFields.add(fields[j]);
            }
         }
      }

      if (!deprecatedInterfaces.isEmpty()
          || !deprecatedClasses.isEmpty()
          || !deprecatedExceptions.isEmpty()
          || !deprecatedErrors.isEmpty()
          || !deprecatedFields.isEmpty()
          || !deprecatedMethods.isEmpty()
          || !deprecatedConstructors.isEmpty()) {

         output.beginDiv(CssClass.DEPRECATION_TOC);
         output.div(CssClass.DEPRECATION_TOC_HEADER, "Contents");
         output.beginDiv(CssClass.DEPRECATION_TOC_LIST);
         if (!deprecatedInterfaces.isEmpty()) {
            output.beginDiv(CssClass.DEPRECATION_TOC_ENTRY);
            output.anchor("#interfaces", "Deprecated Interfaces");
            output.endDiv(CssClass.DEPRECATION_TOC_ENTRY);
         }
         if (!deprecatedClasses.isEmpty()) {
            output.beginDiv(CssClass.DEPRECATION_TOC_ENTRY);
            output.anchor("#classes", "Deprecated Classes");
            output.endDiv(CssClass.DEPRECATION_TOC_ENTRY);
         }
         if (!deprecatedExceptions.isEmpty()) {
            output.beginDiv(CssClass.DEPRECATION_TOC_ENTRY);
            output.anchor("#exceptions", "Deprecated Exceptions");
            output.endDiv(CssClass.DEPRECATION_TOC_ENTRY);
         }
         if (!deprecatedErrors.isEmpty()) {
            output.beginDiv(CssClass.DEPRECATION_TOC_ENTRY);
            output.anchor("#errors", "Deprecated Errors");
            output.endDiv(CssClass.DEPRECATION_TOC_ENTRY);
         }
         if (!deprecatedFields.isEmpty()) {
            output.beginDiv(CssClass.DEPRECATION_TOC_ENTRY);
            output.anchor("#fields", "Deprecated Fields");
            output.endDiv(CssClass.DEPRECATION_TOC_ENTRY);
         }
         if (!deprecatedMethods.isEmpty()) {
            output.beginDiv(CssClass.DEPRECATION_TOC_ENTRY);
            output.anchor("#methods", "Deprecated Methods");
            output.endDiv(CssClass.DEPRECATION_TOC_ENTRY);
         }
         if (!deprecatedConstructors.isEmpty()) {
            output.beginDiv(CssClass.DEPRECATION_TOC_ENTRY);
            output.anchor("#constructors", "Deprecated Constructors");
            output.endDiv(CssClass.DEPRECATION_TOC_ENTRY);
         }
         output.endDiv(CssClass.DEPRECATION_TOC_LIST);
         output.endDiv(CssClass.DEPRECATION_TOC);
         output.beginDiv(CssClass.DEPRECATION_LIST);

         output.anchorName("interfaces");
         printDeprecationSummary(output, deprecatedInterfaces, "Deprecated Interfaces");

         output.anchorName("classes");
         printDeprecationSummary(output, deprecatedClasses, "Deprecated Classes");

         output.anchorName("exceptions");
         printDeprecationSummary(output, deprecatedExceptions, "Deprecated Exceptions");

         output.anchorName("errors");
         printDeprecationSummary(output, deprecatedErrors, "Deprecated Errors");

         output.anchorName("fields");
         printDeprecationSummary(output, deprecatedFields, "Deprecated Fields");

         output.anchorName("methods");
         printDeprecationSummary(output, deprecatedMethods, "Deprecated Methods");

         output.anchorName("constructors");
         printDeprecationSummary(output, deprecatedConstructors, "Deprecated Constructors");

         output.endDiv(CssClass.DEPRECATION_LIST);
      }
      else {
         output.beginDiv(CssClass.DEPRECATION_EMPTY);
         output.print("No deprecated classes or class members in this API.");
         output.endDiv(CssClass.DEPRECATION_EMPTY);
         
      }

      printNavBarBottom(output, "deprecated");
      output.endBody();
      output.endPage();
      output.close();
   }

   private void printAboutPage()
      throws IOException
   {
      HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
                                             "about" + filenameExtension),
                                    ".");
      output.beginPage(getPageTitle("About"), 
                       getOutputCharset(),
                       getStylesheets());
      output.beginBody(CssClass.BODY_CONTENT_ABOUT);

      printNavBarTop(output, "about");

      output.div(CssClass.ABOUT_TITLE, "About");

      output.beginDiv(CssClass.ABOUT_GENERATOR);
      output.print("Generated by ");
      output.print("Gjdoc");
      output.print(" HtmlDoclet ");
      output.print(getDocletVersion());
      output.print(", part of ");
      output.beginAnchor("http://www.gnu.org/software/classpath/cp-tools/", "", "_top");
      output.print("GNU Classpath Tools");
      output.endAnchor();
      output.print(", on ");
      DateFormat format = DateFormat.getDateTimeInstance(DateFormat.LONG,
							 DateFormat.LONG,
							 Locale.US);
      Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"),
					  Locale.US);
      format.setCalendar(cal);
      output.print(format.format(new Date()));
      output.print(".");
      output.endDiv(CssClass.ABOUT_GENERATOR);

      printNavBarBottom(output, "about");

      output.endBody();
      output.endPage();
      output.close();
   }

   private void printSourcePage(File packageDir, ClassDoc classDoc, String sourceXhtml)
      throws IOException
   {
      HtmlPage output = newHtmlPage(new File(packageDir, 
                                             classDoc.name() + "-source" + filenameExtension),
                                    getPathToRoot(packageDir, getTargetDirectory()));
      output.beginPage(getPageTitle("Source for " + classDoc.qualifiedTypeName()), 
                       getOutputCharset(),
                       getStylesheets());

      output.beginBody(CssClass.BODY_CONTENT_SOURCE);

      printNavBarTop(output, "source", classDoc, null, null);

      output.div(CssClass.SOURCE_TITLE, "Source for " + classDoc.qualifiedTypeName());
      output.beginDiv(CssClass.SOURCE);
      output.print(sourceXhtml);
      output.endDiv(CssClass.SOURCE);

      printNavBarBottom(output, "source", classDoc);

      output.endBody();
      output.endPage();

      output.close();
   }

   private void printHelpPage()
      throws IOException
   {
      HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
                                             "help" + filenameExtension),
                                    ".");
      output.beginPage(getPageTitle("Help"), 
                       getOutputCharset(),
                       getStylesheets());
      output.beginBody(CssClass.BODY_CONTENT_HELP);

      printNavBarTop(output, "help");

      InputStream helpIn;
      if (null != optionHelpFile.getValue()){ 
         helpIn = new FileInputStream(optionHelpFile.getValue());
      }
      else {
         helpIn = getClass().getResourceAsStream("/htmldoclet/help.xhtml");
      }
      output.insert(new InputStreamReader(helpIn, "utf-8"));
      helpIn.close();

      printNavBarBottom(output, "help");

      output.endBody();
      output.endPage();
      output.close();
   }

   private void printOverviewPage()
      throws IOException
   {
      HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
                                             "overview-summary" + filenameExtension),
                                    ".");
      output.beginPage(getWindowTitle(), 
                       getOutputCharset(),
                       getStylesheets());
      output.beginBody(CssClass.BODY_CONTENT_OVERVIEW);

      printNavBarTop(output, "overview");

      String overviewHeader;
      if (null != optionDocTitle.getValue()) {
         overviewHeader = optionDocTitle.getValue();
      }
      else if (null != optionTitle.getValue()) {
         overviewHeader = optionTitle.getValue();
      }
      else {
         overviewHeader = null;
      }

      if (null != overviewHeader) {
         output.div(CssClass.OVERVIEW_TITLE, overviewHeader);
      }

      output.beginDiv(CssClass.OVERVIEW_DESCRIPTION_TOP);
      printTags(output, getRootDoc(), getRootDoc().firstSentenceTags(), true);
      output.endDiv(CssClass.OVERVIEW_DESCRIPTION_TOP);

      List packageGroups = getPackageGroups();

      if (packageGroups.isEmpty()) {
      
         printOverviewPackages(output, getAllPackages(),
                               "All Packages");
      }
      else {
         Set otherPackages = new LinkedHashSet();
         otherPackages.addAll(getAllPackages());

         Iterator it = packageGroups.iterator();
         while (it.hasNext()) {
            PackageGroup packageGroup = (PackageGroup)it.next();
            printOverviewPackages(output, 
                                  packageGroup.getPackages(),
                                  packageGroup.getName());
            otherPackages.removeAll(packageGroup.getPackages());
         }

         if (!otherPackages.isEmpty()) {
            printOverviewPackages(output, 
                                  otherPackages,
                                  "Other Packages");
         }
      }

      output.anchorName("description");
      output.beginDiv(CssClass.OVERVIEW_DESCRIPTION_FULL);
      printTags(output, getRootDoc(), getRootDoc().inlineTags(), false);
      output.endDiv(CssClass.OVERVIEW_DESCRIPTION_FULL);

      printNavBarBottom(output, "overview");
      output.endBody();
      output.endPage();
      output.close();
   }

   private void printOverviewPackages(HtmlPage output, Collection packageDocs, String header)
   {
      output.beginDiv(CssClass.TABLE_CONTAINER);
      output.beginTable(CssClass.OVERVIEW_SUMMARY, new String[] { "border", "width" }, new String[] { "1", "100%" });
      output.rowDiv(CssClass.TABLE_HEADER, header);

      Iterator it = packageDocs.iterator();
      while (it.hasNext()) {
         PackageDoc packageDoc = (PackageDoc)it.next();
         output.beginRow();
         
         output.beginCell(CssClass.OVERVIEW_SUMMARY_LEFT);
         output.beginAnchor(getPackageURL(packageDoc) + "package-summary" + filenameExtension);
         output.print(packageDoc.name());
         output.endAnchor();
         output.endCell();

         output.beginCell(CssClass.OVERVIEW_SUMMARY_RIGHT);
         printTags(output, packageDoc, packageDoc.firstSentenceTags(), true);
         output.endCell();
         output.endRow();
      }
      output.endTable();
      output.endDiv(CssClass.TABLE_CONTAINER);
   }

   private void printClassUsagePage(File packageDir, String pathToRoot, ClassDoc classDoc)
      throws IOException
   {
      HtmlPage output = newHtmlPage(new File(packageDir,
                                             classDoc.name() + "-uses" + filenameExtension),
                                    pathToRoot);
      output.beginPage(getPageTitle(classDoc.name()), getOutputCharset(), getStylesheets());
      output.beginBody(CssClass.BODY_CONTENT_USES);
      printNavBarTop(output, "uses", classDoc, null, null);

      output.div(CssClass.USAGE_TITLE, 
                 "Uses of " + getClassTypeName(classDoc) 
                 + " " + classDoc.qualifiedName());

      Map packageToUsageTypeMap = getUsageOfClass(classDoc);
      if (null != packageToUsageTypeMap && !packageToUsageTypeMap.isEmpty()) {

         Iterator packagesIterator = packageToUsageTypeMap.keySet().iterator();
         while (packagesIterator.hasNext()) {
            PackageDoc packageDoc = (PackageDoc)packagesIterator.next();

            output.div(CssClass.USAGE_PACKAGE_TITLE, "Uses in package " + packageDoc.name());

            Map usageTypeToUsersMap = (Map)packageToUsageTypeMap.get(packageDoc);
            Iterator usageTypeIterator = usageTypeToUsersMap.keySet().iterator();
            while (usageTypeIterator.hasNext()) {
               UsageType usageType = (UsageType)usageTypeIterator.next();
               
               output.beginTable(CssClass.USAGE_SUMMARY, new String[] { "border", "width" }, new String[] { "1", "100%" });
               output.rowDiv(CssClass.USAGE_TABLE_HEADER, format("usagetype." + usageType.getId(), 
                                                                 classDoc.qualifiedName()));

               Set users = (Set)usageTypeToUsersMap.get(usageType);
               Iterator userIterator = users.iterator();
               while (userIterator.hasNext()) {
                  Doc user = (Doc)userIterator.next();

                  output.beginRow();

                  if (user instanceof ClassDoc) {
                     output.beginCell(CssClass.USAGE_SUMMARY_LEFT);
                     output.print("class");
                     output.endCell();

                     output.beginCell(CssClass.USAGE_SUMMARY_RIGHT);
                     output.beginDiv(CssClass.USAGE_SUMMARY_SYNOPSIS);
                     printType(output, ((ClassDoc)user));
                     output.endDiv(CssClass.USAGE_SUMMARY_SYNOPSIS);
                     output.beginDiv(CssClass.USAGE_SUMMARY_DESCRIPTION);
                     printTags(output, ((ClassDoc)user), ((ClassDoc)user).firstSentenceTags(), true);
                     output.endDiv(CssClass.USAGE_SUMMARY_DESCRIPTION);
                     output.endCell();
                  }
                  else if (user instanceof FieldDoc) {
                     FieldDoc fieldDoc = (FieldDoc)user;

                     output.beginCell(CssClass.USAGE_SUMMARY_LEFT);
                     printType(output, ((FieldDoc)user).type());
                     output.endCell();

                     output.beginCell(CssClass.USAGE_SUMMARY_RIGHT);
                     output.beginDiv(CssClass.USAGE_SUMMARY_SYNOPSIS);
                     printType(output, ((FieldDoc)user).containingClass());
                     output.print(".");
                     output.beginAnchor(getMemberDocURL(output, (FieldDoc)user));
                     output.print(((FieldDoc)user).name());
                     output.endAnchor();
                     output.endDiv(CssClass.USAGE_SUMMARY_SYNOPSIS);
                     output.beginDiv(CssClass.USAGE_SUMMARY_DESCRIPTION);
                     printTags(output, ((FieldDoc)user), ((FieldDoc)user).firstSentenceTags(), true);
                     output.endDiv(CssClass.USAGE_SUMMARY_DESCRIPTION);
                     output.endCell();
                  }
                  else if (user instanceof MethodDoc) {
                     MethodDoc methodDoc = (MethodDoc)user;

                     output.beginCell(CssClass.USAGE_SUMMARY_LEFT);
                     printType(output, ((MethodDoc)user).returnType());
                     output.endCell();

                     output.beginCell(CssClass.USAGE_SUMMARY_RIGHT);
                     output.beginDiv(CssClass.USAGE_SUMMARY_SYNOPSIS);
                     printType(output, ((MethodDoc)user).containingClass());
                     output.print(".");
                     output.beginAnchor(getMemberDocURL(output, (MethodDoc)user));
                     output.print(((MethodDoc)user).name());
                     output.endAnchor();
                     printParameters(output, (ExecutableMemberDoc)user);
                     output.endDiv(CssClass.USAGE_SUMMARY_SYNOPSIS);
                     output.beginDiv(CssClass.USAGE_SUMMARY_DESCRIPTION);
                     printTags(output, ((MethodDoc)user), ((MethodDoc)user).firstSentenceTags(), true);
                     output.endDiv(CssClass.USAGE_SUMMARY_DESCRIPTION);
                     output.endCell();
                  }
                  else if (user instanceof ConstructorDoc) {
                     ConstructorDoc constructorDoc = (ConstructorDoc)user;

                     output.beginCell(CssClass.USAGE_SUMMARY_RIGHT);
                     output.beginDiv(CssClass.USAGE_SUMMARY_SYNOPSIS);
                     printType(output, ((ConstructorDoc)user).containingClass());
                     output.print(".");
                     output.beginAnchor(getMemberDocURL(output, (ConstructorDoc)user));
                     output.print(((ConstructorDoc)user).name());
                     output.endAnchor();
                     printParameters(output, (ExecutableMemberDoc)user);
                     output.endDiv(CssClass.USAGE_SUMMARY_SYNOPSIS);
                     output.beginDiv(CssClass.USAGE_SUMMARY_DESCRIPTION);
                     printTags(output, ((ConstructorDoc)user), 
                               ((ConstructorDoc)user).firstSentenceTags(), true);
                     output.endDiv(CssClass.USAGE_SUMMARY_DESCRIPTION);
                     output.endCell();
                  }

                  output.endRow();
               }
               output.endTable();
            }
         }
      }
      else {
         output.div(CssClass.USAGE_EMPTY,
                    getClassTypeName(classDoc) 
                    + " " + classDoc.qualifiedName() + " is not used by any class in this documentation set.");
      }
      printNavBarBottom(output, "uses", classDoc);
      output.endBody();
      output.endPage();
      output.close();
   }

   private void printSuperTreeRec(HtmlPage output, ListIterator it, int level)
   {
      if (it.hasPrevious()) {
         ClassDoc cd = (ClassDoc)it.previous();
         output.beginElement("li", new String[] { "class" }, new String[] { "inheritance " + level });
         output.beginElement("code");
         if (it.hasPrevious()) {
            printType(output, cd, true);
         }
         else {
            output.print(cd.qualifiedName() + getTypeParameters(cd));
         }
         output.endElement("code");
         output.endElement("li");

         output.beginElement("li");

         if (it.hasPrevious()) {
            output.beginElement("ul", new String[] { "class" }, new String[] { "inheritance " + (level + 1) });
            printSuperTreeRec(output, it, level + 1);
            output.endElement("ul");
         }

         output.endElement("li");
      }
   }

   private static boolean isSubInterface(ClassDoc classDoc, ClassDoc otherClassDoc) 
   {
      ClassDoc[] interfaces = otherClassDoc.interfaces();
      for (int i=0; i<interfaces.length; ++i) {
         if (classDoc == interfaces[i]) {
            return true;
         }
         else if (isSubInterface(classDoc, interfaces[i])) {
            return true;
         }
      }
      return false;
   }

   private void printCommaSeparatedTypes(HtmlPage output,
                                         Collection list, 
                                         String header, 
                                         CssClass cssClass)
   {
      if (!list.isEmpty()) {
         output.beginDiv(cssClass);
         output.div(CssClass.CLASS_KNOWNIMPLEMENTING_HEADER, header);
         output.beginDiv(CssClass.CLASS_KNOWNIMPLEMENTING_ITEM);
         Iterator it = list.iterator();
         while (it.hasNext()) {
            Type type = (Type)it.next();
            printType(output, type);
            if (it.hasNext()) {
               output.print(", ");
            }
         }
         output.endDiv(CssClass.CLASS_KNOWNIMPLEMENTING_ITEM);
         output.endDiv(cssClass);
      }
   }

   private void printClassPage(File packageDir, String pathToRoot, 
                               ClassDoc classDoc, ClassDoc prevClassDoc, ClassDoc nextClassDoc)
      throws IOException
   {
      HtmlPage output = newHtmlPage(new File(packageDir,
                                             classDoc.name() + filenameExtension),
                                    pathToRoot);
      Set keywords = new LinkedHashSet();
      {
         keywords.add(classDoc.qualifiedName() + " class");
         FieldDoc[] fieldDocs = classDoc.fields();
         for (int i=0; i<fieldDocs.length; ++i) {
            FieldDoc fieldDoc = fieldDocs[i];
            keywords.add(fieldDoc.name());
         }

         MethodDoc[] methodDocs = classDoc.methods();
         for (int i=0; i<methodDocs.length; ++i) {
            MethodDoc methodDoc = methodDocs[i];
            keywords.add(methodDoc.name() + "()");
         }
      }
      String parameters = getTypeParameters(classDoc);
      
      output.beginPage(getPageTitle(classDoc.name()), getOutputCharset(),
                       keywords, getStylesheets());
      output.beginBody(CssClass.BODY_CONTENT_CLASS);
      printNavBarTop(output, "class", classDoc, prevClassDoc, nextClassDoc);
      
      output.beginDiv(CssClass.CLASS_TITLE);
      output.div(CssClass.CLASS_TITLE_PACKAGE, 
                 classDoc.containingPackage().name());
      output.div(CssClass.CLASS_TITLE_CLASS, 
                 getClassTypeName(classDoc) 
                 + " " + classDoc.name()
		 + parameters);
      output.endDiv(CssClass.CLASS_TITLE);

      boolean needSep = false;

      if (classDoc.isInterface()) {

         InterfaceRelation relation
            = (InterfaceRelation)getInterfaceRelations().get(classDoc);

         printCommaSeparatedTypes(output,
                                  relation.superInterfaces, 
                                  "All Superinterfaces:",
                                  CssClass.CLASS_KNOWNIMPLEMENTING);

         printCommaSeparatedTypes(output,
                                  relation.subInterfaces, 
                                  "Known Subinterfaces:",
                                  CssClass.CLASS_KNOWNIMPLEMENTING);

         printCommaSeparatedTypes(output,
                                  relation.implementingClasses, 
                                  "Known Implementing Classes:",
                                  CssClass.CLASS_KNOWNIMPLEMENTING);

         needSep = !relation.superInterfaces.isEmpty()
            || !relation.subInterfaces.isEmpty()
            || !relation.implementingClasses.isEmpty();
      }
      else {   
         needSep = true;

         if (!"java.lang.Object".equals(classDoc.qualifiedName())) {
            LinkedList superClasses = new LinkedList();
            for (ClassDoc cd = classDoc; cd != null; cd = cd.superclass()) {
               superClasses.add(cd);
            }
            output.beginDiv(CssClass.CLASS_INHERITANCETREE);
            output.beginElement("ul", new String[] { "class" }, new String[] { "inheritance 0" });
            printSuperTreeRec(output, superClasses.listIterator(superClasses.size()), 0);
            output.endElement("ul");
            output.endDiv(CssClass.CLASS_INHERITANCETREE);
            
            if (null != classDoc.containingClass()) {
               output.beginDiv(CssClass.CLASS_ENCLOSINGCLASS);
               output.div(CssClass.CLASS_ENCLOSINGCLASS_HEADER, "Enclosing Class:");
               output.beginDiv(CssClass.CLASS_ENCLOSINGCLASS_ITEM);
               printType(output, classDoc.containingClass());
               output.endDiv(CssClass.CLASS_ENCLOSINGCLASS_ITEM);
               output.endDiv(CssClass.CLASS_ENCLOSINGCLASS);
            }

            Set implementedInterfaces = getImplementedInterfaces(classDoc);

            printCommaSeparatedTypes(output,
                                     implementedInterfaces, 
                                     "Implemented Interfaces:",
                                     CssClass.CLASS_KNOWNIMPLEMENTING);

            List knownDirectSubclasses = getKnownDirectSubclasses(classDoc);
            if (!knownDirectSubclasses.isEmpty()) {
               output.beginDiv(CssClass.CLASS_SUBCLASSES);
               output.div(CssClass.CLASS_SUBCLASSES_HEADER, "Known Direct Subclasses:");
               output.beginDiv(CssClass.CLASS_SUBCLASSES_ITEM);
               Iterator it = knownDirectSubclasses.iterator();
               while (it.hasNext()) {
                  printType(output, (ClassDoc)it.next());
                  if (it.hasNext()) {
                     output.print(", ");
                  }
               }

               output.endDiv(CssClass.CLASS_SUBCLASSES_ITEM);
               output.endDiv(CssClass.CLASS_SUBCLASSES_HEADER);
               output.endDiv(CssClass.CLASS_SUBCLASSES);
            }
         }
      }

      if (needSep) {
         output.hr();
      }

      output.beginDiv(CssClass.CLASS_SYNOPSIS);
      output.beginDiv(CssClass.CLASS_SYNOPSIS_DECLARATION);
      output.print(getFullModifiers(classDoc) + ' ' + getClassTypeKeyword(classDoc) 
                   + ' ');
      output.beginSpan(CssClass.CLASS_SYNOPSIS_NAME);
      if (optionLinkSource.getValue() && null != classDoc.position()) {
         output.beginAnchor(getOuterClassDoc(classDoc).name() + "-source" + filenameExtension + "#line." + classDoc.position());
         output.print(classDoc.name() + parameters);
         output.endAnchor();
      }
      else {
         output.print(classDoc.name() + parameters);
      }
      output.endSpan(CssClass.CLASS_SYNOPSIS_NAME);
      output.endDiv(CssClass.CLASS_SYNOPSIS_DECLARATION);

      if (!classDoc.isInterface()) {
         if (null != classDoc.superclass()) {
            output.beginDiv(CssClass.CLASS_SYNOPSIS_SUPERCLASS);
            output.print("extends ");
            printType(output, classDoc.superclass());
            output.endDiv(CssClass.CLASS_SYNOPSIS_SUPERCLASS);
         }
      }

      ClassDoc[] interfaces = classDoc.interfaces();
      if (interfaces.length > 0) {
         output.beginDiv(CssClass.CLASS_SYNOPSIS_IMPLEMENTS);
         if (!classDoc.isInterface()) {
            output.print("implements ");
         }
         else {
            output.print("extends ");
         }
         for (int i=0; i<interfaces.length; ++i) {
            if (i>0) {
               output.print(", ");
            }
            printType(output, interfaces[i]);
         }
         output.endDiv(CssClass.CLASS_SYNOPSIS_IMPLEMENTS);
      }
      output.endDiv(CssClass.CLASS_SYNOPSIS);

      output.hr();

      if (!optionNoComment.getValue()) {
         output.beginDiv(CssClass.CLASS_DESCRIPTION);
         printTags(output, classDoc, classDoc.inlineTags(), false);
         output.endDiv(CssClass.CLASS_DESCRIPTION);

         printTaglets(output, classDoc.tags(), new HtmlTagletContext(classDoc, output, false));
      }


      Set implementedInterfaces = getImplementedInterfaces(classDoc);

      boolean haveInheritedFields = false;
      boolean haveInheritedMethods = false;
      boolean haveInheritedClasses = false;
      {
         if (!classDoc.isInterface()) {
            ClassDoc superClassDoc = classDoc.superclass();
            while (null != superClassDoc
                   && (!haveInheritedFields 
                       || !haveInheritedMethods
                       || !haveInheritedClasses)) {
               if (superClassDoc.fields().length > 0) {
                  haveInheritedFields = true;
               }
               if (superClassDoc.methods().length > 0) {
                  haveInheritedMethods = true;
               }
               if (superClassDoc.innerClasses().length > 0) {
                  haveInheritedClasses = true;
               }
               superClassDoc = superClassDoc.superclass();
            }
         }
      }
      
      printProgramElementDocs(output, getSortedInnerClasses(classDoc), 
                              "Nested Class Summary", haveInheritedClasses,
                              "summary-inner");

      {
         ClassDoc superClassDoc = classDoc.superclass();
         while (null != superClassDoc) {
            printInheritedMembers(output, getSortedInnerClasses(superClassDoc),
                                  "Nested classes/interfaces inherited from class {0}",
                                  superClassDoc);
            superClassDoc = superClassDoc.superclass();
         }
      }

      printProgramElementDocs(output, getSortedFields(classDoc), 
                              "Field Summary", haveInheritedFields,
                              "summary-fields");

      {
         ClassDoc superClassDoc = classDoc.superclass();
         while (null != superClassDoc) {
            printInheritedMembers(output, getSortedFields(superClassDoc),
                                  "Fields inherited from class {0}",
                                  superClassDoc);
            superClassDoc = superClassDoc.superclass();
         }
      }

      {
         Iterator it = implementedInterfaces.iterator();
         while (it.hasNext()) {
            ClassDoc implementedInterface 
               = (ClassDoc)it.next();
            if (!"java.io.Serializable".equals(implementedInterface.qualifiedName())
                && !"java.io.Externalizable".equals(implementedInterface.qualifiedName())) {
               printInheritedMembers(output, getSortedFields(implementedInterface),
                                     "Fields inherited from interface {0}",
                                     implementedInterface);
            }
         } 
      }

      printProgramElementDocs(output, getSortedConstructors(classDoc), 
                              "Constructor Summary", false,
                              "summary-constructors");
      printProgramElementDocs(output, getSortedMethods(classDoc),
                              "Method Summary", haveInheritedMethods,
                              "summary-methods");

      if (classDoc.isInterface()) {
         InterfaceRelation relation 
            = (InterfaceRelation)getInterfaceRelations().get(classDoc);
         Iterator it = relation.superInterfaces.iterator();
         while (it.hasNext()) {
            ClassDoc superClassDoc = (ClassDoc)it.next();
            printInheritedMembers(output, getSortedMethods(superClassDoc),
                                  "Methods inherited from interface {0}",
                                  superClassDoc);
         }
      }
      else {
         ClassDoc superClassDoc = classDoc.superclass();
         while (null != superClassDoc) {
            printInheritedMembers(output, getSortedMethods(superClassDoc),
                                  "Methods inherited from class {0}",
                                  superClassDoc);
            superClassDoc = superClassDoc.superclass();
         }
      }

      printMemberDetails(output, getSortedFields(classDoc), 
                         "Field Details", false, "detail-fields");
      printMemberDetails(output, getSortedConstructors(classDoc), 
                         "Constructor Details", false, "detail-constructors");
      printMemberDetails(output, getSortedMethods(classDoc),
                         "Method Details", false, "detail-methods");

      printNavBarBottom(output, "class", classDoc);

      output.endBody();
      output.endPage();
      output.close();
   }

   private void printInheritedMembers(HtmlPage output,
                                      ProgramElementDoc[] memberDocs, 
                                      String headerFormat,
                                      ClassDoc superclass)
   {
      if (memberDocs.length > 0) {

         output.beginDiv(CssClass.TABLE_CONTAINER);
         output.beginTable(CssClass.CLASS_SUMMARY, new String[] { "border", "width" }, new String[] { "1", "100%" });
         String superclassLink;
         if (superclass.isIncluded()) {
            superclassLink = superclass.containingPackage().name()
               + "." + createTypeHref(output, superclass, false);
         }
         else {
            superclassLink = createTypeHref(output, superclass, true);
         }
         output.rowDiv(CssClass.TABLE_SUB_HEADER, 
                       new MessageFormat(headerFormat).format(new Object[] { 
                          superclassLink 
                       }));

         output.beginRow();
         output.beginCell(CssClass.CLASS_SUMMARY_INHERITED);
         for (int i=0; i<memberDocs.length; ++i) {
            ProgramElementDoc memberDoc = memberDocs[i];
            if (i > 0) {
               output.print(", ");
            }
            String title = null;
            if (memberDoc.isMethod()) {
               title = memberDoc.name() + ((MethodDoc)memberDoc).flatSignature();
            }
            else if (memberDoc.isInterface()) {
               title = "interface " + ((ClassDoc)memberDoc).qualifiedName();
            } 
            else if (memberDoc.isClass()) {
               title = "class " + ((ClassDoc)memberDoc).qualifiedName();
            }
            output.beginAnchor(getMemberDocURL(output, memberDoc), title);
            output.beginSpan(CssClass.CLASS_SUMMARY_INHERITED_MEMBER);
            output.print(memberDoc.name());
            output.endSpan(CssClass.CLASS_SUMMARY_INHERITED_MEMBER);
            output.endAnchor();
         }
         output.endCell();
         output.endRow();
         output.endTable();
         output.endDiv(CssClass.TABLE_CONTAINER);
      }
   }

   private void collectSpecifiedByRecursive(Set specifyingInterfaces, 
                                            ClassDoc classDoc,
                                            MethodDoc methodDoc)
   {
      ClassDoc[] interfaces = classDoc.interfaces();
      for (int i=0; i<interfaces.length; ++i) {
         MethodDoc[] methods = interfaces[i].methods();
         for (int j=0; j<methods.length; ++j) {
            if (methods[j].name().equals(methodDoc.name())
                && methods[j].signature().equals(methodDoc.signature())) {
               specifyingInterfaces.add(methods[j]);
               break;
            }
         }
         collectSpecifiedByRecursive(specifyingInterfaces,
                                     interfaces[i],
                                     methodDoc);
      }
   }

   private void printMemberDetails(HtmlPage output,
                                   ProgramElementDoc[] memberDocs, String header,
                                   boolean isOnSerializedPage,
                                   String anchor)
   {
      if (memberDocs.length > 0) {

         if (null != anchor) {
            output.anchorName(anchor);
         }

         CssClass sectionClass;
         CssClass headerClass;
         if (isOnSerializedPage) {
            sectionClass = CssClass.SERIALIZED_SECTION;
            headerClass = CssClass.SERIALIZED_SECTION_HEADER;
         }
         else {
            sectionClass = CssClass.SECTION;
            headerClass = CssClass.SECTION_HEADER;
         }
         output.div(headerClass, header);
         output.beginDiv(sectionClass);

         for (int i=0; i<memberDocs.length; ++i) {
            if (i>0) {
               output.hr();
            }

            ProgramElementDoc memberDoc = memberDocs[i];

            output.anchorName(getMemberAnchor(memberDoc));

            output.beginDiv(CssClass.MEMBER_DETAIL);
            output.div(CssClass.MEMBER_DETAIL_NAME, memberDoc.name());

            StringBuffer synopsis = new StringBuffer();
            int synopsisLength = 0;

            if (!isOnSerializedPage || !memberDoc.isField()) {
               String fullModifiers = getFullModifiers(memberDoc);
               synopsis.append(fullModifiers);
               synopsisLength += fullModifiers.length();

            }
            if (memberDoc.isMethod() || memberDoc.isField()) {
               Type type;
               if (memberDoc.isMethod()) {
                  type = ((MethodDoc)memberDoc).returnType();
               }
               else {
                  type = ((FieldDoc)memberDoc).type();
               }
               
               synopsis.append(" ");
               synopsisLength ++;
               synopsis.append(createTypeHref(output, type, false));
               if (null != type.asClassDoc() && type.asClassDoc().isIncluded()) {
                  synopsisLength += type.asClassDoc().name().length();
               }
               else {
                  synopsisLength += type.qualifiedTypeName().length();
               }
               synopsisLength += type.dimension().length();
            }

            synopsis.append(" ");
            synopsisLength ++;

            if (optionLinkSource.getValue() && null != memberDoc.position()) {
               ClassDoc containingClass = memberDoc.containingClass();
               while (null != containingClass.containingClass()) {
                  containingClass = containingClass.containingClass();
               }
               String href = containingClass.name() + "-source" + filenameExtension + "#line." + memberDoc.position().line();
               synopsis.append(output.createHrefString(href, memberDoc.name()));
            }
            else {
               synopsis.append(memberDoc.name());
            }
            synopsisLength += memberDoc.name().length();

            if (memberDoc.isConstructor() || memberDoc.isMethod()) {
               //printParameters(output, (ExecutableMemberDoc)memberDoc);
               synopsis.append("(");
               ++ synopsisLength;
               StringBuffer paddingLeft = new StringBuffer();
               for (int j=0; j<synopsisLength; ++j) {
                  paddingLeft.append(' ');
               }
               Parameter[] parameters = ((ExecutableMemberDoc)memberDoc).parameters();
               for (int j=0; j<parameters.length; ++j) {
                  Parameter parameter = parameters[j];
                  synopsis.append(createTypeHref(output, parameter.type(), false));
                  synopsis.append(" ");
                  synopsis.append(parameter.name());
                  if (j < parameters.length - 1) {
                     synopsis.append(",\n");
                     synopsis.append(paddingLeft);
                  }
               }
               synopsis.append(")");
               ClassDoc[] exceptions = ((ExecutableMemberDoc)memberDoc).thrownExceptions();
               if (exceptions.length > 0) {
                  synopsis.append("\n            throws ");
                  for (int j=0; j<exceptions.length; ++j) {
                     ClassDoc exception = exceptions[j];
                     synopsis.append(createTypeHref(output, exception, false));
                     if (j < exceptions.length - 1) {
                        synopsis.append(",\n                   ");
                     }
                  }
               }
            }

            output.beginDiv(CssClass.MEMBER_DETAIL_SYNOPSIS);
            output.print(synopsis.toString());
            output.endDiv(CssClass.MEMBER_DETAIL_SYNOPSIS);

            output.beginDiv(CssClass.MEMBER_DETAIL_BODY);

            Tag[] deprecatedTags = memberDoc.tags("deprecated");
            if (deprecatedTags.length > 0) {
               output.beginDiv(CssClass.DEPRECATED_INLINE);
               output.beginSpan(CssClass.DEPRECATED_HEADER);
               output.print("Deprecated. ");
               output.endSpan(CssClass.DEPRECATED_HEADER);
               output.beginSpan(CssClass.DEPRECATED_BODY);
            }
            for (int j=0; j<deprecatedTags.length; ++j) {
               printTags(output, memberDoc, deprecatedTags[j].inlineTags(), true);
            }
            if (deprecatedTags.length > 0) {
               output.endSpan(CssClass.DEPRECATED_BODY);
               output.beginDiv(CssClass.DEPRECATED_INLINE);
            }

            output.beginDiv(CssClass.MEMBER_DETAIL_DESCRIPTION);
            printTags(output, memberDoc, memberDoc.inlineTags(), false);
            output.endDiv(CssClass.MEMBER_DETAIL_DESCRIPTION);

            if (memberDoc.isConstructor() || memberDoc.isMethod()) {

               if (memberDoc.isMethod()) {
                  Set specifyingInterfaces = new LinkedHashSet();
                  if (memberDoc.containingClass().isInterface()) {
                     collectSpecifiedByRecursive(specifyingInterfaces,
                                                 memberDoc.containingClass(), 
                                                 (MethodDoc)memberDoc);
                  }
                  else {
                     for (ClassDoc cd = memberDoc.containingClass();
                          null != cd; cd = cd.superclass()) {
                        collectSpecifiedByRecursive(specifyingInterfaces,
                                                    cd, 
                                                    (MethodDoc)memberDoc);
                     }
                  }

                  if (!specifyingInterfaces.isEmpty()
                      && !isOnSerializedPage) {
                     output.beginDiv(CssClass.MEMBER_DETAIL_SPECIFIED_BY_LIST);
                     output.div(CssClass.MEMBER_DETAIL_SPECIFIED_BY_HEADER, "Specified by:");
                     Iterator it = specifyingInterfaces.iterator();
                     while (it.hasNext()) {
                        MethodDoc specifyingInterfaceMethod = (MethodDoc)it.next();
                        output.beginDiv(CssClass.MEMBER_DETAIL_SPECIFIED_BY_ITEM);
                        output.beginAnchor(getMemberDocURL(output, 
                                                           specifyingInterfaceMethod));
                        output.print(memberDoc.name());
                        output.endAnchor();
                        output.print(" in interface ");
                        printType(output, specifyingInterfaceMethod.containingClass());
                        output.endDiv(CssClass.MEMBER_DETAIL_SPECIFIED_BY_ITEM);
                     }
                     output.endDiv(CssClass.MEMBER_DETAIL_SPECIFIED_BY_LIST);
                  }
                  
                  ClassDoc overriddenClassDoc = null;
                  MemberDoc specifyingSuperMethod = null;

                  for (ClassDoc superclassDoc = memberDoc.containingClass().superclass();
                       null != superclassDoc && null == overriddenClassDoc;
                       superclassDoc = superclassDoc.superclass()) {
                     
                     MethodDoc[] methods = superclassDoc.methods();
                     for (int j=0; j<methods.length; ++j) {
                        if (methods[j].name().equals(memberDoc.name())
                            && methods[j].signature().equals(((MethodDoc)memberDoc).signature())) {
                           overriddenClassDoc = superclassDoc;
                           specifyingSuperMethod = methods[j];
                           break;
                        }
                     }
                  }

                  if (null != overriddenClassDoc) {
                     output.beginDiv(CssClass.MEMBER_DETAIL_OVERRIDDEN_LIST);
                     output.div(CssClass.MEMBER_DETAIL_OVERRIDDEN_HEADER, "Overrides:");
                     output.beginDiv(CssClass.MEMBER_DETAIL_OVERRIDDEN_ITEM);

                     output.beginAnchor(getMemberDocURL(output, 
                                                        specifyingSuperMethod));
                     output.print(memberDoc.name());
                     output.endAnchor();
                     output.print(" in interface ");
                     printType(output, overriddenClassDoc);

                     output.endDiv(CssClass.MEMBER_DETAIL_OVERRIDDEN_ITEM);
                     output.endDiv(CssClass.MEMBER_DETAIL_OVERRIDDEN_LIST);
                  }
               }

               if (!optionNoComment.getValue()) {

                  ExecutableMemberDoc execMemberDoc
                     = (ExecutableMemberDoc)memberDoc;

                  if (execMemberDoc.paramTags().length > 0) {
                     output.beginDiv(CssClass.MEMBER_DETAIL_PARAMETER_LIST);
                     output.div(CssClass.MEMBER_DETAIL_PARAMETER_HEADER, "Parameters:");
                     Parameter[] parameters = execMemberDoc.parameters();
                     for (int j=0; j<parameters.length; ++j) {
                        Parameter parameter = parameters[j];
                        ParamTag[] paramTags = execMemberDoc.paramTags();
                        ParamTag paramTag = null;
                        for (int k=0; k<paramTags.length; ++k) {
                           if (paramTags[k].parameterName().equals(parameter.name())) {
                              paramTag = paramTags[k];
                              break;
                           }
                        }
                     
                        if (null != paramTag) {
                           output.beginDiv(CssClass.MEMBER_DETAIL_PARAMETER_ITEM);
                           output.beginSpan(CssClass.MEMBER_DETAIL_PARAMETER_ITEM_NAME);
                           output.print(parameter.name());
                           output.endSpan(CssClass.MEMBER_DETAIL_PARAMETER_ITEM_NAME);
                           output.beginSpan(CssClass.MEMBER_DETAIL_PARAMETER_ITEM_SEPARATOR);
                           output.print(" - ");
                           output.endSpan(CssClass.MEMBER_DETAIL_PARAMETER_ITEM_SEPARATOR);
                           output.beginSpan(CssClass.MEMBER_DETAIL_PARAMETER_ITEM_DESCRIPTION);
                           printTags(output, execMemberDoc, paramTag.inlineTags(), false);
                           output.endSpan(CssClass.MEMBER_DETAIL_PARAMETER_ITEM_DESCRIPTION);
                           output.endDiv(CssClass.MEMBER_DETAIL_PARAMETER_ITEM);
                        }
                     }
                     output.endDiv(CssClass.MEMBER_DETAIL_PARAMETER_LIST);
                  }

                  if (execMemberDoc.isMethod() 
                      && !"void".equals(((MethodDoc)execMemberDoc).returnType().typeName())) {

                     Tag[] returnTags = execMemberDoc.tags("return");
                     if (returnTags.length > 0) {
                        Tag returnTag = returnTags[0];

                        output.beginDiv(CssClass.MEMBER_DETAIL_RETURN_LIST);
                        output.div(CssClass.MEMBER_DETAIL_RETURN_HEADER, "Returns:");
                        output.beginDiv(CssClass.MEMBER_DETAIL_RETURN_ITEM);

                        printTags(output, execMemberDoc, returnTag.inlineTags(), false);

                        output.endDiv(CssClass.MEMBER_DETAIL_RETURN_ITEM);
                        output.endDiv(CssClass.MEMBER_DETAIL_RETURN_LIST);
                     }
                  }

                  Set thrownExceptions = getThrownExceptions(execMemberDoc);
                  boolean haveThrowsInfo = false;
                  ThrowsTag[] throwsTags = execMemberDoc.throwsTags();
                  for (int k=0; k<throwsTags.length; ++k) {
                     ThrowsTag throwsTag = throwsTags[k];
                     if (null != throwsTags[k].exception()
                         && (isUncheckedException(throwsTags[k].exception())
                             || thrownExceptions.contains(throwsTag.exception()))) {
                        haveThrowsInfo = true;
                        break;
                     }
                  }

                  if (haveThrowsInfo) {
                     output.beginDiv(CssClass.MEMBER_DETAIL_THROWN_LIST);
                     output.div(CssClass.MEMBER_DETAIL_THROWN_HEADER, "Throws:");

                     for (int k=0; k<throwsTags.length; ++k) {
                        ThrowsTag throwsTag = throwsTags[k];
                        if (null != throwsTag.exception()
                            && (isUncheckedException(throwsTag.exception())
                                || thrownExceptions.contains(throwsTag.exception()))) {
                           output.beginDiv(CssClass.MEMBER_DETAIL_THROWN_ITEM);
                           output.beginSpan(CssClass.MEMBER_DETAIL_THROWN_ITEM_NAME);
                           printType(output, throwsTags[k].exception());
                           output.endSpan(CssClass.MEMBER_DETAIL_THROWN_ITEM_NAME);
                           if (null != throwsTag) {
                              output.beginSpan(CssClass.MEMBER_DETAIL_THROWN_ITEM_SEPARATOR);
                              output.print(" - ");
                              output.endSpan(CssClass.MEMBER_DETAIL_THROWN_ITEM_SEPARATOR);
                              output.beginSpan(CssClass.MEMBER_DETAIL_THROWN_ITEM_DESCRIPTION);
                              printTags(output, execMemberDoc, throwsTag.inlineTags(), false);
                              output.endSpan(CssClass.MEMBER_DETAIL_THROWN_ITEM_DESCRIPTION);
                           }
                           output.endDiv(CssClass.MEMBER_DETAIL_THROWN_ITEM);
                        }
                     }
                     output.endDiv(CssClass.MEMBER_DETAIL_THROWN_LIST);
                  }
               }
            }

            if (!optionNoComment.getValue()) {

               if (memberDoc.isField()) {
                  FieldDoc fieldDoc = ((FieldDoc)memberDoc);
                  if (null != fieldDoc.constantValue()) {
                     output.beginDiv(CssClass.MEMBER_DETAIL_THROWN_LIST);
                     output.div(CssClass.MEMBER_DETAIL_THROWN_HEADER, "Field Value:");
                     output.div(CssClass.MEMBER_DETAIL_THROWN_ITEM, 
                                fieldDoc.constantValueExpression().toString());
                     output.endDiv(CssClass.MEMBER_DETAIL_THROWN_LIST);
                  }
               }

               TagletContext context = new HtmlTagletContext(memberDoc, output, isOnSerializedPage);
               printTaglets(output, memberDoc.tags(), context);
            }

            output.endDiv(CssClass.MEMBER_DETAIL_BODY);
            output.endDiv(CssClass.MEMBER_DETAIL);
         }
         output.endDiv(sectionClass);
      }
   }


   private void printParameters(HtmlPage output, ExecutableMemberDoc memberDoc)
   {
      Parameter[] parameters = memberDoc.parameters();
      output.print("(");
      for (int j=0; j<parameters.length; ++j) {
         if (j > 0) {
            output.print(", ");
         }
         printType(output, parameters[j].type());
         output.print("&nbsp;");
         output.print(parameters[j].name());
      }
      output.print(")");
   }

   private void printProgramElementDocs(HtmlPage output,
                                        ProgramElementDoc[] memberDocs, 
                                        String header,
                                        boolean forceOutputHeader,
                                        String anchor)
   {
      if (memberDocs.length > 0 || forceOutputHeader) {
         output.anchorName(anchor);
         output.beginDiv(CssClass.TABLE_CONTAINER);
         output.beginTable(CssClass.CLASS_SUMMARY, new String[] { "border", "width" }, new String[] { "1", "100%" });
         output.rowDiv(CssClass.TABLE_HEADER, header);

         for (int i=0; i<memberDocs.length; ++i) {
            ProgramElementDoc memberDoc = memberDocs[i];
            output.beginRow();

            if (!memberDoc.isConstructor()) {
               output.beginCell(CssClass.CLASS_SUMMARY_LEFT);
               output.beginDiv(CssClass.CLASS_SUMMARY_LEFT_SYNOPSIS);
               output.print(getSummaryModifiers(memberDoc) + " ");
               if (memberDoc.isMethod()) {
                  printType(output, ((MethodDoc)memberDoc).returnType());
               }
               else if (memberDoc.isField()) {
                  printType(output, ((FieldDoc)memberDoc).type());
               }
               else if (memberDoc.isInterface()) {
                  output.print(" interface");
               }
               else if (memberDoc.isClass()) {
                  output.print(" class");
               }
               output.endDiv(CssClass.CLASS_SUMMARY_LEFT_SYNOPSIS);
               output.endCell();
            }

            output.beginCell(CssClass.CLASS_SUMMARY_RIGHT);
            output.beginDiv(CssClass.CLASS_SUMMARY_RIGHT_LIST);
            output.beginDiv(CssClass.CLASS_SUMMARY_RIGHT_SYNOPSIS);
            if (memberDoc.isClass() || memberDoc.isInterface()) {
               output.beginAnchor(getClassDocURL(output, (ClassDoc)memberDoc));
            }
            else {
               output.beginAnchor("#" + getMemberAnchor(memberDoc));
            }
            output.print(memberDoc.name());
            output.endAnchor();
            if (memberDoc.isConstructor() || memberDoc.isMethod()) {
               printParameters(output, (ExecutableMemberDoc)memberDoc);
            }
            output.endDiv(CssClass.CLASS_SUMMARY_RIGHT_SYNOPSIS);
            Tag[] firstSentenceTags;
            Tag[] deprecatedTags = memberDoc.tags("deprecated");
            if (deprecatedTags.length > 0) {
               firstSentenceTags = deprecatedTags[0].firstSentenceTags();
            }
            else {
               firstSentenceTags = memberDoc.firstSentenceTags();
            }

            if (null != firstSentenceTags && firstSentenceTags.length > 0) {
               output.beginDiv(CssClass.CLASS_SUMMARY_RIGHT_DESCRIPTION);
               if (deprecatedTags.length > 0) {
                  output.beginDiv(CssClass.DEPRECATED);
                  output.beginSpan(CssClass.DEPRECATED_HEADER);
                  output.print("Deprecated. ");
                  output.endSpan(CssClass.DEPRECATED_HEADER);
                  output.beginSpan(CssClass.DEPRECATED_BODY);
               }
               printTags(output, memberDoc, firstSentenceTags, true);
               if (deprecatedTags.length > 0) {
                  output.endSpan(CssClass.DEPRECATED_BODY);
                  output.beginDiv(CssClass.DEPRECATED);
               }
               output.endDiv(CssClass.CLASS_SUMMARY_RIGHT_DESCRIPTION);
            }
            output.endDiv(CssClass.CLASS_SUMMARY_RIGHT_LIST);
            output.endCell();
            output.endRow();
         }
         output.endTable();
         output.endDiv(CssClass.TABLE_CONTAINER);
      }
   }

   private void printTag(final HtmlPage output, 
                         HtmlRepairer repairer,
                         Tag tag, boolean firstSentence,
                         boolean inline,
                         Doc contextDoc)
   {
      TagletContext context = new HtmlTagletContext(contextDoc, output, false);
      if (firstSentence) {
         output.print(renderInlineTags(tag.firstSentenceTags(), context));
      }
      else {
         output.print(renderInlineTags(tag.inlineTags(), context));
      }
   }

   private void printTags(HtmlPage output, Doc contextDoc, Tag[] tags, boolean firstSentence)
   {
      printTags(output, contextDoc, tags, firstSentence, false);
   }

   private void printTags(HtmlPage output, Doc contextDoc, Tag[] tags, boolean firstSentence, boolean inline)
   {
      if (!optionNoComment.getValue()) {
         output.print(renderInlineTags(tags, new HtmlTagletContext(contextDoc, output, false)));
      }

      /*
      if (!optionNoComment.getValue()) {
         output.print(renderInlineTags(tag.firstSentenceTags(), output));
         HtmlRepairer repairer = new HtmlRepairer(getRootDoc(), 
                                                  true, false,
                                                  null, null,
                                                  true);
         for (int i=0; i<tags.length; ++i) {
            printTag(output, repairer, tags[i], firstSentence, inline);
         }
         output.print(repairer.terminateText());
      }
      */
   }

   private String getClassDocURL(HtmlPage output, ClassDoc classDoc)
   {
      return output.getPathToRoot() 
         + "/"
         + getPackageURL(classDoc.containingPackage()) 
         + classDoc.name() + filenameExtension;
   }

   private String getMemberDocURL(HtmlPage output, ProgramElementDoc memberDoc)
   {
      ClassDoc classDoc = memberDoc.containingClass();
      PackageDoc packageDoc = classDoc.containingPackage();
      ExternalDocSet externalDocSet = null;
      if (classDoc.containingPackage().name().length() > 0) {
         externalDocSet = (ExternalDocSet)packageNameToDocSet.get(packageDoc.name());
      }
      StringBuffer result = new StringBuffer();
      result.append(getClassDocURL(output, classDoc));
      result.append('#');
      if (null == externalDocSet) {
         result.append(getMemberAnchor(memberDoc));
      }
      else {
         result.append(getMemberAnchor(memberDoc, externalDocSet.isJavadocCompatible()));
      }
      return result.toString();
   }

   private void printType(HtmlPage output, Type type)
   {
      printType(output, type, false);
   }

   private void printType(HtmlPage output, Type type, boolean fullyQualified)
   {
      output.print(createTypeHref(output, type, fullyQualified));
   }

   private String createTypeHref(HtmlPage output, Type type, boolean fullyQualified)
   {
      ClassDoc asClassDoc = type.asClassDoc();
      String url = null;
      if (null != asClassDoc && asClassDoc.isIncluded()) {
         url = getClassDocURL(output, asClassDoc);
      }
      else if (!type.isPrimitive()) {
         if (type.qualifiedTypeName().length() > type.typeName().length()) {
            String packageName = type.qualifiedTypeName();
            packageName = packageName.substring(0, packageName.length() - type.typeName().length() - 1);
            
            ExternalDocSet externalDocSet
               = (ExternalDocSet)packageNameToDocSet.get(packageName);
            if (null != externalDocSet) {
               url = externalDocSet.getClassDocURL(packageName, type.typeName());
            }
         }
      }

      StringBuffer result = new StringBuffer();
      
      if (null != url && null != asClassDoc) {
	String parameters = getTypeParameters(asClassDoc);
         if (fullyQualified) {
            result.append(output.createHrefString(url,possiblyQualifiedName(asClassDoc) + parameters));
         }
         else {
            StringBuffer title = new StringBuffer();
            title.append(getClassTypeName(asClassDoc));
            title.append(" in ");
            title.append(asClassDoc.containingPackage().name());
            result.append(output.createHrefString(url, asClassDoc.name() + parameters, title.toString()));
         }
      }
      else {
         result.append(possiblyQualifiedName(type));
      }
      result.append(type.dimension());
      return result.toString();
   }

   private void printTaglets(final HtmlPage output, Tag[] tags, TagletContext context) 
   {
      super.printMainTaglets(tags, context, new TagletPrinter() {
            public void printTagletString(String tagletString) {
               output.beginDiv(CssClass.TAGLET);
               output.print(tagletString);
               output.endDiv(CssClass.TAGLET);
            }
         });
   }

   private String getPackageURL(PackageDoc packageDoc)
   {
      if (packageDoc.name().length() > 0) {
         ExternalDocSet externalDocSet = (ExternalDocSet)packageNameToDocSet.get(packageDoc.name());
         String url;
         if (null != externalDocSet) {
            url = externalDocSet.getPackageDocURL(packageDoc.name());
         }
         else {
            url = packageDoc.name().replace('.', '/');
         }
         if (!url.endsWith("/")) {
            return url + '/';
         }
         else {
            return url;
         }
     }
      else {
         return "";
      }
   }

   private String getClassURL(ClassDoc classDoc)
   {
      ExternalDocSet externalDocSet = null;
      if (classDoc.containingPackage().name().length() > 0) {
         externalDocSet = (ExternalDocSet)packageNameToDocSet.get(classDoc.containingPackage().name());
      }
      if (null != externalDocSet) {
         return externalDocSet.getClassDocURL(classDoc.containingPackage().name(), 
                                              classDoc.name());
      }
      else {
         return getPackageURL(classDoc.containingPackage()) + classDoc.name() + filenameExtension;
      }
   }

   protected void run()
      throws DocletConfigurationException, IOException
   {
      if (optionSerialWarn.getValue()) {
         printWarning("Option -serialwarn is currently ignored.");
      }

      if (null != optionTitle.getValue()) {
         printWarning("Option -title is deprecated.");
      }

      if (!optionValidHtml.getValue()) {
         printWarning("Option -validhtml hasn't been specified. Generated HTML will not validate.");
      }


      {
         boolean warningEmitted = false;
         Iterator it = externalDocSets.iterator();
         while (it.hasNext()) {
            ExternalDocSet externalDocSet = (ExternalDocSet)it.next();
            printNotice("Fetching package list for external documentation set.");     
            try {
               externalDocSet.load(getTargetDirectory());
               if (!isJavadocCompatibleNames() && externalDocSet.isJavadocCompatible()
                   && !warningEmitted) {
                  printWarning("Linking to javadoc-compatible documentation. Generated HTML will not validate ");
                  warningEmitted = true;
               }
            }
            catch (FileNotFoundException e) {
               printWarning("Cannot fetch package list from " + externalDocSet.getPackageListDir());
            }
            Iterator pit = externalDocSet.getPackageNames().iterator();
            while (pit.hasNext()) {
               String packageName = (String)pit.next();
               packageNameToDocSet.put(packageName, externalDocSet);
            }
         }
      }
      printNotice("Building cross-reference information...");
      getInterfaceRelations();
      getAllSubClasses();

      printNotice("Writing overview files...");
      printFrameSetPage();
      if (!isSinglePackage()) {
         printPackagesMenuPage();
         printAllClassesMenuPage();
         printOverviewPage();
         if (!optionNoTree.getValue()) {
            printNotice("Writing full tree...");
            printFullTreePage();
         }
      }
      printPackagesListFile();
      printAboutPage();
      if (!optionNoIndex.getValue()) {
         printNotice("Writing index...");
         if (!optionSplitIndex.getValue()) {
            printIndexPage();
         }
         else {
            printSplitIndex();
         }
      }
      if (outputHelpPage && !optionNoHelp.getValue()) {
         printHelpPage();
      }

      // Copy resources

      File resourcesDir = new File(getTargetDirectory(),
                                   "resources");

      if ((resourcesDir.exists() && !resourcesDir.isDirectory())
          || (!resourcesDir.exists() && !resourcesDir.mkdirs())) {
         throw new IOException("Cannot create directory " + resourcesDir);
      }

      // Copy resources

      String[] resourceNames = {
         "gjdoc.js",
         "gjdochtml-clean-layout.css",
         "gjdochtml-clean-color1.css",
         "inherit.png",
         "xhtml11-target10.dtd",
      };

      for (int i=0; i<resourceNames.length; ++i) {
         String resourceName = resourceNames[i];
         File targetFile = new File(resourcesDir,
                                    resourceName);
         InputStream in = getClass().getResourceAsStream("/htmldoclet/" + resourceName);
         if (in == null) {
        	in = new FileInputStream("src/resources/htmldoclet/" + resourceName);
         }
         FileOutputStream out = new FileOutputStream(targetFile);
         IOToolkit.copyStream(in, out);
         in.close();
         out.close();
      }

      // Copy stylesheets

      if (null != optionAddStylesheet.getValue()) { 
         File addStylesheetTargetFile = new File(resourcesDir,
                                                 "user.css");

         IOToolkit.copyFile(optionAddStylesheet.getValue(),
                            addStylesheetTargetFile);
      }

      if (null != optionStylesheetFile.getValue()) { 
         File stylesheetTargetFile = new File(resourcesDir,
                                              "user.css");

         IOToolkit.copyFile(optionStylesheetFile.getValue(),
                            stylesheetTargetFile);
      }

      // Write gjdoc.properties

      File gjdocPropertiesTargetFile = new File(getTargetDirectory(),
                                                "gjdoc.properties");
      writeGjdocProperties(gjdocPropertiesTargetFile);

      /*
      else {
         InputStream cssIn = getClass().getResourceAsStream("/htmldoclet/gjdochtml-vanilla.css");
         FileOutputStream cssOut = new FileOutputStream(stylesheetTargetFile);
         IOToolkit.copyStream(cssIn, cssOut);
         cssIn.close();
         cssOut.close();
      }
      */

      if (!optionNoDeprecatedList.getValue()) {
         printDeprecationPage();
      }

      printSerializationPage();

      Collection packageDocsCollection = getAllPackages();
      PackageDoc[] packageDocs
         = (PackageDoc[])packageDocsCollection.toArray(new PackageDoc[0]);

      for (int i=0; i<packageDocs.length; ++i) {
         PackageDoc packageDoc = packageDocs[i];
         File packageDir = new File(getTargetDirectory(),
                                    packageDoc.name().replace('.', File.separatorChar));
         if (!packageDir.exists() && !packageDir.mkdirs()) {
            throw new IOException("Couldn't create directory " + packageDir);
         }
         try {
            List packageSourceDirs = getPackageSourceDirs(packageDoc);
            Iterator pdIt = packageSourceDirs.iterator();
            while (pdIt.hasNext()) {
               File sourcePackageDir = (File)pdIt.next();
               copyDocFiles(sourcePackageDir, packageDir);
            }
         }
         catch (IOException ignore) {
         }
         String pathToRoot = getPathToRoot(packageDir, getTargetDirectory());
         String packageName = packageDoc.name();
         if (0 == packageName.length()) {
            packageName = "<unnamed>";
         }
         printNotice("Writing HTML files for package " + packageName);
         printPackagePage(packageDir, pathToRoot, packageDoc,
                          (i > 0) ? packageDocs[i - 1] : null,
                          (i < packageDocs.length - 1) ? packageDocs[i + 1] : null);
         if (!optionNoTree.getValue()) {
            printPackageTreePage(packageDir, pathToRoot, packageDoc);
         }
         printPackageClassesMenuPage(packageDir, pathToRoot, packageDoc);
         ClassDoc[] classDocs = packageDoc.allClasses();
         for (int j=0; j<classDocs.length; ++j) {
            ClassDoc classDoc = classDocs[j];
            if (classDoc.isIncluded()) {
               printClassPage(packageDir, pathToRoot, 
                              classDocs[j],
                              (j > 0) ? classDocs[j - 1] : null,
                              (j < classDocs.length - 1) ? classDocs[j + 1] : null
                              );
               if (optionUse.getValue()) {
                  printClassUsagePage(packageDir, pathToRoot, classDocs[j]);
               }
               if (optionLinkSource.getValue() && null == classDoc.containingClass()) {
                  try {
                     File sourceFile = getSourceFile(classDoc);

                     Java2xhtml java2xhtml = new Java2xhtml();
                     Properties properties = new Properties();
                     properties.setProperty("isCodeSnippet", "true");
                     properties.setProperty("hasLineNumbers", "true");
                     java2xhtml.setProperties(properties);
                     
                     StringWriter sourceBuffer = new StringWriter();
                     FileReader sourceReader = new FileReader(sourceFile);
                     IOToolkit.copyStream(sourceReader, sourceBuffer);
                     sourceReader.close();
                     String result = java2xhtml.makeHTML(sourceBuffer.getBuffer(), sourceFile.getName());
                     
                     printSourcePage(packageDir,
                                     classDoc,
                                     result);
                  }
                  catch (IOException e) {
                     printWarning("Cannot locate source file for class " + classDoc.qualifiedTypeName());
                  }
               }
            }
         }
      }
   }

   private String getPathToRoot(File subDir, File rootDir)
   {
      StringBuffer result = new StringBuffer();
      while (!subDir.equals(rootDir)) {
         if (result.length() > 0) {
            result.append("/");
         }
         subDir = subDir.getParentFile();
         result.append("..");
      }
      if (0 == result.length()) {
         result.append(".");
      }
      return result.toString();
   }

   private String getClassTypeName(ClassDoc classDoc) 
   {
      if (classDoc.isInterface()) {
         return "Interface";
      }
      else {
         return "Class";
      }
   }

   private String getClassTypeKeyword(ClassDoc classDoc) 
   {
      if (classDoc.isInterface()) {
         return "interface";
      }
      else {
         return "class";
      }
   }

   private String getMemberAnchor(ProgramElementDoc memberDoc)
   {
      return getMemberAnchor(memberDoc, isJavadocCompatibleNames());
   }

   private String getMemberAnchor(ProgramElementDoc memberDoc, boolean javadocCompatibility)
   {
      StringBuffer anchor = new StringBuffer();
      anchor.append(memberDoc.name());
      if (memberDoc.isConstructor() || memberDoc.isMethod()) {
         if (javadocCompatibility) {
            anchor.append(((ExecutableMemberDoc)memberDoc).signature());
         }
         else {
            anchor.append(':');
            Parameter[] parameters = ((ExecutableMemberDoc)memberDoc).parameters();
            for (int i=0; i<parameters.length; ++i) {
               anchor.append(parameters[i].type().typeName());
               for (int j=0; j<parameters[i].type().dimension().length()/2; ++j) {
                  anchor.append('-');
               }
               if (i < parameters.length - 1) {
                  anchor.append(':');
               }
            }
         }
      }
      return anchor.toString();
   }

   private String getFullModifiers(ProgramElementDoc memberDoc)
   {
      StringBuffer result = new StringBuffer();
      if (memberDoc.isPackagePrivate()) {
         result.append("(package private) ");
      }
      result.append(memberDoc.modifiers());
      if ((memberDoc.isClass() && ((ClassDoc)memberDoc).isAbstract())
          || (memberDoc.isMethod() && ((MethodDoc)memberDoc).isAbstract())) {
         result.append(" abstract");
      }
      return result.toString();
   }

   private String getSummaryModifiers(ProgramElementDoc memberDoc)
   {
      StringBuffer result = new StringBuffer();
      if (memberDoc.isPackagePrivate()) {
         result.append("(package private) ");
      }
      else if (memberDoc.isPrivate()) {
         result.append("private ");
      }
      else if (memberDoc.isProtected()) {
         result.append("protected ");
      }
      if (memberDoc.isStatic()) {
         result.append("static");
      }
      else if ((memberDoc.isClass() && ((ClassDoc)memberDoc).isAbstract())
          || (memberDoc.isMethod() && ((MethodDoc)memberDoc).isAbstract())) {
         result.append("abstract");
      }
      return result.toString();
   }

   protected DocletOption[] getOptions()
   {
      return options;
   }

   private DocletOptionFlag optionNoNavBar = 
     new DocletOptionFlag("-nonavbar");

   private DocletOptionFlag optionNoTree = 
     new DocletOptionFlag("-notree");

   private DocletOptionFlag optionNoDeprecatedList = 
     new DocletOptionFlag("-nodeprecatedlist");

   private DocletOptionFlag optionNoIndex = 
     new DocletOptionFlag("-noindex");

   private DocletOptionFlag optionUse = 
     new DocletOptionFlag("-use");

   private DocletOptionFlag optionNoHelp = 
     new DocletOptionFlag("-nohelp");

   private DocletOptionFlag optionNoComment = 
     new DocletOptionFlag("-nocomment");

   private DocletOptionFlag optionSerialWarn = 
     new DocletOptionFlag("-serialwarn");

   private DocletOptionFlag optionSplitIndex = 
     new DocletOptionFlag("-splitindex");

   private DocletOptionString optionHeader = 
     new DocletOptionString("-header");

   private DocletOptionString optionFooter = 
     new DocletOptionString("-footer");

   private DocletOptionString optionBottom = 
     new DocletOptionString("-bottom");

   private DocletOptionString optionWindowTitle = 
     new DocletOptionString("-windowtitle");

   private DocletOptionString optionDocTitle = 
     new DocletOptionString("-doctitle");

   private DocletOptionString optionTitle = 
     new DocletOptionString("-title");

   private DocletOptionFile optionHelpFile = 
     new DocletOptionFile("-helpfile");

   private DocletOptionFile optionStylesheetFile = 
     new DocletOptionFile("-stylesheetfile");

   private DocletOptionFlag optionLinkSource = 
     new DocletOptionFlag("-linksource");

   private DocletOption optionLink = 
     new DocletOption("-link") {
        
        public int getLength()
        {
           return 2;
        }

        public boolean set(String[] optionArr)
        {
           externalDocSets.add(new ExternalDocSet(optionArr[1], null));
           return true;
        }
     };

   private DocletOption optionLinkOffline = 
     new DocletOption("-linkoffline") {
        
        public int getLength()
        {
           return 3;
        }

        public boolean set(String[] optionArr)
        {
           externalDocSets.add(new ExternalDocSet(optionArr[1], optionArr[2]));
           return true;
        }
     };

   private DocletOptionString optionDocEncoding =
     new DocletOptionString("-docencoding");

   private DocletOptionString optionEncoding =
     new DocletOptionString("-encoding");

   private DocletOptionString optionCharset =
     new DocletOptionString("-charset");

   private DocletOptionFile optionAddStylesheet = 
     new DocletOptionFile("-addstylesheet");

   private DocletOptionFlag optionValidHtml = 
     new DocletOptionFlag("-validhtml");

   private DocletOptionString optionBaseUrl = 
     new DocletOptionString("-baseurl");

   private DocletOption[] options = 
      {
         optionNoNavBar,
         optionNoTree,
         optionNoDeprecatedList,
         optionNoIndex,
         optionNoHelp,
         optionNoComment,
         optionUse,
         optionSplitIndex,
         optionHeader,
         optionFooter,
         optionBottom,
         optionHelpFile,
         optionStylesheetFile,
         optionWindowTitle,
         optionDocTitle,
         optionTitle,
         optionLinkSource,
         optionLink,
         optionLinkOffline,
         optionDocEncoding,
         optionEncoding,
         optionCharset,
         optionAddStylesheet,
         optionValidHtml,
         optionBaseUrl,
      };

   static {
      setInstance(new HtmlDoclet());
   }

   private static String replaceDocRoot(HtmlPage output, String str)
   {
      return StringToolkit.replace(str, "{@docRoot}", output.getPathToRoot());
   }

   private String getOutputDocEncoding()
   {
      String encoding = optionDocEncoding.getValue();

      if (null == encoding) {
         encoding = optionEncoding.getValue();
      }

      return encoding;
   }

   private String getOutputCharset()
   {
      if (null == outputCharset) {

         if (null != optionCharset.getValue()) {
            outputCharset = optionCharset.getValue();
         }
         else {
            String fileEncoding = System.getProperty("file.encoding");
            if (null != fileEncoding) {
               try {
                  outputCharset = Charset.forName(fileEncoding).name();
               }
               catch (Exception ignore) {
               }
            }

            if (null == outputCharset) {
               printWarning("Cannot determine platform default charset, falling back to ISO-8859-1.");
               outputCharset = "ISO-8859-1";
            }
         }
      }
      return outputCharset;
   }

   public InlineTagRenderer getInlineTagRenderer()
   {
      return this;
   }

   public String renderInlineTags(Tag[] tags, TagletContext context)
   {
      StringBuffer result = new StringBuffer();

      HtmlRepairer repairer = new HtmlRepairer(getRootDoc(), 
                                               true, false,
                                               null, null,
                                               true);

      for (int i=0; i<tags.length; ++i) {

         Tag tag = tags[i];

         if ("Text".equals(tag.name())) {
            result.append(repairer.getWellformedHTML(tag.text()));
         }
         else if ("@link".equals(tag.name())) {
            result.append(renderSeeTag((SeeTag)tag, context, false));
         }
         else if ("@linkplain".equals(tag.name())) {
            result.append(renderSeeTag((SeeTag)tag, context, true));
         }
         else if ("@docRoot".equals(tag.name())) {         
            result.append(((HtmlTagletContext)context).getOutput().getPathToRoot());
         }
         else {
            //TagletContext context = TagletContext.OVERVIEW; // FIXME
            Taglet taglet = (Taglet)tagletMap.get(tag.name().substring(1));
            if (null != taglet) {
               if (taglet instanceof GnuExtendedTaglet) {
                  result.append(((GnuExtendedTaglet)taglet).toString(tag, context));
               }
               else {
                  result.append(taglet.toString(tag));
               }
            }
         }
      }
      result.append(repairer.terminateText());
      return result.toString();
   }

   public String renderSeeTag(SeeTag seeTag, TagletContext context, boolean plainFont)
   {
      StringBuffer result = new StringBuffer();

      String href = null;
      String label = null;
      MemberDoc referencedMember = seeTag.referencedMember();
      if (null != seeTag.referencedClass()) {

         href = getClassDocURL(((HtmlTagletContext)context).getOutput(), seeTag.referencedClass());

         Doc doc = context.getDoc();
         ClassDoc classDoc = null;
         if (doc.isClass() || doc.isInterface()) {
            classDoc = (ClassDoc)doc;
         }
         else if (doc.isField() || doc.isMethod() || doc.isConstructor()) {
            classDoc = ((MemberDoc)doc).containingClass();
         }

         if (null == referencedMember
             || seeTag.referencedClass() != classDoc
             || ((HtmlTagletContext)context).isOnSerializedPage()) {

            if (!seeTag.referencedClass().isIncluded()) {
               label = possiblyQualifiedName(seeTag.referencedClass());
            }
            else {
               label = seeTag.referencedClass().typeName();
            }
            if (null != referencedMember) {
               label += '.';
            }
         }
         else {
            label = "";
         }

         if (null != referencedMember) {
            label += referencedMember.name();
            if (referencedMember.isMethod() || referencedMember.isConstructor()) {
               label += ((ExecutableMemberDoc)referencedMember).flatSignature();
            }
            href  += '#' + getMemberAnchor(referencedMember);
         }
         else if (null != seeTag.referencedMemberName()) {
            href = null;
         }
      }
      else {
         String referencedClassName = seeTag.referencedClassName();

         if (null != referencedClassName) {

            String referencedPackageName = null;

            Iterator it = packageNameToDocSet.keySet().iterator();
            while (it.hasNext()) {
               String packageName = (String)it.next();
               if ((null == referencedPackageName
                    || packageName.length() > referencedPackageName.length())
                   && referencedClassName.startsWith(packageName + '.')) {
                  referencedPackageName = packageName;
               }
            }

            if (null != referencedPackageName) {
               ExternalDocSet externalDocSet
                  = (ExternalDocSet)packageNameToDocSet.get(referencedPackageName);

               String className = referencedClassName.substring(referencedPackageName.length() + 1);
               href = externalDocSet.getClassDocURL(referencedPackageName,
                                                    className);
               label = className;

               String referencedMemberName = seeTag.referencedMemberName();

               if (null != referencedMemberName) {
                  label += '.';
                  label += referencedMemberName;
                  href  += '#' + transformReferencedMemberName(referencedMemberName, 
                                                               externalDocSet.isJavadocCompatible());
               }
               else if (null != seeTag.referencedMemberName()) {
                  href = null;
               }
            }
         }
      }
      
      if (null != seeTag.label()
          && seeTag.label().length() > 0) {
         label = seeTag.label();
      }

      if (null == label) {
         label = seeTag.text();
         if (label.startsWith("#")) {
            label = label.substring(1);
         }
         else {
            label = label.replace('#', '.');
         }
         label.trim();
      }
         
      if (null != href) {
         result.append("<a href=\"");
         result.append(href);
         result.append("\">");
         if (!plainFont) {
            result.append("<code>");
         }
         result.append(label);
         if (!plainFont) {
            result.append("</code>");
         }
         result.append("</a>");
      }
      else {
         if (!plainFont) {
            result.append("<code>");
         }
         result.append(label);
         if (!plainFont) {
            result.append("</code>");
         }
      }

      return result.toString();
   }

   protected String renderTag(String tagName, Tag[] tags, TagletContext context)
   {
      Doc doc = context.getDoc();

      if ("see".equals(tagName)
          && ((tags.length > 0)
              || (doc.isClass()
                  && (((ClassDoc)doc).isSerializable()
                      || ((ClassDoc)doc).isExternalizable())))) {
         
         StringBuffer result = new StringBuffer();
         result.append("<dl class=\"tag list\">");
         result.append("<dt class=\"tag section header\"><b>");
         result.append("See Also:");
         result.append("</b></dt>");

         boolean oneLine = true;

         if (oneLine) {
            result.append("<dd>");
         }

         for (int i = 0; i < tags.length; ++i) {
            if (oneLine) {
               if (i > 0) {
                  result.append(", ");
               }
            }
            else {
               result.append("<dd>");
            }
            result.append(renderSeeTag((SeeTag)tags[i], context, false));
            if (!oneLine) {
               result.append("</dd>");
            }
         }

         if ((doc instanceof ClassDoc)
             && (((ClassDoc)doc).isSerializable() || ((ClassDoc)doc).isExternalizable())) {
            if (tags.length > 0) {
               result.append(", ");
            }
            HtmlPage output = ((HtmlTagletContext)context).getOutput();
            result.append("<a href=\"" + output.getPathToRoot() + "/serialized-form" + filenameExtension + "#" + ((ClassDoc)doc).qualifiedName() + "\">Serialized Form</a>");
         }

         if (oneLine) {
            result.append("</dd>");
         }
         result.append("</dl>");
         return result.toString();
      }
      else if (tags.length > 0 
               && "serial".equals(tagName)
               && ((HtmlTagletContext)context).isOnSerializedPage()) {

         return renderInlineTags(tags[0].inlineTags(), context);
      }
      else {
         return "";
      }
   }

   private String getWindowTitle()
   {
      if (null == optionWindowTitle.getValue()) {
         return "Generated API Documentation";
      }
      else {
         return optionWindowTitle.getValue();
      }
   }

   private String getPageTitle(String title)
   {
      if (null == optionWindowTitle.getValue()) {
         return title;
      }
      else {
         return title + " (" + optionWindowTitle.getValue() + ")";
      }
   }

   protected String getDocletVersion()
   {
      if (null == docletVersion) {
         try {
            Properties versionProperties = new Properties();
            InputStream in = getClass().getResourceAsStream("/version.properties");
            if (in == null) {
            	in = new FileInputStream("src/resources/version.properties");
            }
            versionProperties.load(in);
            docletVersion = versionProperties.getProperty("gjdoc.version");
         }
         catch (IOException ignore) {
         }
         if (null == docletVersion) {
            docletVersion = "unknown";
         }
      }
      return docletVersion;
   }

   private Map getStylesheets()
   {
      Map sheets = new HashMap();
      if (null != optionStylesheetFile.getValue()) {
         sheets.put("User-specified", new String[] { 
            "resources/user.css" 
         });
      }
      else {
         List cleanSheets = new LinkedList();
         cleanSheets.add("resources/gjdochtml-clean-layout.css");
         cleanSheets.add("resources/gjdochtml-clean-color1.css");
         if (null != optionAddStylesheet.getValue()) {
            cleanSheets.add("resources/user.css");
         }
         sheets.put("GNU Clean", cleanSheets.toArray(new String[0]));
      }
      return sheets;
   }

   protected boolean isSinglePackage()
   {
      if (getRootDoc().firstSentenceTags().length > 0) {
         return false;
      }
      else if (null != optionDocTitle.getValue() 
               || null != optionTitle.getValue()) {
         return false;
      }
      else {
         return super.isSinglePackage();
      }
   }

  private String getTypeParameters(ClassDoc classDoc)
  {
    String parameters = "";
    TypeVariable[] params = classDoc.typeParameters();
    if (params != null && params.length > 0)
      {
	parameters = "&lt;";
	for (int a = 0; a < params.length; ++a)
	  {
	    parameters += params[a].typeName();
	    Type[] bounds = params[a].bounds();
	    if (bounds != null)
	      {
		parameters += " extends ";
		for (int b = 0; a < bounds.length; ++b)
		  {
		    parameters += bounds[a];
		    if (b != bounds.length - 1)
		      parameters += " & ";
		  }
	      }
	    if (a != params.length - 1)
	      parameters += ",";
	  }
	parameters += "&gt;";
      }
    return parameters;
  }

   private String transformReferencedMemberName(String referencedMemberName,
                                                boolean javadocCompatibility)
   {
      if (!javadocCompatibility) {
         StringBuffer result = new StringBuffer();
         for (int i=0; i<referencedMemberName.length(); ++i) {
            char c = referencedMemberName.charAt(i);
            switch (c) {
            case '(': result.append(':'); break;
            case ')': break;
            case ',': result.append(':'); break;
            case '[': result.append('-'); break;
            case ']': break;
            default:  result.append(c); break;
            }
         }
         return result.toString();
      }
      else {
         return referencedMemberName;
      }
   }

   public void writeGjdocProperties(File outputFile)
      throws IOException
   {
      Properties properties = new Properties();
      properties.setProperty("gjdoc.version", getDocletVersion());
      properties.setProperty("gjdoc.compat", Boolean.toString(isJavadocCompatibleNames()));

      FileOutputStream out = new FileOutputStream(outputFile);
      properties.store(out, "GNU Gjdoc API Documentation Set Descriptor");
      out.close();
   }

   public boolean isJavadocCompatibleNames()
   {
      return !optionValidHtml.getValue();
   }

   private HtmlPage newHtmlPage(File file,
                                String pathToRoot)
      throws IOException
   {
      return new HtmlPage(file,
                          pathToRoot,
                          getOutputDocEncoding(),
                          optionBaseUrl.getValue(),
                          getTargetDirectory());
   }

   private HtmlPage newHtmlPage(File file,
                                String pathToRoot,
                                String docType)
      throws IOException
   {
      return new HtmlPage(file,
                          pathToRoot,
                          getOutputDocEncoding(),
                          optionBaseUrl.getValue(),
                          getTargetDirectory(),
                          docType);
   }
}
