/* gnu.classpath.tools.doclets.xmldoclet.Driver
   Copyright (C) 2001 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.xmldoclet;

import com.sun.javadoc.*;
import java.io.*;

import com.sun.tools.doclets.Taglet;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import java.text.DateFormat;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.TreeSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.HashMap;
import java.util.Properties;
import java.util.Set;
import java.util.SortedSet;
import java.util.StringTokenizer;
import java.util.TreeMap;

import gnu.classpath.tools.gjdoc.TemporaryStore;
import gnu.classpath.tools.gjdoc.GjdocPackageDoc;

import gnu.classpath.tools.doclets.PackageGroup;
import gnu.classpath.tools.doclets.PackageMatcher;
import gnu.classpath.tools.doclets.InvalidPackageWildcardException;

import gnu.classpath.tools.doclets.xmldoclet.doctranslet.DocTranslet;
import gnu.classpath.tools.doclets.xmldoclet.doctranslet.DocTransletOptions;

import gnu.classpath.tools.taglets.AuthorTaglet;
import gnu.classpath.tools.taglets.VersionTaglet;
import gnu.classpath.tools.taglets.SinceTaglet;
import gnu.classpath.tools.taglets.DeprecatedTaglet;
import gnu.classpath.tools.taglets.GenericTaglet;
import gnu.classpath.tools.doclets.StandardTaglet;

import gnu.classpath.tools.java2xhtml.Java2xhtml;

import gnu.classpath.tools.IOToolkit;
import gnu.classpath.tools.FileSystemClassLoader;

/**
 *  A Doclet which retrieves all information presented by the Doclet
 *  API, dumping it to stdout in XML format.
 *
 *  @author Julian Scheid
 */
public class Driver {

   public static final String XMLDOCLET_VERSION = "0.6.1";

   /**
    *  Used for redirecting error messages to <code>/dev/null</code>.
    */
   private static class NullErrorReporter implements DocErrorReporter {
      public void printError(String ignore) {}
      public void printWarning(String ignore) {}
      public void printNotice(String ignore) {}
   }

   /*
    *  Taglet context constants.
    */
   private static final int CONTEXT_CONSTRUCTOR  = 1;
   private static final int CONTEXT_FIELD        = 2;
   private static final int CONTEXT_METHOD       = 3;
   private static final int CONTEXT_OVERVIEW     = 4;
   private static final int CONTEXT_PACKAGE      = 5;
   private static final int CONTEXT_TYPE         = 6;

   /**
    *  All XML output will go to this stream.
    */
   private PrintWriter out;

   /**
    *  How many spaces to indent each XML node level,
    *  i.e. Tab size for output.
    */
   private static int indentStep = 1;

   /**
    *  Won't output superfluous spaces if set to true.
    *  If set to false, output will be more legible.
    */
   private boolean compress = false;

   /**
    *  Won't output warning messages while fixing
    *  HTML code if set to true.
    */
   private boolean noHTMLWarn = false;

   /**
    *  Won't output warning messages when encountering tags
    *  that look like an email address if set to true.
    */
   private boolean noEmailWarn = false;

   /**
    *  Will fix HTML if necessary so that each comment
    *  contains valid XML code if set to true. If set
    *  to false, HTML code will not be modified and
    *  instead encapsulated in a CDATA section.
    */
   private boolean fixHTML = true;

   /**
    *  User-specified name of the directory where the final version of
    *  the generated files will be written to.
    *
    *  If no XSLT sheet is given, the XML output will go directly into
    *  this directory. Otherwise, XML output will go to a temporary
    *  directory and XSLT output will go to this directory.
    */
   private File targetDirectory = null;

   /**
    *  Directory where XML output will be written to. If no XSLT
    *  sheet was given, this is the target directory specified
    *  by the user. Otherwise, this is a temporary directory.
    */
   private File xmlTargetDirectory;

   /**
    *  Contains a number of TargetContexts which describe which XSLT
    *  sheet to apply to the output of this doclet, to what directory
    *  the XSLT output is written, and which postprocess driver to use
    *  to process XSLT output.
    */
   private List targets = new ArrayList();

   /**
    *  XML text to include at the end of every generated page. Read
    *  from the file specified on the command line using -bottomnote.
    *  If present, this will be written to the main output file
    *  (index.xml) in node /gjdoc:rootDoc/gjdoc:bottomnote.
    */
   private String bottomNote;

   /**
    *  Brief description of the package set. Can be specified on the
    *  command line using -title.  This will be written to the main
    *  output file (index.xml) in node
    *  /gjdoc:rootDoc/gjdoc:title. The HTML generating XSLT sheet
    *  uses this for example in window titles.
    */
   private String title;

   /**
    *  Path to the directory where temporary files should be stored.
    *  Defaults to system tempdir, but can be overridden by user 
    *  with -workpath.
    */
   private String workingPath = System.getProperty("java.io.tmpdir");

   /**
    *  Temporary directory created by this doclet where all 
    *  temporary files will be stored in. If no temporary
    *  files are needed (i.e. no XSLT postprocessing stage
    *  specified by user), this is <code>null</code>.
    */
    private File workingDirectory;

   /**
    *  Whether to deep-copy the doc-files subdirectory.
    */
    private boolean docFilesSubdirsEnabled = false;

   /**
    *  Which direct subdirectories of the doc-files directories to exclude.
    *  Set of String.
    */
    private Set excludeDocFilesSubDirs = new HashSet();

   /**
    *  Stores the Doclet API RootDoc we are operating on.
    */
   private RootDoc rootDoc;

   /**
    *  XML namespace prefix used for all tags, except for HTML
    *  tags copied from Javadoc comments. Excluding colon.
    */
   public static final String tagPrefix = "gjdoc";

   /**
    *  Classpath for loading Taglet classes.
    */
   private String tagletPath = null;

   /**
    *  The current class that is being processed.
    *  Set in outputClassDoc().
    */
   private ClassDoc currentClass;

   /**
    *  The current member that is being processed.
    *  Set in outputMemberDoc().
    */
   private MemberDoc currentMember;

   /**
    *  The current constructor/method that is being processed.
    *  Set in outputExecutableMemberDoc().
    */
   private ExecutableMemberDoc currentExecMember;

   /**
    *  Mapping from tag type to Taglet for user Taglets specified on
    *  the command line.
    */
   private Map tagletMap = new LinkedHashMap();

   /**
    *  Keeps track of the tags mentioned by the user during option
    *  processiong so that an error can be emitted if a tag is
    *  mentioned more than once.
    */
   private List mentionedTags = new LinkedList();

   /**
    *  Stores options to be passed to the DocTranslet.
    */
   private DocTransletOptions docTransletOptions = new DocTransletOptions();   

   /**
    *  Stores the package groups specified in the user
    *  options. Contains objects of type PackageGroup.
    */
   private List packageGroups = new LinkedList();

   private HtmlRepairer htmlRepairer;

   public static boolean start(TemporaryStore _rootDocWrapper) {
      return new Driver().instanceStart((RootDoc)_rootDocWrapper.getAndClear());
   }

   /**
    *  Official Doclet entry point.
    */
   public static boolean start(RootDoc _rootDoc) {

      // Create a new XmlDoclet instance and delegate control.
      TemporaryStore tstore = new TemporaryStore(_rootDoc);
      _rootDoc = null;
      return new Driver().instanceStart((RootDoc)tstore.getAndClear());
   }

   /**
    *  Output an XML tag describing a com.sun.javadoc.Type object.
    *  Assumes that the tag does not have subtags.
    *
    *  @param level  Level of indentation. Will be multiplied by 
    *                <code>indentStep</code> to yield actual amount
    *                of whitespace inserted at start of line.
    *  @param tag    Identifier for the XML tag being output.
    *  @param type   The Javadoc Type to be output.
    */
   protected void outputType(int level, String tag, Type type) {
      outputType(level, tag, type, true);
   }

   protected void outputType(int level, String tag, Type type, boolean atomic) {

      boolean isIncluded = false;
      ClassDoc typeAsClassDoc = type.asClassDoc();
      String packageName = null;
      if (null != typeAsClassDoc) {
         isIncluded = typeAsClassDoc.isIncluded();
         packageName = typeAsClassDoc.containingPackage().name();
      }
      println(level, "<"+tagPrefix+":"+tag + " typename=\""+type.typeName()+"\""+
	      " qualifiedtypename=\""+type.qualifiedTypeName()+"\""
	      +(type.dimension().length()==0?"":" dimension=\""+type.dimension()+"\"")
              +(isIncluded?" isIncluded=\"true\"" : "")
              +((null != packageName)?" package=\"" + packageName + "\"" : "")
	      +(atomic?"/":"")+">");
   }

   protected void outputExecutableMemberDocBody(int level, ExecutableMemberDoc memberDoc) {

      currentExecMember = memberDoc;

      outputMemberDocBody(level, memberDoc);

      Parameter[] parameters = memberDoc.parameters();
      for (int i=0, ilim=parameters.length; i<ilim; ++i) {
	 Parameter parameter = parameters[i];
	 outputType(level, "parameter name=\""+parameter.name()+"\"", parameter.type());
      }

      ClassDoc[] exceptions = memberDoc.thrownExceptions();
      for (int i=0, ilim=exceptions.length; i<ilim; ++i) {
	 ClassDoc exception = exceptions[i];
	 outputType(level, "thrownException", exception);
       }

      printAtomTag(level, "signature full=\""+memberDoc.signature()+"\" flat=\""+memberDoc.flatSignature()+"\"");

      if (memberDoc.isNative()) {
	 printAtomTag(level, "isNative");
      }

      if (memberDoc.isSynchronized()) {
	 printAtomTag(level, "isSynchronized");
      }
   }

   protected void outputMethodDoc(int level, MethodDoc methodDoc) {
      println();
      printOpenTag(level, "methoddoc name=\""+methodDoc.name()+"\"");
      outputExecutableMemberDocBody(level+1, methodDoc);
      outputType(level+1, "returns", methodDoc.returnType());
      printCloseTag(level, "methoddoc");
   }

   protected void outputMemberDocBody(int level, MemberDoc memberDoc) {
      currentMember = memberDoc;
      outputProgramElementDocBody(level, memberDoc);
   }

   protected void outputFieldDocBody(int level, FieldDoc fieldDoc) {
      outputType(level, "type", fieldDoc.type());
      if (fieldDoc.isTransient()) {
	 printAtomTag(level, "isTransient");
      }
      if (fieldDoc.isVolatile()) {
	 printAtomTag(level, "isVolatile");
      }
   }

