/**
*******************************************************************************
* Copyright (C) 2004, International Business Machines Corporation and         *
* others. All Rights Reserved.                                                *
*******************************************************************************
*/

/**
 * Generate a list of ICU's public APIs, sorted by qualified name and signature
 * public APIs are all non-internal, non-package apis in com.ibm.icu.[lang|math|text|util].
 * For each API, list
 * - public, package, protected, or private (PB PK PT PR)
 * - static or non-static (STK NST)
 * - final or non-final (FN NF)
 * - synchronized or non-synchronized (SYN NSY)
 * - stable, draft, deprecated, obsolete (ST DR DP OB)
 * - abstract or non-abstract (AB NA)
 * - constructor, member, field (C M F)
 *
 * Requires JDK 1.4.2 or later
 * 
 * Sample invocation:
 * c:/j2sdk1.4.2/bin/javadoc 
 *   -classpath c:/jd2sk1.4.2/lib/tools.jar 
 *   -doclet com.ibm.icu.dev.tool.docs.CheckAPI 
 *   -docletpath c:/doug/cvsproj/icu4j/src 
 *   -sourcepath c:/eclipse2.1/workspace2/icu4j/src 
 *   -compare c:/doug/cvsproj/icu4j/src/com/ibm/icu/dev/tool/docs/api2_6_1.txt 
 *   -output foo 
 *   com.ibm.icu.text
 */

package com.ibm.icu.dev.tool.docs;

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

public class CheckAPI {
    RootDoc root;
    String compare; // file
    String compareName;
    TreeSet compareSet;
    TreeSet results;
    boolean html;
    String srcName = "Current"; // default source name
    String output;
    
    private static final int DATA_FILE_VERSION = 1;
    private static final char SEP = ';';

    private static final int STA = 0, STA_DRAFT = 0, STA_STABLE = 1, STA_DEPRECATED = 2, STA_OBSOLETE = 3;
    private static final int VIS = 1, VIS_PACKAGE = 0, VIS_PUBLIC= 1, VIS_PROTECTED = 2, VIS_PRIVATE = 3;
    private static final int STK = 2, STK_STATIC = 1;
    private static final int FIN = 3, FIN_FINAL = 1;
    private static final int SYN = 4, SYN_SYNCHRONIZED = 1;
    private static final int ABS = 5, ABS_ABSTRACT = 1;
    private static final int CAT = 6, CAT_CLASS = 0, CAT_FIELD = 1, CAT_CONSTRUCTOR = 2, CAT_METHOD = 3;
    private static final int PAK = 7;
    private static final int CLS = 8;
    private static final int NAM = 9;
    private static final int SIG = 10;
    private static final int EXC = 11;
    private static final int NUM_TYPES = 11;

    static abstract class APIInfo {
	public abstract int getVal(int typ);
	public abstract String get(int typ, boolean brief);
	public abstract void write(BufferedWriter w, boolean brief, boolean html, boolean detail);
    }
	
    final static class Info extends APIInfo {
	private int    info;
	private String pack; // package
	private String cls; // enclosing class
	private String name; // name
	private String sig;  // signature, class: inheritance, method: signature, field: type, const: signature
	private String exc;  // throws 
	
	public int getVal(int typ) {
	    validateType(typ);
	    return (info >> (typ*2)) & 0x3;
	}

	public String get(int typ, boolean brief) {
	    validateType(typ);
	    String[] vals = brief ? shortNames[typ] : names[typ];
	    if (vals == null) {
		switch (typ) {
		case PAK: return pack;
		case CLS: return cls;
		case NAM: return name;
		case SIG: return sig;
		case EXC: return exc;
		}
	    }
	    int val = (info >> (typ*2)) & 0x3;
	    return vals[val];
	}

	private void setType(int typ, int val) {
	    validateType(typ);
	    info &= ~(0x3 << (typ*2));
	    info |= (val&0x3) << (typ * 2);
	}

