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

import com.sun.javadoc.*;
import com.sun.tools.doclets.*;
import org.clearsilver.HDF;
import org.clearsilver.CS;
import java.util.*;
import java.io.*;

public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Scoped
{
    public static final Comparator<ClassInfo> comparator = new Comparator<ClassInfo>() {
        public int compare(ClassInfo a, ClassInfo b) {
            return a.name().compareTo(b.name());
        }
    };

    public static final Comparator<ClassInfo> qualifiedComparator = new Comparator<ClassInfo>() {
        public int compare(ClassInfo a, ClassInfo b) {
            return a.qualifiedName().compareTo(b.qualifiedName());
        }
    };

    public ClassInfo(
            ClassDoc cl,
            String rawCommentText, SourcePositionInfo position,
            boolean isPublic, boolean isProtected, boolean isPackagePrivate,
            boolean isPrivate, boolean isStatic,
            boolean isInterface, boolean isAbstract, boolean isOrdinaryClass,
            boolean isException, boolean isError, boolean isEnum, boolean isAnnotation,
            boolean isFinal, boolean isIncluded, String name,
            String qualifiedName, String qualifiedTypeName, boolean isPrimitive)
    {
        super(rawCommentText, position);

        mClass = cl;
        mIsPublic = isPublic;
        mIsProtected = isProtected;
        mIsPackagePrivate = isPackagePrivate;
        mIsPrivate = isPrivate;
        mIsStatic = isStatic;
        mIsInterface = isInterface;
        mIsAbstract = isAbstract;
        mIsOrdinaryClass = isOrdinaryClass;
        mIsException = isException;
        mIsError = isError;
        mIsEnum = isEnum;
        mIsAnnotation = isAnnotation;
        mIsFinal = isFinal;
        mIsIncluded = isIncluded;
        mName = name;
        mQualifiedName = qualifiedName;
        mQualifiedTypeName = qualifiedTypeName;
        mIsPrimitive = isPrimitive;
        mNameParts = name.split("\\.");
    }

    public void init(TypeInfo typeInfo, ClassInfo[] interfaces, TypeInfo[] interfaceTypes,
            ClassInfo[] innerClasses,
            MethodInfo[] constructors, MethodInfo[] methods, MethodInfo[] annotationElements,
            FieldInfo[] fields, FieldInfo[] enumConstants,
            PackageInfo containingPackage, ClassInfo containingClass,
            ClassInfo superclass, TypeInfo superclassType, AnnotationInstanceInfo[] annotations)
    {
        mTypeInfo = typeInfo;
        mRealInterfaces = interfaces;
        mRealInterfaceTypes = interfaceTypes;
        mInnerClasses = innerClasses;
        mAllConstructors = constructors;
        mAllSelfMethods = methods;
        mAnnotationElements = annotationElements;
        mAllSelfFields = fields;
        mEnumConstants = enumConstants;
        mContainingPackage = containingPackage;
        mContainingClass = containingClass;
        mRealSuperclass = superclass;
        mRealSuperclassType = superclassType;
        mAnnotations = annotations;

        // after providing new methods and new superclass info,clear any cached
        // lists of self + superclass methods, ctors, etc.
        mSuperclassInit = false;
        mConstructors = null;
        mMethods = null;
        mSelfMethods = null;
        mFields = null;
        mSelfFields = null;
        mSelfAttributes = null;
        mDeprecatedKnown = false;
        
        Arrays.sort(mEnumConstants, FieldInfo.comparator);
        Arrays.sort(mInnerClasses, ClassInfo.comparator);
    }

    public void init2() {
        // calling this here forces the AttrTagInfo objects to be linked to the AttribtueInfo
        // objects
        selfAttributes();
    }
    
    public void init3(TypeInfo[] types, ClassInfo[] realInnerClasses){
      mTypeParameters = types;
      mRealInnerClasses = realInnerClasses;
    }
    
    public ClassInfo[] getRealInnerClasses(){
      return mRealInnerClasses;
    }
    
    public TypeInfo[] getTypeParameters(){
      return mTypeParameters;
    }

    public boolean checkLevel()
    {
        int val = mCheckLevel;
        if (val >= 0) {
            return val != 0;
        } else {
            boolean v = DroidDoc.checkLevel(mIsPublic, mIsProtected,
                                                mIsPackagePrivate, mIsPrivate, isHidden());
            mCheckLevel = v ? 1 : 0;
            return v;
        }
    }

    public int compareTo(Object that) {
        if (that instanceof ClassInfo) {
            return mQualifiedName.compareTo(((ClassInfo)that).mQualifiedName);
        } else {
            return this.hashCode() - that.hashCode();
        }
    }

    public ContainerInfo parent()
    {
        return this;
    }

    public boolean isPublic()
    {
        return mIsPublic;
    }

    public boolean isProtected()
    {
        return mIsProtected;
    }

    public boolean isPackagePrivate()
    {
        return mIsPackagePrivate;
    }

    public boolean isPrivate()
    {
        return mIsPrivate;
    }

    public boolean isStatic()
    {
        return mIsStatic;
    }

    public boolean isInterface()
    {
        return mIsInterface;
    }

    public boolean isAbstract()
    {
        return mIsAbstract;
    }

    public PackageInfo containingPackage()
    {
        return mContainingPackage;
    }

    public ClassInfo containingClass()
    {
        return mContainingClass;
    }

    public boolean isOrdinaryClass()
    {
        return mIsOrdinaryClass;
    }

    public boolean isException()
    {
        return mIsException;
    }

    public boolean isError()
    {
        return mIsError;
    }

    public boolean isEnum()
    {
        return mIsEnum;
    }

    public boolean isAnnotation()
    {
        return mIsAnnotation;
    }

    public boolean isFinal()
    {
        return mIsFinal;
    }

    public boolean isIncluded()
    {
        return mIsIncluded;
    }

    public HashSet<String> typeVariables()
    {
        HashSet<String> result = TypeInfo.typeVariables(mTypeInfo.typeArguments());
        ClassInfo cl = containingClass();
        while (cl != null) {
            TypeInfo[] types = cl.asTypeInfo().typeArguments();
            if (types != null) {
                TypeInfo.typeVariables(types, result);
            }
            cl = cl.containingClass();
        }
        return result;
    }

    private static void gatherHiddenInterfaces(ClassInfo cl, HashSet<ClassInfo> interfaces) {
        for (ClassInfo iface: cl.mRealInterfaces) {
            if (iface.checkLevel()) {
                interfaces.add(iface);
            } else {
                gatherHiddenInterfaces(iface, interfaces);
            }
        }
    }

    public ClassInfo[] interfaces()
    {
        if (mInterfaces == null) {
            if (checkLevel()) {
                HashSet<ClassInfo> interfaces = new HashSet<ClassInfo>();
                ClassInfo superclass = mRealSuperclass;
                while (superclass != null && !superclass.checkLevel()) {
                    gatherHiddenInterfaces(superclass, interfaces);
                    superclass = superclass.mRealSuperclass;
                }
                gatherHiddenInterfaces(this, interfaces);
                mInterfaces = interfaces.toArray(new ClassInfo[interfaces.size()]);
            } else {
                // put something here in case someone uses it
                mInterfaces = mRealInterfaces;
            }
            Arrays.sort(mInterfaces, ClassInfo.qualifiedComparator);
        }
        return mInterfaces;
    }

    public ClassInfo[] realInterfaces()
    {
        return mRealInterfaces;
    }

    TypeInfo[] realInterfaceTypes()
    {
        return mRealInterfaceTypes;
    }

    public String name()
    {
        return mName;
    }

    public String[] nameParts()
    {
        return mNameParts;
    }

    public String leafName()
    {
        return mNameParts[mNameParts.length-1];
    }

    public String qualifiedName()
    {
        return mQualifiedName;
    }

    public String qualifiedTypeName()
    {
        return mQualifiedTypeName;
    }

    public boolean isPrimitive()
    {
        return mIsPrimitive;
    }

    public MethodInfo[] allConstructors() {
        return mAllConstructors;
    }

    public MethodInfo[] constructors()
    {
        if (mConstructors == null) {
            MethodInfo[] methods = mAllConstructors;
            ArrayList<MethodInfo> ctors = new ArrayList<MethodInfo>();
            for (int i=0; i<methods.length; i++) {
                MethodInfo m = methods[i];
                if (!m.isHidden()) {
                    ctors.add(m);
                }
            }
            mConstructors = ctors.toArray(new MethodInfo[ctors.size()]);
            Arrays.sort(mConstructors, MethodInfo.comparator);
        }
        return mConstructors;
    }

    public ClassInfo[] innerClasses()
    {
        return mInnerClasses;
    }

    public TagInfo[] inlineTags()
    {
        return comment().tags();
    }

    public TagInfo[] firstSentenceTags()
    {
        return comment().briefTags();
    }
    
    public boolean isDeprecated() {
        boolean deprecated = false;
        if (!mDeprecatedKnown) {
            boolean commentDeprecated = (comment().deprecatedTags().length > 0);
            boolean annotationDeprecated = false;
            for (AnnotationInstanceInfo annotation : annotations()) {
                if (annotation.type().qualifiedName().equals("java.lang.Deprecated")) {
                    annotationDeprecated = true;
                    break;
                }
            }

            if (commentDeprecated != annotationDeprecated) {
                Errors.error(Errors.DEPRECATION_MISMATCH, position(),
                        "Class " + qualifiedName()
                        + ": @Deprecated annotation and @deprecated comment do not match");
            }

            mIsDeprecated = commentDeprecated | annotationDeprecated;
            mDeprecatedKnown = true;
        }
        return mIsDeprecated;
    }

    public TagInfo[] deprecatedTags()
    {
        // Should we also do the interfaces?
        return comment().deprecatedTags();
    }

    public MethodInfo[] methods()
    {
        if (mMethods == null) {
            TreeMap<String,MethodInfo> all = new TreeMap<String,MethodInfo>();

            ClassInfo[] ifaces = interfaces();
            for (ClassInfo iface: ifaces) {
                if (iface != null) {
                    MethodInfo[] inhereted = iface.methods();
                    for (MethodInfo method: inhereted) {
                        String key = method.name() + method.signature();
                        all.put(key, method);
                    }
                }
            }

            ClassInfo superclass = superclass();
            if (superclass != null) {
                MethodInfo[] inhereted = superclass.methods();
                for (MethodInfo method: inhereted) {
                    String key = method.name() + method.signature();
                    all.put(key, method);
                }
            }

            MethodInfo[] methods = selfMethods();
            for (MethodInfo method: methods) {
                String key = method.name() + method.signature();
                MethodInfo old = all.put(key, method);
            }

            mMethods = all.values().toArray(new MethodInfo[all.size()]);
        }
        return mMethods;
    }

    public MethodInfo[] annotationElements()
    {
        return mAnnotationElements;
    }

    public AnnotationInstanceInfo[] annotations()
    {
        return mAnnotations;
    }

    private static void addFields(ClassInfo cl, TreeMap<String,FieldInfo> all)
    {
        FieldInfo[] fields = cl.fields();
        int N = fields.length;
        for (int i=0; i<N; i++) {
            FieldInfo f = fields[i];
            all.put(f.name(), f);
        }
    }

    public FieldInfo[] fields()
    {
        if (mFields == null) {
            int N;
            TreeMap<String,FieldInfo> all = new TreeMap<String,FieldInfo>();

            ClassInfo[] interfaces = interfaces();
            N = interfaces.length;
            for (int i=0; i<N; i++) {
                addFields(interfaces[i], all);
            }

            ClassInfo superclass = superclass();
            if (superclass != null) {
                addFields(superclass, all);
            }

            FieldInfo[] fields = selfFields();
            N = fields.length;
            for (int i=0; i<N; i++) {
                FieldInfo f = fields[i];
                if (!f.isHidden()) {
                    String key = f.name();
                    all.put(key, f);
                }
            }

            mFields = all.values().toArray(new FieldInfo[0]);
        }
        return mFields;
    }

    public void gatherFields(ClassInfo owner, ClassInfo cl, HashMap<String,FieldInfo> fields) {
        FieldInfo[] flds = cl.selfFields();
        for (FieldInfo f: flds) {
            if (f.checkLevel()) {
                fields.put(f.name(), f.cloneForClass(owner));
            }
        }
    }

    public FieldInfo[] selfFields()
    {
        if (mSelfFields == null) {
            HashMap<String,FieldInfo> fields = new HashMap<String,FieldInfo>();
            // our hidden parents
            if (mRealSuperclass != null && !mRealSuperclass.checkLevel()) {
                gatherFields(this, mRealSuperclass, fields);
            }
            for (ClassInfo iface: mRealInterfaces) {
                if (!iface.checkLevel()) {
                    gatherFields(this, iface, fields);
                }
            }
            // mine
            FieldInfo[] selfFields = mAllSelfFields;
            for (int i=0; i<selfFields.length; i++) {
                FieldInfo f = selfFields[i];
                if (!f.isHidden()) {
                    fields.put(f.name(), f);
                }
            }
            // combine and return in
            mSelfFields = fields.values().toArray(new FieldInfo[fields.size()]);
            Arrays.sort(mSelfFields, FieldInfo.comparator);
        }
        return mSelfFields;
    }

    public FieldInfo[] allSelfFields() {
        return mAllSelfFields;
    }

    public void gatherMethods(ClassInfo owner, ClassInfo cl, HashMap<String,MethodInfo> methods) {
        MethodInfo[] meth = cl.selfMethods();
        for (MethodInfo m: meth) {
            if (m.checkLevel()) {
                methods.put(m.name()+m.signature(), m.cloneForClass(owner));
            }
        }
    }

    public MethodInfo[] selfMethods()
    {
        if (mSelfMethods == null) {
            HashMap<String,MethodInfo> methods = new HashMap<String,MethodInfo>();
            // our hidden parents
            if (mRealSuperclass != null && !mRealSuperclass.checkLevel()) {
                gatherMethods(this, mRealSuperclass, methods);
            }
            for (ClassInfo iface: mRealInterfaces) {
                if (!iface.checkLevel()) {
                    gatherMethods(this, iface, methods);
                }
            }
            // mine
            MethodInfo[] selfMethods = mAllSelfMethods;
            for (int i=0; i<selfMethods.length; i++) {
                MethodInfo m = selfMethods[i];
                if (m.checkLevel()) {
                    methods.put(m.name()+m.signature(), m);
                }
            }
            // combine and return it
            mSelfMethods = methods.values().toArray(new MethodInfo[methods.size()]);
            Arrays.sort(mSelfMethods, MethodInfo.comparator);
        }
        return mSelfMethods;
    }

    public MethodInfo[] allSelfMethods() {
        return mAllSelfMethods;
    }
    
    public void addMethod(MethodInfo method) {
        MethodInfo[] methods = new MethodInfo[mAllSelfMethods.length + 1];
        int i = 0;
        for (MethodInfo m : mAllSelfMethods) {
            methods[i] = m;
            i++;
        }
        methods[i] = method;
        mAllSelfMethods = methods;
    }

    public AttributeInfo[] selfAttributes()
    {
        if (mSelfAttributes == null) {
            TreeMap<FieldInfo,AttributeInfo> attrs = new TreeMap<FieldInfo,AttributeInfo>();

            // the ones in the class comment won't have any methods
            for (AttrTagInfo tag: comment().attrTags()) {
                FieldInfo field = tag.reference();
                if (field != null) {
                    AttributeInfo attr = attrs.get(field);
                    if (attr == null) {
                        attr = new AttributeInfo(this, field);
                        attrs.put(field, attr);
                    }
                    tag.setAttribute(attr);
                }
            }

            // in the methods
            for (MethodInfo m: selfMethods()) {
                for (AttrTagInfo tag: m.comment().attrTags()) {
                    FieldInfo field = tag.reference();
                    if (field != null) {
                        AttributeInfo attr = attrs.get(field);
                        if (attr == null) {
                            attr = new AttributeInfo(this, field);
                            attrs.put(field, attr);
                        }
                        tag.setAttribute(attr);
                        attr.methods.add(m);
                    }
                }
            }
            
            //constructors too
           for (MethodInfo m: constructors()) {
              for (AttrTagInfo tag: m.comment().attrTags()) {
                  FieldInfo field = tag.reference();
                  if (field != null) {
                      AttributeInfo attr = attrs.get(field);
                      if (attr == null) {
                          attr = new AttributeInfo(this, field);
                          attrs.put(field, attr);
                      }
                      tag.setAttribute(attr);
                      attr.methods.add(m);
                  }
              }
          }

            mSelfAttributes = attrs.values().toArray(new AttributeInfo[attrs.size()]);
            Arrays.sort(mSelfAttributes, AttributeInfo.comparator);
        }
        return mSelfAttributes;
    }

    public FieldInfo[] enumConstants()
    {
        return mEnumConstants;
    }

    public ClassInfo superclass()
    {
        if (!mSuperclassInit) {
            if (this.checkLevel()) {
                // rearrange our little inheritance hierarchy, because we need to hide classes that
                // don't pass checkLevel
                ClassInfo superclass = mRealSuperclass;
                while (superclass != null && !superclass.checkLevel()) {
                    superclass = superclass.mRealSuperclass;
                }
                mSuperclass = superclass;
            } else {
                mSuperclass = mRealSuperclass;
            }
        }
        return mSuperclass;
    }

    public ClassInfo realSuperclass()
    {
        return mRealSuperclass;
    }

    /** always the real superclass, not the collapsed one we get through superclass(),
     * also has the type parameter info if it's generic.
     */
    public TypeInfo superclassType()
    {
        return mRealSuperclassType;
    }

    public TypeInfo asTypeInfo()
    {
        return mTypeInfo;
    }

    TypeInfo[] interfaceTypes()
    {
        ClassInfo[] infos = interfaces();
        int len = infos.length;
        TypeInfo[] types = new TypeInfo[len];
        for (int i=0; i<len; i++) {
            types[i] = infos[i].asTypeInfo();
        }
        return types;
    }

    public String htmlPage()
    {
        String s = containingPackage().name();
        s = s.replace('.', '/');
        s += '/';
        s += name();
        s += ".html";
        s = DroidDoc.javadocDir + s;
        return s;
    }

    /** Even indirectly */
    public boolean isDerivedFrom(ClassInfo cl)
    {
        ClassInfo dad = this.superclass();
        if (dad != null) {
            if (dad.equals(cl)) {
                return true;
            } else {
                if (dad.isDerivedFrom(cl)) {
                    return true;
                }
            }
        }
        for (ClassInfo iface: interfaces()) {
            if (iface.equals(cl)) {
                return true;
            } else {
                if (iface.isDerivedFrom(cl)) {
                    return true;
                }
            }
        }
        return false;
    }

    public void makeKeywordEntries(List<KeywordEntry> keywords)
    {
        if (!checkLevel()) {
            return;
        }

        String htmlPage = htmlPage();
        String qualifiedName = qualifiedName();

        keywords.add(new KeywordEntry(name(), htmlPage,
                "class in " + containingPackage().name()));

        FieldInfo[] fields = selfFields();
        FieldInfo[] enumConstants = enumConstants();
        MethodInfo[] ctors = constructors();
        MethodInfo[] methods = selfMethods();

        // enum constants
        for (FieldInfo field: enumConstants()) {
            if (field.checkLevel()) {
                keywords.add(new KeywordEntry(field.name(),
                            htmlPage + "#" + field.anchor(),
                            "enum constant in " + qualifiedName));
            }
        }

        // constants
        for (FieldInfo field: fields) {
            if (field.isConstant() && field.checkLevel()) {
                keywords.add(new KeywordEntry(field.name(),
                            htmlPage + "#" + field.anchor(),
                            "constant in " + qualifiedName));
            }
        }

        // fields
        for (FieldInfo field: fields) {
            if (!field.isConstant() && field.checkLevel()) {
                keywords.add(new KeywordEntry(field.name(),
                            htmlPage + "#" + field.anchor(),
                            "field in " + qualifiedName));
            }
        }

        // public constructors
        for (MethodInfo m: ctors) {
            if (m.isPublic() && m.checkLevel()) {
                keywords.add(new KeywordEntry(m.name() + m.prettySignature(),
                            htmlPage + "#" + m.anchor(),
                            "constructor in " + qualifiedName));
            }
        }

        // protected constructors
        if (DroidDoc.checkLevel(DroidDoc.SHOW_PROTECTED)) {
            for (MethodInfo m: ctors) {
                if (m.isProtected() && m.checkLevel()) {
                    keywords.add(new KeywordEntry(m.name() + m.prettySignature(),
                                htmlPage + "#" + m.anchor(),
                                "constructor in " + qualifiedName));
                }
            }
        }

        // package private constructors
        if (DroidDoc.checkLevel(DroidDoc.SHOW_PACKAGE)) {
            for (MethodInfo m: ctors) {
                if (m.isPackagePrivate() && m.checkLevel()) {
                    keywords.add(new KeywordEntry(m.name() + m.prettySignature(),
                                htmlPage + "#" + m.anchor(),
                                "constructor in " + qualifiedName));
                }
            }
        }

        // private constructors
        if (DroidDoc.checkLevel(DroidDoc.SHOW_PRIVATE)) {
            for (MethodInfo m: ctors) {
                if (m.isPrivate() && m.checkLevel()) {
                    keywords.add(new KeywordEntry(m.name() + m.prettySignature(),
                                htmlPage + "#" + m.anchor(),
                                "constructor in " + qualifiedName));
                }
            }
        }

        // public methods
        for (MethodInfo m: methods) {
            if (m.isPublic() && m.checkLevel()) {
                keywords.add(new KeywordEntry(m.name() + m.prettySignature(),
                            htmlPage + "#" + m.anchor(),
                            "method in " + qualifiedName));
            }
        }

        // protected methods
        if (DroidDoc.checkLevel(DroidDoc.SHOW_PROTECTED)) {
            for (MethodInfo m: methods) {
                if (m.isProtected() && m.checkLevel()) {
                    keywords.add(new KeywordEntry(m.name() + m.prettySignature(),
                                htmlPage + "#" + m.anchor(),
                                "method in " + qualifiedName));
                }
            }
        }

        // package private methods
        if (DroidDoc.checkLevel(DroidDoc.SHOW_PACKAGE)) {
            for (MethodInfo m: methods) {
                if (m.isPackagePrivate() && m.checkLevel()) {
                    keywords.add(new KeywordEntry(m.name() + m.prettySignature(),
                                htmlPage + "#" + m.anchor(),
                                "method in " + qualifiedName));
                }
            }
        }

        // private methods
        if (DroidDoc.checkLevel(DroidDoc.SHOW_PRIVATE)) {
            for (MethodInfo m: methods) {
                if (m.isPrivate() && m.checkLevel()) {
                    keywords.add(new KeywordEntry(m.name() + m.prettySignature(),
                                htmlPage + "#" + m.anchor(),
                                "method in " + qualifiedName));
                }
            }
        }
    }

    public void makeLink(HDF data, String base)
    {
        data.setValue(base + ".label", this.name());
        if (!this.isPrimitive() && this.isIncluded() && this.checkLevel()) {
            data.setValue(base + ".link", this.htmlPage());
        }
    }

    public static void makeLinkListHDF(HDF data, String base, ClassInfo[] classes) {
        final int N = classes.length;
        for (int i=0; i<N; i++) {
            ClassInfo cl = classes[i];
            if (cl.checkLevel()) {
                cl.asTypeInfo().makeHDF(data, base + "." + i);
            }
        }
    }

    /**
     * Used in lists of this class (packages, nested classes, known subclasses)
     */
    public void makeShortDescrHDF(HDF data, String base)
    {
        mTypeInfo.makeHDF(data, base + ".type");
        data.setValue(base + ".kind", this.kind());
        TagInfo.makeHDF(data, base + ".shortDescr", this.firstSentenceTags());
        TagInfo.makeHDF(data, base + ".deprecated", deprecatedTags());
    }

    /**
     * Turns into the main class page
     */
    public void makeHDF(HDF data)
    {
        int i, j, n;
        String name = name();
        String qualified = qualifiedName();
        AttributeInfo[] selfAttributes = selfAttributes();
        MethodInfo[] methods = selfMethods();
        FieldInfo[] fields = selfFields();
        FieldInfo[] enumConstants = enumConstants();
        MethodInfo[] ctors = constructors();
        ClassInfo[] inners = innerClasses();

        // class name
        mTypeInfo.makeHDF(data, "class.type");
        mTypeInfo.makeQualifiedHDF(data, "class.qualifiedType");
        data.setValue("class.name", name);
        data.setValue("class.qualified", qualified);
        String scope = "";
        if (isProtected()) {
            data.setValue("class.scope", "protected");
        }
        else if (isPublic()) {
            data.setValue("class.scope", "public");
        }
        if (isStatic()) {
            data.setValue("class.static", "static");
        }
        if (isFinal()) {
            data.setValue("class.final", "final");
        }
        if (isAbstract() && !isInterface()) {
            data.setValue("class.abstract", "abstract");
        }

        // class info
        String kind = kind();
        if (kind != null) {
            data.setValue("class.kind", kind);
        }

        // the containing package -- note that this can be passed to type_link,
        // but it also contains the list of all of the packages
        containingPackage().makeClassLinkListHDF(data, "class.package");

        // inheritance hierarchy
        Vector<ClassInfo> superClasses = new Vector<ClassInfo>();
        superClasses.add(this);
        ClassInfo supr = superclass();
        while (supr != null) {
            superClasses.add(supr);
            supr = supr.superclass();
        }
        n = superClasses.size();
        for (i=0; i<n; i++) {
            supr = superClasses.elementAt(n-i-1);

            supr.asTypeInfo().makeQualifiedHDF(data, "class.inheritance." + i + ".class");
            supr.asTypeInfo().makeHDF(data, "class.inheritance." + i + ".short_class");
            j = 0;
            for (TypeInfo t: supr.interfaceTypes()) {
                t.makeHDF(data, "class.inheritance." + i + ".interfaces." + j);
                j++;
            }
        }

        // class description
        TagInfo.makeHDF(data, "class.descr", inlineTags());
        TagInfo.makeHDF(data, "class.seeAlso", comment().seeTags());
        TagInfo.makeHDF(data, "class.deprecated", deprecatedTags());

        // known subclasses
        TreeMap<String, ClassInfo> direct = new TreeMap<String, ClassInfo>();
        TreeMap<String, ClassInfo> indirect = new TreeMap<String, ClassInfo>();
        ClassInfo[] all = Converter.rootClasses();
        for (ClassInfo cl: all) {
            if (cl.superclass() != null && cl.superclass().equals(this)) {
                direct.put(cl.name(), cl);
            }
            else if (cl.isDerivedFrom(this)) {
                indirect.put(cl.name(), cl);
            }
        }
        // direct
        i = 0;
        for (ClassInfo cl: direct.values()) {
            if (cl.checkLevel()) {
                cl.makeShortDescrHDF(data, "class.subclasses.direct." + i);
            }
            i++;
        }
        // indirect
        i = 0;
        for (ClassInfo cl: indirect.values()) {
            if (cl.checkLevel()) {
                cl.makeShortDescrHDF(data, "class.subclasses.indirect." + i);
            }
            i++;
        }

        // nested classes
        i=0;
        for (ClassInfo inner: inners) {
            if (inner.checkLevel()) {
                inner.makeShortDescrHDF(data, "class.inners." + i);
            }
            i++;
        }

        // enum constants
        i=0;
        for (FieldInfo field: enumConstants) {
            if (field.isConstant()) {
                field.makeHDF(data, "class.enumConstants." + i);
                i++;
            }
        }

        // constants
        i=0;
        for (FieldInfo field: fields) {
            if (field.isConstant()) {
                field.makeHDF(data, "class.constants." + i);
                i++;
            }
        }

        // fields
        i=0;
        for (FieldInfo field: fields) {
            if (!field.isConstant()) {
                field.makeHDF(data, "class.fields." + i);
                i++;
            }
        }

        // public constructors
        i=0;
        for (MethodInfo ctor: ctors) {
            if (ctor.isPublic()) {
                ctor.makeHDF(data, "class.ctors.public." + i);
                i++;
            }
        }

        // protected constructors
        if (DroidDoc.checkLevel(DroidDoc.SHOW_PROTECTED)) {
            i=0;
            for (MethodInfo ctor: ctors) {
                if (ctor.isProtected()) {
                    ctor.makeHDF(data, "class.ctors.protected." + i);
                    i++;
                }
            }
        }

        // package private constructors
        if (DroidDoc.checkLevel(DroidDoc.SHOW_PACKAGE)) {
            i=0;
            for (MethodInfo ctor: ctors) {
                if (ctor.isPackagePrivate()) {
                    ctor.makeHDF(data, "class.ctors.package." + i);
                    i++;
                }
            }
        }

        // private constructors
        if (DroidDoc.checkLevel(DroidDoc.SHOW_PRIVATE)) {
            i=0;
            for (MethodInfo ctor: ctors) {
                if (ctor.isPrivate()) {
                    ctor.makeHDF(data, "class.ctors.private." + i);
                    i++;
                }
            }
        }

        // public methods
        i=0;
        for (MethodInfo method: methods) {
            if (method.isPublic()) {
                method.makeHDF(data, "class.methods.public." + i);
                i++;
            }
        }

        // protected methods
        if (DroidDoc.checkLevel(DroidDoc.SHOW_PROTECTED)) {
            i=0;
            for (MethodInfo method: methods) {
                if (method.isProtected()) {
                    method.makeHDF(data, "class.methods.protected." + i);
                    i++;
                }
            }
        }

        // package private methods
        if (DroidDoc.checkLevel(DroidDoc.SHOW_PACKAGE)) {
            i=0;
            for (MethodInfo method: methods) {
                if (method.isPackagePrivate()) {
                    method.makeHDF(data, "class.methods.package." + i);
                    i++;
                }
            }
        }

        // private methods
        if (DroidDoc.checkLevel(DroidDoc.SHOW_PRIVATE)) {
            i=0;
            for (MethodInfo method: methods) {
                if (method.isPrivate()) {
                    method.makeHDF(data, "class.methods.private." + i);
                    i++;
                }
            }
        }

        // xml attributes
        i=0;
        for (AttributeInfo attr: selfAttributes) {
            if (attr.checkLevel()) {
                attr.makeHDF(data, "class.attrs." + i);
                i++;
            }
        }

        // inherited methods
        Set<ClassInfo> interfaces = new TreeSet<ClassInfo>();
        addInterfaces(interfaces(), interfaces);
        ClassInfo cl = superclass();
        i=0;
        while (cl != null) {
            addInterfaces(cl.interfaces(), interfaces);
            makeInheritedHDF(data, i, cl);
            cl = cl.superclass();
            i++;
        }
        for (ClassInfo iface: interfaces) {
            makeInheritedHDF(data, i, iface);
            i++;
        }
    }

    private static void addInterfaces(ClassInfo[] ifaces, Set<ClassInfo> out)
    {
        for (ClassInfo cl: ifaces) {
            out.add(cl);
            addInterfaces(cl.interfaces(), out);
        }
    }

    private static void makeInheritedHDF(HDF data, int index, ClassInfo cl)
    {
        int i;

        String base = "class.inherited." + index;
        data.setValue(base + ".qualified", cl.qualifiedName());
        if (cl.checkLevel()) {
            data.setValue(base + ".link", cl.htmlPage());
        }
        String kind = cl.kind();
        if (kind != null) {
            data.setValue(base + ".kind", kind);
        }
        
        // xml attributes
        i=0;
        for (AttributeInfo attr: cl.selfAttributes()) {
            attr.makeHDF(data, base + ".attrs." + i);
            i++;
        }

        // methods
        i=0;
        for (MethodInfo method: cl.selfMethods()) {
            method.makeHDF(data, base + ".methods." + i);
            i++;
        }

        // fields
        i=0;
        for (FieldInfo field: cl.selfFields()) {
            if (!field.isConstant()) {
                field.makeHDF(data, base + ".fields." + i);
                i++;
            }
        }

        // constants
        i=0;
        for (FieldInfo field: cl.selfFields()) {
            if (field.isConstant()) {
                field.makeHDF(data, base + ".constants." + i);
                i++;
            }
        }
    }

    public boolean isHidden()
    {
        int val = mHidden;
        if (val >= 0) {
            return val != 0;
        } else {
            boolean v = isHiddenImpl();
            mHidden = v ? 1 : 0;
            return v;
        }
    }

    public boolean isHiddenImpl()
    {
        ClassInfo cl = this;
        while (cl != null) {
            PackageInfo pkg = cl.containingPackage();
            if (pkg.isHidden()) {
                return true;
            }
            if (cl.comment().isHidden()) {
                return true;
            }
            cl = cl.containingClass();
        }
        return false;
    }

    private MethodInfo matchMethod(MethodInfo[] methods, String name,
                                    String[] params, String[] dimensions)
    {
        int len = methods.length;
        for (int i=0; i<len; i++) {
            MethodInfo method = methods[i];
            if (method.name().equals(name)) {
                if (params == null) {
                    return method;
                } else {
                    if (method.matchesParams(params, dimensions)) {
                        return method;
                    }
                }
            }
        }
        return null;
    }

    public MethodInfo findMethod(String name,
                                    String[] params, String[] dimensions)
    {
        // first look on our class, and our superclasses

        // for methods
        MethodInfo rv;
        rv = matchMethod(methods(), name, params, dimensions);

        if (rv != null) {
            return rv;
        }

        // for constructors
        rv = matchMethod(constructors(), name, params, dimensions);
        if (rv != null) {
            return rv;
        }

        // then recursively look at our containing class
        ClassInfo containing = containingClass();
        if (containing != null) {
            return containing.findMethod(name, params, dimensions);
        }

        return null;
    }

    private ClassInfo searchInnerClasses(String[] nameParts, int index)
    {
        String part = nameParts[index];

        ClassInfo[] inners = mInnerClasses;
        for (ClassInfo in: inners) {
            String[] innerParts = in.nameParts();
            if (part.equals(innerParts[innerParts.length-1])) {
                if (index == nameParts.length-1) {
                    return in;
                } else {
                    return in.searchInnerClasses(nameParts, index+1);
                }
            }
        }
        return null;
    }

    public ClassInfo extendedFindClass(String className)
    {
        // ClassDoc.findClass has this bug that we're working around here:
        // If you have a class PackageManager with an inner class PackageInfo
        // and you call it with "PackageInfo" it doesn't find it.
        return searchInnerClasses(className.split("\\."), 0);
    }

    public ClassInfo findClass(String className)
    {
        return Converter.obtainClass(mClass.findClass(className));
    }

    public ClassInfo findInnerClass(String className)
    {
        // ClassDoc.findClass won't find inner classes.  To deal with that,
        // we try what they gave us first, but if that didn't work, then
        // we see if there are any periods in className, and start searching
        // from there.
        String[] nodes = className.split("\\.");
        ClassDoc cl = mClass;
        for (String n: nodes) {
            cl = cl.findClass(n);
            if (cl == null) {
                return null;
            }
        }
        return Converter.obtainClass(cl);
    }

    public FieldInfo findField(String name)
    {
        // first look on our class, and our superclasses
        for (FieldInfo f: fields()) {
            if (f.name().equals(name)) {
                return f;
            }
        }
        
        // then look at our enum constants (these are really fields, maybe
        // they should be mixed into fields().  not sure)
        for (FieldInfo f: enumConstants()) {
            if (f.name().equals(name)) {
                return f;
            }
        }

        // then recursively look at our containing class
        ClassInfo containing = containingClass();
        if (containing != null) {
            return containing.findField(name);
        }

        return null;
    }

    public static ClassInfo[] sortByName(ClassInfo[] classes)
    {
        int i;
        Sorter[] sorted = new Sorter[classes.length];
        for (i=0; i<sorted.length; i++) {
            ClassInfo cl = classes[i];
            sorted[i] = new Sorter(cl.name(), cl);
        }

        Arrays.sort(sorted);

        ClassInfo[] rv = new ClassInfo[classes.length];
        for (i=0; i<rv.length; i++) {
            rv[i] = (ClassInfo)sorted[i].data;
        }

        return rv;
    }

    public boolean equals(ClassInfo that)
    {
        if (that != null) {
            return this.qualifiedName().equals(that.qualifiedName());
        } else {
            return false;
        }
    }
    
    public void setNonWrittenConstructors(MethodInfo[] nonWritten) {
        mNonWrittenConstructors = nonWritten;
    }
    
    public MethodInfo[] getNonWrittenConstructors() {
        return mNonWrittenConstructors;
    }

    public String kind()
    {
        if (isOrdinaryClass()) {
            return "class";
        }
        else if (isInterface()) {
            return "interface";
        }
        else if (isEnum()) {
            return "enum";
        }
        else if (isError()) {
            return "class";
        }
        else if (isException()) {
            return "class";
        }
        else if (isAnnotation()) {
            return "@interface";
        }
        return null;
    }
    
    public void setHiddenMethods(MethodInfo[] mInfo){
        mHiddenMethods = mInfo;
    }
    public MethodInfo[] getHiddenMethods(){
        return mHiddenMethods;
    }
    public String toString(){
        return this.qualifiedName();
    }
    
    public void setReasonIncluded(String reason) {
        mReasonIncluded = reason;
    }
    
    public String getReasonIncluded() {
        return mReasonIncluded; 
    }

    private ClassDoc mClass;

    // ctor
    private boolean mIsPublic;
    private boolean mIsProtected;
    private boolean mIsPackagePrivate;
    private boolean mIsPrivate;
    private boolean mIsStatic;
    private boolean mIsInterface;
    private boolean mIsAbstract;
    private boolean mIsOrdinaryClass;
    private boolean mIsException;
    private boolean mIsError;
    private boolean mIsEnum;
    private boolean mIsAnnotation;
    private boolean mIsFinal;
    private boolean mIsIncluded;
    private String mName;
    private String mQualifiedName;
    private String mQualifiedTypeName;
    private boolean mIsPrimitive;
    private TypeInfo mTypeInfo;
    private String[] mNameParts;

    // init
    private ClassInfo[] mRealInterfaces;
    private ClassInfo[] mInterfaces;
    private TypeInfo[] mRealInterfaceTypes;
    private ClassInfo[] mInnerClasses;
    private MethodInfo[] mAllConstructors;
    private MethodInfo[] mAllSelfMethods;
    private MethodInfo[] mAnnotationElements; // if this class is an annotation
    private FieldInfo[] mAllSelfFields;
    private FieldInfo[] mEnumConstants;
    private PackageInfo mContainingPackage;
    private ClassInfo mContainingClass;
    private ClassInfo mRealSuperclass;
    private TypeInfo mRealSuperclassType;
    private ClassInfo mSuperclass;
    private AnnotationInstanceInfo[] mAnnotations;
    private boolean mSuperclassInit;
    private boolean mDeprecatedKnown;

    // lazy
    private MethodInfo[] mConstructors;
    private ClassInfo[] mRealInnerClasses;
    private MethodInfo[] mSelfMethods;
    private FieldInfo[] mSelfFields;
    private AttributeInfo[] mSelfAttributes;
    private MethodInfo[] mMethods;
    private FieldInfo[] mFields;
    private TypeInfo[] mTypeParameters;
    private MethodInfo[] mHiddenMethods;
    private int mHidden = -1;
    private int mCheckLevel = -1;
    private String mReasonIncluded;
    private MethodInfo[] mNonWrittenConstructors;
    private boolean mIsDeprecated;
}