   private void outputFieldDoc(int level, FieldDoc fieldDoc) {
      println();
      printOpenTag(level, "fielddoc name=\""+fieldDoc.name()+"\"");
      outputMemberDocBody(level+1, fieldDoc);
      outputFieldDocBody(level+1, fieldDoc);
      printCloseTag(level, "fielddoc");
   }

   protected void outputConstructorDoc(int level, ConstructorDoc constructorDoc) {
      println();
      printOpenTag(level, "constructordoc name=\""+constructorDoc.name()+"\"");
      outputExecutableMemberDocBody(level+1, constructorDoc);
      printCloseTag(level, "constructordoc");
   }

   protected void outputSuperInterfacesRec(int level, ClassDoc classDoc) {
      if (null!=classDoc) {
	 ClassDoc[] interfaces = classDoc.interfaces();
         if (null != interfaces) {
            for (int i=0, ilim=interfaces.length; i<ilim; ++i) {
               outputType(level, "superimplements", interfaces[i]);
            }
         }
	 outputSuperInterfacesRec(level, classDoc.superclass());
      }
   }

   protected void outputClassDocSummary(ClassDoc classDoc) {
      println();
      printOpenTag(1, "classdoc name=\""+classDoc.name()+"\" qualifiedtypename=\""+classDoc.qualifiedName()+"\" isIncluded=\"true\"");
      if (null!=classDoc.superclass()) {
	 outputType(2, "superclass", classDoc.superclass());
      }

      ClassDoc[] interfaces = classDoc.interfaces();
      for (int i=0, ilim=interfaces.length; i<ilim; ++i) {
	 outputType(2, "implements", interfaces[i]);
      }
      outputSuperInterfacesRec(2, classDoc.superclass());

      printAtomTag(2, "containingPackage name=\""+classDoc.containingPackage().name()+"\"");
      if (classDoc.isError()) {
         printAtomTag(2, "isError");
      }
      if (classDoc.isException()) {
         printAtomTag(2, "isException");
      }
      if (classDoc.isInterface()) {
         printAtomTag(2, "isInterface");
      }
      if (classDoc.isOrdinaryClass()) {
         printAtomTag(2, "isOrdinaryClass");
      }

      printCloseTag(1, "classdoc");
   }

   protected void outputPackageDoc(PackageDoc packageDoc) {
      println();
      printOpenTag(1, "packagedoc name=\""+packageDoc.name()+"\"");
      if (packageDoc.firstSentenceTags().length > 0) {
	 printOpenTag(2, "firstSentenceTags", false);
	 outputTags(3, packageDoc.firstSentenceTags(), true, CONTEXT_PACKAGE);
	 printCloseTag(0, "firstSentenceTags");
	 printOpenTag(2, "inlineTags", false);
	 outputTags(3, packageDoc.inlineTags(), true, CONTEXT_PACKAGE);
	 printCloseTag(0, "inlineTags");
      }

      if (packageDoc.tags().length > 0) {
	 printOpenTag(2, "tags");
	 outputTags(3, packageDoc.tags(), true, CONTEXT_PACKAGE);
	 printCloseTag(2, "tags");
      }

      if (packageDoc.seeTags().length > 0) {
	 printOpenTag(2, "seeTags");
	 outputTags(3, packageDoc.seeTags(), true, CONTEXT_PACKAGE);
	 printCloseTag(2, "seeTags");
      }

      ClassDoc[] allClasses = (ClassDoc[]) packageDoc.allClasses().clone();
      Arrays.sort(allClasses);

      if (false) {
	 for (int i = 0, ilim = allClasses.length; i < ilim; ++ i) {
	    printAtomTag(2, "containsClass qualifiedtypename=\""+allClasses[i].qualifiedTypeName()+"\"");
	 }
      }

      printCloseTag(1, "packagedoc");
   }

   protected void outputClassDoc(ClassDoc classDoc) throws IOException {

      currentClass = classDoc;

      println();
      printOpenTag(1, "classdoc xmlns=\"http://www.w3.org/TR/REC-html40\" xmlns:"+tagPrefix+"=\"http://www.gnu.org/software/cp-tools/gjdocxml\" name=\""+classDoc.name()+"\" qualifiedtypename=\""+classDoc.qualifiedName()+"\"");

      ClassDoc[] interfaces = classDoc.interfaces();
      for (int i=0, ilim=interfaces.length; i<ilim; ++i) {
	 outputType(2, "implements", interfaces[i]);
      }
      outputSuperInterfacesRec(2, classDoc.superclass());

      outputProgramElementDocBody(2, classDoc);
      if (classDoc.isAbstract())
	 printAtomTag(2, "isAbstract");
      if (classDoc.isSerializable())
	 printAtomTag(2, "isSerializable");
      if (classDoc.isExternalizable())
	 printAtomTag(2, "isExternalizable");
      if (classDoc.definesSerializableFields()) {
	 printAtomTag(2, "definesSerializableFields");
      }

      ConstructorDoc[] constructors = classDoc.constructors();
      for (int i=0, ilim=constructors.length; i<ilim; ++i) {
	 outputConstructorDoc(2, constructors[i]);
      }

      MethodDoc[] methods = classDoc.methods();
      for (int i=0, ilim=methods.length; i<ilim; ++i) {
	 outputMethodDoc(2, methods[i]);
      }

      FieldDoc[] fields = classDoc.fields();
      for (int i=0, ilim=fields.length; i<ilim; ++i) {
	 outputFieldDoc(2, fields[i]);
      }

      if (classDoc.serializableFields().length > 0) {
	 printOpenTag(2, "serializableFields");

         FieldDoc[] sfields = classDoc.serializableFields();
         for (int i=0, ilim=sfields.length; i<ilim; ++i) {
            outputFieldDoc(2, sfields[i]);
         }
	 printCloseTag(2, "serializableFields");
      }

      Java2xhtml java2xhtml = new Java2xhtml();
      Properties properties = new Properties();
      properties.setProperty("isCodeSnippet", "true");
      properties.setProperty("hasLineNumbers", "true");
      java2xhtml.setProperties(properties);

      if (null == classDoc.containingClass() && docTransletOptions.linksource) {
         printOpenTag(2, "source");
         StringWriter sourceBuffer = new StringWriter();
         File sourceFile = new File(((GjdocPackageDoc)classDoc.containingPackage()).packageDirectory(),
                                    classDoc.name() + ".java");
         FileReader sourceReader = new FileReader(sourceFile);
         IOToolkit.copyStream(sourceReader, sourceBuffer);
         print(java2xhtml.makeHTML(sourceBuffer.getBuffer(), sourceFile.getName()));
         printCloseTag(2, "source");      
      }

      ClassDoc superclassDoc = classDoc.superclass();
      while (superclassDoc != null) {
	 outputType(2, "superclass", superclassDoc, false);

         // FIXME: remove the following after adjusting the XSLT sheets:
         printAtomTag(3, "containingPackage name=\"" + superclassDoc.containingPackage().name() + "\"");

         MethodDoc[] superMethods = superclassDoc.methods();
         if (null != superMethods) {
            for (int i=0, ilim=superMethods.length; i<ilim; ++i) {
               printAtomTag(3, "methoddoc name=\"" + superMethods[i].name() + "\" signature=\"" + superMethods[i].signature() + "\"");
            }
         }
         
         FieldDoc[] superFields = superclassDoc.fields();
         if (null != superFields) {
            for (int i=0, ilim=superFields.length; i<ilim; ++i) {
               printAtomTag(3, "fielddoc name=\"" + superFields[i].name() + "\"");
            }
         }
         printCloseTag(2, "superclass");
         
         superclassDoc = superclassDoc.superclass();
      }

      outputUsage(classDoc, 2);

      printCloseTag(1, "classdoc");

      currentClass = null;
      currentMember = null;
      currentExecMember = null;
   }

   protected int outputHeritageOpen(int level, ClassDoc classDoc) {

      ClassDoc superClassDoc = classDoc.superclass();
      if (null != superClassDoc) {
         level = outputHeritageOpen(level, superClassDoc);
         ++ level;
      }
      outputType(level, "heritage", classDoc, false);
      return level;
   }

   protected void outputHeritageClose(int level, ClassDoc classDoc) {

      ClassDoc superClassDoc = classDoc.superclass();
      if (null != superClassDoc) {
         outputHeritageClose(level + 1, superClassDoc);
      }
      printCloseTag(level, "heritage");
   }

   protected void outputDocBody(int level, Doc doc) {

      int context = CONTEXT_TYPE;

      if (doc.isClass()) {
	 printAtomTag(level, "isClass");

         ClassDoc classDoc = (ClassDoc)doc;
         ClassDoc[] classes = rootDoc.classes();
         for (int i=0, ilim=classes.length; i<ilim; ++i) {
            if (classes[i].superclass() == classDoc) {
               outputType(level, "extended-by", classes[i]);
            }
         }

         outputHeritageOpen(level, classDoc);
         outputHeritageClose(level, classDoc);
      }
      if (doc.isConstructor()) {
	 printAtomTag(level, "isConstructor");
         context = CONTEXT_CONSTRUCTOR;
      }
      if (doc.isError()) {
	 printAtomTag(level, "isError");
      }
      if (doc.isException()) {
	 printAtomTag(level, "isException");
      }
      if (doc.isField()) {
	 printAtomTag(level, "isField");
         context = CONTEXT_FIELD;
      }
      if (doc.isIncluded()) {
	 printAtomTag(level, "isIncluded");
      }
      if (doc.isInterface()) {
	 printAtomTag(level, "isInterface");

         ClassDoc classDoc = (ClassDoc)doc;
         ClassDoc[] classes = rootDoc.classes();
         for (int i=0, ilim=classes.length; i<ilim; ++i) {
            ClassDoc[] implementedInterfaces = classes[i].interfaces();
            for (int j=0; j<implementedInterfaces.length; ++j) {
               if (implementedInterfaces[j] == classDoc) {
                  if (classDoc.isInterface()) {
                        outputType(level, "subinterface", classes[i]);
                  }
                  else {
                     outputType(level, "implemented-by", classes[i]);
                  }
                  break;
               }
            }
         }
      }
      if (doc.isMethod()) {
	 printAtomTag(level, "isMethod");
         context = CONTEXT_METHOD;
      }
      if (doc.isOrdinaryClass()) {
	 printAtomTag(level, "isOrdinaryClass");
      }

      if (doc.inlineTags().length > 0) {
	 printOpenTag(level, "inlineTags", false);
	 outputTags(level+1, doc.inlineTags(), true, context);
	 printCloseTag(0, "inlineTags");
      }

      if (doc.firstSentenceTags().length > 0) {
	 printOpenTag(level, "firstSentenceTags", false);
	 outputTags(level+1, doc.firstSentenceTags(), true, context);
	 printCloseTag(0, "firstSentenceTags");
      }

      if (doc.tags().length > 0) {
	 printOpenTag(level, "tags");
         outputTaglets(level+1, doc.tags(), true, context);
	 printCloseTag(level, "tags");
      }

      if (doc.seeTags().length > 0) {
	 printOpenTag(level, "seeTags");
	 outputTags(level+1, doc.seeTags(), true, context);
	 printCloseTag(level, "seeTags");
      }

      SourcePosition position = doc.position();
      if (null != position) {
	 printAtomTag(level, "position file=\"" + position.file().getAbsolutePath() + "\" line=\"" + position.line() + "\" column=\"" + position.column() + "\"");
      }
   }

