/*
 * Copyright 2006 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.doctool;

import com.google.doctool.LinkResolver.ExtraClassResolver;

import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.ConstructorDoc;
import com.sun.javadoc.Doc;
import com.sun.javadoc.DocErrorReporter;
import com.sun.javadoc.ExecutableMemberDoc;
import com.sun.javadoc.FieldDoc;
import com.sun.javadoc.MemberDoc;
import com.sun.javadoc.MethodDoc;
import com.sun.javadoc.PackageDoc;
import com.sun.javadoc.ParamTag;
import com.sun.javadoc.Parameter;
import com.sun.javadoc.ProgramElementDoc;
import com.sun.javadoc.RootDoc;
import com.sun.javadoc.SeeTag;
import com.sun.javadoc.SourcePosition;
import com.sun.javadoc.Tag;
import com.sun.javadoc.Type;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Stack;

/**
 * Generates XML from Javadoc source, with particular idioms to make it possible
 * to translate into either expository doc or API doc.
 */
public class Booklet {

  private static final String OPT_BKCODE = "-bkcode";
  private static final String OPT_BKDOCPKG = "-bkdocpkg";
  private static final String OPT_BKOUT = "-bkout";

  private static Booklet sBooklet;

  public static void main(String[] args) {
    // Strip off our arguments at the beginning.
    //
    com.sun.tools.javadoc.Main.execute(args);
  }

  public static int optionLength(String option) {
    if (option.equals(OPT_BKOUT)) {
      return 2;
    } else if (option.equals(OPT_BKDOCPKG)) {
      return 2;
    } else if (option.equals(OPT_BKCODE)) {
      return 1;
    }
    return 0;
  }