	private void setType(int typ, String val) {
	    validateType(typ);
	    String[] vals = shortNames[typ];
	    if (vals == null) {
		switch (typ) {
		case PAK: pack = val; break;
		case CLS: cls = val; break;
		case NAM: name = val; break;
		case SIG: sig = val; break;
		case EXC: exc = val; break;
		}
		return;
	    }

	    for (int i = 0; i < vals.length; ++i) {
		if (val.equalsIgnoreCase(vals[i])) {
		    info &= ~(0x3 << (typ*2));
		    info |= i << (typ*2);
		    return;
		}
	    }

	    throw new IllegalArgumentException("unrecognized value '" + val + "' for type '" + typeNames[typ] + "'");
	}

	public void write(BufferedWriter w, boolean brief, boolean html, boolean detail) {
	    try {
		if (brief) {
		    for (int i = 0; i < NUM_TYPES; ++i) {
			String s = get(i, true);
			if (s != null) {
			    w.write(s);
			}
			w.write(SEP);
		    }
		} else {
		    // remove all occurrences of icu packages from the param string
		    // fortunately, all the packages have 4 chars (lang, math, text, util).
		    String xsig = sig;
		    if (!detail) {
			final String ICUPACK = "com.ibm.icu.";
			StringBuffer buf = new StringBuffer();
			for (int i = 0; i < sig.length();) {
			    int n = sig.indexOf(ICUPACK, i);
			    if (n == -1) {
				buf.append(sig.substring(i));
				break;
			    }
			    buf.append(sig.substring(i, n));
			    i = n + ICUPACK.length() + 5; // trailing 'xxxx.'
			}
			xsig = buf.toString();
		    }

		    // construct signature
		    for (int i = STA; i < CAT; ++i) { // include status
			String s = get(i, false);
			if (s != null && s.length() > 0) {
			    if (i == STA) {
				w.write('(');
				w.write(s);
				w.write(')');
			    } else {
				w.write(s);
			    }
			    w.write(' ');
			}
		    }

		    int val = getVal(CAT);
		    switch (val) {
		    case CAT_CLASS:
			if (sig.indexOf("extends") == -1) {
			    w.write("interface ");
			} else {
			    w.write("class ");
			}
			if (cls.length() > 0) {
			    w.write(cls);
			    w.write('.');
			}
			w.write(name);
			if (detail) {
			    w.write(' ');
			    w.write(sig);
			}
			break;

		    case CAT_FIELD:
			w.write(xsig);
			w.write(' ');
			w.write(name);
			break;

		    case CAT_METHOD:
		    case CAT_CONSTRUCTOR:
			int n = xsig.indexOf('(');
			if (n > 0) {
			    w.write(xsig.substring(0, n));
			    w.write(' ');
			} else {
			    n = 0;
			}
			w.write(name);
			w.write(xsig.substring(n));
			break;
		    }
		}
		w.newLine();
	    }
	    catch (IOException e) {
		RuntimeException re = new RuntimeException("IO Error");
		re.initCause(e);
		throw re;
	    }
	}

	public boolean read(BufferedReader r) {
	    int i = 0;
	    try {
		for (; i < NUM_TYPES; ++i) {
		    setType(i, readToken(r));
		}
		r.readLine(); // swallow line end sequence
	    }
	    catch (IOException e) {
		if (i == 0) { // assume if first read returns error, we have reached end of input
		    return false;
		}
		RuntimeException re = new RuntimeException("IO Error");
		re.initCause(e);
		throw re;
	    }

	    return true;
	}