   protected void outputProgramElementDocBody(int level, ProgramElementDoc programElementDoc) {
      outputDocBody(level, programElementDoc);
      printAtomTag(level, "containingPackage name=\""+programElementDoc.containingPackage().name()+"\"");
      if (null!=programElementDoc.containingClass()) {
	 outputType(level, "containingClass", programElementDoc.containingClass());
      }
      String access;
      if (programElementDoc.isPublic()) 
	 access="public";
      else if (programElementDoc.isProtected()) 
	 access="protected";
      else if (programElementDoc.isPrivate()) 
	 access="private";
      else if (programElementDoc.isPackagePrivate()) 
	 access="package";
      else
	 throw new RuntimeException("Huh? "+programElementDoc+" is neither public, protected, private nor package protected.");
      printAtomTag(level, "access scope=\""+access+"\"");
      if (programElementDoc.isFinal())
	 printAtomTag(level, "isFinal");
      if (programElementDoc.isStatic())
	 printAtomTag(level, "isStatic");
   }

   protected void outputTags(int level, Tag[] tags, boolean descend, int context) {

      for (int i=0; i<tags.length; ++i) {
         outputTag(tags[i], level, descend, context, i == tags.length-1);
      }
   }

   protected void outputTag(Tag tag, int level, boolean descend, int context, boolean lastTag) {

      if (!"Text".equals(tag.name())) {
         printOpenTag(0 /* don't introduce additional whitespace */, 
                      "tag kind=\""+tag.kind()+"\" name=\""+tag.name()+"\"", false);
      }
      if (tag instanceof ThrowsTag) {
         ThrowsTag throwsTag = (ThrowsTag)tag;
         if (null!=throwsTag.exception()) {
            outputType(level+1, "exception", throwsTag.exception());
         }
         else {
            StringBuffer sb = new StringBuffer("Exception ");
            sb.append(throwsTag.exceptionName());
            sb.append(" not found in ");
            if (currentExecMember instanceof MethodDoc) {
               MethodDoc m = (MethodDoc)currentExecMember;
               sb.append(m.returnType().typeName());
               sb.append(m.returnType().dimension());
               sb.append(' ');
            }
            sb.append(currentClass.qualifiedName());
            sb.append('.');
            sb.append(currentExecMember.name());
            sb.append('(');
            Parameter[] params = currentExecMember.parameters();
            for (int j=0; j < params.length; j++) {
               sb.append(params[j].type().typeName());
               sb.append(params[j].type().dimension());
               sb.append(' ');
               sb.append(params[j].name());
               if (j != params.length-1)
                  sb.append(", ");
            }
            sb.append(')');
            printWarning(sb.toString());

            printAtomTag(level+1, "exception typename=\""+throwsTag.exceptionName()+"\"");
         }
      }
      else if (tag instanceof ParamTag) {
         ParamTag paramTag = (ParamTag)tag;
         printAtomTag(level+1, "parameter name=\""+paramTag.parameterName()+"\"");
      }

      if (null != tag.text()) {
         //printOpenTag(level+1, "text", false);
         if (fixHTML) {
            print(htmlRepairer.getWellformedHTML(tag.text()));
         }
         else {
            print("<![CDATA["+cdata(tag.text())+"]]>");
         }
         //printCloseTag(0 /* don't introduce additional whitespace */, "text");
      }
      else {
         printWarning("Tag got null text: "+tag);
      }

      if ((descend && ("@throws".equals(tag.name()) || "@param".equals(tag.name()))) || "@deprecated".equals(tag.name())) {
         if (tag.firstSentenceTags().length>0) {
            printOpenTag(level+1, "firstSentenceTags", false);
            outputTags(level+2, tag.firstSentenceTags(), false, context);
            printCloseTag(0, "firstSentenceTags");
         }
	    
         if (tag.inlineTags().length>0) {
            printOpenTag(level+1, "inlineTags", false);
            outputTags(level+2, tag.firstSentenceTags(), false, context);
            printCloseTag(0, "inlineTags");
         }
      }

      if (fixHTML && lastTag) {
         String terminateText = htmlRepairer.terminateText();
         if (null != terminateText && terminateText.length() > 0) {
            print(terminateText);
         }
      }

      if (!"Text".equals(tag.name())) {

         Taglet inlineTaglet = (Taglet)tagletMap.get(tag.name().substring(1));
         if (null != inlineTaglet && inlineTaglet.isInlineTag()) {
            printOpenTag(0, "inlineTagletText", false);
            print(inlineTaglet.toString(tag));
            printCloseTag(0, "inlineTagletText");
         }

         printCloseTag(0, "tag", false);
      }
   }

   void outputTaglets(int level, Tag[] tags, boolean descend, int context) 
   {
      for (Iterator it = tagletMap.keySet().iterator(); it.hasNext(); ) {
         String tagName = (String)it.next();
         Object o = tagletMap.get(tagName);
         Taglet taglet = (Taglet)o;

         if (!taglet.isInlineTag()
             && ((context != CONTEXT_CONSTRUCTOR || taglet.inConstructor())
                 || (context != CONTEXT_FIELD || taglet.inField())
                 || (context != CONTEXT_METHOD || taglet.inMethod())
                 || (context != CONTEXT_OVERVIEW || taglet.inOverview())
                 || (context != CONTEXT_PACKAGE || taglet.inPackage())
                 || (context != CONTEXT_TYPE || taglet.inType()))) {
            
            List tagsOfThisType = new ArrayList();
            for (int i=0, ilim=tags.length; i<ilim; ++i) {
               if (tags[i].name().substring(1).equals(tagName)) {
                  tagsOfThisType.add(tags[i]);
               }
            }

            if (!tagsOfThisType.isEmpty()) {
               Tag[] tagletTags = (Tag[])tagsOfThisType.toArray(new Tag[tagsOfThisType.size()]);
               if (taglet instanceof StandardTaglet) {
                  Iterator tagIterator = tagsOfThisType.iterator();
                  while (tagIterator.hasNext()) {
                     Tag tag = (Tag)tagIterator.next();
                     outputTag(tag, level, descend, context, !tagIterator.hasNext());
                  }
               }
               else {
                  String tagletString = taglet.toString(tagletTags);
                  if (null != tagletString) {
                     printOpenTag(0, "tag name=\"" + tagName + "\" taglet-generated=\"true\"");
                     if (fixHTML) {
                        print(htmlRepairer.getWellformedHTML(tagletString));
                        print(htmlRepairer.terminateText());
                     }
                     else {
                        print("<![CDATA["+cdata(tagletString)+"]]>");
                     }
                     printCloseTag(0, "tag", false);
                  }
               }
            }
         }
      }
   }

