/**
*******************************************************************************
* 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
 *
 * 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;
    }
}