	public boolean read(ProgramElementDoc doc) {

	    // Doc. name
	    // Doc. isField, isMethod, isConstructor, isClass, isInterface
	    // ProgramElementDoc. containingClass, containingPackage
	    // ProgramElementDoc. isPublic, isProtected, isPrivate, isPackagePrivate
	    // ProgramElementDoc. isStatic, isFinal
	    // MemberDoc.isSynthetic
	    // ExecutableMemberDoc isSynchronized, signature
	    // Type.toString() // e.g. "String[][]"
	    // ClassDoc.isAbstract, superClass, interfaces, fields, methods, constructors, innerClasses
	    // FieldDoc type
	    // ConstructorDoc qualifiedName
	    // MethodDoc isAbstract, returnType

	    
	    // status
	    setType(STA, tagStatus(doc));

	    // visibility
	    if (doc.isPublic()) {
		setType(VIS, VIS_PUBLIC);
	    } else if (doc.isProtected()) {
		setType(VIS, VIS_PROTECTED);
	    } else if (doc.isPrivate()) {
		setType(VIS, VIS_PRIVATE);
	    } else {
		// default is package
	    }

	    // static
	    if (doc.isStatic()) {
		setType(STK, STK_STATIC);
	    } else {
		// default is non-static
	    }

	    // final
	    if (doc.isFinal()) {
		setType(FIN, FIN_FINAL);
	    } else {
		// default is non-final
	    }

	    // type
	    if (doc.isField()) {
		setType(CAT, CAT_FIELD);
	    } else if (doc.isMethod()) {
		setType(CAT, CAT_METHOD);
	    } else if (doc.isConstructor()) {
		setType(CAT, CAT_CONSTRUCTOR);
	    } else if (doc.isClass() || doc.isInterface()) {
		setType(CAT, CAT_CLASS);
	    }

	    setType(PAK, doc.containingPackage().name());
	    setType(CLS, (doc.isClass() || doc.isInterface() || (doc.containingClass() == null)) ? "" : doc.containingClass().name());
	    setType(NAM, doc.name());

	    if (doc instanceof FieldDoc) {
		FieldDoc fdoc = (FieldDoc)doc;
		setType(SIG, fdoc.type().toString());
	    } else if (doc instanceof ClassDoc) {
		ClassDoc cdoc = (ClassDoc)doc;

		if (cdoc.isClass() && cdoc.isAbstract()) { // interfaces are abstract by default, don't mark them as abstract
		    setType(ABS, ABS_ABSTRACT);
		}

		StringBuffer buf = new StringBuffer();
		if (cdoc.isClass()) {
		    buf.append("extends ");
		    buf.append(cdoc.superclass().qualifiedName());
		}
		ClassDoc[] imp = cdoc.interfaces();
		if (imp != null && imp.length > 0) {
		    if (buf.length() > 0) {
			buf.append(" ");
		    }
		    buf.append("implements");
		    for (int i = 0; i < imp.length; ++i) {
			if (i != 0) {
			    buf.append(",");
			}
			buf.append(" ");
			buf.append(imp[i].qualifiedName());
		    }
		}
		setType(SIG, buf.toString());
	    } else {
		ExecutableMemberDoc emdoc = (ExecutableMemberDoc)doc;
		if (emdoc.isSynchronized()) {
		    setType(SYN, SYN_SYNCHRONIZED);
		}

		if (doc instanceof MethodDoc) {
		    MethodDoc mdoc = (MethodDoc)doc;
		    if (mdoc.isAbstract()) {
			setType(ABS, ABS_ABSTRACT);
		    }
		    setType(SIG, mdoc.returnType().toString() + emdoc.signature());
		} else {
		    // constructor
		    setType(SIG, emdoc.signature());
		}
	    }

	    return true;
	}

	public static Comparator defaultComparator() {
	    final Comparator c = new Comparator() {
		    public int compare(Object lhs, Object rhs) {
			Info lhi = (Info)lhs;
			Info rhi = (Info)rhs;
			int result = lhi.pack.compareTo(rhi.pack);
			if (result == 0) {
			    result = (lhi.getVal(CAT) == CAT_CLASS ? lhi.name : lhi.cls)
				.compareTo(rhi.getVal(CAT) == CAT_CLASS ? rhi.name : rhi.cls);
			    if (result == 0) {
				result = lhi.getVal(CAT)- rhi.getVal(CAT);
				if (result == 0) {
				    result = lhi.name.compareTo(rhi.name);
				    if (result == 0) {
					result = lhi.sig.compareTo(rhi.sig);
				    }
				}
			    }
			}
			return result;
		    }
		};
	    return c;
	}

	public static Comparator changedComparator() {
	    final Comparator c = new Comparator() {
		    public int compare(Object lhs, Object rhs) {
			Info lhi = (Info)lhs;
			Info rhi = (Info)rhs;
			int result = lhi.pack.compareTo(rhi.pack);
			if (result == 0) {
			    result = (lhi.getVal(CAT) == CAT_CLASS ? lhi.name : lhi.cls)
				.compareTo(rhi.getVal(CAT) == CAT_CLASS ? rhi.name : rhi.cls);
			    if (result == 0) {
				result = lhi.getVal(CAT)- rhi.getVal(CAT);
				if (result == 0) {
				    result = lhi.name.compareTo(rhi.name);
				    if (result == 0 && lhi.getVal(CAT) != CAT_CLASS) {
					result = lhi.sig.compareTo(rhi.sig);
				    }
				}
			    }
			}
			return result;
		    }
		};
	    return c;
	}