   /**
    *  Inofficial entry point. We got an instance here.
    */
   protected boolean instanceStart(RootDoc _rootDoc) {

      this.rootDoc = _rootDoc;
      _rootDoc = null;

      boolean xmlOnly = true;

      // Set the default Taglet order

      registerTaglet(new VersionTaglet());
      registerTaglet(new AuthorTaglet());
      //registerTaglet(new SinceTaglet());
      registerTaglet(new StandardTaglet("deprecated"));
      registerTaglet(new StandardTaglet("see"));
      registerTaglet(new StandardTaglet("param"));

      // Set the built-in Taglet filter

      AuthorTaglet.setTagletEnabled(false);
      VersionTaglet.setTagletEnabled(false);
      SinceTaglet.setTagletEnabled(true);
      DeprecatedTaglet.setTagletEnabled(true);

      try {
	 {

	    // Process command line options passed through to this doclet
	    
	    TargetContext targetContext = null;
	    
	    TargetContext htmlTargetContext
               = new TargetContext(DocTranslet.fromClasspath("/doctranslets/html/gjdoc.xsl"), 
                                   targetDirectory);

	    for (int i=0, ilim=rootDoc.options().length; i<ilim; ++i) {

	       String[] option = rootDoc.options()[i];
	       String optionTag = option[0];

	       if ("-d".equals(optionTag)) {
		  if (null == targetDirectory) {
		     targetDirectory = new File(option[1]);
		  }
		  if (null != targetContext) {
		     targetContext.setTargetDirectory(targetDirectory);
		  }
	       }

	       else if ("-nofixhtml".equals(optionTag)) {
		  fixHTML = false;
                  printError("-nofixhtml currently not supported.");
                  return false;
	       }
	       else if ("-compress".equals(optionTag)) {
		  compress = true;
	       }
	       else if ("-nohtmlwarn".equals(optionTag)) {
		  noHTMLWarn = true;
	       }
	       else if ("-noemailwarn".equals(optionTag)) {
		  noEmailWarn = true;
	       }
	       else if ("-indentstep".equals(optionTag)) {
		  indentStep = Integer.parseInt(option[1]);
	       }
	       else if ("-doctranslet".equals(optionTag)) {
		  targets.add(targetContext = new TargetContext(DocTranslet.fromJarFile(new File(option[1])), 
                                                                targetDirectory));
	       }
	       else if ("-genhtml".equals(optionTag)) {
		  htmlTargetContext.setTargetDirectory(targetDirectory);
		  targets.add(targetContext = htmlTargetContext);
                  xmlOnly = false;
	       } 
	       else if ("-geninfo".equals(optionTag)) {
                  targetContext
                              = new TargetContext(DocTranslet.fromClasspath("/doctranslets/info/gengj.xsl"), 
                                                  targetDirectory);
		  targets.add(targetContext);
		  if (!fixHTML) {
		     printNotice("NOTE: -geninfo implies -fixhtml.");
		     fixHTML = true;
		  }
                  xmlOnly = false;
	       }
	       else if ("-gendocbook".equals(optionTag)) {
                  targetContext = new TargetContext(DocTranslet.fromClasspath("/doctranslets/docbook/gengj.xsl"), 
                                                    targetDirectory);
		  targets.add(targetContext);
		  if (!fixHTML) {
		     printNotice("NOTE: -gendocbook implies -fixhtml.");
		     fixHTML = true;
		  }
	       }
	       else if ("-genpdf".equals(optionTag)) {
                  targetContext
                     = new TargetContext(DocTranslet.fromClasspath("/doctranslets/docbook/gengj.xsl"), 
                                         targetDirectory);
                                         /** "gnu.classpath.tools.doclets.xmldoclet.DocBookPostprocessor") **/
		  targets.add(targetContext);
		  if (!fixHTML) {
		     printNotice("NOTE: -genpdf implies -fixhtml.");
		     fixHTML = true;
		  }
	       }
	       else if ("-xmlonly".equals(optionTag)) {
		  xmlOnly = true;
	       }
	       else if ("-bottomnote".equals(optionTag)) {

		  FileReader reader = new FileReader(option[1]);
		  StringWriter writer = new StringWriter();
		  char[] buf = new char[256];
		  int nread;
		  while ((nread = reader.read(buf)) >= 0) {
		     writer.write(buf, 0, nread);
		  }
		  writer.flush();
		  bottomNote = writer.toString();
		  writer.close();
		  reader.close();
	       }
	       else if ("-title".equals(optionTag)) {

		  title = option[1];
	       }
	       else if ("-workpath".equals(optionTag)) {

		  workingPath = option[1];
	       }
	       else if ("-tagletpath".equals(optionTag)) {

                  if (null == tagletPath) {
                     tagletPath = option[1];
                  }
                  else {
                     tagletPath = tagletPath + File.pathSeparator + option[1];
                  }
	       }
               else if ("-taglet".equals(optionTag)) {

                  boolean tagletLoaded = false;

                  String useTagletPath = this.tagletPath;
                  if (null == useTagletPath) {
                     useTagletPath = System.getProperty("java.class.path");
                  }

                  try {
                     Class tagletClass;
                     try {
                        tagletClass
                           = new FileSystemClassLoader(useTagletPath).loadClass(option[1]);
                     }
                     catch (ClassNotFoundException e) {
                        // If not found on specified tagletpath, try default classloader
                        tagletClass
                           = Class.forName(option[1]);
                     }
                     Method registerTagletMethod
                        = tagletClass.getDeclaredMethod("register", new Class[] { java.util.Map.class });

                     if (!registerTagletMethod.getReturnType().equals(Void.TYPE)) {
                        printError("Taglet class '" + option[1] + "' found, but register method doesn't return void.");
                     }
                     else if (registerTagletMethod.getExceptionTypes().length > 0) {
                        printError("Taglet class '" + option[1] + "' found, but register method contains throws clause.");
                     }
                     else if ((registerTagletMethod.getModifiers() & (Modifier.STATIC | Modifier.PUBLIC | Modifier.ABSTRACT)) != (Modifier.STATIC | Modifier.PUBLIC)) {
                        printError("Taglet class '" + option[1] + "' found, but register method isn't public static, or is abstract..");
                     }
                     else {
                        Map tempMap = new HashMap();
                        registerTagletMethod.invoke(null, new Object[] { tempMap });
                        tagletLoaded = true;
                        String name = (String)tempMap.keySet().iterator().next();
                        Taglet taglet = (Taglet)tempMap.get(name);
                        tagletMap.put(name, taglet);
                        mentionedTags.add(taglet);
                     }
                  }
                  catch (NoSuchMethodException e) {
                     printError("Taglet class '" + option[1] + "' found, but doesn't contain the register method.");
                  }
                  catch (SecurityException e) {
                     printError("Taglet class '" + option[1] + "' cannot be loaded: " + e.getMessage());
                  }
                  catch (InvocationTargetException e) {
                     printError("Taglet class '" + option[1] + "' found, but register method throws exception: " + e.toString());
                  }
                  catch (IllegalAccessException e) {
                     printError("Taglet class '" + option[1] + "' found, but there was a problem when accessing the register method: " + e.toString());
                  }
                  catch (IllegalArgumentException e) {
                     printError("Taglet class '" + option[1] + "' found, but there was a problem when accessing the register method: " + e.toString());
                  }
                  catch (ClassNotFoundException e) {
                     printError("Taglet class '" + option[1] + "' cannot be found.");
                  }
                  if (!tagletLoaded) {
                     return false;
                  }
               }
	       else if ("-author".equals(optionTag)) {
                  AuthorTaglet.setTagletEnabled(true);
               }
	       else if ("-version".equals(optionTag)) {
                  VersionTaglet.setTagletEnabled(true);
               }
	       else if ("-nosince".equals(optionTag)) {
                  SinceTaglet.setTagletEnabled(false);
               }
	       else if ("-nodeprecated".equals(optionTag)) {
                  DeprecatedTaglet.setTagletEnabled(false);
               }
	       else if ("-authormail".equals(optionTag)) {
                  
		  if ("no-replace".equalsIgnoreCase(option[1])) {
                     AuthorTaglet.setEmailReplacementType(AuthorTaglet.EmailReplacement.NO_REPLACEMENT);
                  }
		  else if ("mailto-name".equalsIgnoreCase(option[1])) {
                     AuthorTaglet.setEmailReplacementType(AuthorTaglet.EmailReplacement.MAILTO_NAME);
                  }
		  else if ("name-mailto-address".equalsIgnoreCase(option[1])) {
                     AuthorTaglet.setEmailReplacementType(AuthorTaglet.EmailReplacement.NAME_MAILTO_ADDRESS);
                  }
		  else if ("name-mangled-address".equalsIgnoreCase(option[1])) {
                     AuthorTaglet.setEmailReplacementType(AuthorTaglet.EmailReplacement.NAME_MANGLED_ADDRESS);
                  }
                  else {
                     printError("Invalid value for option '-authortag-email'. Allowed values are:"
                                + " no-replace, mailto-name, name-mailto-address, name-mangled-address.");
                     return false;
                  }
	       }
	       else if ("-mailmangledot".equals(optionTag)) {
                  AuthorTaglet.setDotReplacement(option[1]);
               }
	       else if ("-mailmangleat".equals(optionTag)) {
                  AuthorTaglet.setAtReplacement(option[1]);
               }
	       else if ("-docfilessubdirs".equals(optionTag)) {
                  docFilesSubdirsEnabled = true;
               }
	       else if ("-excludedocfilessubdir".equals(optionTag)) {
                  StringTokenizer st = new StringTokenizer(option[1]);
                  while (st.hasMoreTokens()) {
                     excludeDocFilesSubDirs.add(st.nextToken());
                  }
               }
	       else if ("-nonavbar".equals(optionTag)) {
                  docTransletOptions.nonavbar = true;
               }
	       else if ("-noindex".equals(optionTag)) {
                  docTransletOptions.noindex = true;
               }
	       else if ("-notree".equals(optionTag)) {
                  docTransletOptions.notree = true;
               }
	       else if ("-nocomment".equals(optionTag)) {
                  docTransletOptions.nocomment = true;
               }
	       else if ("-nohelp".equals(optionTag)) {
                  docTransletOptions.nohelp = true;
               }
	       else if ("-splitindex".equals(optionTag)) {
                  docTransletOptions.splitindex = true;
               }
	       else if ("-linksource".equals(optionTag)) {
                  docTransletOptions.linksource = true;
               }
	       else if ("-windowtitle".equals(optionTag)) {
                  docTransletOptions.windowtitle = option[1];
               }
	       else if ("-helpfile".equals(optionTag)) {
                  docTransletOptions.helpfile = new File(option[1]).toURL().toString();
               }
	       else if ("-stylesheetfile".equals(optionTag)) {
                  docTransletOptions.stylesheetfile = new File(option[1]).toURL().toString();
               }
	       else if ("-header".equals(optionTag)) {
                  docTransletOptions.header = option[1];
               }
	       else if ("-footer".equals(optionTag)) {
                  docTransletOptions.footer = option[1];
               }
	       else if ("-bottom".equals(optionTag)) {
                  docTransletOptions.bottom = option[1];
               }
	       else if ("-doctitle".equals(optionTag)) {
                  docTransletOptions.doctitle = option[1];
               }
	       else if ("-nodeprecatedlist".equals(optionTag)) {
                  docTransletOptions.nodeprecatedlist = true;
               }
	       else if ("-uses".equals(optionTag)) {
                  docTransletOptions.uses = true;
               }
	       else if ("-group".equals(optionTag)) {
                  if (!processGroupOption(option[1], option[2])) {
                     printError("Invalid package wildcard list in -group option \"" + option[1] + "\" " + option[2]);
                     return false;
                  }
               }
	       else if ("-tag".equals(optionTag)) {
                  String tagSpec = option[1];
                  boolean validTagSpec = false;
                  int ndx1 = tagSpec.indexOf(':');
                  if (ndx1 < 0) {
                     Taglet taglet = (Taglet)tagletMap.get(tagSpec);
                     if (null == taglet) {
                        printError("There is no standard tag '" + tagSpec + "'.");
                     }
                     else {
                        if (mentionedTags.contains(taglet)) {
                           printError("Tag '" + tagSpec + "' has been added or moved before.");
                        }
                        else {
                           mentionedTags.add(taglet);
                           
                           // re-append taglet
                           tagletMap.remove(tagSpec);
                           tagletMap.put(tagSpec, taglet);
                        }
                     }
                  }
                  else {
                     int ndx2 = tagSpec.indexOf(':', ndx1 + 1);
                     if (ndx2 > ndx1 && ndx2 < tagSpec.length() - 1) {
                        String tagName = tagSpec.substring(0, ndx1);
                        String tagHead = null;
                        if (tagSpec.charAt(ndx2 + 1) == '\"') {
                           if (tagSpec.charAt(tagSpec.length() - 1) == '\"') {
                              tagHead = tagSpec.substring(ndx2 + 2, tagSpec.length() - 1);
                              validTagSpec = true;
                           }
                        }
                        else {
                           tagHead = tagSpec.substring(ndx2 + 1);
                           validTagSpec = true;
                        }

                        boolean tagScopeOverview = false;
                        boolean tagScopePackages = false;
                        boolean tagScopeTypes = false;
                        boolean tagScopeConstructors = false;
                        boolean tagScopeMethods = false;
                        boolean tagScopeFields = false;
                        boolean tagDisabled = false;
                        
                     tag_option_loop:
                        for (int n=ndx1+1; n<ndx2; ++n) {
                           switch (tagSpec.charAt(n)) {
                           case 'X': 
                              tagDisabled = true;
                              break;
                           case 'a':
                              tagScopeOverview = true;
                              tagScopePackages = true;
                              tagScopeTypes = true;
                              tagScopeConstructors = true;
                              tagScopeMethods = true;
                              tagScopeFields = true;
                              break;
                           case 'o':
                              tagScopeOverview = true;
                              break;
                           case 'p':
                              tagScopePackages = true;
                              break;
                           case 't':
                              tagScopeTypes = true;
                              break;
                           case 'c':
                              tagScopeConstructors = true;
                              break;
                           case 'm':
                              tagScopeMethods = true;
                              break;
                           case 'f':
                              tagScopeFields = true;
                              break;
                           default:
                              validTagSpec = false;
                              break tag_option_loop;
                           }
                        }
                        
                        if (validTagSpec) {
                           GenericTaglet taglet
                              = new GenericTaglet(tagName,
                                                  tagHead,
                                                  tagScopeOverview,
                                                  tagScopePackages,
                                                  tagScopeTypes,
                                                  tagScopeConstructors,
                                                  tagScopeMethods,
                                                  tagScopeFields);
                           taglet.setTagletEnabled(!tagDisabled);
                           taglet.register(tagletMap);
                           mentionedTags.add(taglet);
                        }
                     }
                  }
                  if (!validTagSpec) {
                     printError("Value for option -tag must be in format \"<tagname>:Xaoptcmf:<taghead>\".");
                  }
               }
	    }

            // Use current directory if target directory hasn't been set.
            if (null == targetDirectory) {
               targetDirectory = new File(System.getProperty("user.dir"));
            }
            if (null != targetContext) {
               targetContext.setTargetDirectory(targetDirectory);
            }

	    // It is illegal to specify targets AND -xmlonly.

	    if (xmlOnly && targets.size() > 0) {

	       printError("You can only specify one of -xmlonly and a target format.");
	       return false;
	    }

	    // If no target was specified and XML only was not
	    // requested, use HTML as default target.

	    if (!xmlOnly && targets.size() == 0) {
	       targets.add(targetContext = htmlTargetContext);
	    }

	    // Set the same target directory for all output.

	    // FIXME: Allow separate target directories for different
	    // output formats.

	    for (Iterator it = targets.iterator(); it.hasNext(); ) {
	       TargetContext t = (TargetContext)it.next();
	       t.setTargetDirectory(targetDirectory);
	    }

	    // Create temporary directory if necessary

	    if (xmlOnly) {

	       xmlTargetDirectory = targetDirectory;
	    }
	    else {

	       File workingTopDirectory = new File(workingPath);

	       workingDirectory = new File(workingTopDirectory, "gjdoc.tmp."+System.currentTimeMillis());
	    
	       if (!workingDirectory.mkdir()) {
		  printError("Cannot create temporary directory at "+System.getProperty("java.io.tmpdir"));
		  return false;
	       }

	       File xmlTempDirectory = new File(workingDirectory, "xmloutput");

	       if (!xmlTempDirectory.mkdir()) {
		  printError("Cannot create temporary directory for XML output at "+System.getProperty("java.io.tmpdir"));
		  return false;
	       }

	       xmlTargetDirectory = xmlTempDirectory;
	    }

            // Create target directory if necessary

            if (!targetDirectory.exists()) {
               printNotice("Creating destination directory: \""
                           + targetDirectory + "\"");
               if (!targetDirectory.mkdirs()) {
                  printError("Failed to create destination directory \""
                             + targetDirectory + "\"");
                  return false;
               }
            }

            // Check for deprecation

            boolean hasDeprecatedClasses = false;
            boolean hasDeprecatedInterfaces = false;
            boolean hasDeprecatedExceptions = false;
            boolean hasDeprecatedErrors = false;
            boolean hasDeprecatedMethods = false;
            boolean hasDeprecatedFields = false;

            {
               ClassDoc[] classes = rootDoc.classes();
               for (int i = 0, ilim = classes.length; i < ilim; ++ i) {
                  ClassDoc c = classes[i];
                  Tag[] deprecatedTags = c.tags("deprecated");
                  if (null != deprecatedTags && 0 != deprecatedTags.length) {
                     if (c.isInterface()) {
                        hasDeprecatedInterfaces = true;
                     }
                     else if (c.isException()) {
                        hasDeprecatedExceptions = true;
                     }
                     else if (c.isError()) {
                        hasDeprecatedErrors = true;
                     }
                     else /*if (c.isOrdinaryClass())*/ {
                        hasDeprecatedClasses = true;
                     }
                  }
                  
                  MethodDoc[] methods = c.methods();
                  for (int j = 0, jlim = methods.length; j < jlim; ++ j) {
                     MethodDoc m = methods[j];
                     deprecatedTags = m.tags("deprecated");
                     if (null != deprecatedTags && 0 != deprecatedTags.length) {
                        hasDeprecatedMethods = true;
                     }
                  }
                  
                  FieldDoc[] fields = c.fields();
                  for (int j = 0, jlim = fields.length; j < jlim; ++ j) {
                     FieldDoc f = fields[j];
                     deprecatedTags = f.tags("deprecated");
                     if (null != deprecatedTags && 0 != deprecatedTags.length) {
                        hasDeprecatedFields = true;
                     }
                  }
               }
            }

            htmlRepairer = new HtmlRepairer(rootDoc, noHTMLWarn, noEmailWarn,
                                            currentClass, currentMember,
                                            false);

            collectUsage();

            // Begin XML generation

	    printNotice("Writing XML Index file...");

	    // Assign output stream

	    setTargetFile("index.xml");

	    // Output XML document header

	    println(0, "<?xml version=\"1.0\"?>");
	    println("<!DOCTYPE gjdoc SYSTEM \"dtd/gjdoc.dtd\">");
	    println();
	    printOpenTag(0, "rootdoc xmlns=\"http://www.w3.org/TR/REC-html40\" xmlns:gjdoc=\"http://www.gnu.org/software/cp-tools/gjdocxml\"");

	    println();
	    println(1, "<!-- Tags from overview page, if available -->");

            if (rootDoc.firstSentenceTags().length > 0) {
               printOpenTag(2, "firstSentenceTags", false);
               outputTags(3, rootDoc.firstSentenceTags(), true, CONTEXT_PACKAGE);
               printCloseTag(0, "firstSentenceTags");
            }

            if (rootDoc.inlineTags().length > 0) {
               printOpenTag(2, "inlineTags");
               outputTags(3, rootDoc.inlineTags(), true, CONTEXT_PACKAGE);
               printCloseTag(2, "inlineTags");
            }
	 
	    if (null != bottomNote) {
	       printOpenTag(1, "bottomnote");
	       print(bottomNote);
	       printCloseTag(1, "bottomnote");
	    }

	    if (null != title) {
	       printOpenTag(1, "title");
	       println(2, title);
	       printCloseTag(1, "title");
	    }
	 
	    printOpenTag(1, "created");
	    println(2, DateFormat.getDateInstance(DateFormat.LONG, Locale.US).format(new java.util.Date()));
	    printCloseTag(1, "created");

            if (hasDeprecatedClasses) printAtomTag(1, "hasDeprecatedClasses");
            if (hasDeprecatedInterfaces) printAtomTag(1, "hasDeprecatedInterfaces");
            if (hasDeprecatedExceptions) printAtomTag(1, "hasDeprecatedExceptions");
            if (hasDeprecatedErrors) printAtomTag(1, "hasDeprecatedErrors");
            if (hasDeprecatedMethods) printAtomTag(1, "hasDeprecatedMethods");
            if (hasDeprecatedFields) printAtomTag(1, "hasDeprecatedFields");

	    // Output summary of all classes specified on command line

	    println();
	    println(1, "<!-- Classes specified by user on command line -->");
	    ClassDoc[] specifiedClasses = rootDoc.specifiedClasses();
	    for (int i=0, ilim=specifiedClasses.length; i<ilim; ++i) {
	       ClassDoc sc = specifiedClasses[i];
	       printAtomTag(1, "specifiedclass fqname=\""+sc.qualifiedName()+"\" name=\""+sc.name()+"\"");
	    }
	    specifiedClasses = null;

	    // Output summary of all packages specified on command line

	    println();
	    println(1, "<!-- Packages specified by user on command line -->");
	    PackageDoc[] specifiedPackages = rootDoc.specifiedPackages();
	    for (int i=0, ilim=specifiedPackages.length; i<ilim; ++i) {
	       PackageDoc sp = specifiedPackages[i];
	       printAtomTag(1, "specifiedpackage name=\""+sp.name()+"\"");
	    }
	    specifiedPackages = null;

	    // Output package group information specified on the
	    // command line

	    println();
	    println(1, "<!-- Package groups specified by user on command line -->");
            {
               Iterator packageGroupIt = packageGroups.iterator();
               while (packageGroupIt.hasNext()) {
                  PackageGroup packageGroup = (PackageGroup)packageGroupIt.next();
                  SortedSet groupedPackages = packageGroup.getPackages();
                  if (groupedPackages.isEmpty()) {
                     printWarning("Package group named '" 
                                  + packageGroup.getName() + "' didn't match any packages.");
                  }
                  else {
                     printOpenTag(1, "packagegroup name=\"" + packageGroup.getName() + "\"");
                     Iterator groupedPackageIt = groupedPackages.iterator();
                     while (groupedPackageIt.hasNext()) {
                        PackageDoc groupedPackageDoc = (PackageDoc)groupedPackageIt.next();
                        printAtomTag(2, "package name=\"" + groupedPackageDoc.name() + "\"");
                     }
                     printCloseTag(1, "packagegroup");
                  }
               }
               packageGroups = null;
            }

	    // Output information on all packages for which documentation
	    // has been made available via the Doclet API

	    println();
	    println(1, "<!-- Documentation for all packages -->");
	    PackageDoc[] packages = rootDoc.specifiedPackages();
	    for (int i=0, ilim=packages.length; i<ilim; ++i) {
	       PackageDoc c = packages[i];
	       outputPackageDoc(c);
	    }
	    packages = null;

	    // Output brief summary on all classes for which documentation
	    // has been made available via the Doclet API.
	    //
	    // While this is redundant, it can speed up XSLT
	    // processing by orders of magnitude

	    println();
	    println(1, "<!-- Brief summary for all classes -->");
	    ClassDoc[] sumclasses = rootDoc.classes();
	    for (int i=0, ilim=sumclasses.length; i<ilim; ++i) {
	       ClassDoc c = sumclasses[i];
	       outputClassDocSummary(c);
	    }
	    sumclasses = null;
	    
	    // Output closing tag, finish output stream

	    println();
	    printCloseTag(0, "rootdoc");

	    closeTargetFile();

            createIndexByName();



	    // Output information on all classes for which documentation
	    // has been made available via the Doclet API
	    
	    println();
	    println(1, "<!-- Documentation for all classes -->");
	    ClassDoc[] classes = rootDoc.classes();
            String prevPackageName = null;
	    for (int i = 0, ilim = classes.length; i < ilim; ++ i) {
	       ClassDoc c = classes[i];

               if (isVerbose()) {
                  printNotice("Writing XML information for "+c.qualifiedName()+"...");
               }
               else {
                  String packageName = c.containingPackage().name();
                  if (null == prevPackageName || !packageName.equals(prevPackageName)) {
                     printNotice("Writing XML information for "+packageName+"...");
                     prevPackageName = packageName;
                  }
               }
	       
	       setTargetFile(c.qualifiedName().replace('/','.')+".xml");
	       
	       println("<?xml version=\"1.0\"?>");
               println("<!DOCTYPE gjdoc SYSTEM \"dtd/gjdoc.dtd\">");
	       
	       outputClassDoc(c);
	       
	       closeTargetFile();
	    }
	    classes = null;
	 }
	 
         // Copy DTD files to temporary directory
         
         // FIXME: try to solve this via jar: URLs. but this will
         // probably break libxmlj compatibility (?)
         
         String[] resources = new String[] {
            "gjdoc.dtd",
            "gjdoc-alphaindex.dtd",
            "dbcentx.mod",
            "ent/iso-amsa.ent",
            "ent/iso-amsb.ent",
            "ent/iso-amsc.ent",
            "ent/iso-amsn.ent",
            "ent/iso-amso.ent",
            "ent/iso-amsr.ent",
            "ent/iso-box.ent",
            "ent/iso-cyr1.ent",
            "ent/iso-cyr2.ent",
            "ent/iso-dia.ent",
            "ent/iso-grk1.ent",
            "ent/iso-grk2.ent",
            "ent/iso-grk3.ent",
            "ent/iso-grk4.ent",
            "ent/iso-lat1.ent",
            "ent/iso-lat2.ent",
            "ent/iso-num.ent",
            "ent/iso-pub.ent",
            "ent/iso-tech.ent",
         };

         File tempDtdDirectory = new File(xmlTargetDirectory, "dtd");
         File tempDtdEntDirectory = new File(tempDtdDirectory, "ent");

         if ((tempDtdDirectory.exists() || tempDtdDirectory.mkdir())
             && (tempDtdEntDirectory.exists() || tempDtdEntDirectory.mkdir())) {
            for (int i = 0; i < resources.length; ++ i) {
               copyResourceToFile("/dtd/" + resources[i], 
                                  new File(tempDtdDirectory, resources[i]));
            }
         }
         else {
            printError("Cannot create temporary directories for DTD data at " + tempDtdDirectory);
            return false;
         }

         // Copy package data-dir directory

         {
            PackageDoc[] packages = rootDoc.specifiedPackages();
            for (int i=0, ilim=packages.length; i<ilim; ++i) {
               PackageDoc c = packages[i];
               if (c instanceof GjdocPackageDoc) {
                  copyPackageDataDir((GjdocPackageDoc)c);
               }
            }
         }

	 // All information has been output. Apply stylesheet if given.

	 gnu.classpath.tools.gjdoc.Main.releaseRootDoc();
         
	 this.currentClass = null;
	 this.currentMember = null;
	 this.currentExecMember = null;
	 
	 System.gc();	 

	 // From this point we are only operating on files, so we don't
	 // need this anymore and can free up some memory

         for (Iterator it = targets.iterator(); it.hasNext(); ) {

            TargetContext target = (TargetContext)it.next();

	    // We have XSLT postprocessing, run DocTranslet.

            //DocTranslet docTranslet = DocTranslet.fromClasspath("/doctranslets/html/gjdoc.xsl");
            
            //docTranslet.setOptions(docTransletOptions);

            target.getDocTranslet().setOptions(docTransletOptions);

            target.getDocTranslet().apply(xmlTargetDirectory, 
                                          target.getTargetDirectory(), 
                                          rootDoc);
	 }

	 // Done

	 targets = null;

	 System.gc();
         Runtime.getRuntime().runFinalization();

	 return true;
      }
      catch (Exception e) {

	 // Something went wrong. Report to stderr and pass error to
	 // Javadoc Reporter

	 e.printStackTrace();
	 printError(e.toString());

         Throwable rootCause = e.getCause();
         if (null != rootCause) {
            while (null != rootCause.getCause()) {
               rootCause = rootCause.getCause();
            }
            System.err.println("Root cause:");
            rootCause.printStackTrace();
         }

	 return false;
      }
      finally {

	 // In any case, delete the working directory if we created one

	 if (null != workingDirectory) {

	    if (!deleteRecursive(workingDirectory)) {
	       printWarning("Could not delete temporary directory at "+workingDirectory);
	    }
	 }

	 printNotice("Done.");
      }
   }