  public static String slurpSource(SourcePosition position) {
    FileReader fr = null;
    try {
      fr = new FileReader(position.file());
      BufferedReader br = new BufferedReader(fr);
      for (int i = 0, n = position.line() - 1; i < n; ++i) {
        br.readLine();
      }

      StringBuffer lines = new StringBuffer();
      String line = br.readLine();
      int braceDepth = 0;
      int indent = -1;
      boolean seenSemiColonOrBrace = false;
      while (line != null) {
        if (indent == -1) {
          for (indent = 0; Character.isWhitespace(line.charAt(indent)); ++indent) {
            // just accumulate
          }
        }

        if (line.length() >= indent) {
          line = line.substring(indent);
        }

        lines.append(line + "\n");
        for (int i = 0, n = line.length(); i < n; ++i) {
          char c = line.charAt(i);
          if (c == '{') {
            seenSemiColonOrBrace = true;
            ++braceDepth;
          } else if (c == '}') {
            --braceDepth;
          } else if (c == ';') {
            seenSemiColonOrBrace = true;
          }
        }

        if (braceDepth > 0 || !seenSemiColonOrBrace) {
          line = br.readLine();
        } else {
          break;
        }
      }

      String code = lines.toString();
      return code;
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        if (fr != null) {
          fr.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return "";
  }

  public static boolean start(RootDoc rootDoc) {
    getBooklet().process(rootDoc);
    return true;
  }

  public static boolean validOptions(String[][] options,
      DocErrorReporter reporter) {
    return getBooklet().analyzeOptions(options, reporter);
  }

  private static Booklet getBooklet() {
    if (sBooklet == null) {
      sBooklet = new Booklet();
    }
    return sBooklet;
  }

  private String outputPath;

  private HashSet packagesToGenerate;

  private RootDoc initialRootDoc;

  private String rootDocId;

  private boolean showCode;

  private HashSet standardTagKinds = new HashSet();

  private Stack tagStack = new Stack();

  private PrintWriter pw;

  public Booklet() {
    // Set up standard tags (to ignore during tag processing)
    //
    standardTagKinds.add("@see");
    standardTagKinds.add("@serial");
    standardTagKinds.add("@throws");
    standardTagKinds.add("@param");
    standardTagKinds.add("@id");
  }

  private boolean analyzeOptions(String[][] options, DocErrorReporter reporter) {
    for (int i = 0, n = options.length; i < n; ++i) {
      if (options[i][0].equals(OPT_BKOUT)) {
        outputPath = options[i][1];
      } else if (options[i][0].equals(OPT_BKDOCPKG)) {
        String[] packages = options[i][1].split(";");
        packagesToGenerate = new HashSet();
        for (int packageIndex = 0; packageIndex < packages.length; ++packageIndex) {
          packagesToGenerate.add(packages[packageIndex]);
        }
      } else if (options[i][0].equals(OPT_BKCODE)) {
        showCode = true;
      }
    }

    if (outputPath == null) {
      reporter.printError("You must specify an output directory with "
          + OPT_BKOUT);
      return false;
    }

    return true;
  }

  private void begin(String tag) {
    pw.print("<" + tag + ">");
    tagStack.push(tag);
  }

  private void begin(String tag, String attr, String value) {
    pw.print("<" + tag + " " + attr + "='" + value + "'>");
    tagStack.push(tag);
  }

  private void beginCDATA() {
    pw.print("<![CDATA[");
  }

  private void beginEndln(String tag) {
    pw.println("<" + tag + "/>");
  }

  private void beginln(String tag) {
    pw.println();
    begin(tag);
  }

  private void beginln(String tag, String attr, String value) {
    pw.println();
    begin(tag, attr, value);
  }

  private void emitDescription(ClassDoc enclosing, Doc forWhat,
      Tag[] leadInline, Tag[] descInline) {
    emitJRELink(enclosing, forWhat);

    beginln("lead");
    processTags(leadInline);
    endln();

    beginln("description");
    processTags(descInline);
    endln();
  }

  private void emitIdentity(String id, String name) {
    beginln("id");
    text(id);
    endln();

    beginln("name");
    text(name);
    endln();
  }

  private void emitJRELink(ClassDoc enclosing, Doc doc) {
    String jreLink = "http://java.sun.com/j2se/1.5.0/docs/api/";
    if (doc instanceof ClassDoc) {
      ClassDoc classDoc = (ClassDoc) doc;
      String pkg = classDoc.containingPackage().name();
      if (!pkg.startsWith("java.")) {
        return;
      }
      String clazz = classDoc.name();

      jreLink += pkg.replace('.', '/') + "/";
      jreLink += clazz;
      jreLink += ".html";
    } else if (doc instanceof ExecutableMemberDoc) {
      ExecutableMemberDoc execMemberDoc = (ExecutableMemberDoc) doc;
      String pkg = enclosing.containingPackage().name();
      if (!pkg.startsWith("java.")) {
        return;
      }
      String clazz = enclosing.name();
      String method = execMemberDoc.name();
      String sig = execMemberDoc.signature();

      jreLink += pkg.replace('.', '/') + "/";
      jreLink += clazz;
      jreLink += ".html";
      jreLink += "#";
      jreLink += method;
      jreLink += sig;
    } else if (doc instanceof PackageDoc) {
      String pkg = doc.name();
      if (!pkg.startsWith("java.")) {
        return;
      }
      jreLink += pkg.replace('.', '/') + "/package-summary.html";
    } else if (doc instanceof FieldDoc) {
      FieldDoc fieldDoc = (FieldDoc) doc;
      String pkg = enclosing.containingPackage().name();
      if (!pkg.startsWith("java.")) {
        return;
      }
      String clazz = fieldDoc.containingClass().name();
      String field = fieldDoc.name();

      jreLink += pkg.replace('.', '/') + "/";
      jreLink += clazz;
      jreLink += ".html";
      jreLink += "#";
      jreLink += field;
    }

    // Add the link.
    //
    beginln("jre");
    text(jreLink);
    endln();
  }

  private void emitLocation(Doc doc) {
    Doc parent = getParentDoc(doc);
    if (parent != null) {
      beginln("location");
      emitLocationLink(parent);
      endln();
    }
  }

  private void emitLocationLink(Doc doc) {
    // Intentionally reverses the order.
    //
    String myId;
    String myTitle;
    if (doc instanceof MemberDoc) {
      MemberDoc memberDoc = (MemberDoc) doc;
      myId = getId(memberDoc);
      myTitle = memberDoc.name();
    } else if (doc instanceof ClassDoc) {
      ClassDoc classDoc = (ClassDoc) doc;
      myId = getId(classDoc);
      myTitle = classDoc.name();
    } else if (doc instanceof PackageDoc) {
      PackageDoc pkgDoc = (PackageDoc) doc;
      myId = getId(pkgDoc);
      myTitle = pkgDoc.name();
    } else if (doc instanceof RootDoc) {
      myId = rootDocId;
      myTitle = initialRootDoc.name();
    } else {
      throw new IllegalStateException(
          "Expected only a member, type, or package");
    }

    Doc parent = getParentDoc(doc);
    if (parent != null) {
      emitLocationLink(parent);
    }

    beginln("link", "ref", myId);

    Tag[] titleTag = doc.tags("@title");
    if (titleTag.length > 0) {
      myTitle = titleTag[0].text().trim();
    }

    if (myTitle == null || myTitle.length() == 0) {
      myTitle = "[NO TITLE]";
    }

    text(myTitle);

    endln();
  }

  private void emitModifiers(ProgramElementDoc doc) {
    if (doc.isPrivate()) {
      beginEndln("isPrivate");
    } else if (doc.isProtected()) {
      beginEndln("isProtected");
    } else if (doc.isPublic()) {
      beginEndln("isPublic");
    } else if (doc.isPackagePrivate()) {
      beginEndln("isPackagePrivate");
    }

    if (doc.isStatic()) {
      beginEndln("isStatic");
    }

    if (doc.isFinal()) {
      beginEndln("isFinal");
    }

    if (doc instanceof MethodDoc) {
      MethodDoc methodDoc = (MethodDoc) doc;

      if (methodDoc.isAbstract()) {
        beginEndln("isAbstract");
      }

      if (methodDoc.isSynchronized()) {
        beginEndln("isSynchronized");
      }
    }
  }

  private void emitOutOfLineTags(Tag[] tags) {
    beginln("tags");
    processTags(tags);
    endln();
  }

  private void emitType(Type type) {
    ClassDoc typeAsClass = type.asClassDoc();

    if (typeAsClass != null) {
      begin("type", "ref", getId(typeAsClass));
    } else {
      begin("type");
    }

    String typeName = type.typeName();
    String dims = type.dimension();

    text(typeName + dims);

    end();
  }

  private void end() {
    pw.print("</" + tagStack.pop() + ">");
  }

  private void endCDATA() {
    pw.print("]]>");
  }

  private void endln() {
    end();
    pw.println();
  }

  private MethodDoc findMatchingInterfaceMethodDoc(ClassDoc[] interfaces,
      MethodDoc methodDoc) {
    if (interfaces != null) {
      // Look through the methods on superInterface for a matching methodDoc.
      //
      for (int intfIndex = 0; intfIndex < interfaces.length; ++intfIndex) {
        ClassDoc currentIntfDoc = interfaces[intfIndex];
        MethodDoc[] intfMethodDocs = currentIntfDoc.methods();
        for (int methodIndex = 0; methodIndex < intfMethodDocs.length; ++methodIndex) {
          MethodDoc intfMethodDoc = intfMethodDocs[methodIndex];
          String methodDocName = methodDoc.name();
          String intfMethodDocName = intfMethodDoc.name();
          if (methodDocName.equals(intfMethodDocName)) {
            if (methodDoc.signature().equals(intfMethodDoc.signature())) {
              // It's a match!
              //
              return intfMethodDoc;
            }
          }
        }

        // Try the superinterfaces of this interface.
        //
        MethodDoc foundMethodDoc = findMatchingInterfaceMethodDoc(
            currentIntfDoc.interfaces(), methodDoc);
        if (foundMethodDoc != null) {
          return foundMethodDoc;
        }
      }
    }

    // Just didn't find it anywhere. Must not be based on an implemented
    // interface.
    //
    return null;
  }

  private ExtraClassResolver getExtraClassResolver(Tag tag) {

    if (tag.holder() instanceof PackageDoc) {
      return new ExtraClassResolver() {
        public ClassDoc findClass(String className) {
          return initialRootDoc.classNamed(className);
        }
      };
    }

    return null;
  }

  private String getId(ClassDoc classDoc) {
    return classDoc.qualifiedName();
  }

  private String getId(ExecutableMemberDoc memberDoc) {
    // Use the mangled name to look up a unique id (based on its hashCode).
    //
    String clazz = memberDoc.containingClass().qualifiedName();
    String id = clazz + "#" + memberDoc.name() + memberDoc.signature();
    return id;
  }

  private String getId(FieldDoc fieldDoc) {
    String clazz = fieldDoc.containingClass().qualifiedName();
    String id = clazz + "#" + fieldDoc.name();
    return id;
  }

  private String getId(MemberDoc memberDoc) {
    if (memberDoc.isMethod()) {
      return getId((MethodDoc) memberDoc);
    } else if (memberDoc.isConstructor()) {
      return getId((ConstructorDoc) memberDoc);
    } else if (memberDoc.isField()) {
      return getId((FieldDoc) memberDoc);
    } else {
      throw new RuntimeException("Unknown member type");
    }
  }

  private String getId(PackageDoc packageDoc) {
    return packageDoc.name();
  }

  private Doc getParentDoc(Doc doc) {
    if (doc instanceof MemberDoc) {
      MemberDoc memberDoc = (MemberDoc) doc;
      return memberDoc.containingClass();
    } else if (doc instanceof ClassDoc) {
      ClassDoc classDoc = (ClassDoc) doc;
      Doc enclosingClass = classDoc.containingClass();
      if (enclosingClass != null) {
        return enclosingClass;
      } else {
        return classDoc.containingPackage();
      }
    } else if (doc instanceof PackageDoc) {
      return initialRootDoc;
    } else if (doc instanceof RootDoc) {
      return null;
    } else {
      throw new IllegalStateException(
          "Expected only a member, type, or package");
    }
  }

  private boolean looksSynthesized(ExecutableMemberDoc memberDoc) {
    SourcePosition memberPos = memberDoc.position();
    int memberLine = memberPos.line();

    SourcePosition classPos = memberDoc.containingClass().position();
    int classLine = classPos.line();

    if (memberLine == classLine) {
      return true;
    } else {
      return false;
    }
  }

  private void process(ClassDoc enclosing, ClassDoc classDoc) {
    // Make sure it isn't a @skip-ped topic.
    //
    if (classDoc.tags("@skip").length > 0) {
      // This one is explicitly skipped right now.
      //
      return;
    }

    if (classDoc.isInterface()) {
      beginln("interface");
    } else {
      beginln("class");
    }

    emitIdentity(getId(classDoc), classDoc.name());
    emitLocation(classDoc);
    emitDescription(enclosing, classDoc, classDoc.firstSentenceTags(),
        classDoc.inlineTags());
    emitOutOfLineTags(classDoc.tags());
    emitModifiers(classDoc);

    ClassDoc superclassDoc = classDoc.superclass();
    if (superclassDoc != null) {
      beginln("superclass", "ref", getId(superclassDoc));
      text(superclassDoc.name());
      endln();
    }

    ClassDoc[] superinterfacesDoc = classDoc.interfaces();
    for (int i = 0; i < superinterfacesDoc.length; i++) {
      ClassDoc superinterfaceDoc = superinterfacesDoc[i];
      beginln("superinterface", "ref", getId(superinterfaceDoc));
      text(superinterfaceDoc.name());
      endln();
    }

    ClassDoc[] cda = classDoc.innerClasses();
    for (int i = 0; i < cda.length; i++) {
      process(classDoc, cda[i]);
    }

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

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

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

    endln();
  }

  private void process(ClassDoc enclosing, ExecutableMemberDoc memberDoc) {
    if (looksSynthesized(memberDoc)) {
      // Skip it.
      //
      return;
    }

    // Make sure it isn't a @skip-ped member.
    //
    if (memberDoc.tags("@skip").length > 0) {
      // This one is explicitly skipped right now.
      //
      return;
    }

    if (memberDoc instanceof MethodDoc) {
      beginln("method");
      emitIdentity(getId(memberDoc), memberDoc.name());
      emitLocation(memberDoc);

      // If this method is not explicitly documented, use the best inherited
      // one.
      //
      String rawComment = memberDoc.getRawCommentText();
      if (rawComment.length() == 0) {
        // Switch out the member doc being used.
        //
        MethodDoc methodDoc = (MethodDoc) memberDoc;
        MethodDoc superMethodDoc = methodDoc.overriddenMethod();

        if (superMethodDoc == null) {

          ClassDoc classDocToTry = methodDoc.containingClass();
          while (classDocToTry != null) {
            // See if this is a method from an interface.
            // If so, borrow its description.
            //
            superMethodDoc = findMatchingInterfaceMethodDoc(
                classDocToTry.interfaces(), methodDoc);

            if (superMethodDoc != null) {
              break;
            }

            classDocToTry = classDocToTry.superclass();
          }
        }

        if (superMethodDoc != null) {
          // Borrow the description from the superclass/superinterface.
          //
          memberDoc = superMethodDoc;
        }
      }
    } else if (memberDoc instanceof ConstructorDoc) {
      beginln("constructor");
      emitIdentity(getId(memberDoc), memberDoc.containingClass().name());
      emitLocation(memberDoc);
    } else {
      throw new IllegalStateException("What kind of executable member is this?");
    }

    emitDescription(enclosing, memberDoc, memberDoc.firstSentenceTags(),
        memberDoc.inlineTags());
    emitOutOfLineTags(memberDoc.tags());
    emitModifiers(memberDoc);

    begin("flatSignature");
    text(memberDoc.flatSignature());
    end();

    // Return type if it's a method
    //
    if (memberDoc instanceof MethodDoc) {
      emitType(((MethodDoc) memberDoc).returnType());
    }

    // Parameters
    //
    beginln("params");
    Parameter[] pda = memberDoc.parameters();
    for (int i = 0; i < pda.length; i++) {
      Parameter pd = pda[i];

      begin("param");
      emitType(pd.type());
      begin("name");
      text(pd.name());
      end();
      end();
    }
    endln();

    // Exceptions thrown
    //
    ClassDoc[] tea = memberDoc.thrownExceptions();
    if (tea.length > 0) {
      beginln("throws");
      for (int i = 0; i < tea.length; ++i) {
        ClassDoc te = tea[i];
        beginln("throw", "ref", getId(te));
        text(te.name());
        endln();
      }
      endln();
    }

    // Maybe show code
    //
    if (showCode) {
      SourcePosition pos = memberDoc.position();
      if (pos != null) {
        beginln("code");
        String source = slurpSource(pos);
        begin("pre", "class", "code");
        beginCDATA();
        text(source);
        endCDATA();
        endln();
        endln();
      }
    }

    endln();
  }

  private void process(ClassDoc enclosing, FieldDoc fieldDoc) {
    // Make sure it isn't @skip-ped.
    //
    if (fieldDoc.tags("@skip").length > 0) {
      // This one is explicitly skipped right now.
      //
      return;
    }

    String commentText = fieldDoc.commentText();
    if (fieldDoc.isPrivate()
        && (commentText == null || commentText.length() == 0)) {
      return;
    }

    beginln("field");
    emitIdentity(fieldDoc.qualifiedName(), fieldDoc.name());
    emitLocation(fieldDoc);
    emitDescription(enclosing, fieldDoc, fieldDoc.firstSentenceTags(),
        fieldDoc.inlineTags());
    emitOutOfLineTags(fieldDoc.tags());
    emitModifiers(fieldDoc);
    emitType(fieldDoc.type());
    endln();
  }

  private void process(PackageDoc packageDoc) {
    beginln("package");

    emitIdentity(packageDoc.name(), packageDoc.name());
    emitLocation(packageDoc);
    emitDescription(null, packageDoc, packageDoc.firstSentenceTags(),
        packageDoc.inlineTags());
    emitOutOfLineTags(packageDoc.tags());

    // Top-level classes
    //
    ClassDoc[] cda = packageDoc.allClasses();
    for (int i = 0; i < cda.length; i++) {
      ClassDoc cd = cda[i];

      // Make sure we have source.
      //
      SourcePosition p = cd.position();
      if (p == null || p.line() == 0) {
        // Skip this since it isn't ours (otherwise we would have source).
        //
        continue;
      }

      if (cd.containingClass() == null) {
        process(cd, cda[i]);
      } else {
        // Not a top-level class.
        //
        cd = cda[i];
      }
    }

    endln();
  }

  private void process(RootDoc rootDoc) {
    try {
      initialRootDoc = rootDoc;
      File outputFile = new File(outputPath);
      outputFile.getParentFile().mkdirs();
      FileWriter fw = new FileWriter(outputFile);
      pw = new PrintWriter(fw, true);

      beginln("booklet");

      rootDocId = "";
      String title = "";
      Tag[] idTags = rootDoc.tags("@id");
      if (idTags.length > 0) {
        rootDocId = idTags[0].text();
      } else {
        initialRootDoc.printWarning("Expecting @id in an overview html doc; see -overview");
      }

      Tag[] titleTags = rootDoc.tags("@title");
      if (titleTags.length > 0) {
        title = titleTags[0].text();
      } else {
        initialRootDoc.printWarning("Expecting @title in an overview html doc; see -overview");
      }

      emitIdentity(rootDocId, title);
      emitLocation(rootDoc);
      emitDescription(null, rootDoc, rootDoc.firstSentenceTags(),
          rootDoc.inlineTags());
      emitOutOfLineTags(rootDoc.tags());

      // Create a list of the packages to iterate over.
      //
      HashSet packageNames = new HashSet();
      ClassDoc[] cda = initialRootDoc.classes();
      for (int i = 0; i < cda.length; i++) {
        ClassDoc cd = cda[i];
        // Only top-level classes matter.
        //
        if (cd.containingClass() == null) {
          packageNames.add(cd.containingPackage().name());
        }
      }

      // Packages
      //
      for (Iterator iter = packageNames.iterator(); iter.hasNext();) {
        String packageName = (String) iter.next();

        // Only process this package if either no "docpkg" is set, or it is
        // included.
        //
        if (packagesToGenerate == null
            || packagesToGenerate.contains(packageName)) {
          PackageDoc pd = initialRootDoc.packageNamed(packageName);
          process(pd);
        }
      }

      endln();
    } catch (Exception e) {
      e.printStackTrace();
      initialRootDoc.printError("Caught exception: " + e.toString());
    }
  }

  private void processSeeTag(SeeTag seeTag) {
    String ref = null;
    ClassDoc cd = null;
    PackageDoc pd = null;
    MemberDoc md = null;
    String title = null;

    // Check for HTML links
    if (seeTag.text().startsWith("<")) {
      // TODO: ignore for now
      return;
    }
    // Ordered: most-specific to least-specific
    if (null != (md = seeTag.referencedMember())) {
      ref = getId(md);
    } else if (null != (cd = seeTag.referencedClass())) {
      ref = getId(cd);

      // See if the target has a title.
      //
      Tag[] titleTag = cd.tags("@title");
      if (titleTag.length > 0) {
        title = titleTag[0].text().trim();
        if (title.length() == 0) {
          title = null;
        }
      }
    } else if (null != (pd = seeTag.referencedPackage())) {
      ref = getId(pd);
    }

    String label = seeTag.label();

    // If there is a label, use it.
    if (label == null || label.trim().length() == 0) {

      // If there isn't a label, see if the @see target has a @title.
      //
      if (title != null) {
        label = title;
      } else {
        label = seeTag.text();

        if (label.endsWith(".")) {
          label = label.substring(0, label.length() - 1);
        }

        // Rip off all but the last interesting part to prevent fully-qualified
        // names everywhere.
        //
        int last1 = label.lastIndexOf('.');
        int last2 = label.lastIndexOf('#');

        if (last2 > last1) {
          // Use the class name plus the member name.
          //
          label = label.substring(last1 + 1).replace('#', '.');
        } else if (last1 != -1) {
          label = label.substring(last1 + 1);
        }

        if (label.charAt(0) == '.') {
          // Started with "#" so remove the dot.
          //
          label = label.substring(1);
        }
      }
    }

    if (ref != null) {
      begin("link", "ref", ref);
      text(label != null ? label.trim() : "");
      end();
    } else {
      initialRootDoc.printWarning(seeTag.position(),
          "Unverifiable cross-reference to '" + seeTag.text() + "'");
      // The link probably won't work, but emit it anyway.
      begin("link");
      text(label != null ? label.trim() : "");
      end();
    }
  }

  private void processTags(Tag[] tags) {
    for (int i = 0; i < tags.length; i++) {
      Tag tag = tags[i];
      String tagKind = tag.kind();
      if (tagKind.equals("Text")) {
        text(tag.text());
      } else if (tagKind.equals("@see")) {
        processSeeTag((SeeTag) tag);
      } else if (tagKind.equals("@param")) {
        ParamTag paramTag = (ParamTag) tag;
        beginln("param");
        begin("name");
        text(paramTag.parameterName());
        end();
        begin("description");
        processTags(paramTag.inlineTags());
        end();
        endln();
      } else if (tagKind.equals("@example")) {
        ExtraClassResolver extraClassResolver = getExtraClassResolver(tag);
        SourcePosition pos = LinkResolver.resolveLink(tag, extraClassResolver);
        String source = slurpSource(pos);
        begin("pre", "class", "code");
        beginCDATA();
        text(source);
        endCDATA();
        endln();
      } else if (tagKind.equals("@gwt.include")) {
        String contents = ResourceIncluder.getResourceFromClasspathScrubbedForHTML(tag);
        begin("pre", "class", "code");
        text(contents);
        endln();
      } else if (!standardTagKinds.contains(tag.name())) {
        // Custom tag; pass it along other tag.
        //
        String tagName = tag.name().substring(1);
        begin(tagName);
        processTags(tag.inlineTags());
        end();
      }
    }
  }

  private void text(String s) {
    pw.print(s);
  }
}