	public static Comparator classFirstComparator() {
	    final Comparator c = new Comparator() {
		    public int compare(Object lhs, Object rhs) {
			Info lhi = (Info)lhs;
			Info rhi = (Info)rhs;
			int result = lhi.pack.compareTo(rhi.pack);
			if (result == 0) {
			    boolean lcls = lhi.getVal(CAT) == CAT_CLASS;
			    boolean rcls = rhi.getVal(CAT) == CAT_CLASS;
			    result = lcls == rcls ? 0 : (lcls ? -1 : 1);
			    if (result == 0) {
				result = (lcls ? lhi.name : lhi.cls).compareTo(rcls ? rhi.name : rhi.cls);
				if (result == 0) {
				    result = lhi.getVal(CAT)- rhi.getVal(CAT);
				    if (result == 0) {
					result = lhi.name.compareTo(rhi.name);
					if (result == 0 && !lcls) {
					    result = lhi.sig.compareTo(rhi.sig);
					}
				    }
				}
			    }
			}
			return result;
		    }
		};
	    return c;
	}

	private static final String[] typeNames = {
	    "status", "visibility", "static", "final", "synchronized", 
	    "abstract", "category", "package", "class", "name", "signature"
	};

	private static final String[][] names = {
	    { "draft     ", "stable    ", "deprecated", "obsolete  " },
	    { "package", "public", "protected", "private" },
	    { "", "static" },
	    { "", "final" },
	    { "", "synchronized" },
	    { "", "abstract" },
	    { "class", "field", "constructor", "method"  },
	    null,
	    null,
	    null,
	    null,
	    null
	};

	private static final String[][] shortNames = {
	    { "DR", "ST", "DP", "OB" },
	    { "PK", "PB", "PT", "PR" },
	    { "NS", "ST" },
	    { "NF", "FN" },
	    { "NS", "SY" },
	    { "NA", "AB" },
	    { "L", "F", "C", "M" },
	    null,
	    null,
	    null,
	    null,
	    null
	};

	private static void validateType(int typ) {
	    if (typ < 0 || typ > NUM_TYPES) {
		throw new IllegalArgumentException("bad type index: " + typ);
	    }
	}

	public String toString() {
	    return get(NAM, true);
	}
    }

    static final class DeltaInfo extends APIInfo {
	private Info a;
	private Info b;

	DeltaInfo(Info a, Info b) {
	    this.a = a;
	    this.b = b;
	}

	public int getVal(int typ) {
	    return a.getVal(typ);
	}

	public String get(int typ, boolean brief) {
	    return a.get(typ, brief);
	}

	public void write(BufferedWriter w, boolean brief, boolean html, boolean detail) {
	    a.write(w, brief, html, detail);
	    try {
		if (html) {
		    w.write("<br>");
		}
		w.newLine();
	    } 
	    catch (Exception e) {
	    }
	    b.write(w, brief, html, detail);
	}

	public String toString() {
	    return a.get(NAM, true);
	}
    }

    public static int optionLength(String option) {
        if (option.equals("-html")) {
            return 1;
	} else if (option.equals("-name")) {
	    return 2;
	} else if (option.equals("-output")) {
	    return 2;
        } else if (option.equals("-compare")) {
            return 2;
        }
	return 0;
    }

    public static boolean start(RootDoc root) {
        return new CheckAPI(root).run();
    }