   /**
    * Recursively delete the specified directory and its contents,
    * like <code>rm -Rf directory</code>
    *
    * @return <code>true</code> on success
    */
   private static boolean deleteRecursive(File directory) {

      boolean success = true;

      File[] files = directory.listFiles();

      for (int i=0, ilim=files.length; i<ilim; ++i) {

	 File file = files[i];

	 if (file.isDirectory()) {

	    success = deleteRecursive(file) && success;
	 }
	 else {

	    success = file.delete() && success;
	 }
      }

      return directory.delete() && success;
   }

   /**
    *  Prints a string to stdout and appends a newline.  Convenience
    *  method.  
    */
   protected void println(String str) {
      out.println(str);
   }

   /**
    *  Prints a string to stdout without appending a newline.
    *  Convenience method.  
    */
   protected void print(String str) {
      out.print(str);
   }

   /**
    *  In standard mode, prints an empty line to stdout.
    *  In thight mode, nothing happens.
    *  Convenience method.  
    */
   protected void println() {
      if (!compress) {
	 out.println();
      }
   }

   /**
    *  In standard mode, prints the given text indented to stdout and appends newline. 
    *  In tight mode, doesn't print indentation or newlines.
    */
   protected void print(int indentLevel, String msg) {
      if (compress) {
	 out.print(msg);
      }
      else {
	 StringBuffer indentation = new StringBuffer();
	 for (int i=0; i<indentLevel*indentStep; ++i) {
	    indentation.append(' ');
	 }
	 out.print(indentation+msg);
      }
   }
   
