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

    @Override
    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());
        data.setValue(base + ".since", getSince());
    }

    /**
     * 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);
        }
        data.setValue("class.since", getSince());

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

        if (cl.mIsIncluded) {
            data.setValue(base + ".included", "true");
        }

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

    @Override
    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 != null && 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;
    }
    @Override
    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;
}