    CheckAPI(RootDoc root) {
        this.root = root;

	//	this.compare = "c:/doug/cvsproj/icu4j/src/com/ibm/icu/dev/tool/docs/api2_8.txt";

        String[][] options = root.options();
        for (int i = 0; i < options.length; ++i) {
            String opt = options[i][0];
            if (opt.equals("-html")) {
                this.html = true;
            } else if (opt.equals("-name")) {
		this.srcName = options[i][1];
            } else if (opt.equals("-output")) {
		this.output = options[i][1];
	    } else if (opt.equals("-compare")) {
                this.compare = options[i][1];
	    }
	}

	if (compare != null) {
	    try {
		// URL url = new URL(compare);
		File f = new File(compare);
		InputStream is = new FileInputStream(f);
		InputStreamReader isr = new InputStreamReader(is);
		BufferedReader br = new BufferedReader(isr);

		// read header line
		int version = Integer.parseInt(readToken(br));
		// check version if we change it later, probably can just rebuild though
		this.compareName = readToken(br);
		br.readLine();

		// read data
		this.compareSet = new TreeSet(Info.defaultComparator());
		for (Info info = new Info(); info.read(br); info = new Info()) {
		    compareSet.add(info);
		}
	    }
	    catch (Exception e) {
		RuntimeException re = new RuntimeException("error reading " + compare);
		re.initCause(e);
		throw re;
	    }
	}
	    
	results = new TreeSet(Info.defaultComparator());
    }

    private boolean run() {
        doDocs(root.classes());

	OutputStream os = System.out;
	if (output != null) {
	    try {
		os = new FileOutputStream(output);
	    }
	    catch (FileNotFoundException e) {
		RuntimeException re = new RuntimeException(e.getMessage());
		re.initCause(e);
		throw re;
	    }
	}

	BufferedWriter bw = null;
	try {
	    OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
	    bw = new BufferedWriter(osw);

	    if (compareSet == null) {
		// writing data file
		bw.write(String.valueOf(DATA_FILE_VERSION) + SEP); // header version
		bw.write(srcName + SEP); // source name
		bw.newLine();
		writeResults(results, bw, true, false, false);
	    } else {
		// writing comparison info
		TreeSet removed = (TreeSet)compareSet.clone();
		removed.removeAll(results);

		TreeSet added = (TreeSet)results.clone();
		added.removeAll(compareSet);

		Iterator ai = added.iterator();
		Iterator ri = removed.iterator();
		ArrayList changed = new ArrayList();
		Comparator c = Info.changedComparator();
		Info a = null, r = null;
		while (ai.hasNext() && ri.hasNext()) {
		    if (a == null) a = (Info)ai.next();
		    if (r == null) r = (Info)ri.next();
		    int result = c.compare(a, r);
		    if (result < 0) {
			a = null;
		    } else if (result > 0) {
			r = null;
		    } else {
			changed.add(new DeltaInfo(a, r));
			a = null; ai.remove();
			r = null; ri.remove();
		    }
		}

		added = stripAndResort(added);
		removed = stripAndResort(removed);

		if (html) {
		    String title = "API Comparison: " + srcName + " with " + compareName;

		    bw.write("<html>");
		    bw.newLine();
		    bw.write("<head>");
		    bw.newLine();
		    bw.write("<title>");
		    bw.write(title);
		    bw.write("</title>");
		    bw.newLine();
		    bw.write("<body>");
		    bw.newLine();

		    bw.write("<h1>");
		    bw.write(title);
		    bw.write("</h1>");
		    bw.newLine();

		    bw.write("<hr/>");
		    bw.newLine();
		    bw.write("<h2>");
		    bw.write("Removed from " + compareName);
		    bw.write("</h2>");
		    bw.newLine();

		    if (removed.size() > 0) {
			writeResults(removed, bw, false, true, false);
		    } else {
			bw.write("<p>(no API removed)</p>");
		    }
		    bw.newLine();

		    bw.write("<hr/>");
		    bw.newLine();
		    bw.write("<h2>");
		    bw.write("Changed in " + srcName);
		    bw.write("</h2>");
		    bw.newLine();

		    if (changed.size() > 0) {
			writeResults(changed, bw, false, true, true);
		    } else {
			bw.write("<p>(no API changed)</p>");
		    }
		    bw.newLine();

		    bw.write("<hr/>");
		    bw.newLine();
		    bw.write("<h2>");
		    bw.write("Added in " + srcName);
		    bw.write("</h2>");
		    bw.newLine();

		    if (added.size() > 0) {
			writeResults(added, bw, false, true, false);
		    } else {
			bw.write("<p>(no API added)</p>");
		    }
		    bw.write("<hr/>");
		    bw.newLine();
		    bw.write("<p><i>Contents generated by CheckAPI tool.<br/>Copyright (C) 2004, International Business Machines Corporation, All Rights Reserved.</i></p>");
		    bw.newLine();
		    bw.write("</body>");
		    bw.newLine();
		    bw.write("</html>");
		    bw.newLine();
		} else {
		    bw.write("Comparing " + srcName + " with " + compareName);
		    bw.newLine();
		    bw.newLine();

		    bw.newLine();
		    bw.write("=== Removed from " + compareName + " ===");
		    bw.newLine();
		    if (removed.size() > 0) {
			writeResults(removed, bw, false, false, false);
		    } else {
			bw.write("(no API removed)");
		    }
		    bw.newLine();

		    bw.newLine();
		    bw.write("=== Changed in " + srcName + " ===");
		    bw.newLine();
		    if (changed.size() > 0) {
			writeResults(changed, bw, false, false, true);
		    } else {
			bw.write("(no API changed)");
		    }
		    bw.newLine();

		    bw.newLine();
		    bw.write("=== Added in " + srcName + " ===");
		    bw.newLine();
		    if (added.size() > 0) {
			writeResults(added, bw, false, false, false);
		    } else {
			bw.write("(no API added)");
		    }
		    bw.newLine();
		}
	    }

	    bw.close();
	} catch (IOException e) {
	    try { bw.close(); } catch (IOException e2) {}
	    RuntimeException re = new RuntimeException("write error: " + e.getMessage());
	    re.initCause(e);
	    throw re;
	}

        return false;
    }