   /**
    *  In tight mode, prints a message at a given indentation level.
    *  In standard mode, appends a newline in addition.
    */
   protected void println(int indentLevel, String msg) {
      print(indentLevel, msg);
      if (!compress) out.println();
   }

   /**
    *  Prints an atom tag at the given indentation level.
    */
   protected void printAtomTag(int level, String tag) {
      println(level, "<"+tagPrefix+":"+replaceCharsInTag(tag)+"/>");
   }

   /**
    *  Prints an open tag at the given indentation level.
    */
   protected void printOpenTag(int level, String tag) {
      printOpenTag(level, replaceCharsInTag(tag), true);
   }

   /**
    *  Prints an open tag at the given indentation level and
    *  conditionally appends a newline (if not in tight mode).
    */
   protected void printOpenTag(int level, String tag, boolean appendNewline) {
      if (appendNewline && !compress) {
	 println(level, "<"+tagPrefix+":"+replaceCharsInTag(tag)+">");
      }
      else {
	 print(level, "<"+tagPrefix+":"+replaceCharsInTag(tag)+">");
      }
   }

   /**
    *  Prints a close tag at the given indentation level.
    */
   protected void printCloseTag(int level, String tag) {
      printCloseTag(level, tag, true);
   }

   /**
    *  Prints a close tag at the given indentation level and
    *  conditionally appends a newline (if not in tight mode).
    */
   protected void printCloseTag(int level, String tag, boolean appendNewline) {
      if (appendNewline && !compress) {
	 println(level, "</"+tagPrefix+":"+replaceCharsInTag(tag)+">");
      }
      else {
	 print(level, "</"+tagPrefix+":"+replaceCharsInTag(tag)+">");
      }
   }

