/**
*******************************************************************************
* Copyright (C) 2004-2005, 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
 *
 * todo: separate generation of data files (which requires taglet) from 
 * comparison and report generation (which does not require it)
 * todo: provide command-line control of filters of which subclasses/packages to process
 * todo: record full inheritance heirarchy, not just immediate inheritance 
 * todo: allow for aliasing comparisons (force (pkg.)*class to be treated as though it 
 * were in a different pkg/class heirarchy (facilitates comparison of icu4j and java)
 */

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 = "ICU4J API Comparison: " + srcName + " with " + compareName;

                    bw.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
                    bw.newLine();
                    bw.write("<html>");
                    bw.newLine();
                    bw.write("<head>");
                    bw.newLine();
                    bw.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">");
                    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;
    }
}