    private void doDocs(ProgramElementDoc[] docs) {
        if (docs != null && docs.length > 0) {
            for (int i = 0; i < docs.length; ++i) {
		doDoc(docs[i]);
            }
        }
    }

    private void doDoc(ProgramElementDoc doc) {
	if (ignore(doc)) return;

	if (doc.isClass() || doc.isInterface()) {
	    ClassDoc cdoc = (ClassDoc)doc;
	    doDocs(cdoc.fields());
	    doDocs(cdoc.constructors());
	    doDocs(cdoc.methods());
	    doDocs(cdoc.innerClasses());
	}

	Info info = new Info();
	if (info.read(doc)) {
	    results.add(info);
	}
    }

    private boolean ignore(ProgramElementDoc doc) {
	if (doc == null) return true;
	if (doc.isPrivate() || doc.isPackagePrivate()) return true;
	if (doc instanceof ConstructorDoc && ((ConstructorDoc)doc).isSynthetic()) return true;
	if (doc.qualifiedName().indexOf(".misc") != -1) return true;
        Tag[] tags = doc.tags();
        for (int i = 0; i < tags.length; ++i) {
	    if (tagKindIndex(tags[i].kind()) == INTERNAL) return true;
	}

	return false;
    }

    private static void writeResults(Collection c, BufferedWriter w, boolean brief, boolean html, boolean detail) {
	Iterator iter = c.iterator();
	String pack = null;
	String clas = null;
	while (iter.hasNext()) {
	    APIInfo info = (APIInfo)iter.next();
	    if (brief) {
		info.write(w, brief, false, detail);
	    } else {
		try {
		    String p = info.get(PAK, true);
		    if (!p.equals(pack)) {
			w.newLine();
			if (html) {
			    if (clas != null) {
				w.write("</ul>");
				w.newLine();
			    }
			    if (pack != null) {
				w.write("</ul>");
				w.newLine();
			    }
			    
			    w.write("<h3>Package ");
			    w.write(p);
			    w.write("</h3>");
			    w.newLine();
			    w.write("<ul>");
			    w.newLine();
			} else {
			    w.write("Package ");
			    w.write(p);
			    w.write(':');
			}
			w.newLine();
			w.newLine();
			
			pack = p;
			clas = null;
		    }

		    if (info.getVal(CAT) != CAT_CLASS) {
			String name = info.get(CLS, true);
			if (!name.equals(clas)) {
			    if (html) {
				if (clas != null) {
				    w.write("</ul>");
				}
				w.write("<li>");
				w.write(name);
				w.newLine();
				w.write("<ul>");
			    } else {
				w.write(name);
				w.newLine();
			    }
			    clas = name;
			}
			w.write("    ");
		    }
		    if (html) {
			w.write("<li>");
			info.write(w, brief, html, detail);
			w.write("</li>");
		    } else {
			info.write(w, brief, html, detail);
		    }
		}
		catch (IOException e) {
		    System.err.println("IOException " + e.getMessage() + " writing " + info);
		}
	    }
	}
	if (html) {
	    try {
		if (clas != null) {
		    w.write("</ul>");
		    w.newLine();
		}
		if (pack != null) {
		    w.write("</ul>");
		    w.newLine();
		}
	    } 
	    catch (IOException e) {
	    }
	}
    }