   public static int optionLength(String option) {
      if ("-d".equals(option)) return 2;
      else if ("-fixhtml".equals(option)) return 1;
      else if ("-compress".equals(option)) return 1;
      else if ("-nohtmlwarn".equals(option)) return 1;
      else if ("-noemailwarn".equals(option)) return 1;
      else if ("-indentstep".equals(option)) return 2;
      else if ("-xslsheet".equals(option)) return 2;
      else if ("-xsltdriver".equals(option)) return 2;
      else if ("-postprocess".equals(option)) return 2;
      else if ("-genhtml".equals(option)) return 1;
      else if ("-geninfo".equals(option)) return 1;
      else if ("-gendocbook".equals(option)) return 1;
      else if ("-xmlonly".equals(option)) return 1;
      else if ("-bottomnote".equals(option)) return 2;
      else if ("-workpath".equals(option)) return 2;
      else if ("-title".equals(option)) return 2;
      else if ("-tagletpath".equals(option)) return 2;
      else if ("-taglet".equals(option)) return 2;
      else if ("-authormail".equals(option)) return 2;
      else if ("-mailmangledot".equals(option)) return 2;
      else if ("-mailmangleat".equals(option)) return 2;
      else if ("-noindex".equals(option)) return 1;
      else if ("-nocomment".equals(option)) return 1;
      else if ("-notree".equals(option)) return 1;
      else if ("-nohelp".equals(option)) return 1;
      else if ("-nonavbar".equals(option)) return 1;
      else if ("-splitindex".equals(option)) return 1;
      else if ("-author".equals(option)) return 1;
      else if ("-version".equals(option)) return 1;
      else if ("-nosince".equals(option)) return 1;
      else if ("-nodeprecated".equals(option)) return 1;
      else if ("-linksource".equals(option)) return 1;
      else if ("-windowtitle".equals(option)) return 2;
      else if ("-helpfile".equals(option)) return 2;
      else if ("-stylesheetfile".equals(option)) return 2;
      else if ("-tag".equals(option)) return 2;
      else if ("-header".equals(option)) return 2;
      else if ("-footer".equals(option)) return 2;
      else if ("-bottom".equals(option)) return 2;
      else if ("-doctitle".equals(option)) return 2;
      else if ("-nodeprecatedlist".equals(option)) return 1;
      else if ("-uses".equals(option)) return 1;
      else if ("-group".equals(option)) return 3;

      else return -1;
   }

   public static boolean validOptions(String[][] options) {
      return true;
   }


   /**
    *  Workaround for non well-formed comments: fix tag contents
    *  by replacing <code>&lt;</code> with <code>&amp;lt;</code>,
    *  <code>&gt;</code> with <code>&amp;gt;</code> and
    *  <code>&amp;</code> with <code>&amp;amp;</code>.
    *
    *  @param tagContent  String to process
    *
    *  @return given String with all special characters replaced by 
    *          HTML entities.
    */
   private static String replaceCharsInTag(String tagContent) {
      return 
	 replaceString(
	    replaceString(
	       replaceString(
		  tagContent, 
		  "<", "&lt;"
		  ), 
	       ">", "&gt;"
	       ),
	    "&", "&amp;"
	    );
   }

   /**
    *  Replaces all occurences of string <code>needle</code> within string
    *  <code>haystack</code> by string <code>replacement</code>.
    *
    *  @param haystack    The string to search and replace in.
    *  @param needle      The string which is searched for.
    *  @param replacement The string by which every occurence of <code>needle</code> is replaced.
    */
   private static String replaceString(String haystack, String needle, String replacement) {
      int ndx = haystack.indexOf(needle);
      if (ndx<0)
	 return haystack;
      else
	 return haystack.substring(0, ndx) + replacement 
	    + replaceString(haystack.substring(ndx+needle.length()), needle, replacement);
   }