    private static String readToken(BufferedReader r) throws IOException {
	char[] buf = new char[256];
	int i = 0;
	for (; i < buf.length; ++i) {
	    int c = r.read();
	    if (c == -1) {
		throw new IOException("unexpected EOF");
	    } else if (c == SEP) {
		break;
	    }
	    buf[i] = (char)c;
	}
	if (i == buf.length) {
	    throw new IOException("unterminated token" + new String(buf));
	}
	    
	return new String(buf, 0, i);
    }

    private static TreeSet stripAndResort(TreeSet t) {
	stripClassInfo(t);
	TreeSet r = new TreeSet(Info.classFirstComparator());
	r.addAll(t);
	return r;
    }
	private static void stripClassInfo(Collection c) {
	    // c is sorted with class info first
	    Iterator iter = c.iterator();
	    String cname = null;
	    while (iter.hasNext()) {
		Info info = (Info)iter.next();
		String cls = info.get(CLS, true);
		if (cname != null) {
		    if (cname.equals(cls)) {
			iter.remove();
			continue;
		    }
		    cname = null;
		} 
		if (info.getVal(CAT) == CAT_CLASS) {
		    cname = info.get(NAM, true);
		}
	    }
	}

	private static int tagStatus(final Doc doc) {
	    class Result {
		int res = -1;
		void set(int val) { if (res != -1) throw new RuntimeException("bad doc: " + doc); res = val; }
		int get() {
		    if (res == -1) {
			System.err.println("warning: no tag for " + doc);
			return 0;
		    }
		    return res;
		}
	    };

	    Tag[] tags = doc.tags();
	    Result result = new Result();
	    for (int i = 0; i < tags.length; ++i) {
		Tag tag = tags[i];

		String kind = tag.kind();
		int ix = tagKindIndex(kind);

		switch (ix) {
		case INTERNAL:
		    result.set(-2);
		    break;

		case DRAFT:
		    result.set(STA_DRAFT);
		    break;

		case STABLE:
		    result.set(STA_STABLE);
		    break;

		case DEPRECATED:
		    result.set(STA_DEPRECATED);
		    break;

		case OBSOLETE:
		    result.set(STA_OBSOLETE);
		    break;

		case SINCE:
		case EXCEPTION:
		case VERSION:
		case UNKNOWN:
		case AUTHOR:
		case SEE:
		case PARAM:
		case RETURN:
		case THROWS:
		case SERIAL:
		    break;

		default:
		    throw new RuntimeException("unknown index " + ix + " for tag: " + kind);
		}
	    }

	    return result.get();
	}

    private static final int UNKNOWN = -1;
    private static final int INTERNAL = 0;
    private static final int DRAFT = 1;
    private static final int STABLE = 2;
    private static final int SINCE = 3;
    private static final int DEPRECATED = 4;
    private static final int AUTHOR = 5;
    private static final int SEE = 6;
    private static final int VERSION = 7;
    private static final int PARAM = 8;
    private static final int RETURN = 9;
    private static final int THROWS = 10;
    private static final int OBSOLETE = 11;
    private static final int EXCEPTION = 12;
    private static final int SERIAL = 13;

    private static int tagKindIndex(String kind) {
	final String[] tagKinds = {
	    "@internal", "@draft", "@stable", "@since", "@deprecated", "@author", "@see", "@version",
	    "@param", "@return", "@throws", "@obsolete", "@exception", "@serial"
	};

        for (int i = 0; i < tagKinds.length; ++i) {
            if (kind.equals(tagKinds[i])) {
                return i;
            }
        }
        return UNKNOWN;
    }
}