   protected void setTargetFile(String filename) throws IOException {

      OutputStream fileOut = new FileOutputStream(new File(xmlTargetDirectory, filename));
      out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(fileOut, "UTF8")));;
   }

   protected void closeTargetFile() {

      out.flush();
      out.close();
   }

   private String cdata(String str) {

      if (null==str) {
	 return str;
      } // end of if ((null==str)

      StringBuffer rc = new StringBuffer();
      for (int i=0; i<str.length(); ++i) {
	 char c = str.charAt(i);
	 if (c==0x09 || c==0x0a || c==0x0d || (c>=0x20 && c<=0xd7ff) || (c>=0xe000 && c<=0xfffd) || (c>=0x10000 && c<=0x10ffff)) {
	    rc.append(c);
	 }
	 else {
	    printWarning("Invalid Unicode character 0x"+Integer.toString(c, 16)+" in javadoc markup has been stripped.");
	 } // end of else
	 
      }
      return rc.toString();
   }

   static void copyResourceToFile(String resourceName, File target) throws IOException {
      
      InputStream in = Driver.class.getResourceAsStream(resourceName);

      if (null != in) {

	 FileOutputStream out = new FileOutputStream(target);
	 int size;
	 byte[] buffer = new byte[512];
	 while ((size = in.read(buffer)) >= 0) {
	    out.write(buffer, 0, size);
	 }
	 out.close();
      }
      else {

	 throw new IOException("Can't find resource named "+resourceName);
      }
   }

   private void printError(String error) {
      if (null != rootDoc) {
	 rootDoc.printError(error);
      }
      else {
	 System.err.println("ERROR: "+error);
      }
   }

   private void printWarning(String warning) {
      if (null != rootDoc) {
	 rootDoc.printWarning(warning);
      }
      else {
	 System.err.println("WARNING: "+warning);
      }
   }

   private void printNotice(String notice) {
      if (null != rootDoc) {
	 rootDoc.printNotice(notice);
      }
      else {
	 System.err.println(notice);
      }
   }

   /**
    *  Copy the contents of the input directory to the output
    *  directory. The output directory must exist.
    */
   private void copyPackageDataDir(GjdocPackageDoc packageDoc) throws IOException {
      File docFilesSourceDirectory
         = new File(packageDoc.packageDirectory(), "doc-files");
      File docFilesTargetDirectory
         = new File(this.targetDirectory, 
                    packageDoc.name().replace('.', File.separatorChar));
      if (docFilesSourceDirectory.exists()) {
         printNotice("Copying files from " + docFilesSourceDirectory);
         copyDirectory(docFilesSourceDirectory, docFilesTargetDirectory,
                       docFilesSubdirsEnabled,
                       excludeDocFilesSubDirs);
      }
   }

   /**
    *  Recursively copy the contents of the input directory to the
    *  output directory. The output directory must exist.
    */
   private static void copyDirectory(File sourceDir, File targetDir, 
                                     boolean recursive,
                                     Set excludeDirs) throws IOException {
      if (!targetDir.exists() && !targetDir.mkdirs()) {
         throw new IOException("Cannot create directory " + targetDir);
      }

      File[] sourceFiles = sourceDir.listFiles();
      for (int i=0; i<sourceFiles.length; ++i) {
         if (sourceFiles[i].isDirectory()) {
            if (recursive && (null == excludeDirs 
                              || !excludeDirs.contains(sourceFiles[i].getName()))) {
               File targetSubDir = new File(targetDir, 
                                            sourceFiles[i].getName());
               if (targetSubDir.exists() || targetSubDir.mkdir()) {
                  copyDirectory(sourceFiles[i], targetSubDir, recursive, null);
               }
               else {
                  throw new IOException("Cannot create directory " + targetSubDir);
               }
            }
         }
         else {
            copyFile(sourceFiles[i], new File(targetDir, sourceFiles[i].getName()));
         }
      }
   }

   /**
    *  Copy the contents of the input file to the output file. The
    *  output file's parent directory must exist.
    */
   private static void copyFile(File sourceFile, File targetFile) throws IOException {

      InputStream in = new FileInputStream(sourceFile);
      OutputStream out = new FileOutputStream(targetFile);
      int nread;
      byte[] buf = new byte[512];
      while ((nread = in.read(buf)) >= 0) {
         out.write(buf, 0, nread);
      }
      in.close();
      out.close();
   }

   private void createIndexByName() throws IOException {
      // Create index

      // Collect index
            
      Map indexMap = new TreeMap(new Comparator() {
            public int compare(Object o1, Object o2) {
               return o1.toString().toLowerCase().compareTo(o2.toString().toLowerCase());
            }
         });

      // Add packages to index

      PackageDoc[] packages = rootDoc.specifiedPackages();
      for (int i=0, ilim=packages.length; i<ilim; ++i) {
         PackageDoc c = packages[i];
         indexMap.put(c.name(), c);
      }

      // Add classes, fields and methods to index

      ClassDoc[] sumclasses = rootDoc.classes();
      for (int i=0, ilim=sumclasses.length; i<ilim; ++i) {
         ClassDoc c = sumclasses[i];
         if (null == c.containingClass()) {
            indexMap.put(c.name(), c);
         }
         else {
            indexMap.put(c.name().substring(c.containingClass().name().length() + 1), c);
         }
         FieldDoc[] fields = c.fields();
         for (int j=0, jlim=fields.length; j<jlim; ++j) {
            indexMap.put(fields[j].name(), fields[j]);
         }
         MethodDoc[] methods = c.methods();
         for (int j=0, jlim=methods.length; j<jlim; ++j) {
            MethodDoc method = methods[j];
            StringBuffer signature = new StringBuffer();
            signature.append(method.name());
            signature.append('(');
            Parameter[] parameters = method.parameters();
            for (int k=0, klim=parameters.length; k<klim; ++k) {
               if (k > 0) {
                  signature.append(", ");
               }
               signature.append(parameters[k].typeName());
            }
            signature.append(')');
            indexMap.put(signature.toString(), method);
         }
      }

      // Assign output stream

      setTargetFile("alphaindex.xml");

      // Output XML document header

      println(0, "<?xml version=\"1.0\"?>");
      println("<!DOCTYPE gjdoc SYSTEM \"dtd/gjdoc-alphaindex.dtd\">");
      println();
      printOpenTag(0, "alphaindex xmlns=\"http://www.w3.org/TR/REC-html40\" xmlns:gjdoc=\"http://www.gnu.org/software/cp-tools/gjdocxml\"");
      
      Iterator it = indexMap.keySet().iterator();

      char previousCategoryLetter = '\0';
      boolean categoryOpen = false;

      while (it.hasNext()) {
         String key = (String)it.next();
         Doc entry = (Doc)indexMap.get(key);

         char firstChar = Character.toUpperCase(key.charAt(0));
         if (firstChar != previousCategoryLetter) {
            if (categoryOpen) {
               printCloseTag(1, "category");
            }
            printOpenTag(1, "category letter=\"" + firstChar + "\"");
            categoryOpen = true;
            previousCategoryLetter = firstChar;
         }

         printOpenTag(2, "entry name=\"" + key + "\"");
         if (entry instanceof PackageDoc) {
            printAtomTag(3, "isPackage");
         }
         else if (entry instanceof ClassDoc) {
            printAtomTag(3, "isClass");
            ClassDoc centry = (ClassDoc)entry;
            currentClass = centry;
            printAtomTag(3, "containingPackage name=\"" + centry.containingPackage().name() + "\"");
            if (null != centry.containingClass()) {
               printAtomTag(3, "containingClass name=\"" + centry.containingClass().name() + "\"");
            }
            if (centry.isInterface()) {
               printAtomTag(3, "isInterface");
            }
            if (centry.isException()) {
               printAtomTag(3, "isException");
            }
            if (centry.isError()) {
               printAtomTag(3, "isError");
            }
            if (centry.isOrdinaryClass()) {
               printAtomTag(3, "isOrdinaryClass");
            }
         }
         else if (entry instanceof ProgramElementDoc) {
            ProgramElementDoc pentry = (ProgramElementDoc)entry;
            currentClass = pentry.containingClass();
            printAtomTag(3, "containingPackage name=\"" + pentry.containingPackage().name() + "\"");
            printAtomTag(3, "containingClass name=\"" + pentry.containingClass().name() + "\"");
            if (pentry.isMethod()) {
               printAtomTag(3, "isMethod");
               ExecutableMemberDoc mentry = (ExecutableMemberDoc)pentry;
               printAtomTag(3, "signature full=\""+mentry.signature()+"\" flat=\""+mentry.flatSignature()+"\"");
               printAtomTag(3, "method name=\"" + mentry.name() + "\"");
            }
            if (pentry.isField()) {
               printAtomTag(3, "isField");
            }
         }

         Tag[] tags = entry.firstSentenceTags();
         for (int i=0, ilim=tags.length; i<ilim; ++i) {
            Tag tag = tags[i];
            if (tag.firstSentenceTags().length>0) {
               printOpenTag(3, "firstSentenceTags", false);
               outputTags(4, tag.firstSentenceTags(), false, CONTEXT_TYPE);
               printCloseTag(3, "firstSentenceTags");
            }
         }


         printCloseTag(2, "entry");
      }

      if (categoryOpen) {
         printCloseTag(1, "category");
      }

      printCloseTag(0, "alphaindex");

      closeTargetFile();
   }

   private static class UsageType
   {
      public static final UsageType CLASS_DERIVED_FROM = new UsageType("class-derived-from");
      public static final UsageType FIELD_OF_TYPE = new UsageType("field-of-type");
      public static final UsageType METHOD_WITH_RETURN_TYPE = new UsageType("method-with-return-type");
      public static final UsageType METHOD_WITH_PARAMETER_TYPE = new UsageType("method-with-parameter-type");
      public static final UsageType METHOD_WITH_THROWN_TYPE = new UsageType("method-with-thrown-type");
      public static final UsageType CONSTRUCTOR_WITH_PARAMETER_TYPE = new UsageType("constructor-with-parameter-type");
      public static final UsageType CONSTRUCTOR_WITH_THROWN_TYPE = new UsageType("constructor-with-thrown-type");
      private String id;

      private UsageType(String id)
      {
         this.id = id;
      }

      public String toString() { 
         return "UsageType{id=" + id + "}"; 
      }

      public String getId() {
         return id;
      }
   }

   /**
    *  ClassDoc -> (PackageDoc -> (UsageType -> (Set of Doc)))
    */
   private Map usedClassToPackagesMap = new HashMap();

   private void addUsedBy(ClassDoc usedClass, UsageType usageType, Doc user, PackageDoc userPackage)
   {
      Map packageToUsageTypeMap = (Map)usedClassToPackagesMap.get(usedClass);
      if (null == packageToUsageTypeMap) {
         packageToUsageTypeMap = new HashMap();
         usedClassToPackagesMap.put(usedClass, packageToUsageTypeMap);
      }

      Map usageTypeToUsersMap = (Map)packageToUsageTypeMap.get(userPackage);
      if (null == usageTypeToUsersMap) {
         usageTypeToUsersMap = new HashMap();
         packageToUsageTypeMap.put(userPackage, usageTypeToUsersMap);
      }

      Set userSet = (Set)usageTypeToUsersMap.get(usageType);
      if (null == userSet) {
         userSet = new TreeSet(); // FIXME: we need the collator from Main here
         usageTypeToUsersMap.put(usageType, userSet);
      }
      userSet.add(user);
   }

   /**
    *  Create the cross reference database.
    */
   private void collectUsage() {

      ClassDoc[] classes = rootDoc.classes();
      for (int i = 0, ilim = classes.length; i < ilim; ++ i) {
         ClassDoc clazz = classes[i];

         // classes derived from
         for (ClassDoc superclass = clazz.superclass(); superclass != null; 
              superclass = superclass.superclass()) {
            addUsedBy(superclass, UsageType.CLASS_DERIVED_FROM, clazz, clazz.containingPackage());
         }

         FieldDoc[] fields = clazz.fields();
         for (int j = 0, jlim = fields.length; j < jlim; ++ j) {
            FieldDoc field = fields[j];

            // fields of type                  
            ClassDoc fieldType = field.type().asClassDoc();
            if (null != fieldType) {
               addUsedBy(fieldType, UsageType.FIELD_OF_TYPE, 
                         field, clazz.containingPackage());
            }
         }

         MethodDoc[] methods = clazz.methods();
         for (int j = 0, jlim = methods.length; j < jlim; ++ j) {
            MethodDoc method = methods[j];

            // methods with return type

            ClassDoc returnType = method.returnType().asClassDoc();
            if (null != returnType) {
               addUsedBy(returnType, UsageType.METHOD_WITH_RETURN_TYPE, 
                         method, clazz.containingPackage());
            }
            Parameter[] parameters = method.parameters();
            for (int k=0; k<parameters.length; ++k) {

               // methods with parameter type

               Parameter parameter = parameters[k];
               ClassDoc parameterType = parameter.type().asClassDoc();
               if (null != parameterType) {
                  addUsedBy(parameterType, UsageType.METHOD_WITH_PARAMETER_TYPE, 
                            method, clazz.containingPackage());
               }
            }

            // methods which throw

            ClassDoc[] thrownExceptions = method.thrownExceptions();
            for (int k = 0, klim = thrownExceptions.length; k < klim; ++ k) {
               ClassDoc thrownException = thrownExceptions[k];
               addUsedBy(thrownException, UsageType.METHOD_WITH_THROWN_TYPE, 
                         method, clazz.containingPackage());
            }
         }
                  
         ConstructorDoc[] constructors = clazz.constructors();
         for (int j = 0, jlim = constructors.length; j < jlim; ++ j) {

            ConstructorDoc constructor = constructors[j];

            Parameter[] parameters = constructor.parameters();
            for (int k = 0, klim = parameters.length; k < klim; ++ k) {

               // constructors with parameter type
                     
               Parameter parameter = parameters[k];
               ClassDoc parameterType = parameter.type().asClassDoc();
               if (null != parameterType) {
                  addUsedBy(parameterType, UsageType.CONSTRUCTOR_WITH_PARAMETER_TYPE, 
                            constructor, clazz.containingPackage());
               }
            }

            // constructors which throw

            ClassDoc[] thrownExceptions = constructor.thrownExceptions();
            for (int k = 0, klim = thrownExceptions.length; k < klim; ++ k) {
               ClassDoc thrownException = thrownExceptions[k];
               addUsedBy(thrownException, UsageType.CONSTRUCTOR_WITH_THROWN_TYPE, 
                         constructor, clazz.containingPackage());
            }
         }
      }
   }

   private void outputUsage(ClassDoc clazz, int level) {

      Map packageToUsageTypeMap = (Map)usedClassToPackagesMap.get(clazz);
      if (null != packageToUsageTypeMap) {
         printOpenTag(level, "references");

         Iterator packagesIterator = packageToUsageTypeMap.keySet().iterator();

         while (packagesIterator.hasNext()) {
            PackageDoc packageDoc = (PackageDoc)packagesIterator.next();
            printOpenTag(level + 1, "referencing-package name=\"" + packageDoc.name() + "\"");
            Map usageTypeToUsersMap = (Map)packageToUsageTypeMap.get(packageDoc);
            Iterator usageTypeIterator = usageTypeToUsersMap.keySet().iterator();
            while (usageTypeIterator.hasNext()) {
               UsageType usageType = (UsageType)usageTypeIterator.next();
               printOpenTag(level + 2, "usage-type id=\"" + usageType.getId() + "\"");
               Set users = (Set)usageTypeToUsersMap.get(usageType);
               Iterator userIterator = users.iterator();
               while (userIterator.hasNext()) {
                  Doc user = (Doc)userIterator.next();
                  if (user instanceof ClassDoc) {
                     printAtomTag(level + 3, "user"
                                  + " class=\"" + ((ClassDoc)user).name() + "\"");
                  }
                  else if (user instanceof FieldDoc) {
                     FieldDoc fieldDoc = (FieldDoc)user;
                     printAtomTag(level + 3, "user"
                                  + " class=\"" + fieldDoc.containingClass().name() + "\""
                                  + " field=\"" + fieldDoc.name() + "\"");
                  }
                  else if (user instanceof MethodDoc) {
                     MethodDoc methodDoc = (MethodDoc)user;
                     printAtomTag(level + 3, "user"
                                  + " class=\"" + methodDoc.containingClass().name() + "\""
                                  + " method=\"" + methodDoc.name() + "\""
                                  + " signature=\"" + methodDoc.signature() + "\""
                                  + " flatSignature=\"" + methodDoc.flatSignature() + "\"");
                  }
                  else if (user instanceof ConstructorDoc) {
                     ConstructorDoc constructorDoc = (ConstructorDoc)user;
                     printAtomTag(level + 3, "user"
                                  + " class=\"" + constructorDoc.containingClass().name() + "\""
                                  + " signature=\"" + constructorDoc.signature() + "\""
                                  + " flatSignature=\"" + constructorDoc.flatSignature() + "\"");
                  }
               }
               printCloseTag(level +2, "usage-type");
            }
            printCloseTag(level + 1, "referencing-package");
         }

         printCloseTag(level, "references");
      }
   }

   private boolean processGroupOption(String groupName, String colonSeparatedPackageList)
   {
      try {
         PackageMatcher packageMatcher = new PackageMatcher();

         StringTokenizer tokenizer = new StringTokenizer(colonSeparatedPackageList, ":");
         while (tokenizer.hasMoreTokens()) {
            String packageWildcard = tokenizer.nextToken();
            packageMatcher.addWildcard(packageWildcard);
         }

         SortedSet groupPackages = packageMatcher.filter(rootDoc.specifiedPackages());

         packageGroups.add(new PackageGroup(groupName, groupPackages));

         return true;
      }
      catch (InvalidPackageWildcardException e) {
         return false;
      }
   }

   private void registerTaglet(Taglet taglet)
   {
      tagletMap.put(taglet.getName(), taglet);
   }

   private boolean isVerbose()
   {
      return false;
   }
}
