diff --git a/tools/droiddoc/src/Android.mk b/tools/droiddoc/src/Android.mk
new file mode 100644
index 0000000..abd2581
--- /dev/null
+++ b/tools/droiddoc/src/Android.mk
@@ -0,0 +1,69 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := docs
+
+LOCAL_SRC_FILES := \
+    AnnotationInstanceInfo.java \
+    AnnotationValueInfo.java \
+	AttributeInfo.java \
+	AttrTagInfo.java \
+	ClassInfo.java \
+	DroidDoc.java \
+	ClearPage.java \
+	Comment.java \
+	ContainerInfo.java \
+	Converter.java \
+	DocFile.java \
+	DocInfo.java \
+	Errors.java \
+	FieldInfo.java \
+	Hierarchy.java \
+	InheritedTags.java \
+	KeywordEntry.java \
+    LinkReference.java \
+	LiteralTagInfo.java \
+	MemberInfo.java \
+	MethodInfo.java \
+	NavTree.java \
+	PackageInfo.java \
+	ParamTagInfo.java \
+	ParameterInfo.java \
+	ParsedTagInfo.java \
+	Proofread.java \
+	SampleCode.java \
+	SampleTagInfo.java \
+    Scoped.java \
+	SeeTagInfo.java \
+	Sorter.java \
+	SourcePositionInfo.java \
+    Stubs.java \
+	TagInfo.java \
+    TextTagInfo.java \
+	ThrowsTagInfo.java \
+	TodoFile.java \
+	TypeInfo.java
+
+LOCAL_JAVA_LIBRARIES := \
+	clearsilver
+
+LOCAL_CLASSPATH := \
+	$(HOST_JDK_TOOLS_JAR)
+
+LOCAL_MODULE:= droiddoc
+
+include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/droiddoc/src/AnnotationInstanceInfo.java b/tools/droiddoc/src/AnnotationInstanceInfo.java
new file mode 100644
index 0000000..07d4aa3
--- /dev/null
+++ b/tools/droiddoc/src/AnnotationInstanceInfo.java
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+class AnnotationInstanceInfo
+{
+    private ClassInfo mType;
+    private AnnotationValueInfo[] mElementValues;
+
+    public AnnotationInstanceInfo(ClassInfo type, AnnotationValueInfo[] elementValues)
+    {
+        mType = type;
+        mElementValues = elementValues;
+    }
+
+    ClassInfo type()
+    {
+        return mType;
+    }
+
+    AnnotationValueInfo[] elementValues()
+    {
+        return mElementValues;
+    }
+
+    public String toString()
+    {
+        StringBuilder str = new StringBuilder();
+        str.append("@");
+        str.append(mType.qualifiedName());
+        str.append("(");
+        AnnotationValueInfo[] values = mElementValues;
+        final int N = values.length;
+        for (int i=0; i<N; i++) {
+            AnnotationValueInfo value = values[i];
+            str.append(value.element().name());
+            str.append("=");
+            str.append(value.valueString());
+            if (i != N-1) {
+                str.append(",");
+            }
+        }
+        str.append(")");
+        return str.toString();
+    }
+}
+
diff --git a/tools/droiddoc/src/AnnotationValueInfo.java b/tools/droiddoc/src/AnnotationValueInfo.java
new file mode 100644
index 0000000..a2d869a
--- /dev/null
+++ b/tools/droiddoc/src/AnnotationValueInfo.java
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+public class AnnotationValueInfo
+{
+    private Object mValue;
+    private String mString;
+    private MethodInfo mElement;
+
+    public AnnotationValueInfo(MethodInfo element)
+    {
+        mElement = element;
+    }
+
+    public void init(Object value)
+    {
+        mValue = value;
+    }
+
+    public MethodInfo element()
+    {
+        return mElement;
+    }
+
+    public Object value()
+    {
+        return mValue;
+    }
+
+    public String valueString()
+    {
+        Object v = mValue;
+        if (v instanceof TypeInfo) {
+            return ((TypeInfo)v).fullName();
+        }
+        else if (v instanceof FieldInfo) {
+            StringBuilder str = new StringBuilder();
+            FieldInfo f = (FieldInfo)v;
+            str.append(f.containingClass().qualifiedName());
+            str.append('.');
+            str.append(f.name());
+            return str.toString();
+        }
+        else if (v instanceof AnnotationInstanceInfo) {
+            return v.toString();
+        }
+        else if (v instanceof AnnotationValueInfo[]) {
+            StringBuilder str = new StringBuilder();
+            AnnotationValueInfo[] array = (AnnotationValueInfo[])v;
+            final int N = array.length;
+            str.append("{");
+            for (int i=0; i<array.length; i++) {
+                str.append(array[i].valueString());
+                if (i != N-1) {
+                    str.append(",");
+                }
+            }
+            str.append("}");
+            return str.toString();
+        }
+        else {
+            return FieldInfo.constantLiteralValue(v);
+        }
+    }
+}
+
diff --git a/tools/droiddoc/src/AttrTagInfo.java b/tools/droiddoc/src/AttrTagInfo.java
new file mode 100644
index 0000000..abc5452
--- /dev/null
+++ b/tools/droiddoc/src/AttrTagInfo.java
@@ -0,0 +1,140 @@
+/*
+ * 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 java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import org.clearsilver.HDF;
+import org.clearsilver.CS;
+
+
+public class AttrTagInfo extends TagInfo
+{
+    private static final String REF_COMMAND = "ref";
+    private static final String NAME_COMMAND = "name";
+    private static final String DESCRIPTION_COMMAND = "description";
+    private static final Pattern TEXT = Pattern.compile("(\\S+)\\s*(.*)", Pattern.DOTALL);
+    private static final Pattern NAME_TEXT = Pattern.compile("(\\S+)(.*)",
+                                                Pattern.DOTALL);
+
+    private ContainerInfo mBase;
+    private String mCommand;
+
+    // if mCommand == "ref"
+    private FieldInfo mRefField;
+    private AttributeInfo mAttrInfo;
+
+    // if mCommand == "name"
+    private String mAttrName;
+
+    // if mCommand == "description"
+    private Comment mDescrComment;
+
+    AttrTagInfo(String name, String kind, String text, ContainerInfo base,
+            SourcePositionInfo position)
+    {
+        super(name, kind, text, position);
+        mBase = base;
+
+        parse(text, base, position);
+    }
+
+    void parse(String text, ContainerInfo base, SourcePositionInfo position) {
+        Matcher m;
+
+        m = TEXT.matcher(text);
+        if (!m.matches()) {
+            Errors.error(Errors.BAD_ATTR_TAG, position, "Bad @attr tag: " + text);
+            return;
+        }
+
+        String command = m.group(1);
+        String more = m.group(2);
+
+        if (REF_COMMAND.equals(command)) {
+            String ref = more.trim();
+            LinkReference linkRef = LinkReference.parse(ref, mBase, position, false);
+            if (!linkRef.good) {
+                Errors.error(Errors.BAD_ATTR_TAG, position, "Unresolved @attr ref: " + ref);
+                return;
+            }
+            if (!(linkRef.memberInfo instanceof FieldInfo)) {
+                Errors.error(Errors.BAD_ATTR_TAG, position, "@attr must be a field: " + ref);
+                return;
+            }
+            mCommand = command;
+            mRefField = (FieldInfo)linkRef.memberInfo;
+        }
+        else if (NAME_COMMAND.equals(command)) {
+            m = NAME_TEXT.matcher(more);
+            if (!m.matches() || m.group(2).trim().length() != 0) {
+                Errors.error(Errors.BAD_ATTR_TAG, position, "Bad @attr name tag: " + more);
+                return;
+            }
+            mCommand = command;
+            mAttrName = m.group(1);
+        }
+        else if (DESCRIPTION_COMMAND.equals(command)) {
+            mCommand = command;
+            mDescrComment = new Comment(more, base, position);
+        }
+        else {
+            Errors.error(Errors.BAD_ATTR_TAG, position, "Bad @attr command: " + command);
+        }
+    }
+
+    public FieldInfo reference() {
+        return REF_COMMAND.equals(mCommand) ? mRefField : null;
+    }
+    
+    public String name() {
+        return NAME_COMMAND.equals(mCommand) ? mAttrName : null;
+    }
+
+    public Comment description() {
+        return DESCRIPTION_COMMAND.equals(mCommand) ? mDescrComment : null;
+    }
+
+    public void makeHDF(HDF data, String base)
+    {
+        super.makeHDF(data, base);
+    }
+
+    public void setAttribute(AttributeInfo info) {
+        mAttrInfo = info;
+    }
+
+    public static void makeReferenceHDF(HDF data, String base, AttrTagInfo[] tags)
+    {
+        int i=0;
+        for (AttrTagInfo t: tags) {
+            if (REF_COMMAND.equals(t.mCommand)) {
+                if (t.mAttrInfo == null) {
+                    String msg = "ERROR: unlinked attr: " + t.mRefField.name();
+                    if (false) {
+                        System.out.println(msg);
+                    } else {
+                        throw new RuntimeException(msg);
+                    }
+                } else {
+                    data.setValue(base + "." + i + ".name", t.mAttrInfo.name());
+                    data.setValue(base + "." + i + ".href", t.mAttrInfo.htmlPage());
+                    i++;
+                }
+            }
+        }
+    }
+
+}
diff --git a/tools/droiddoc/src/AttributeInfo.java b/tools/droiddoc/src/AttributeInfo.java
new file mode 100644
index 0000000..a24106b
--- /dev/null
+++ b/tools/droiddoc/src/AttributeInfo.java
@@ -0,0 +1,100 @@
+/*
+ * 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 java.util.ArrayList;
+import java.util.Comparator;
+
+import org.clearsilver.HDF;
+import org.clearsilver.CS;
+
+public class AttributeInfo {
+    public static final Comparator<AttributeInfo> comparator = new Comparator<AttributeInfo>() {
+        public int compare(AttributeInfo a, AttributeInfo b) {
+            return a.name().compareTo(b.name());
+        }
+    };
+    
+    public FieldInfo attrField;
+    public ArrayList<MethodInfo> methods = new ArrayList<MethodInfo>();
+    
+    private ClassInfo mClass;
+    private String mName;
+    private Comment mComment;
+
+    public AttributeInfo(ClassInfo cl, FieldInfo f) {
+        mClass = cl;
+        attrField = f;
+    }
+
+    public String name() {
+        if (mName == null) {
+            for (AttrTagInfo comment: attrField.comment().attrTags()) {
+                String n = comment.name();
+                if (n != null) {
+                    mName = n;
+                    return n;
+                }
+            }
+        }
+        return mName;
+    }
+
+    public Comment comment() {
+        if (mComment == null) {
+            for (AttrTagInfo attr: attrField.comment().attrTags()) {
+                Comment c = attr.description();
+                if (c != null) {
+                    mComment = c;
+                    return c;
+                }
+            }
+        }
+        if (mComment == null) {
+            return new Comment("", mClass, new SourcePositionInfo());
+        }
+        return mComment;
+    }
+    
+    public String anchor() {
+        return "attr_" + name();
+    }
+    public String htmlPage() {
+        return mClass.htmlPage() + "#" + anchor();
+    }
+
+    public void makeHDF(HDF data, String base) {
+        data.setValue(base + ".name", name());
+        data.setValue(base + ".anchor", anchor());
+        data.setValue(base + ".href", htmlPage());
+        data.setValue(base + ".R.name", attrField.name());
+        data.setValue(base + ".R.href", attrField.htmlPage());
+        TagInfo.makeHDF(data, base + ".deprecated", attrField.comment().deprecatedTags());
+        TagInfo.makeHDF(data, base + ".shortDescr", comment().briefTags());
+        TagInfo.makeHDF(data, base + ".descr", comment().tags());
+
+        int i=0;
+        for (MethodInfo m: methods) {
+            String s = base + ".methods." + i;
+            data.setValue(s + ".href", m.htmlPage());
+            data.setValue(s + ".name", m.name() + m.prettySignature());
+        }
+    }
+
+    public boolean checkLevel() {
+        return attrField.checkLevel();
+    }
+}
+
diff --git a/tools/droiddoc/src/ClassInfo.java b/tools/droiddoc/src/ClassInfo.java
new file mode 100644
index 0000000..36edbf8
--- /dev/null
+++ b/tools/droiddoc/src/ClassInfo.java
@@ -0,0 +1,1463 @@
+/*
+ * 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()
+    {
+        TagInfo[] result = comment().deprecatedTags();
+        if (result.length == 0) {
+            if (comment().undeprecateTags().length == 0) {
+                if (superclass() != null) {
+                    result = superclass().deprecatedTags();
+                }
+            }
+        }
+        // should we also do the interfaces?
+        return result;
+    }
+
+    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;
+}
diff --git a/tools/droiddoc/src/ClearPage.java b/tools/droiddoc/src/ClearPage.java
new file mode 100644
index 0000000..2a8fced
--- /dev/null
+++ b/tools/droiddoc/src/ClearPage.java
@@ -0,0 +1,226 @@
+/*
+ * 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 org.clearsilver.HDF;
+import org.clearsilver.CS;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+
+public class ClearPage
+{
+    /*
+    public ClearPage()
+    {
+        String templ = "templates/index.cs";
+        String filename = "docs/index.html";
+
+        data.setValue("A.B.C", "1");
+        data.setValue("A.B.D", "2");
+    }
+    */
+
+    public static ArrayList<String> hdfFiles = new ArrayList<String>();
+
+    private static ArrayList<String> mTemplateDirs = new ArrayList<String>();
+    private static boolean mTemplateDirSet = false;
+
+    public static String outputDir = "docs";
+    public static String htmlDir = null;
+    public static String toroot = null;
+
+    public static void addTemplateDir(String dir)
+    {
+        mTemplateDirSet = true;
+        mTemplateDirs.add(dir);
+
+        File hdfFile = new File(dir, "data.hdf");
+        if (hdfFile.canRead()) {
+            hdfFiles.add(hdfFile.getPath());
+        }
+    }
+
+    private static int countSlashes(String s)
+    {
+        final int N = s.length();
+        int slashcount = 0;
+        for (int i=0; i<N; i++) {
+            if (s.charAt(i) == '/') {
+                slashcount++;
+            }
+        }
+        return slashcount;
+    }
+
+    public static void write(HDF data, String templ, String filename)
+    {
+        write(data, templ, filename, false);
+    }
+
+    public static void write(HDF data, String templ, String filename, boolean fullPath)
+    {
+        if (htmlDir != null) {
+            data.setValue("hasindex", "true");
+        }
+
+        String toroot;
+        if (ClearPage.toroot != null) {
+            toroot = ClearPage.toroot;
+        } else {
+            int slashcount = countSlashes(filename);
+            if (slashcount > 0) {
+                toroot = "";
+                for (int i=0; i<slashcount; i++) {
+                    toroot += "../";
+                }
+            } else {
+                toroot = "./";
+            }
+        }
+        data.setValue("toroot", toroot);
+
+        data.setValue("filename", filename);
+
+        if (!fullPath) {
+            filename = outputDir + "/" + filename;
+        }
+
+        int i=0;
+        if (htmlDir != null) {
+            data.setValue("hdf.loadpaths." + i, htmlDir);
+            i++;
+        }
+        if (mTemplateDirSet) {
+            for (String dir: mTemplateDirs) {
+                data.setValue("hdf.loadpaths." + i, dir);
+                i++;
+            }
+        } else {
+            data.setValue("hdf.loadpaths." + i, "templates");
+        }
+        
+        CS cs = new CS(data);
+        cs.parseFile(templ);
+
+        File file = new File(outputFilename(filename));
+        
+        ensureDirectory(file);
+
+        OutputStreamWriter stream = null;
+        try {
+            stream = new OutputStreamWriter(
+                            new FileOutputStream(file));
+            String rendered = cs.render();
+            stream.write(rendered, 0, rendered.length());
+        }
+        catch (IOException e) {
+            System.out.println("error: " + e.getMessage() + "; when writing file: " + filename);
+        }
+        finally {
+            if (stream != null) {
+                try {
+                    stream.close();
+                }
+                catch (IOException e) {
+                }
+            }
+        }
+    }
+
+    // recursively create the directories to the output
+    public static void ensureDirectory(File f)
+    {
+        File parent = f.getParentFile();
+        if (parent != null) {
+            parent.mkdirs();
+        }
+    }
+
+    public static void copyFile(File from, String toPath)
+    {
+        File to = new File(outputDir + "/" + toPath);
+        FileInputStream in;
+        FileOutputStream out;
+        try {
+            if (!from.exists()) {
+                throw new IOException();
+            }
+            in = new FileInputStream(from);
+        }
+        catch (IOException e) {
+            System.err.println(from.getAbsolutePath() + ": Error opening file");
+            return ;
+        }
+        ensureDirectory(to);
+        try {
+            out = new FileOutputStream(to);
+        }
+        catch (IOException e) {
+            System.err.println(from.getAbsolutePath() + ": Error opening file");
+            return ;
+        }
+
+        long sizel = from.length();
+        final int maxsize = 64*1024;
+        int size = sizel > maxsize ? maxsize : (int)sizel;
+        byte[] buf = new byte[size];
+        while (true) {
+            try {
+                size = in.read(buf);
+            }
+            catch (IOException e) {
+                System.err.println(from.getAbsolutePath()
+                        + ": error reading file");
+                break;
+            }
+            if (size > 0) {
+                try {
+                    out.write(buf, 0, size);
+                }
+                catch (IOException e) {
+                    System.err.println(from.getAbsolutePath()
+                        + ": error writing file");
+                }
+            } else {
+                break;
+            }
+        }
+        try {
+            in.close();
+        }
+        catch (IOException e) {
+        }
+        try {
+            out.close();
+        }
+        catch (IOException e) {
+        }
+    }
+    
+    /** Takes a string that ends w/ .html and changes the .html to htmlExtension */
+    public static String outputFilename(String htmlFile) {
+        if (!DroidDoc.htmlExtension.equals(".html") && htmlFile.endsWith(".html")) {
+            return htmlFile.substring(0, htmlFile.length()-5) + DroidDoc.htmlExtension;
+        } else {
+            return htmlFile;
+        }
+    }
+
+}
diff --git a/tools/droiddoc/src/Comment.java b/tools/droiddoc/src/Comment.java
new file mode 100644
index 0000000..3a24357
--- /dev/null
+++ b/tools/droiddoc/src/Comment.java
@@ -0,0 +1,394 @@
+/*
+ * 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 java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import java.util.ArrayList;
+
+public class Comment
+{
+    static final Pattern LEADING_WHITESPACE = Pattern.compile(
+                                "^[ \t\n\r]*(.*)$",
+                                Pattern.DOTALL);
+
+    static final Pattern TAG_BEGIN = Pattern.compile(
+                                "[\r\n][\r\n \t]*@",
+                                Pattern.DOTALL);
+
+    static final Pattern TAG = Pattern.compile(
+                                "(@[^ \t\r\n]+)[ \t\r\n]+(.*)",
+                                Pattern.DOTALL);
+
+    static final Pattern INLINE_TAG = Pattern.compile(
+                                "(.*?)\\{(@[^ \t\r\n\\}]+)[ \t\r\n]*(.*?)\\}",
+                                Pattern.DOTALL);
+
+    static final Pattern FIRST_SENTENCE = Pattern.compile(
+                                "((.*?)\\.)[ \t\r\n\\<](.*)",
+                                Pattern.DOTALL);
+
+    private static final String[] KNOWN_TAGS = new String[] {
+            "@author",
+            "@since",
+            "@version",
+            "@deprecated",
+            "@undeprecate",
+            "@docRoot",
+            "@inheritDoc",
+            "@more",
+            "@code",
+            "@samplecode",
+            "@sample",
+            "@include",
+            "@serial",
+            "@com.intel.drl.spec_ref",
+            "@ar.org.fitc.spec_ref",
+        };
+
+    public Comment(String text, ContainerInfo base, SourcePositionInfo sp)
+    {
+        mText = text;
+        mBase = base;
+        // sp now points to the end of the text, not the beginning!
+        mPosition = SourcePositionInfo.findBeginning(sp, text);
+    }
+
+    private void parseRegex(String text)
+    {
+        Matcher m;
+
+        m = LEADING_WHITESPACE.matcher(text);
+        m.matches();
+        text = m.group(1);
+
+        m = TAG_BEGIN.matcher(text);
+
+        int start = 0;
+        int end = 0;
+        while (m.find()) {
+            end = m.start();
+
+            tag(text, start, end);
+
+            start = m.end()-1; // -1 is the @
+        }
+        end = text.length();
+        tag(text, start, end);
+    }
+
+    private void tag(String text, int start, int end)
+    {
+        SourcePositionInfo pos = SourcePositionInfo.add(mPosition, mText, start);
+
+        if (start >= 0 && end > 0 && (end-start) > 0) {
+            text = text.substring(start, end);
+
+            Matcher m = TAG.matcher(text);
+            if (m.matches()) {
+                // out of line tag
+                tag(m.group(1), m.group(2), false, pos);
+            } else {
+                // look for inline tags
+                m = INLINE_TAG.matcher(text);
+                start = 0;
+                while (m.find()) {
+                    String str = m.group(1);
+                    String tagname = m.group(2);
+                    String tagvalue = m.group(3);
+                    tag(null, m.group(1), true, pos);
+                    tag(tagname, tagvalue, true, pos);
+                    start = m.end();
+                }
+                int len = text.length();
+                if (start != len) {
+                    tag(null, text.substring(start), true, pos);
+                }
+            }
+        }
+    }
+
+    private void tag(String name, String text, boolean isInline, SourcePositionInfo pos)
+    {
+        /*
+        String s = isInline ? "inline" : "outofline";
+        System.out.println("---> " + s
+                + " name=[" + name + "] text=[" + text + "]");
+        */
+        if (name == null) {
+            mInlineTagsList.add(new TextTagInfo("Text", "Text", text, pos));
+        }
+        else if (name.equals("@param")) {
+            mParamTagsList.add(new ParamTagInfo("@param", "@param", text, mBase, pos));
+        }
+        else if (name.equals("@see")) {
+            mSeeTagsList.add(new SeeTagInfo("@see", "@see", text, mBase, pos));
+        }
+        else if (name.equals("@link") || name.equals("@linkplain")) {
+            mInlineTagsList.add(new SeeTagInfo(name, "@see", text, mBase, pos));
+        }
+        else if (name.equals("@throws") || name.equals("@exception")) {
+            mThrowsTagsList.add(new ThrowsTagInfo("@throws", "@throws", text, mBase, pos));
+        }
+        else if (name.equals("@return")) {
+            mReturnTagsList.add(new ParsedTagInfo("@return", "@return", text, mBase, pos));
+        }
+        else if (name.equals("@deprecated")) {
+            if (text.length() == 0) {
+                Errors.error(Errors.MISSING_COMMENT, pos,
+                        "@deprecated tag with no explanatory comment");
+                text = "No replacement.";
+            }
+            mDeprecatedTagsList.add(new ParsedTagInfo("@deprecated", "@deprecated", text, mBase, pos));
+        }
+        else if (name.equals("@literal")) {
+            mInlineTagsList.add(new LiteralTagInfo(name, name, text, pos));
+        }
+        else if (name.equals("@hide") || name.equals("@doconly")) {
+            // nothing
+        }
+        else if (name.equals("@attr")) {
+            AttrTagInfo tag = new AttrTagInfo("@attr", "@attr", text, mBase, pos);
+            mAttrTagsList.add(tag);
+            Comment c = tag.description();
+            if (c != null) {
+                for (TagInfo t: c.tags()) {
+                    mInlineTagsList.add(t);
+                }
+            }
+        }
+        else if (name.equals("@undeprecate")) {
+            mUndeprecateTagsList.add(new TextTagInfo("@undeprecate", "@undeprecate", text, pos));
+        }
+        else if (name.equals("@include") || name.equals("@sample")) {
+            mInlineTagsList.add(new SampleTagInfo(name, "@include", text, mBase, pos));
+        }
+        else {
+            boolean known = false;
+            for (String s: KNOWN_TAGS) {
+                if (s.equals(name)) {
+                    known = true;
+                    break;
+                }
+            }
+            if (!known) {
+                Errors.error(Errors.UNKNOWN_TAG, pos == null ? null : new SourcePositionInfo(pos),
+                        "Unknown tag: " + name);
+            }
+            TagInfo t = new TextTagInfo(name, name, text, pos);
+            if (isInline) {
+                mInlineTagsList.add(t);
+            } else {
+                mTagsList.add(t);
+            }
+        }
+    }
+
+    private void parseBriefTags()
+    {
+        int N = mInlineTagsList.size();
+
+        // look for "@more" tag, which means that we might go past the first sentence.
+        int more = -1;
+        for (int i=0; i<N; i++) {
+            if (mInlineTagsList.get(i).name().equals("@more")) {
+                more = i;
+            } 
+        }
+          if (more >= 0) {
+            for (int i=0; i<more; i++) {
+                mBriefTagsList.add(mInlineTagsList.get(i));
+            }
+        } else {
+            for (int i=0; i<N; i++) {
+                TagInfo t = mInlineTagsList.get(i);
+                if (t.name().equals("Text")) {
+                    Matcher m = FIRST_SENTENCE.matcher(t.text());
+                    if (m.matches()) {
+                        String text = m.group(1);
+                        TagInfo firstSentenceTag = new TagInfo(t.name(), t.kind(), text, t.position());
+                        mBriefTagsList.add(firstSentenceTag);
+                        break;
+                    }
+                }
+                mBriefTagsList.add(t);
+                
+            }
+        }
+    }
+
+    public TagInfo[] tags()
+    {
+        init();
+        return mInlineTags;
+    }
+
+    public TagInfo[] tags(String name)
+    {
+        init();
+        ArrayList<TagInfo> results = new ArrayList<TagInfo>();
+        int N = mInlineTagsList.size();
+        for (int i=0; i<N; i++) {
+            TagInfo t = mInlineTagsList.get(i);
+            if (t.name().equals(name)) {
+                results.add(t);
+            }
+        }
+        return results.toArray(new TagInfo[results.size()]);
+    }
+
+    public ParamTagInfo[] paramTags()
+    {
+        init();
+        return mParamTags;
+    }
+
+    public SeeTagInfo[] seeTags()
+    {
+        init();
+        return mSeeTags;
+    }
+
+    public ThrowsTagInfo[] throwsTags()
+    {
+        init();
+        return mThrowsTags;
+    }
+
+    public TagInfo[] returnTags()
+    {
+        init();
+        return mReturnTags;
+    }
+
+    public TagInfo[] deprecatedTags()
+    {
+        init();
+        return mDeprecatedTags;
+    }
+
+    public TagInfo[] undeprecateTags()
+    {
+        init();
+        return mUndeprecateTags;
+    }
+
+    public AttrTagInfo[] attrTags()
+    {
+        init();
+        return mAttrTags;
+    }
+
+    public TagInfo[] briefTags()
+    {
+        init();
+        return mBriefTags;
+    }
+
+    public boolean isHidden()
+    {
+        if (mHidden >= 0) {
+            return mHidden != 0;
+        } else {
+            if (DroidDoc.checkLevel(DroidDoc.SHOW_HIDDEN)) {
+                mHidden = 0;
+                return false;
+            }
+            boolean b = mText.indexOf("@hide") >= 0;
+            mHidden = b ? 1 : 0;
+            return b;
+        }
+    }
+    
+    public boolean isDocOnly() {
+        if (mDocOnly >= 0) {
+            return mDocOnly != 0;
+        } else {
+            boolean b = (mText != null) && (mText.indexOf("@doconly") >= 0);
+            mDocOnly = b ? 1 : 0;
+            return b;
+        }
+    }
+
+    private void init()
+    {
+        if (!mInitialized) {
+            initImpl();
+        }
+    }
+
+    private void initImpl()
+    {
+        isHidden();
+        isDocOnly();
+        parseRegex(mText);
+        parseBriefTags();
+        mText = null;
+        mInitialized = true;
+
+        mInlineTags = mInlineTagsList.toArray(new TagInfo[mInlineTagsList.size()]);
+        mParamTags = mParamTagsList.toArray(new ParamTagInfo[mParamTagsList.size()]);
+        mSeeTags = mSeeTagsList.toArray(new SeeTagInfo[mSeeTagsList.size()]);
+        mThrowsTags = mThrowsTagsList.toArray(new ThrowsTagInfo[mThrowsTagsList.size()]);
+        mReturnTags = ParsedTagInfo.joinTags(mReturnTagsList.toArray(
+                                             new ParsedTagInfo[mReturnTagsList.size()]));
+        mDeprecatedTags = ParsedTagInfo.joinTags(mDeprecatedTagsList.toArray(
+                                        new ParsedTagInfo[mDeprecatedTagsList.size()]));
+        mUndeprecateTags = mUndeprecateTagsList.toArray(new TagInfo[mUndeprecateTagsList.size()]);
+        mAttrTags = mAttrTagsList.toArray(new AttrTagInfo[mAttrTagsList.size()]);
+        mBriefTags = mBriefTagsList.toArray(new TagInfo[mBriefTagsList.size()]);
+
+        mParamTagsList = null;
+        mSeeTagsList = null;
+        mThrowsTagsList = null;
+        mReturnTagsList = null;
+        mDeprecatedTagsList = null;
+        mUndeprecateTagsList = null;
+        mAttrTagsList = null;
+        mBriefTagsList = null;
+    }
+
+    boolean mInitialized;
+    int mHidden = -1;
+    int mDocOnly = -1;
+    String mText;
+    ContainerInfo mBase;
+    SourcePositionInfo mPosition;
+    int mLine = 1;
+
+    TagInfo[] mInlineTags;
+    TagInfo[] mTags;
+    ParamTagInfo[] mParamTags;
+    SeeTagInfo[] mSeeTags;
+    ThrowsTagInfo[] mThrowsTags;
+    TagInfo[] mBriefTags;
+    TagInfo[] mReturnTags;
+    TagInfo[] mDeprecatedTags;
+    TagInfo[] mUndeprecateTags;
+    AttrTagInfo[] mAttrTags;
+
+    ArrayList<TagInfo> mInlineTagsList = new ArrayList<TagInfo>();
+    ArrayList<TagInfo> mTagsList = new ArrayList<TagInfo>();
+    ArrayList<ParamTagInfo> mParamTagsList = new ArrayList<ParamTagInfo>();
+    ArrayList<SeeTagInfo> mSeeTagsList = new ArrayList<SeeTagInfo>();
+    ArrayList<ThrowsTagInfo> mThrowsTagsList = new ArrayList<ThrowsTagInfo>();
+    ArrayList<TagInfo> mBriefTagsList = new ArrayList<TagInfo>();
+    ArrayList<ParsedTagInfo> mReturnTagsList = new ArrayList<ParsedTagInfo>();
+    ArrayList<ParsedTagInfo> mDeprecatedTagsList = new ArrayList<ParsedTagInfo>();
+    ArrayList<TagInfo> mUndeprecateTagsList = new ArrayList<TagInfo>();
+    ArrayList<AttrTagInfo> mAttrTagsList = new ArrayList<AttrTagInfo>();
+
+    
+}
diff --git a/tools/droiddoc/src/ContainerInfo.java b/tools/droiddoc/src/ContainerInfo.java
new file mode 100644
index 0000000..b8a3e10
--- /dev/null
+++ b/tools/droiddoc/src/ContainerInfo.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+public interface ContainerInfo
+{
+    public String qualifiedName();
+    public boolean checkLevel();
+}
diff --git a/tools/droiddoc/src/Converter.java b/tools/droiddoc/src/Converter.java
new file mode 100644
index 0000000..4014f7f
--- /dev/null
+++ b/tools/droiddoc/src/Converter.java
@@ -0,0 +1,744 @@
+/*
+ * 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.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+
+public class Converter
+{
+    private static RootDoc root;
+
+    public static void makeInfo(RootDoc r)
+    {
+        root = r;
+
+        int N, i;
+
+        // create the objects
+        ClassDoc[] classDocs = r.classes();
+        N = classDocs.length;
+        for (i=0; i<N; i++) {
+            Converter.obtainClass(classDocs[i]);
+        }
+        ArrayList<ClassInfo> classesNeedingInit2 = new ArrayList<ClassInfo>();
+        // fill in the fields that reference other classes
+        while (mClassesNeedingInit.size() > 0) {
+            i = mClassesNeedingInit.size()-1;
+            ClassNeedingInit clni = mClassesNeedingInit.get(i);
+            mClassesNeedingInit.remove(i);
+
+            initClass(clni.c, clni.cl);
+            classesNeedingInit2.add(clni.cl);
+        }
+        mClassesNeedingInit = null;
+        for (ClassInfo cl: classesNeedingInit2) {
+            cl.init2();
+        }
+
+        finishAnnotationValueInit();
+
+        // fill in the "root" stuff
+        mRootClasses = Converter.convertClasses(r.classes());
+    }
+
+    private static ClassInfo[] mRootClasses;
+    public static ClassInfo[] rootClasses()
+    {
+        return mRootClasses;
+    }
+
+    public static ClassInfo[] allClasses() {
+        return (ClassInfo[])mClasses.all();
+    }
+
+    private static void initClass(ClassDoc c, ClassInfo cl)
+    {
+        MethodDoc[] annotationElements;
+        if (c instanceof AnnotationTypeDoc) {
+            annotationElements = ((AnnotationTypeDoc)c).elements();
+        } else {
+            annotationElements = new MethodDoc[0];
+        }
+        cl.init(Converter.obtainType(c),
+                Converter.convertClasses(c.interfaces()),
+                Converter.convertTypes(c.interfaceTypes()),
+                Converter.convertClasses(c.innerClasses()),
+                Converter.convertMethods(c.constructors(false)),
+                Converter.convertMethods(c.methods(false)),
+                Converter.convertMethods(annotationElements),
+                Converter.convertFields(c.fields(false)),
+                Converter.convertFields(c.enumConstants()),
+                Converter.obtainPackage(c.containingPackage()),
+                Converter.obtainClass(c.containingClass()),
+                Converter.obtainClass(c.superclass()),
+                Converter.obtainType(c.superclassType()),
+                Converter.convertAnnotationInstances(c.annotations())
+                );
+          cl.setHiddenMethods(Converter.getHiddenMethods(c.methods(false)));
+          cl.setNonWrittenConstructors(Converter.convertNonWrittenConstructors(c.constructors(false)));
+          cl.init3(Converter.convertTypes(c.typeParameters()), Converter.convertClasses(c.innerClasses(false)));
+    }
+
+    public static ClassInfo obtainClass(String className)
+    {
+        return Converter.obtainClass(root.classNamed(className));
+    }
+
+    public static PackageInfo obtainPackage(String packageName)
+    {
+        return Converter.obtainPackage(root.packageNamed(packageName));
+    }
+
+    private static TagInfo convertTag(Tag tag)
+    {
+        return new TextTagInfo(tag.name(), tag.kind(), tag.text(),
+                                Converter.convertSourcePosition(tag.position()));
+    }
+
+    private static ThrowsTagInfo convertThrowsTag(ThrowsTag tag,
+                                                ContainerInfo base)
+    {
+        return new ThrowsTagInfo(tag.name(), tag.text(), tag.kind(),
+                              Converter.obtainClass(tag.exception()),
+                              tag.exceptionComment(), base,
+                              Converter.convertSourcePosition(tag.position()));
+    }
+
+    private static ParamTagInfo convertParamTag(ParamTag tag,
+                                                ContainerInfo base)
+    {
+        return new ParamTagInfo(tag.name(), tag.kind(), tag.text(),
+                              tag.isTypeParameter(), tag.parameterComment(),
+                              tag.parameterName(),
+                              base,
+                              Converter.convertSourcePosition(tag.position()));
+    }
+
+    private static SeeTagInfo convertSeeTag(SeeTag tag, ContainerInfo base)
+    {
+        return new SeeTagInfo(tag.name(), tag.kind(), tag.text(), base,
+                              Converter.convertSourcePosition(tag.position()));
+    }
+
+    private static SourcePositionInfo convertSourcePosition(SourcePosition sp)
+    {
+        if (sp == null) {
+            return null;
+        }
+        return new SourcePositionInfo(sp.file().toString(), sp.line(),
+                                        sp.column());
+    }
+
+    public static TagInfo[] convertTags(Tag[] tags, ContainerInfo base)
+    {
+        int len = tags.length;
+        TagInfo[] out = new TagInfo[len];
+        for (int i=0; i<len; i++) {
+            Tag t = tags[i];
+            /*
+            System.out.println("Tag name='" + t.name() + "' kind='"
+                    + t.kind() + "'");
+            */
+            if (t instanceof SeeTag) {
+                out[i] = Converter.convertSeeTag((SeeTag)t, base);
+            }
+            else if (t instanceof ThrowsTag) {
+                out[i] = Converter.convertThrowsTag((ThrowsTag)t, base);
+            }
+            else if (t instanceof ParamTag) {
+                out[i] = Converter.convertParamTag((ParamTag)t, base);
+            }
+            else {
+                out[i] = Converter.convertTag(t);
+            }
+        }
+        return out;
+    }
+
+    public static ClassInfo[] convertClasses(ClassDoc[] classes)
+    {
+        if (classes == null) return null;
+        int N = classes.length;
+        ClassInfo[] result = new ClassInfo[N];
+        for (int i=0; i<N; i++) {
+            result[i] = Converter.obtainClass(classes[i]);
+        }
+        return result;
+    }
+
+    private static ParameterInfo convertParameter(Parameter p, SourcePosition pos)
+    {
+        if (p == null) return null;
+        ParameterInfo pi = new ParameterInfo(p.name(), p.typeName(),
+                Converter.obtainType(p.type()),
+                Converter.convertSourcePosition(pos));
+        return pi;
+    }
+
+    private static ParameterInfo[] convertParameters(Parameter[] p, MemberDoc m)
+    {
+        SourcePosition pos = m.position();
+        int len = p.length;
+        ParameterInfo[] q = new ParameterInfo[len];
+        for (int i=0; i<len; i++) {
+            q[i] = Converter.convertParameter(p[i], pos);
+        }
+        return q;
+    }
+
+    private static TypeInfo[] convertTypes(Type[] p)
+    {
+        if (p == null) return null;
+        int len = p.length;
+        TypeInfo[] q = new TypeInfo[len];
+        for (int i=0; i<len; i++) {
+            q[i] = Converter.obtainType(p[i]);
+        }
+        return q;
+    }
+
+    private Converter()
+    {
+    }
+
+    private static class ClassNeedingInit
+    {
+        ClassNeedingInit(ClassDoc c, ClassInfo cl)
+        {
+            this.c = c;
+            this.cl = cl;
+        }
+        ClassDoc c;
+        ClassInfo cl;
+    };
+    private static ArrayList<ClassNeedingInit> mClassesNeedingInit
+                                            = new ArrayList<ClassNeedingInit>();
+
+    static ClassInfo obtainClass(ClassDoc o)
+    {
+        return (ClassInfo)mClasses.obtain(o);
+    }
+    private static Cache mClasses = new Cache()
+    {
+        protected Object make(Object o)
+        {
+            ClassDoc c = (ClassDoc)o;
+            ClassInfo cl = new ClassInfo(
+                    c,
+                    c.getRawCommentText(),
+                    Converter.convertSourcePosition(c.position()),
+                    c.isPublic(),
+                    c.isProtected(),
+                    c.isPackagePrivate(),
+                    c.isPrivate(),
+                    c.isStatic(),
+                    c.isInterface(),
+                    c.isAbstract(),
+                    c.isOrdinaryClass(),
+                    c.isException(),
+                    c.isError(),
+                    c.isEnum(),
+                    (c instanceof AnnotationTypeDoc),
+                    c.isFinal(),
+                    c.isIncluded(),
+                    c.name(),
+                    c.qualifiedName(),
+                    c.qualifiedTypeName(),
+                    c.isPrimitive());
+            if (mClassesNeedingInit != null) {
+                mClassesNeedingInit.add(new ClassNeedingInit(c, cl));
+            }
+            return cl;
+        }
+        protected void made(Object o, Object r)
+        {
+            if (mClassesNeedingInit == null) {
+                initClass((ClassDoc)o, (ClassInfo)r);
+                ((ClassInfo)r).init2();
+            }
+        } 
+        ClassInfo[] all()
+        {
+            return (ClassInfo[])mCache.values().toArray(new ClassInfo[mCache.size()]);
+        }
+    };
+    
+    private static MethodInfo[] getHiddenMethods(MethodDoc[] methods){
+      if (methods == null) return null;
+      ArrayList<MethodInfo> out = new ArrayList<MethodInfo>();
+      int N = methods.length;
+      for (int i=0; i<N; i++) {
+          MethodInfo m = Converter.obtainMethod(methods[i]);
+          //System.out.println(m.toString() + ": ");
+          //for (TypeInfo ti : m.getTypeParameters()){
+            //  if (ti.asClassInfo() != null){
+                //System.out.println(" " +ti.asClassInfo().toString());
+              //} else {
+                //System.out.println(" null");
+              //}
+            //}
+          if (m.isHidden()) {
+              out.add(m);
+          }
+      }
+      return out.toArray(new MethodInfo[out.size()]);
+    }
+
+    /**
+     * Convert MethodDoc[] into MethodInfo[].  Also filters according
+     * to the -private, -public option, because the filtering doesn't seem
+     * to be working in the ClassDoc.constructors(boolean) call.
+     */
+    private static MethodInfo[] convertMethods(MethodDoc[] methods)
+    {
+        if (methods == null) return null;
+        ArrayList<MethodInfo> out = new ArrayList<MethodInfo>();
+        int N = methods.length;
+        for (int i=0; i<N; i++) {
+            MethodInfo m = Converter.obtainMethod(methods[i]);
+            //System.out.println(m.toString() + ": ");
+            //for (TypeInfo ti : m.getTypeParameters()){
+              //  if (ti.asClassInfo() != null){
+                  //System.out.println(" " +ti.asClassInfo().toString());
+                //} else {
+                  //System.out.println(" null");
+                //}
+              //}
+            if (m.checkLevel()) {
+                out.add(m);
+            }
+        }
+        return out.toArray(new MethodInfo[out.size()]);
+    }
+
+    private static MethodInfo[] convertMethods(ConstructorDoc[] methods)
+    {
+        if (methods == null) return null;
+        ArrayList<MethodInfo> out = new ArrayList<MethodInfo>();
+        int N = methods.length;
+        for (int i=0; i<N; i++) {
+            MethodInfo m = Converter.obtainMethod(methods[i]);
+            if (m.checkLevel()) {
+                out.add(m);
+            }
+        }
+        return out.toArray(new MethodInfo[out.size()]);
+    }
+    
+    private static MethodInfo[] convertNonWrittenConstructors(ConstructorDoc[] methods)
+    {
+        if (methods == null) return null;
+        ArrayList<MethodInfo> out = new ArrayList<MethodInfo>();
+        int N = methods.length;
+        for (int i=0; i<N; i++) {
+            MethodInfo m = Converter.obtainMethod(methods[i]);
+            if (!m.checkLevel()) {
+                out.add(m);
+            }
+        }
+        return out.toArray(new MethodInfo[out.size()]);
+    }
+
+    private static MethodInfo obtainMethod(MethodDoc o)
+    {
+        return (MethodInfo)mMethods.obtain(o);
+    }
+    private static MethodInfo obtainMethod(ConstructorDoc o)
+    {
+        return (MethodInfo)mMethods.obtain(o);
+    }
+    private static Cache mMethods = new Cache()
+    {
+        protected Object make(Object o)
+        {
+            if (o instanceof AnnotationTypeElementDoc) {
+                AnnotationTypeElementDoc m = (AnnotationTypeElementDoc)o;
+                MethodInfo result = new MethodInfo(
+                                m.getRawCommentText(),
+                                Converter.convertTypes(m.typeParameters()),
+                                m.name(), m.signature(), 
+                                Converter.obtainClass(m.containingClass()),
+                                Converter.obtainClass(m.containingClass()),
+                                m.isPublic(), m.isProtected(),
+                                m.isPackagePrivate(), m.isPrivate(),
+                                m.isFinal(), m.isStatic(), m.isSynthetic(),
+                                m.isAbstract(), m.isSynchronized(), m.isNative(), true,
+                                "annotationElement",
+                                m.flatSignature(),
+                                Converter.obtainMethod(m.overriddenMethod()),
+                                Converter.obtainType(m.returnType()),
+                                Converter.convertParameters(m.parameters(), m),
+                                Converter.convertClasses(m.thrownExceptions()),
+                                Converter.convertSourcePosition(m.position()),
+                                Converter.convertAnnotationInstances(m.annotations())
+                            );
+                result.setVarargs(m.isVarArgs());
+                result.init(Converter.obtainAnnotationValue(m.defaultValue(), result));
+                return result;
+            }
+            else if (o instanceof MethodDoc) {
+                MethodDoc m = (MethodDoc)o;
+                MethodInfo result = new MethodInfo(
+                                m.getRawCommentText(),
+                                Converter.convertTypes(m.typeParameters()),
+                                m.name(), m.signature(), 
+                                Converter.obtainClass(m.containingClass()),
+                                Converter.obtainClass(m.containingClass()),
+                                m.isPublic(), m.isProtected(),
+                                m.isPackagePrivate(), m.isPrivate(),
+                                m.isFinal(), m.isStatic(), m.isSynthetic(),
+                                m.isAbstract(), m.isSynchronized(), m.isNative(), false,
+                                "method",
+                                m.flatSignature(),
+                                Converter.obtainMethod(m.overriddenMethod()),
+                                Converter.obtainType(m.returnType()),
+                                Converter.convertParameters(m.parameters(), m),
+                                Converter.convertClasses(m.thrownExceptions()),
+                                Converter.convertSourcePosition(m.position()),
+                                Converter.convertAnnotationInstances(m.annotations())
+                           );
+                result.setVarargs(m.isVarArgs());
+                result.init(null);
+                return result;
+            }
+            else {
+                ConstructorDoc m = (ConstructorDoc)o;
+                MethodInfo result = new MethodInfo(
+                                m.getRawCommentText(),
+                                Converter.convertTypes(m.typeParameters()),
+                                m.name(), m.signature(), 
+                                Converter.obtainClass(m.containingClass()),
+                                Converter.obtainClass(m.containingClass()),
+                                m.isPublic(), m.isProtected(),
+                                m.isPackagePrivate(), m.isPrivate(),
+                                m.isFinal(), m.isStatic(), m.isSynthetic(),
+                                false, m.isSynchronized(), m.isNative(), false,
+                                "constructor",
+                                m.flatSignature(),
+                                null,
+                                null,
+                                Converter.convertParameters(m.parameters(), m),
+                                Converter.convertClasses(m.thrownExceptions()),
+                                Converter.convertSourcePosition(m.position()),
+                                Converter.convertAnnotationInstances(m.annotations())
+                            );
+                result.setVarargs(m.isVarArgs());
+                result.init(null);
+                return result;
+            }
+        }
+    };
+
+
+    private static FieldInfo[] convertFields(FieldDoc[] fields)
+    {
+        if (fields == null) return null;
+        ArrayList<FieldInfo> out = new ArrayList<FieldInfo>();
+        int N = fields.length;
+        for (int i=0; i<N; i++) {
+            FieldInfo f = Converter.obtainField(fields[i]);
+            if (f.checkLevel()) {
+                out.add(f);
+            }
+        }
+        return out.toArray(new FieldInfo[out.size()]);
+    }
+
+    private static FieldInfo obtainField(FieldDoc o)
+    {
+        return (FieldInfo)mFields.obtain(o);
+    }
+    private static FieldInfo obtainField(ConstructorDoc o)
+    {
+        return (FieldInfo)mFields.obtain(o);
+    }
+    private static Cache mFields = new Cache()
+    {
+        protected Object make(Object o)
+        {
+            FieldDoc f = (FieldDoc)o;
+            return new FieldInfo(f.name(),
+                            Converter.obtainClass(f.containingClass()),
+                            Converter.obtainClass(f.containingClass()),
+                            f.isPublic(), f.isProtected(),
+                            f.isPackagePrivate(), f.isPrivate(),
+                            f.isFinal(), f.isStatic(), f.isTransient(), f.isVolatile(),
+                            f.isSynthetic(),
+                            Converter.obtainType(f.type()),
+                            f.getRawCommentText(), f.constantValue(),
+                            Converter.convertSourcePosition(f.position()),
+                            Converter.convertAnnotationInstances(f.annotations())
+                        );
+        }
+    };
+
+    private static PackageInfo obtainPackage(PackageDoc o)
+    {
+        return (PackageInfo)mPackagees.obtain(o);
+    }
+    private static Cache mPackagees = new Cache()
+    {
+        protected Object make(Object o)
+        {
+            PackageDoc p = (PackageDoc)o;
+            return new PackageInfo(p, p.name(),
+                    Converter.convertSourcePosition(p.position()));
+        }
+    };
+
+    private static TypeInfo obtainType(Type o)
+    {
+        return (TypeInfo)mTypes.obtain(o);
+    }
+    private static Cache mTypes = new Cache()
+    {
+       protected Object make(Object o)
+       {
+           Type t = (Type)o;
+           String simpleTypeName;
+           if (t instanceof ClassDoc) {
+               simpleTypeName = ((ClassDoc)t).name();
+           } else {
+               simpleTypeName = t.simpleTypeName();
+           }
+           TypeInfo ti = new TypeInfo(t.isPrimitive(), t.dimension(),
+                   simpleTypeName, t.qualifiedTypeName(),
+                   Converter.obtainClass(t.asClassDoc()));
+           return ti;
+       }
+        protected void made(Object o, Object r)
+        {
+            Type t = (Type)o;
+            TypeInfo ti = (TypeInfo)r;
+            if (t.asParameterizedType() != null) {
+                ti.setTypeArguments(Converter.convertTypes(
+                            t.asParameterizedType().typeArguments()));
+            }
+            else if (t instanceof ClassDoc) {
+                ti.setTypeArguments(Converter.convertTypes(((ClassDoc)t).typeParameters()));
+            }
+            else if (t.asTypeVariable() != null) {
+                ti.setBounds(null, Converter.convertTypes((t.asTypeVariable().bounds())));
+                ti.setIsTypeVariable(true);
+            }
+            else if (t.asWildcardType() != null) {
+                ti.setIsWildcard(true);
+                ti.setBounds(Converter.convertTypes(t.asWildcardType().superBounds()),
+                             Converter.convertTypes(t.asWildcardType().extendsBounds()));
+            }
+        }
+        protected Object keyFor(Object o)
+        {  
+            Type t = (Type)o;
+            String keyString = o.getClass().getName() + "/" + o.toString() + "/";
+            if (t.asParameterizedType() != null){
+              keyString += t.asParameterizedType().toString() +"/";
+              if (t.asParameterizedType().typeArguments() != null){
+              for(Type ty : t.asParameterizedType().typeArguments()){
+                keyString += ty.toString() + "/";
+              }
+              }
+            }else{
+              keyString += "NoParameterizedType//";
+            }
+            if (t.asTypeVariable() != null){
+              keyString += t.asTypeVariable().toString() +"/";
+              if (t.asTypeVariable().bounds() != null){
+              for(Type ty : t.asTypeVariable().bounds()){
+                keyString += ty.toString() + "/";
+              }
+              }
+            }else{
+              keyString += "NoTypeVariable//";
+            }
+            if (t.asWildcardType() != null){
+              keyString += t.asWildcardType().toString() +"/";
+              if (t.asWildcardType().superBounds() != null){
+              for(Type ty : t.asWildcardType().superBounds()){
+                keyString += ty.toString() + "/";
+              }
+              }
+              if (t.asWildcardType().extendsBounds() != null){
+                for(Type ty : t.asWildcardType().extendsBounds()){
+                  keyString += ty.toString() + "/";
+                }
+                }
+            }else{
+              keyString += "NoWildCardType//";
+            }
+            
+            
+            
+            return keyString;
+        }
+    };
+    
+
+
+    private static MemberInfo obtainMember(MemberDoc o)
+    {
+        return (MemberInfo)mMembers.obtain(o);
+    }
+    private static Cache mMembers = new Cache()
+    {
+        protected Object make(Object o)
+        {
+            if (o instanceof MethodDoc) {
+                return Converter.obtainMethod((MethodDoc)o);
+            }
+            else if (o instanceof ConstructorDoc) {
+                return Converter.obtainMethod((ConstructorDoc)o);
+            }
+            else if (o instanceof FieldDoc) {
+                return Converter.obtainField((FieldDoc)o);
+            }
+            else {
+                return null;
+            }
+        }
+    };
+
+    private static AnnotationInstanceInfo[] convertAnnotationInstances(AnnotationDesc[] orig)
+    {
+        int len = orig.length;
+        AnnotationInstanceInfo[] out = new AnnotationInstanceInfo[len];
+        for (int i=0; i<len; i++) {
+            out[i] = Converter.obtainAnnotationInstance(orig[i]);
+        }
+        return out;
+    }
+
+
+    private static AnnotationInstanceInfo obtainAnnotationInstance(AnnotationDesc o)
+    {
+        return (AnnotationInstanceInfo)mAnnotationInstances.obtain(o);
+    }
+    private static Cache mAnnotationInstances = new Cache()
+    {
+        protected Object make(Object o)
+        {
+            AnnotationDesc a = (AnnotationDesc)o;
+            ClassInfo annotationType = Converter.obtainClass(a.annotationType());
+            AnnotationDesc.ElementValuePair[] ev = a.elementValues();
+            AnnotationValueInfo[] elementValues = new AnnotationValueInfo[ev.length];
+            for (int i=0; i<ev.length; i++) {
+                elementValues[i] = obtainAnnotationValue(ev[i].value(),
+                                            Converter.obtainMethod(ev[i].element()));
+            }
+            return new AnnotationInstanceInfo(annotationType, elementValues);
+        }
+    };
+
+
+    private abstract static class Cache
+    {
+        void put(Object key, Object value)
+        {
+            mCache.put(key, value);
+        }
+        Object obtain(Object o)
+        {
+            if (o == null ) {
+                return null;
+            }
+            Object k = keyFor(o);
+            Object r = mCache.get(k);
+            if (r == null) {
+                r = make(o);
+                mCache.put(k, r);
+                made(o, r);
+            }
+            return r;
+        }
+        protected HashMap<Object,Object> mCache = new HashMap<Object,Object>();
+        protected abstract Object make(Object o);
+        protected void made(Object o, Object r)
+        {
+        }
+        protected Object keyFor(Object o) { return o; }
+        Object[] all() { return null; }
+    }
+
+    // annotation values
+    private static HashMap<AnnotationValue,AnnotationValueInfo> mAnnotationValues = new HashMap();
+    private static HashSet<AnnotationValue> mAnnotationValuesNeedingInit = new HashSet();
+
+    private static AnnotationValueInfo obtainAnnotationValue(AnnotationValue o, MethodInfo element)
+    {
+        if (o == null) {
+            return null;
+        }
+        AnnotationValueInfo v = mAnnotationValues.get(o);
+        if (v != null) return v;
+        v = new AnnotationValueInfo(element);
+        mAnnotationValues.put(o, v);
+        if (mAnnotationValuesNeedingInit != null) {
+            mAnnotationValuesNeedingInit.add(o);
+        } else {
+            initAnnotationValue(o, v);
+        }
+        return v;
+    }
+
+    private static void initAnnotationValue(AnnotationValue o, AnnotationValueInfo v) {
+        Object orig = o.value();
+        Object converted;
+        if (orig instanceof Type) {
+            // class literal
+            converted = Converter.obtainType((Type)orig);
+        }
+        else if (orig instanceof FieldDoc) {
+            // enum constant
+            converted = Converter.obtainField((FieldDoc)orig);
+        }
+        else if (orig instanceof AnnotationDesc) {
+            // annotation instance
+            converted = Converter.obtainAnnotationInstance((AnnotationDesc)orig);
+        }
+        else if (orig instanceof AnnotationValue[]) {
+            AnnotationValue[] old = (AnnotationValue[])orig;
+            AnnotationValueInfo[] array = new AnnotationValueInfo[old.length];
+            for (int i=0; i<array.length; i++) {
+                array[i] = Converter.obtainAnnotationValue(old[i], null);
+            }
+            converted = array;
+        }
+        else {
+            converted = orig;
+        }
+        v.init(converted);
+    }
+
+    private static void finishAnnotationValueInit()
+    {
+        int depth = 0;
+        while (mAnnotationValuesNeedingInit.size() > 0) {
+            HashSet<AnnotationValue> set = mAnnotationValuesNeedingInit;
+            mAnnotationValuesNeedingInit = new HashSet();
+            for (AnnotationValue o: set) {
+                AnnotationValueInfo v = mAnnotationValues.get(o);
+                initAnnotationValue(o, v);
+            }
+            depth++;
+        }
+        mAnnotationValuesNeedingInit = null;
+    }
+}
diff --git a/tools/droiddoc/src/DocFile.java b/tools/droiddoc/src/DocFile.java
new file mode 100644
index 0000000..f53a35c
--- /dev/null
+++ b/tools/droiddoc/src/DocFile.java
@@ -0,0 +1,137 @@
+/*
+ * 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 org.clearsilver.HDF;
+import org.clearsilver.CS;
+import java.util.*;
+import java.io.*;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+
+public class DocFile
+{
+    private static final Pattern LINE = Pattern.compile("(.*)[\r]?\n",
+                                                        Pattern.MULTILINE);
+    private static final Pattern PROP = Pattern.compile("([^=]+)=(.*)");
+
+    public static String readFile(String filename)
+    {
+        try {
+            File f = new File(filename);
+            int length = (int)f.length();
+            FileReader reader = new FileReader(f);
+            char[] buf = new char[length];
+            int index = 0;
+            int amt;
+            while (true) {
+                amt = reader.read(buf, index, length-index);
+
+                if (amt < 1) {
+                    break;
+                }
+
+                index += amt;
+            }
+            return new String(buf, 0, index);
+        }
+        catch (IOException e) {
+            return null;
+        }
+    }
+
+    public static void writePage(String docfile, String relative,
+                                    String outfile)
+    {
+        HDF hdf = DroidDoc.makeHDF();
+
+        /*
+        System.out.println("docfile='" + docfile
+                            + "' relative='" + relative + "'"
+                            + "' outfile='" + outfile + "'");
+        */
+
+        String filedata = readFile(docfile);
+
+        // The document is properties up until the line "@jd:body".
+        // Any blank lines are ignored.
+        int start = -1;
+        int lineno = 1;
+        Matcher lines = LINE.matcher(filedata);
+        String line = null;
+        while (lines.find()) {
+            line = lines.group(1);
+            if (line.length() > 0) {
+                if (line.equals("@jd:body")) {
+                    start = lines.end();
+                    break;
+                }
+                Matcher prop = PROP.matcher(line);
+                if (prop.matches()) {
+                    String key = prop.group(1);
+                    String value = prop.group(2);
+                    hdf.setValue(key, value);
+                } else {
+                    break;
+                }
+            }
+            lineno++;
+        }
+        if (start < 0) {
+            System.err.println(docfile + ":" + lineno + ": error parsing docfile");
+            if (line != null) {
+                System.err.println(docfile + ":" + lineno + ":" + line);
+            }
+            System.exit(1);
+        }
+
+        // if they asked to only be for a certain template, maybe skip it
+        String fromTemplate = hdf.getValue("template.which", "");
+        String fromPage = hdf.getValue("page.onlyfortemplate", "");
+        if (!"".equals(fromPage) && !fromTemplate.equals(fromPage)) {
+            return;
+        }
+
+        // and the actual text after that
+        String commentText = filedata.substring(start);
+
+        Comment comment = new Comment(commentText, null,
+                                    new SourcePositionInfo(docfile, lineno, 1));
+        TagInfo[] tags = comment.tags();
+
+        TagInfo.makeHDF(hdf, "root.descr", tags);
+
+        hdf.setValue("commentText", commentText);
+        
+        if (outfile.indexOf("sdk/") != -1) {
+            hdf.setValue("sdk", "true");
+            if (outfile.indexOf("index.html") != -1) {
+                ClearPage.write(hdf, "sdkpage.cs", outfile);
+            } else {
+                ClearPage.write(hdf, "docpage.cs", outfile);
+            }
+        } else if (outfile.indexOf("guide/") != -1){
+            hdf.setValue("guide", "true");
+            ClearPage.write(hdf, "docpage.cs", outfile);
+        } else if (outfile.indexOf("publish/") != -1){
+            hdf.setValue("publish", "true");
+            ClearPage.write(hdf, "docpage.cs", outfile);
+        } else {
+            ClearPage.write(hdf, "nosidenavpage.cs", outfile);
+        }
+    }
+
+}
diff --git a/tools/droiddoc/src/DocInfo.java b/tools/droiddoc/src/DocInfo.java
new file mode 100644
index 0000000..2530dc2
--- /dev/null
+++ b/tools/droiddoc/src/DocInfo.java
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+public abstract class DocInfo
+{
+    public DocInfo(String rawCommentText, SourcePositionInfo sp)
+    {
+        mRawCommentText = rawCommentText;
+        mPosition = sp;
+    }
+
+    public boolean isHidden()
+    {
+        return comment().isHidden();
+    }
+
+    public boolean isDocOnly() {
+        return comment().isDocOnly();
+    }
+    
+    public String getRawCommentText()
+    {
+        return mRawCommentText;
+    }
+
+    public Comment comment()
+    {
+        if (mComment == null) {
+            mComment = new Comment(mRawCommentText, parent(), mPosition);
+        }
+        return mComment;
+    }
+
+    public SourcePositionInfo position()
+    {
+        return mPosition;
+    }
+
+    public abstract ContainerInfo parent();
+
+    private String mRawCommentText;
+    Comment mComment;
+    SourcePositionInfo mPosition;
+}
+
diff --git a/tools/droiddoc/src/DroidDoc.java b/tools/droiddoc/src/DroidDoc.java
new file mode 100644
index 0000000..f664c41
--- /dev/null
+++ b/tools/droiddoc/src/DroidDoc.java
@@ -0,0 +1,1342 @@
+/*
+ * 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 org.clearsilver.HDF;
+
+import java.util.*;
+import java.io.*;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+public class DroidDoc
+{
+    private static final String SDK_CONSTANT_ANNOTATION = "android.annotation.SdkConstant";
+    private static final String SDK_CONSTANT_TYPE_ACTIVITY_ACTION = "android.annotation.SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION";
+    private static final String SDK_CONSTANT_TYPE_BROADCAST_ACTION = "android.annotation.SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION";
+    private static final String SDK_CONSTANT_TYPE_SERVICE_ACTION = "android.annotation.SdkConstant.SdkConstantType.SERVICE_INTENT_ACTION";
+    private static final String SDK_CONSTANT_TYPE_CATEGORY = "android.annotation.SdkConstant.SdkConstantType.INTENT_CATEGORY";
+    private static final String SDK_WIDGET_ANNOTATION = "android.annotation.Widget";
+    private static final String SDK_LAYOUT_ANNOTATION = "android.annotation.Layout";
+
+    private static final int TYPE_NONE = 0;
+    private static final int TYPE_WIDGET = 1;
+    private static final int TYPE_LAYOUT = 2;
+    private static final int TYPE_LAYOUT_PARAM = 3;
+    
+    public static final int SHOW_PUBLIC = 0x00000001;
+    public static final int SHOW_PROTECTED = 0x00000003;
+    public static final int SHOW_PACKAGE = 0x00000007;
+    public static final int SHOW_PRIVATE = 0x0000000f;
+    public static final int SHOW_HIDDEN = 0x0000001f;
+
+    public static int showLevel = SHOW_PROTECTED;
+
+    public static final String javadocDir = "reference/";
+    public static String htmlExtension;
+
+    public static RootDoc root;
+    public static ArrayList<String[]> mHDFData = new ArrayList<String[]>();
+    public static Map<Character,String> escapeChars = new HashMap<Character,String>();
+    public static String title = "";
+
+    public static boolean checkLevel(int level)
+    {
+        return (showLevel & level) == level;
+    }
+
+    public static boolean checkLevel(boolean pub, boolean prot, boolean pkgp,
+            boolean priv, boolean hidden)
+    {
+        int level = 0;
+        if (hidden && !checkLevel(SHOW_HIDDEN)) {
+            return false;
+        }
+        if (pub && checkLevel(SHOW_PUBLIC)) {
+            return true;
+        }
+        if (prot && checkLevel(SHOW_PROTECTED)) {
+            return true;
+        }
+        if (pkgp && checkLevel(SHOW_PACKAGE)) {
+            return true;
+        }
+        if (priv && checkLevel(SHOW_PRIVATE)) {
+            return true;
+        }
+        return false;
+    }
+    
+    public static boolean start(RootDoc r)
+    {
+        String keepListFile = null;
+        String proofreadFile = null;
+        String todoFile = null;
+        String sdkValuePath = null;
+        ArrayList<SampleCode> sampleCodes = new ArrayList<SampleCode>();
+        String stubsDir = null;
+        //Create the dependency graph for the stubs directory
+        boolean apiXML = false;
+        String apiFile = null;
+        String debugStubsFile = "";
+        HashSet<String> stubPackages = null;
+
+        root = r;
+
+        String[][] options = r.options();
+        for (String[] a: options) {
+            if (a[0].equals("-d")) {
+                ClearPage.outputDir = a[1];
+            }
+            else if (a[0].equals("-templatedir")) {
+                ClearPage.addTemplateDir(a[1]);
+            }
+            else if (a[0].equals("-hdf")) {
+                mHDFData.add(new String[] {a[1], a[2]});
+            }
+            else if (a[0].equals("-toroot")) {
+                ClearPage.toroot = a[1];
+            }
+            else if (a[0].equals("-samplecode")) {
+                sampleCodes.add(new SampleCode(a[1], a[2], a[3]));
+            }
+            else if (a[0].equals("-htmldir")) {
+                ClearPage.htmlDir = a[1];
+            }
+            else if (a[0].equals("-title")) {
+                DroidDoc.title = a[1];
+            }
+            else if (a[0].equals("-werror")) {
+                Errors.setWarningsAreErrors(true);
+            }
+            else if (a[0].equals("-error") || a[0].equals("-warning")
+                    || a[0].equals("-hide")) {
+                try {
+                    int level = -1;
+                    if (a[0].equals("-error")) {
+                        level = Errors.ERROR;
+                    }
+                    else if (a[0].equals("-warning")) {
+                        level = Errors.WARNING;
+                    }
+                    else if (a[0].equals("-hide")) {
+                        level = Errors.HIDDEN;
+                    }
+                    Errors.setErrorLevel(Integer.parseInt(a[1]), level);
+                }
+                catch (NumberFormatException e) {
+                    // already printed below
+                    return false;
+                }
+            }
+            else if (a[0].equals("-keeplist")) {
+                keepListFile = a[1];
+            }
+            else if (a[0].equals("-proofread")) {
+                proofreadFile = a[1];
+            }
+            else if (a[0].equals("-todo")) {
+                todoFile = a[1];
+            }
+            else if (a[0].equals("-public")) {
+                showLevel = SHOW_PUBLIC;
+            }
+            else if (a[0].equals("-protected")) {
+                showLevel = SHOW_PROTECTED;
+            }
+            else if (a[0].equals("-package")) {
+                showLevel = SHOW_PACKAGE;
+            }
+            else if (a[0].equals("-private")) {
+                showLevel = SHOW_PRIVATE;
+            }
+            else if (a[0].equals("-hidden")) {
+                showLevel = SHOW_HIDDEN;
+            }
+            else if (a[0].equals("-stubs")) {
+                stubsDir = a[1];
+            }
+            else if (a[0].equals("-stubpackages")) {
+                stubPackages = new HashSet();
+                for (String pkg: a[1].split(":")) {
+                    stubPackages.add(pkg);
+                }
+            }
+            else if (a[0].equals("-sdkvalues")) {
+                sdkValuePath = a[1];
+            }
+            else if (a[0].equals("-apixml")) {
+                apiXML = true;
+                apiFile = a[1];
+            }
+        }
+
+        // read some prefs from the template
+        if (!readTemplateSettings()) {
+            return false;
+        }
+
+        // Set up the data structures
+        Converter.makeInfo(r);
+
+        // Files for proofreading
+        if (proofreadFile != null) {
+            Proofread.initProofread(proofreadFile);
+        }
+        if (todoFile != null) {
+            TodoFile.writeTodoFile(todoFile);
+        }
+
+        // HTML Pages
+        if (ClearPage.htmlDir != null) {
+            writeHTMLPages();
+        }
+
+        // Navigation tree
+        NavTree.writeNavTree(javadocDir);
+
+        // Packages Pages
+        writePackages(javadocDir
+                        + (ClearPage.htmlDir!=null
+                            ? "packages" + htmlExtension
+                            : "index" + htmlExtension));
+
+        // Classes
+        writeClassLists();
+        writeClasses();
+        writeHierarchy();
+ //      writeKeywords();
+
+        // Lists for JavaScript
+        writeLists();
+        if (keepListFile != null) {
+            writeKeepList(keepListFile);
+        }
+
+        // Sample Code
+        for (SampleCode sc: sampleCodes) {
+            sc.write();
+        }
+
+        // Index page
+        writeIndex();
+
+        Proofread.finishProofread(proofreadFile);
+
+        // Stubs
+        if (stubsDir != null) {
+            Stubs.writeStubs(stubsDir, apiXML, apiFile, stubPackages);
+        }
+        
+        if (sdkValuePath != null) {
+            writeSdkValues(sdkValuePath);
+        }
+
+        Errors.printErrors();
+        return !Errors.hadError;
+    }
+
+    private static void writeIndex() {
+        HDF data = makeHDF();
+        ClearPage.write(data, "index.cs", javadocDir + "index" + htmlExtension);
+    }
+
+    private static boolean readTemplateSettings()
+    {
+        HDF data = makeHDF();
+        htmlExtension = data.getValue("template.extension", ".html");
+        int i=0;
+        while (true) {
+            String k = data.getValue("template.escape." + i + ".key", "");
+            String v = data.getValue("template.escape." + i + ".value", "");
+            if ("".equals(k)) {
+                break;
+            }
+            if (k.length() != 1) {
+                System.err.println("template.escape." + i + ".key must have a length of 1: " + k);
+                return false;
+            }
+            escapeChars.put(k.charAt(0), v);
+            i++;
+        }
+        return true;
+    }
+
+    public static String escape(String s) {
+        if (escapeChars.size() == 0) {
+            return s;
+        }
+        StringBuffer b = null;
+        int begin = 0;
+        final int N = s.length();
+        for (int i=0; i<N; i++) {
+            char c = s.charAt(i);
+            String mapped = escapeChars.get(c);
+            if (mapped != null) {
+                if (b == null) {
+                    b = new StringBuffer(s.length() + mapped.length());
+                }
+                if (begin != i) {
+                    b.append(s.substring(begin, i));
+                }
+                b.append(mapped);
+                begin = i+1;
+            }
+        }
+        if (b != null) {
+            if (begin != N) {
+                b.append(s.substring(begin, N));
+            }
+            return b.toString();
+        }
+        return s;
+    }
+
+    public static void setPageTitle(HDF data, String title)
+    {
+        String s = title;
+        if (DroidDoc.title.length() > 0) {
+            s += " - " + DroidDoc.title;
+        }
+        data.setValue("page.title", s);
+    }
+
+    public static LanguageVersion languageVersion()
+    {
+        return LanguageVersion.JAVA_1_5;
+    }
+
+    public static int optionLength(String option)
+    {
+        if (option.equals("-d")) {
+            return 2;
+        }
+        if (option.equals("-templatedir")) {
+            return 2;
+        }
+        if (option.equals("-hdf")) {
+            return 3;
+        }
+        if (option.equals("-toroot")) {
+            return 2;
+        }
+        if (option.equals("-samplecode")) {
+            return 4;
+        }
+        if (option.equals("-htmldir")) {
+            return 2;
+        }
+        if (option.equals("-title")) {
+            return 2;
+        }
+        if (option.equals("-werror")) {
+            return 1;
+        }
+        if (option.equals("-hide")) {
+            return 2;
+        }
+        if (option.equals("-warning")) {
+            return 2;
+        }
+        if (option.equals("-error")) {
+            return 2;
+        }
+        if (option.equals("-keeplist")) {
+            return 2;
+        }
+        if (option.equals("-proofread")) {
+            return 2;
+        }
+        if (option.equals("-todo")) {
+            return 2;
+        }
+        if (option.equals("-public")) {
+            return 1;
+        }
+        if (option.equals("-protected")) {
+            return 1;
+        }
+        if (option.equals("-package")) {
+            return 1;
+        }
+        if (option.equals("-private")) {
+            return 1;
+        }
+        if (option.equals("-hidden")) {
+            return 1;
+        }
+        if (option.equals("-stubs")) {
+            return 2;
+        }
+        if (option.equals("-stubpackages")) {
+            return 2;
+        }
+        if (option.equals("-sdkvalues")) {
+            return 2;
+        }
+        if (option.equals("-apixml")) {
+            return 2;
+        }
+        return 0;
+    }
+    
+    public static boolean validOptions(String[][] options, DocErrorReporter r)
+    {
+        for (String[] a: options) {
+            if (a[0].equals("-error") || a[0].equals("-warning")
+                    || a[0].equals("-hide")) {
+                try {
+                    Integer.parseInt(a[1]);
+                }
+                catch (NumberFormatException e) {
+                    r.printError("bad -" + a[0] + " value must be a number: "
+                            + a[1]);
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    public static HDF makeHDF()
+    {
+        HDF data = new HDF();
+
+        for (String[] p: mHDFData) {
+            data.setValue(p[0], p[1]);
+        }
+
+        try {
+            for (String p: ClearPage.hdfFiles) {
+                data.readFile(p);
+            }
+        }
+        catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+
+        return data;
+    }
+
+    public static HDF makePackageHDF()
+    {
+        HDF data = makeHDF();
+        ClassInfo[] classes = Converter.rootClasses();
+
+        SortedMap<String, PackageInfo> sorted = new TreeMap<String, PackageInfo>();
+        for (ClassInfo cl: classes) {
+            PackageInfo pkg = cl.containingPackage();
+            String name;
+            if (pkg == null) {
+                name = "";
+            } else {
+                name = pkg.name();
+            }
+            sorted.put(name, pkg);
+        }
+
+        int i = 0;
+        for (String s: sorted.keySet()) {
+            PackageInfo pkg = sorted.get(s);
+
+            if (pkg.isHidden()) {
+                continue;
+            }
+            Boolean allHidden = true;
+            int pass = 0;
+            ClassInfo[] classesToCheck = null;
+            while (pass < 5 ) {
+                switch(pass) {
+                case 0:
+                    classesToCheck = pkg.ordinaryClasses();
+                    break;
+                case 1:
+                    classesToCheck = pkg.enums();
+                    break;
+                case 2:
+                    classesToCheck = pkg.errors();
+                    break;
+                case 3:
+                    classesToCheck = pkg.exceptions();
+                    break;
+                case 4:
+                    classesToCheck = pkg.interfaces();
+                    break;
+                default:
+                    System.err.println("Error reading package: " + pkg.name());
+                    break;
+                }
+                for (ClassInfo cl : classesToCheck) {
+                    if (!cl.isHidden()) {
+                        allHidden = false;
+                        break;
+                    }
+                }
+                if (!allHidden) {
+                    break;
+                }
+                pass++;
+            }
+            if (allHidden) {
+                continue;
+            }
+
+            data.setValue("reference", "true");
+            data.setValue("docs.packages." + i + ".name", s);
+            data.setValue("docs.packages." + i + ".link", pkg.htmlPage());
+            TagInfo.makeHDF(data, "docs.packages." + i + ".shortDescr",
+                                               pkg.firstSentenceTags());
+            i++;
+        }
+
+        return data;
+    }
+
+    public static void writeDirectory(File dir, String relative)
+    {
+        File[] files = dir.listFiles();
+        int i, count = files.length;
+        for (i=0; i<count; i++) {
+            File f = files[i];
+            if (f.isFile()) {
+                String templ = relative + f.getName();
+                int len = templ.length();
+                if (len > 3 && ".cs".equals(templ.substring(len-3))) {
+                    HDF data = makeHDF();
+                    String filename = templ.substring(0,len-3) + htmlExtension;
+                    ClearPage.write(data, templ, filename);
+                }
+                else if (len > 3 && ".jd".equals(templ.substring(len-3))) {
+                    String filename = templ.substring(0,len-3) + htmlExtension;
+                    DocFile.writePage(f.getAbsolutePath(), relative, filename);
+                }
+                else {
+                    ClearPage.copyFile(f, templ);
+                }
+            }
+            else if (f.isDirectory()) {
+                writeDirectory(f, relative + f.getName() + "/");
+            }
+        }
+    }
+
+    public static void writeHTMLPages()
+    {
+        File f = new File(ClearPage.htmlDir);
+        if (!f.isDirectory()) {
+            System.err.println("htmlDir not a directory: " + ClearPage.htmlDir);
+        }
+        writeDirectory(f, "");
+    }
+
+    public static void writeLists()
+    {
+        HDF data = makeHDF();
+
+        ClassInfo[] classes = Converter.rootClasses();
+
+        SortedMap<String, Object> sorted = new TreeMap<String, Object>();
+        for (ClassInfo cl: classes) {
+            if (cl.isHidden()) {
+                continue;
+            }
+            sorted.put(cl.qualifiedName(), cl);
+            PackageInfo pkg = cl.containingPackage();
+            String name;
+            if (pkg == null) {
+                name = "";
+            } else {
+                name = pkg.name();
+            }
+            sorted.put(name, pkg);
+        }
+
+        int i = 0;
+        for (String s: sorted.keySet()) {
+            data.setValue("docs.pages." + i + ".id" , ""+i);
+            data.setValue("docs.pages." + i + ".label" , s);
+
+            Object o = sorted.get(s);
+            if (o instanceof PackageInfo) {
+                PackageInfo pkg = (PackageInfo)o;
+                data.setValue("docs.pages." + i + ".link" , pkg.htmlPage());
+                data.setValue("docs.pages." + i + ".type" , "package");
+            }
+            else if (o instanceof ClassInfo) {
+                ClassInfo cl = (ClassInfo)o;
+                data.setValue("docs.pages." + i + ".link" , cl.htmlPage());
+                data.setValue("docs.pages." + i + ".type" , "class");
+            }
+            i++;
+        }
+
+        ClearPage.write(data, "lists.cs", javadocDir + "lists.js");
+    }
+
+    public static void cantStripThis(ClassInfo cl, HashSet<ClassInfo> notStrippable) {
+        if (!notStrippable.add(cl)) {
+            // slight optimization: if it already contains cl, it already contains
+            // all of cl's parents
+            return;
+        }
+        ClassInfo supr = cl.superclass();
+        if (supr != null) {
+            cantStripThis(supr, notStrippable);
+        }
+        for (ClassInfo iface: cl.interfaces()) {
+            cantStripThis(iface, notStrippable);
+        }
+    }
+
+    private static String getPrintableName(ClassInfo cl) {
+        ClassInfo containingClass = cl.containingClass();
+        if (containingClass != null) {
+            // This is an inner class.
+            String baseName = cl.name();
+            baseName = baseName.substring(baseName.lastIndexOf('.') + 1);
+            return getPrintableName(containingClass) + '$' + baseName;
+        }
+        return cl.qualifiedName();
+    }
+
+    /**
+     * Writes the list of classes that must be present in order to
+     * provide the non-hidden APIs known to javadoc.
+     *
+     * @param filename the path to the file to write the list to
+     */
+    public static void writeKeepList(String filename) {
+        HashSet<ClassInfo> notStrippable = new HashSet<ClassInfo>();
+        ClassInfo[] all = Converter.allClasses();
+        Arrays.sort(all); // just to make the file a little more readable
+
+        // If a class is public and not hidden, then it and everything it derives
+        // from cannot be stripped.  Otherwise we can strip it.
+        for (ClassInfo cl: all) {
+            if (cl.isPublic() && !cl.isHidden()) {
+                cantStripThis(cl, notStrippable);
+            }
+        }
+        PrintStream stream = null;
+        try {
+            stream = new PrintStream(filename);
+            for (ClassInfo cl: notStrippable) {
+                stream.println(getPrintableName(cl));
+            }
+        }
+        catch (FileNotFoundException e) {
+            System.err.println("error writing file: " + filename);
+        }
+        finally {
+            if (stream != null) {
+                stream.close();
+            }
+        }
+    }
+
+    private static PackageInfo[] sVisiblePackages = null;
+    public static PackageInfo[] choosePackages() {
+        if (sVisiblePackages != null) {
+            return sVisiblePackages;
+        }
+
+        ClassInfo[] classes = Converter.rootClasses();
+        SortedMap<String, PackageInfo> sorted = new TreeMap<String, PackageInfo>();
+        for (ClassInfo cl: classes) {
+            PackageInfo pkg = cl.containingPackage();
+            String name;
+            if (pkg == null) {
+                name = "";
+            } else {
+                name = pkg.name();
+            }
+            sorted.put(name, pkg);
+        }
+
+        ArrayList<PackageInfo> result = new ArrayList();
+
+        for (String s: sorted.keySet()) {
+            PackageInfo pkg = sorted.get(s);
+
+            if (pkg.isHidden()) {
+                continue;
+            }
+            Boolean allHidden = true;
+            int pass = 0;
+            ClassInfo[] classesToCheck = null;
+            while (pass < 5 ) {
+                switch(pass) {
+                case 0:
+                    classesToCheck = pkg.ordinaryClasses();
+                    break;
+                case 1:
+                    classesToCheck = pkg.enums();
+                    break;
+                case 2:
+                    classesToCheck = pkg.errors();
+                    break;
+                case 3:
+                    classesToCheck = pkg.exceptions();
+                    break;
+                case 4:
+                    classesToCheck = pkg.interfaces();
+                    break;
+                default:
+                    System.err.println("Error reading package: " + pkg.name());
+                    break;
+                }
+                for (ClassInfo cl : classesToCheck) {
+                    if (!cl.isHidden()) {
+                        allHidden = false;
+                        break;
+                    }
+                }
+                if (!allHidden) {
+                    break;
+                }
+                pass++;
+            }
+            if (allHidden) {
+                continue;
+            }
+
+            result.add(pkg);
+        }
+
+        sVisiblePackages = result.toArray(new PackageInfo[result.size()]);
+        return sVisiblePackages;
+    }
+
+    public static void writePackages(String filename)
+    {
+        HDF data = makePackageHDF();
+
+        int i = 0;
+        for (PackageInfo pkg: choosePackages()) {
+            writePackage(pkg);
+
+            data.setValue("docs.packages." + i + ".name", pkg.name());
+            data.setValue("docs.packages." + i + ".link", pkg.htmlPage());
+            TagInfo.makeHDF(data, "docs.packages." + i + ".shortDescr",
+                            pkg.firstSentenceTags());
+
+            i++;
+        }
+
+        setPageTitle(data, "Package Index");
+
+        TagInfo.makeHDF(data, "root.descr",
+                Converter.convertTags(root.inlineTags(), null));
+
+        ClearPage.write(data, "packages.cs", filename);
+        ClearPage.write(data, "package-list.cs", javadocDir + "package-list");
+
+        Proofread.writePackages(filename,
+                Converter.convertTags(root.inlineTags(), null));
+    }
+
+    public static void writePackage(PackageInfo pkg)
+    {
+        // these this and the description are in the same directory,
+        // so it's okay
+        HDF data = makePackageHDF();
+
+        String name = pkg.name();
+
+        data.setValue("package.name", name);
+        data.setValue("package.descr", "...description...");
+
+        makeClassListHDF(data, "package.interfaces", 
+                         ClassInfo.sortByName(pkg.interfaces()));
+        makeClassListHDF(data, "package.classes",
+                         ClassInfo.sortByName(pkg.ordinaryClasses()));
+        makeClassListHDF(data, "package.enums",
+                         ClassInfo.sortByName(pkg.enums()));
+        makeClassListHDF(data, "package.exceptions",
+                         ClassInfo.sortByName(pkg.exceptions()));
+        makeClassListHDF(data, "package.errors",
+                         ClassInfo.sortByName(pkg.errors()));
+        TagInfo.makeHDF(data, "package.shortDescr",
+                         pkg.firstSentenceTags());
+        TagInfo.makeHDF(data, "package.descr", pkg.inlineTags());
+
+        String filename = pkg.htmlPage();
+        setPageTitle(data, name);
+        ClearPage.write(data, "package.cs", filename);
+
+        filename = pkg.fullDescriptionHtmlPage();
+        setPageTitle(data, name + " Details");
+        ClearPage.write(data, "package-descr.cs", filename);
+
+        Proofread.writePackage(filename, pkg.inlineTags());
+    }
+
+    public static void writeClassLists()
+    {
+        int i;
+        HDF data = makePackageHDF();
+
+        ClassInfo[] classes = PackageInfo.filterHidden(
+                                    Converter.convertClasses(root.classes()));
+        if (classes.length == 0) {
+            return ;
+        }
+
+        Sorter[] sorted = new Sorter[classes.length];
+        for (i=0; i<sorted.length; i++) {
+            ClassInfo cl = classes[i];
+            String name = cl.name();
+            sorted[i] = new Sorter(name, cl);
+        }
+
+        Arrays.sort(sorted);
+
+        // make a pass and resolve ones that have the same name
+        int firstMatch = 0;
+        String lastName = sorted[0].label;
+        for (i=1; i<sorted.length; i++) {
+            String s = sorted[i].label;
+            if (!lastName.equals(s)) {
+                if (firstMatch != i-1) {
+                    // there were duplicates
+                    for (int j=firstMatch; j<i; j++) {
+                        PackageInfo pkg = ((ClassInfo)sorted[j].data).containingPackage();
+                        if (pkg != null) {
+                            sorted[j].label = sorted[j].label + " (" + pkg.name() + ")";
+                        }
+                    }
+                }
+                firstMatch = i;
+                lastName = s;
+            }
+        }
+
+        // and sort again
+        Arrays.sort(sorted);
+
+        for (i=0; i<sorted.length; i++) {
+            String s = sorted[i].label;
+            ClassInfo cl = (ClassInfo)sorted[i].data;
+            char first = Character.toUpperCase(s.charAt(0));
+            cl.makeShortDescrHDF(data, "docs.classes." + first + '.' + i);
+        }
+
+        setPageTitle(data, "Class Index");
+        ClearPage.write(data, "classes.cs", javadocDir + "classes" + htmlExtension);
+    }
+
+    // we use the word keywords because "index" means something else in html land
+    // the user only ever sees the word index
+/*    public static void writeKeywords()
+    {
+        ArrayList<KeywordEntry> keywords = new ArrayList<KeywordEntry>();
+
+        ClassInfo[] classes = PackageInfo.filterHidden(Converter.convertClasses(root.classes()));
+
+        for (ClassInfo cl: classes) {
+            cl.makeKeywordEntries(keywords);
+        }
+
+        HDF data = makeHDF();
+
+        Collections.sort(keywords);
+        
+        int i=0;
+        for (KeywordEntry entry: keywords) {
+            String base = "keywords." + entry.firstChar() + "." + i;
+            entry.makeHDF(data, base);
+            i++;
+        }
+
+        setPageTitle(data, "Index");
+        ClearPage.write(data, "keywords.cs", javadocDir + "keywords" + htmlExtension);
+    } */
+
+    public static void writeHierarchy()
+    {
+        ClassInfo[] classes = Converter.rootClasses();
+        ArrayList<ClassInfo> info = new ArrayList<ClassInfo>();
+        for (ClassInfo cl: classes) {
+            if (!cl.isHidden()) {
+                info.add(cl);
+            }
+        }
+        HDF data = makePackageHDF();
+        Hierarchy.makeHierarchy(data, info.toArray(new ClassInfo[info.size()]));
+        setPageTitle(data, "Class Hierarchy");
+        ClearPage.write(data, "hierarchy.cs", javadocDir + "hierarchy" + htmlExtension);
+    }
+
+    public static void writeClasses()
+    {
+        ClassInfo[] classes = Converter.rootClasses();
+
+        for (ClassInfo cl: classes) {
+            HDF data = makePackageHDF();
+            if (!cl.isHidden()) {
+                writeClass(cl, data);
+            }
+        }
+    }
+
+    public static void writeClass(ClassInfo cl, HDF data)
+    {
+        cl.makeHDF(data);
+
+        setPageTitle(data, cl.name());
+        ClearPage.write(data, "class.cs", cl.htmlPage());
+
+        Proofread.writeClass(cl.htmlPage(), cl);
+    }
+
+    public static void makeClassListHDF(HDF data, String base,
+            ClassInfo[] classes)
+    {
+        for (int i=0; i<classes.length; i++) {
+            ClassInfo cl = classes[i];
+            if (!cl.isHidden()) {
+                cl.makeShortDescrHDF(data, base + "." + i);
+            }
+        }
+    }
+
+    public static String linkTarget(String source, String target)
+    {
+        String[] src = source.split("/");
+        String[] tgt = target.split("/");
+
+        int srclen = src.length;
+        int tgtlen = tgt.length;
+
+        int same = 0;
+        while (same < (srclen-1)
+                && same < (tgtlen-1)
+                && (src[same].equals(tgt[same]))) {
+            same++;
+        }
+
+        String s = "";
+
+        int up = srclen-same-1;
+        for (int i=0; i<up; i++) {
+            s += "../";
+        }
+
+
+        int N = tgtlen-1;
+        for (int i=same; i<N; i++) {
+            s += tgt[i] + '/';
+        }
+        s += tgt[tgtlen-1];
+
+        return s;
+    }
+
+    /**
+     * Returns true if the given element has an @hide annotation.
+     */
+    private static boolean hasHideAnnotation(Doc doc) {
+        return doc.getRawCommentText().indexOf("@hide") != -1;
+    }
+
+    /**
+     * Returns true if the given element is hidden.
+     */
+    private static boolean isHidden(Doc doc) {
+        // Methods, fields, constructors.
+        if (doc instanceof MemberDoc) {
+            return hasHideAnnotation(doc);
+        }
+
+        // Classes, interfaces, enums, annotation types.
+        if (doc instanceof ClassDoc) {
+            ClassDoc classDoc = (ClassDoc) doc;
+
+            // Check the containing package.
+            if (hasHideAnnotation(classDoc.containingPackage())) {
+                return true;
+            }
+
+            // Check the class doc and containing class docs if this is a
+            // nested class.
+            ClassDoc current = classDoc;
+            do {
+                if (hasHideAnnotation(current)) {
+                    return true;
+                }
+
+                current = current.containingClass();
+            } while (current != null);
+        }
+
+        return false;
+    }
+
+    /**
+     * Filters out hidden elements.
+     */
+    private static Object filterHidden(Object o, Class<?> expected) {
+        if (o == null) {
+            return null;
+        }
+
+        Class type = o.getClass();
+        if (type.getName().startsWith("com.sun.")) {
+            // TODO: Implement interfaces from superclasses, too.
+            return Proxy.newProxyInstance(type.getClassLoader(),
+                    type.getInterfaces(), new HideHandler(o));
+        } else if (o instanceof Object[]) {
+            Class<?> componentType = expected.getComponentType();
+            Object[] array = (Object[]) o;
+            List<Object> list = new ArrayList<Object>(array.length);
+            for (Object entry : array) {
+                if ((entry instanceof Doc) && isHidden((Doc) entry)) {
+                    continue;
+                }
+                list.add(filterHidden(entry, componentType));
+            }
+            return list.toArray(
+                    (Object[]) Array.newInstance(componentType, list.size()));
+        } else {
+            return o;
+        }
+    }
+
+    /**
+     * Filters hidden elements out of method return values.
+     */
+    private static class HideHandler implements InvocationHandler {
+
+        private final Object target;
+
+        public HideHandler(Object target) {
+            this.target = target;
+        }
+
+        public Object invoke(Object proxy, Method method, Object[] args)
+                throws Throwable {
+            String methodName = method.getName();
+            if (args != null) {
+                if (methodName.equals("compareTo") ||
+                    methodName.equals("equals") ||
+                    methodName.equals("overrides") ||
+                    methodName.equals("subclassOf")) {
+                    args[0] = unwrap(args[0]);
+                }
+            }
+
+            if (methodName.equals("getRawCommentText")) {
+                return filterComment((String) method.invoke(target, args));
+            }
+            
+            // escape "&" in disjunctive types.
+            if (proxy instanceof Type && methodName.equals("toString")) {
+                return ((String) method.invoke(target, args))
+                        .replace("&", "&amp;");
+            }
+
+            try {
+                return filterHidden(method.invoke(target, args),
+                        method.getReturnType());
+            } catch (InvocationTargetException e) {
+                throw e.getTargetException();
+            }
+        }
+
+        private String filterComment(String s) {
+            if (s == null) {
+                return null;
+            }
+
+            s = s.trim();
+
+            // Work around off by one error
+            while (s.length() >= 5
+                    && s.charAt(s.length() - 5) == '{') {
+                s += "&nbsp;";
+            }
+
+            return s;
+        }
+
+        private static Object unwrap(Object proxy) {
+            if (proxy instanceof Proxy)
+                return ((HideHandler)Proxy.getInvocationHandler(proxy)).target;
+            return proxy;
+        }
+    }
+
+    public static String scope(Scoped scoped) {
+        if (scoped.isPublic()) {
+            return "public";
+        }
+        else if (scoped.isProtected()) {
+            return "protected";
+        }
+        else if (scoped.isPackagePrivate()) {
+            return "";
+        }
+        else if (scoped.isPrivate()) {
+            return "private";
+        }
+        else {
+            throw new RuntimeException("invalid scope for object " + scoped);
+        }
+    }
+    
+    /**
+     * Collect the values used by the Dev tools and write them in files packaged with the SDK
+     * @param output the ouput directory for the files.
+     */
+    private static void writeSdkValues(String output) {
+        ArrayList<String> activityActions = new ArrayList<String>();
+        ArrayList<String> broadcastActions = new ArrayList<String>();
+        ArrayList<String> serviceActions = new ArrayList<String>();
+        ArrayList<String> categories = new ArrayList<String>();
+        
+        ArrayList<ClassInfo> layouts = new ArrayList<ClassInfo>();
+        ArrayList<ClassInfo> widgets = new ArrayList<ClassInfo>();
+        ArrayList<ClassInfo> layoutParams = new ArrayList<ClassInfo>();
+        
+        ClassInfo[] classes = Converter.allClasses();
+
+        // Go through all the fields of all the classes, looking SDK stuff.
+        for (ClassInfo clazz : classes) {
+            
+            // first check constant fields for the SdkConstant annotation.
+            FieldInfo[] fields = clazz.allSelfFields();
+            for (FieldInfo field : fields) {
+                Object cValue = field.constantValue();
+                if (cValue != null) {
+                    AnnotationInstanceInfo[] annotations = field.annotations();
+                    if (annotations.length > 0) {
+                        for (AnnotationInstanceInfo annotation : annotations) {
+                            if (SDK_CONSTANT_ANNOTATION.equals(annotation.type().qualifiedName())) {
+                                AnnotationValueInfo[] values = annotation.elementValues();
+                                if (values.length > 0) {
+                                    String type = values[0].valueString();
+                                    if (SDK_CONSTANT_TYPE_ACTIVITY_ACTION.equals(type)) {
+                                        activityActions.add(cValue.toString());
+                                    } else if (SDK_CONSTANT_TYPE_BROADCAST_ACTION.equals(type)) {
+                                        broadcastActions.add(cValue.toString());
+                                    } else if (SDK_CONSTANT_TYPE_SERVICE_ACTION.equals(type)) {
+                                        serviceActions.add(cValue.toString());
+                                    } else if (SDK_CONSTANT_TYPE_CATEGORY.equals(type)) {
+                                        categories.add(cValue.toString());
+                                    }
+                                }
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+            
+            // Now check the class for @Widget or if its in the android.widget package
+            // (unless the class is hidden or abstract, or non public)
+            if (clazz.isHidden() == false && clazz.isPublic() && clazz.isAbstract() == false) {
+                boolean annotated = false;
+                AnnotationInstanceInfo[] annotations = clazz.annotations();
+                if (annotations.length > 0) {
+                    for (AnnotationInstanceInfo annotation : annotations) {
+                        if (SDK_WIDGET_ANNOTATION.equals(annotation.type().qualifiedName())) {
+                            widgets.add(clazz);
+                            annotated = true;
+                            break;
+                        } else if (SDK_LAYOUT_ANNOTATION.equals(annotation.type().qualifiedName())) {
+                            layouts.add(clazz);
+                            annotated = true;
+                            break;
+                        }
+                    }
+                }
+                
+                if (annotated == false) {
+                    // lets check if this is inside android.widget
+                    PackageInfo pckg = clazz.containingPackage();
+                    String packageName = pckg.name();
+                    if ("android.widget".equals(packageName) ||
+                            "android.view".equals(packageName)) {
+                        // now we check what this class inherits either from android.view.ViewGroup
+                        // or android.view.View, or android.view.ViewGroup.LayoutParams
+                        int type = checkInheritance(clazz);
+                        switch (type) {
+                            case TYPE_WIDGET:
+                                widgets.add(clazz);
+                                break;
+                            case TYPE_LAYOUT:
+                                layouts.add(clazz);
+                                break;
+                            case TYPE_LAYOUT_PARAM:
+                                layoutParams.add(clazz);
+                                break;
+                        }
+                    }
+                }
+            }
+        }
+
+        // now write the files, whether or not the list are empty.
+        // the SDK built requires those files to be present.
+
+        Collections.sort(activityActions);
+        writeValues(output + "/activity_actions.txt", activityActions);
+
+        Collections.sort(broadcastActions);
+        writeValues(output + "/broadcast_actions.txt", broadcastActions);
+
+        Collections.sort(serviceActions);
+        writeValues(output + "/service_actions.txt", serviceActions);
+
+        Collections.sort(categories);
+        writeValues(output + "/categories.txt", categories);
+        
+        // before writing the list of classes, we do some checks, to make sure the layout params
+        // are enclosed by a layout class (and not one that has been declared as a widget)
+        for (int i = 0 ; i < layoutParams.size();) {
+            ClassInfo layoutParamClass = layoutParams.get(i);
+            ClassInfo containingClass = layoutParamClass.containingClass();
+            if (containingClass == null || layouts.indexOf(containingClass) == -1) {
+                layoutParams.remove(i);
+            } else {
+                i++;
+            }
+        }
+        
+        writeClasses(output + "/widgets.txt", widgets, layouts, layoutParams);
+    }
+    
+    /**
+     * Writes a list of values into a text files.
+     * @param pathname the absolute os path of the output file.
+     * @param values the list of values to write.
+     */
+    private static void writeValues(String pathname, ArrayList<String> values) {
+        FileWriter fw = null;
+        BufferedWriter bw = null;
+        try {
+            fw = new FileWriter(pathname, false);
+            bw = new BufferedWriter(fw);
+            
+            for (String value : values) {
+                bw.append(value).append('\n');
+            }
+        } catch (IOException e) {
+            // pass for now
+        } finally {
+            try {
+                if (bw != null) bw.close();
+            } catch (IOException e) {
+                // pass for now
+            }
+            try {
+                if (fw != null) fw.close();
+            } catch (IOException e) {
+                // pass for now
+            }
+        }
+    }
+
+    /**
+     * Writes the widget/layout/layout param classes into a text files.
+     * @param pathname the absolute os path of the output file.
+     * @param widgets the list of widget classes to write.
+     * @param layouts the list of layout classes to write.
+     * @param layoutParams the list of layout param classes to write.
+     */
+    private static void writeClasses(String pathname, ArrayList<ClassInfo> widgets,
+            ArrayList<ClassInfo> layouts, ArrayList<ClassInfo> layoutParams) {
+        FileWriter fw = null;
+        BufferedWriter bw = null;
+        try {
+            fw = new FileWriter(pathname, false);
+            bw = new BufferedWriter(fw);
+            
+            // write the 3 types of classes.
+            for (ClassInfo clazz : widgets) {
+                writeClass(bw, clazz, 'W');
+            }
+            for (ClassInfo clazz : layoutParams) {
+                writeClass(bw, clazz, 'P');
+            }
+            for (ClassInfo clazz : layouts) {
+                writeClass(bw, clazz, 'L');
+            }
+        } catch (IOException e) {
+            // pass for now
+        } finally {
+            try {
+                if (bw != null) bw.close();
+            } catch (IOException e) {
+                // pass for now
+            }
+            try {
+                if (fw != null) fw.close();
+            } catch (IOException e) {
+                // pass for now
+            }
+        }
+    }
+
+    /**
+     * Writes a class name and its super class names into a {@link BufferedWriter}.
+     * @param writer the BufferedWriter to write into
+     * @param clazz the class to write
+     * @param prefix the prefix to put at the beginning of the line.
+     * @throws IOException
+     */
+    private static void writeClass(BufferedWriter writer, ClassInfo clazz, char prefix)
+            throws IOException {
+        writer.append(prefix).append(clazz.qualifiedName());
+        ClassInfo superClass = clazz;
+        while ((superClass = superClass.superclass()) != null) {
+            writer.append(' ').append(superClass.qualifiedName());
+        }
+        writer.append('\n');
+    }
+    
+    /**
+     * Checks the inheritance of {@link ClassInfo} objects. This method return
+     * <ul>
+     * <li>{@link #TYPE_LAYOUT}: if the class extends <code>android.view.ViewGroup</code></li>
+     * <li>{@link #TYPE_WIDGET}: if the class extends <code>android.view.View</code></li>
+     * <li>{@link #TYPE_LAYOUT_PARAM}: if the class extends <code>android.view.ViewGroup$LayoutParams</code></li>
+     * <li>{@link #TYPE_NONE}: in all other cases</li>
+     * </ul> 
+     * @param clazz the {@link ClassInfo} to check.
+     */
+    private static int checkInheritance(ClassInfo clazz) {
+        if ("android.view.ViewGroup".equals(clazz.qualifiedName())) {
+            return TYPE_LAYOUT;
+        } else if ("android.view.View".equals(clazz.qualifiedName())) {
+            return TYPE_WIDGET;
+        } else if ("android.view.ViewGroup.LayoutParams".equals(clazz.qualifiedName())) {
+            return TYPE_LAYOUT_PARAM;
+        }
+        
+        ClassInfo parent = clazz.superclass();
+        if (parent != null) {
+            return checkInheritance(parent);
+        }
+        
+        return TYPE_NONE;
+    }
+}
diff --git a/tools/droiddoc/src/Errors.java b/tools/droiddoc/src/Errors.java
new file mode 100644
index 0000000..dfeac88
--- /dev/null
+++ b/tools/droiddoc/src/Errors.java
@@ -0,0 +1,143 @@
+/*
+ * 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 java.util.SortedSet;
+import java.util.TreeSet;
+
+public class Errors
+{
+    public static boolean hadError = false;
+    private static boolean warningsAreErrors = false;
+    private static TreeSet<Message> allErrors = new TreeSet<Message>();
+
+    private static class Message implements Comparable {
+        SourcePositionInfo pos;
+        int level;
+        String msg;
+
+        Message(SourcePositionInfo p, int l, String m) {
+            pos = p;
+            level = l;
+            msg = m;
+        }
+
+        public int compareTo(Object o) {
+            Message that = (Message)o;
+            int r = this.pos.compareTo(that.pos);
+            if (r != 0) return r;
+            return this.msg.compareTo(that.msg);
+        }
+
+        public String toString() {
+            String whereText = this.pos == null ? "unknown: " : this.pos.toString() + ':';
+            return whereText + this.msg;
+        }
+    }
+
+    public static void error(Error error, SourcePositionInfo where, String text) {
+        if (error.level == HIDDEN) {
+            return;
+        }
+
+        int level = (!warningsAreErrors && error.level == WARNING) ? WARNING : ERROR;
+        String which = level == WARNING ? " warning " : " error ";
+        String message = which + error.code + ": " + text;
+
+        if (where == null) {
+            where = new SourcePositionInfo("unknown", 0, 0);
+        }
+
+        allErrors.add(new Message(where, level, message));
+
+        if (error.level == ERROR || (warningsAreErrors && error.level == WARNING)) {
+            hadError = true;
+        }
+    }
+
+    public static void printErrors() {
+        for (Message m: allErrors) {
+            if (m.level == WARNING) {
+                System.err.println(m.toString());
+            }
+        }
+        for (Message m: allErrors) {
+            if (m.level == ERROR) {
+                System.err.println(m.toString());
+            }
+        }
+    }
+
+    public static int HIDDEN = 0;
+    public static int WARNING = 1;
+    public static int ERROR = 2;
+
+    public static void setWarningsAreErrors(boolean val) {
+        warningsAreErrors = val;
+    }
+
+    public static class Error {
+        public int code;
+        public int level;
+
+        public Error(int code, int level)
+        {
+            this.code = code;
+            this.level = level;
+        }
+    }
+
+    public static Error UNRESOLVED_LINK = new Error(1, WARNING);
+    public static Error BAD_INCLUDE_TAG = new Error(2, WARNING);
+    public static Error UNKNOWN_TAG = new Error(3, WARNING);
+    public static Error UNKNOWN_PARAM_TAG_NAME = new Error(4, WARNING);
+    public static Error UNDOCUMENTED_PARAMETER = new Error(5, HIDDEN);
+    public static Error BAD_ATTR_TAG = new Error(6, ERROR);
+    public static Error BAD_INHERITDOC = new Error(7, HIDDEN);
+    public static Error HIDDEN_LINK = new Error(8, WARNING);
+    public static Error HIDDEN_CONSTRUCTOR = new Error(9, WARNING);
+    public static Error UNAVAILABLE_SYMBOL = new Error(10, ERROR);
+    public static Error HIDDEN_SUPERCLASS = new Error(11, WARNING);
+    public static Error DEPRECATED = new Error(12, HIDDEN);
+    public static Error DEPRECATION_MISMATCH = new Error(13, WARNING);
+    public static Error MISSING_COMMENT = new Error(14, WARNING);
+    public static Error IO_ERROR = new Error(15, HIDDEN);
+
+    public static Error[] ERRORS = {
+            UNRESOLVED_LINK,
+            BAD_INCLUDE_TAG,
+            UNKNOWN_TAG,
+            UNKNOWN_PARAM_TAG_NAME,
+            UNDOCUMENTED_PARAMETER,
+            BAD_ATTR_TAG,
+            BAD_INHERITDOC,
+            HIDDEN_LINK,
+            HIDDEN_CONSTRUCTOR,
+            UNAVAILABLE_SYMBOL,
+            HIDDEN_SUPERCLASS,
+            DEPRECATED,
+            IO_ERROR,
+        };
+
+    public static boolean setErrorLevel(int code, int level) {
+        for (Error e: ERRORS) {
+            if (e.code == code) {
+                e.level = level;
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/tools/droiddoc/src/FieldInfo.java b/tools/droiddoc/src/FieldInfo.java
new file mode 100644
index 0000000..536d798
--- /dev/null
+++ b/tools/droiddoc/src/FieldInfo.java
@@ -0,0 +1,315 @@
+/*
+ * 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 org.clearsilver.HDF;
+import org.clearsilver.CS;
+
+import java.util.Comparator;
+
+public class FieldInfo extends MemberInfo
+{
+    public static final Comparator<FieldInfo> comparator = new Comparator<FieldInfo>() {
+        public int compare(FieldInfo a, FieldInfo b) {
+            return a.name().compareTo(b.name());
+        }
+    };
+    
+    public FieldInfo(String name, ClassInfo containingClass, ClassInfo realContainingClass,
+                        boolean isPublic, boolean isProtected,
+                        boolean isPackagePrivate, boolean isPrivate,
+                        boolean isFinal, boolean isStatic, boolean isTransient, boolean isVolatile,
+                        boolean isSynthetic, TypeInfo type, String rawCommentText,
+                        Object constantValue,
+                        SourcePositionInfo position,
+                        AnnotationInstanceInfo[] annotations)
+    {
+        super(rawCommentText, name, null, containingClass, realContainingClass,
+                isPublic, isProtected, isPackagePrivate, isPrivate,
+                isFinal, isStatic, isSynthetic, chooseKind(isFinal, isStatic), position,
+                annotations);
+        mIsTransient = isTransient;
+        mIsVolatile = isVolatile;
+        mType = type;
+        mConstantValue = constantValue;
+    }
+
+    public FieldInfo cloneForClass(ClassInfo newContainingClass) {
+        return new FieldInfo(name(), newContainingClass, realContainingClass(),
+                isPublic(), isProtected(), isPackagePrivate(),
+                isPrivate(), isFinal(), isStatic(), isTransient(), isVolatile(),
+                isSynthetic(), mType, getRawCommentText(), mConstantValue, position(),
+                annotations());
+    }
+
+    static String chooseKind(boolean isFinal, boolean isStatic)
+    {
+        if (isStatic && isFinal) {
+            return "constant";
+        } else {
+            return "field";
+        }
+    }
+
+    public TypeInfo type()
+    {
+        return mType;
+    }
+
+    public boolean isConstant()
+    {
+        return isStatic() && isFinal();
+    }
+
+    public TagInfo[] firstSentenceTags()
+    {
+        return comment().briefTags();
+    }
+
+    public TagInfo[] inlineTags()
+    {
+        return comment().tags();
+    }
+
+    public Object constantValue()
+    {
+        return mConstantValue;
+    }
+
+    public String constantLiteralValue()
+    {
+        return constantLiteralValue(mConstantValue);
+    }
+    
+    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(),
+                        "Field " + mContainingClass.qualifiedName() + "." + name()
+                        + ": @Deprecated annotation and @deprecated comment do not match");
+            }
+
+            mIsDeprecated = commentDeprecated | annotationDeprecated;
+            mDeprecatedKnown = true;
+        }
+        return mIsDeprecated;
+    }
+
+    public static String constantLiteralValue(Object val)
+    {
+        String str = null;
+        if (val != null) {
+            if (val instanceof Boolean
+                    || val instanceof Byte
+                    || val instanceof Short
+                    || val instanceof Integer) 
+            {
+                str = val.toString();
+            }
+            //catch all special values
+            else if (val instanceof Double){
+                Double dbl = (Double) val;
+                    if (dbl.toString().equals("Infinity")){
+                        str = "(1.0 / 0.0)";
+                    } else if (dbl.toString().equals("-Infinity")) {
+                        str = "(-1.0 / 0.0)";
+                    } else if (dbl.isNaN()) {
+                        str = "(0.0 / 0.0)";
+                    } else {
+                        str = dbl.toString();
+                    }
+            }
+            else if (val instanceof Long) {
+                str = val.toString() + "L";
+            }
+            else if (val instanceof Float) {
+                Float fl = (Float) val;
+                if (fl.toString().equals("Infinity")) {
+                    str = "(1.0f / 0.0f)";
+                } else if (fl.toString().equals("-Infinity")) {
+                    str = "(-1.0f / 0.0f)";
+                } else if (fl.isNaN()) {
+                    str = "(0.0f / 0.0f)";
+                } else {
+                    str = val.toString() + "f";
+                }
+            }
+            else if (val instanceof Character) {
+                str = String.format("\'\\u%04x\'", val);
+            }
+            else if (val instanceof String) {
+                str = "\"" + javaEscapeString((String)val) + "\"";
+            }
+            else {
+                str = "<<<<" +val.toString() + ">>>>";
+            }
+        }
+        if (str == null) {
+            str = "null";
+        }
+        return str;
+    }
+
+    public static String javaEscapeString(String str) {
+        String result = "";
+        final int N = str.length();
+        for (int i=0; i<N; i++) {
+            char c = str.charAt(i);
+            if (c == '\\') {
+                result += "\\\\";
+            }
+            else if (c == '\t') {
+                result += "\\t";
+            }
+            else if (c == '\b') {
+                result += "\\b";
+            }
+            else if (c == '\r') {
+                result += "\\r";
+            }
+            else if (c == '\n') {
+                result += "\\n";
+            }
+            else if (c == '\f') {
+                result += "\\f";
+            }
+            else if (c == '\'') {
+                result += "\\'";
+            }
+            else if (c == '\"') {
+                result += "\\\"";
+            }
+            else if (c >= ' ' && c <= '~') {
+                result += c;
+            }
+            else {
+                result += String.format("\\u%04x", new Integer((int)c));
+            }
+        }
+        return result;
+    }
+
+
+    public void makeHDF(HDF data, String base)
+    {
+        data.setValue(base + ".kind", kind());
+        type().makeHDF(data, base + ".type");
+        data.setValue(base + ".name", name());
+        data.setValue(base + ".href", htmlPage());
+        data.setValue(base + ".anchor", anchor());
+        TagInfo.makeHDF(data, base + ".shortDescr", firstSentenceTags());
+        TagInfo.makeHDF(data, base + ".descr", inlineTags());
+        TagInfo.makeHDF(data, base + ".deprecated", comment().deprecatedTags());
+        TagInfo.makeHDF(data, base + ".seeAlso", comment().seeTags());
+        data.setValue(base + ".final", isFinal() ? "final" : "");
+        data.setValue(base + ".static", isStatic() ? "static" : "");
+        if (isPublic()) {
+            data.setValue(base + ".scope", "public");
+        }
+        else if (isProtected()) {
+            data.setValue(base + ".scope", "protected");
+        }
+        else if (isPackagePrivate()) {
+            data.setValue(base + ".scope", "");
+        }
+        else if (isPrivate()) {
+            data.setValue(base + ".scope", "private");
+        }
+        Object val = mConstantValue;
+        if (val != null) {
+            String dec = null;
+            String hex = null;
+            String str = null;
+
+            if (val instanceof Boolean) {
+                str = ((Boolean)val).toString();
+            }
+            else if (val instanceof Byte) {
+                dec = String.format("%d", val);
+                hex = String.format("0x%02x", val);
+            }
+            else if (val instanceof Character) {
+                dec = String.format("\'%c\'", val);
+                hex = String.format("0x%04x", val);
+            }
+            else if (val instanceof Double) {
+                str = ((Double)val).toString();
+            }
+            else if (val instanceof Float) {
+                str = ((Float)val).toString();
+            }
+            else if (val instanceof Integer) {
+                dec = String.format("%d", val);
+                hex = String.format("0x%08x", val);
+            }
+            else if (val instanceof Long) {
+                dec = String.format("%d", val);
+                hex = String.format("0x%016x", val);
+            }
+            else if (val instanceof Short) {
+                dec = String.format("%d", val);
+                hex = String.format("0x%04x", val);
+            }
+            else if (val instanceof String) {
+                str = "\"" + ((String)val) + "\"";
+            }
+            else {
+                str = "";
+            }
+
+            if (dec != null && hex != null) {
+                data.setValue(base + ".constantValue.dec", DroidDoc.escape(dec));
+                data.setValue(base + ".constantValue.hex", DroidDoc.escape(hex));
+            }
+            else {
+                data.setValue(base + ".constantValue.str", DroidDoc.escape(str));
+                data.setValue(base + ".constantValue.isString", "1");
+            }
+        }
+    }
+
+    public boolean isExecutable()
+    {
+        return false;
+    }
+
+    public boolean isTransient()
+    {
+        return mIsTransient;
+    }
+
+    public boolean isVolatile()
+    {
+        return mIsVolatile;
+    }
+
+    boolean mIsTransient;
+    boolean mIsVolatile;
+    boolean mDeprecatedKnown;
+    boolean mIsDeprecated;
+    TypeInfo mType;
+    Object mConstantValue;
+}
+
diff --git a/tools/droiddoc/src/Hierarchy.java b/tools/droiddoc/src/Hierarchy.java
new file mode 100755
index 0000000..ac5e1dc
--- /dev/null
+++ b/tools/droiddoc/src/Hierarchy.java
@@ -0,0 +1,155 @@
+/*
+ * 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 java.util.HashMap;
+import java.util.TreeSet;
+import java.util.Set;
+import org.clearsilver.HDF;
+
+public class Hierarchy
+{
+    public static void makeHierarchy(HDF hdf, ClassInfo[] classes)
+    {
+        HashMap<String,TreeSet<String>> nodes
+                                    = new HashMap<String,TreeSet<String>>();
+
+        for (ClassInfo cl: classes) {
+            String name = cl.qualifiedName();
+
+            TreeSet<String> me = nodes.get(name);
+            if (me == null) {
+                me = new TreeSet<String>();
+                nodes.put(name, me);
+            }
+
+            ClassInfo superclass = cl.superclass();
+            String sname = superclass != null
+                                    ? superclass.qualifiedName() : null;
+            if (sname != null) {
+                TreeSet<String> s = nodes.get(sname);
+                if (s == null) {
+                    s = new TreeSet<String>();
+                    nodes.put(sname, s);
+                }
+                s.add(name);
+            }
+        }
+
+        /*
+        Set<String> keys = nodes.keySet();
+        for (String n: keys) {
+            System.out.println("class: " + n);
+
+            TreeSet<String> values = nodes.get(n);
+            for (String v: values) {
+                System.out.println("       - " + v);
+            }
+        }
+        */
+
+        int depth = depth(nodes, "java.lang.Object");
+
+        hdf.setValue("classes.0", "");
+        hdf.setValue("colspan", "" + depth);
+
+        recurse(nodes, "java.lang.Object", hdf.getObj("classes.0"),depth,depth);
+
+        if (false) {
+            Set<String> keys = nodes.keySet();
+            if (keys.size() > 0) {
+                System.err.println("The following classes are hidden but"
+                        + " are superclasses of not-hidden classes");
+                for (String n: keys) {
+                    System.err.println("  " + n);
+                }
+            }
+        }
+    }
+
+    private static int depth(HashMap<String,TreeSet<String>> nodes,
+                                String name)
+    {
+        int d = 0;
+        TreeSet<String> derived = nodes.get(name);
+        if (derived != null && derived.size() > 0) {
+            for (String s: derived) {
+                int n = depth(nodes, s);
+                if (n > d) {
+                    d = n;
+                }
+            }
+        }
+        return d + 1;
+    }
+
+    private static boolean exists(ClassInfo cl)
+    {
+        return cl != null && !cl.isHidden() && cl.isIncluded();
+    }
+
+    private static void recurse(HashMap<String,TreeSet<String>> nodes,
+                                String name, HDF hdf, 
+                                int totalDepth, int remainingDepth)
+    {
+        int i;
+
+        hdf.setValue("indent", "" + (totalDepth-remainingDepth-1));
+        hdf.setValue("colspan", "" + remainingDepth);
+
+        ClassInfo cl = Converter.obtainClass(name);
+
+        hdf.setValue("class.label", cl.name());
+        hdf.setValue("class.qualified", cl.qualifiedName());
+        if (cl.checkLevel()) {
+            hdf.setValue("class.link", cl.htmlPage());
+        }
+
+        if (exists(cl)) {
+            hdf.setValue("exists", "1");
+        }
+
+        i = 0;
+        for (ClassInfo iface: cl.interfaces()) {
+            hdf.setValue("interfaces." + i + ".class.label", iface.name());
+            hdf.setValue("interfaces." + i + ".class.qualified", iface.qualifiedName());
+            if (iface.checkLevel()) {
+                hdf.setValue("interfaces." + i + ".class.link", iface.htmlPage());
+            }
+            if (exists(cl)) {
+                hdf.setValue("interfaces." + i + ".exists", "1");
+            }
+            i++;
+        }
+
+        TreeSet<String> derived = nodes.get(name);
+        if (derived != null && derived.size() > 0) {
+            hdf.setValue("derived", "");
+            HDF children = hdf.getObj("derived");
+            i = 0;
+            remainingDepth--;
+            for (String s: derived) {
+                String index = "" + i;
+                children.setValue(index, "");
+                recurse(nodes, s, children.getObj(index), totalDepth,
+                        remainingDepth);
+                i++;
+            }
+        }
+
+        nodes.remove(name);
+    }
+}
+
diff --git a/tools/droiddoc/src/InheritedTags.java b/tools/droiddoc/src/InheritedTags.java
new file mode 100644
index 0000000..242170c
--- /dev/null
+++ b/tools/droiddoc/src/InheritedTags.java
@@ -0,0 +1,27 @@
+/*
+ * 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 org.clearsilver.HDF;
+import org.clearsilver.CS;
+import java.util.*;
+import java.io.*;
+
+public interface InheritedTags
+{
+    TagInfo[] tags();
+    InheritedTags inherited();
+}
+
diff --git a/tools/droiddoc/src/KeywordEntry.java b/tools/droiddoc/src/KeywordEntry.java
new file mode 100644
index 0000000..7e5e357
--- /dev/null
+++ b/tools/droiddoc/src/KeywordEntry.java
@@ -0,0 +1,51 @@
+/*
+ * 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 org.clearsilver.HDF;
+import org.clearsilver.CS;
+
+class KeywordEntry implements Comparable
+{
+    KeywordEntry(String label, String href, String comment)
+    {
+        this.label = label;
+        this.href = href;
+        this.comment = comment;
+    }
+
+    public void makeHDF(HDF data, String base)
+    {
+        data.setValue(base + ".label", this.label);
+        data.setValue(base + ".href", this.href);
+        data.setValue(base + ".comment", this.comment);
+    }
+
+    public char firstChar()
+    {
+        return Character.toUpperCase(this.label.charAt(0));
+    }
+
+    public int compareTo(Object that)
+    {
+        return this.label.compareToIgnoreCase(((KeywordEntry)that).label);
+    }
+
+    private String label;
+    private String href;
+    private String comment;
+}
+
+
diff --git a/tools/droiddoc/src/LinkReference.java b/tools/droiddoc/src/LinkReference.java
new file mode 100644
index 0000000..bbcd4db
--- /dev/null
+++ b/tools/droiddoc/src/LinkReference.java
@@ -0,0 +1,440 @@
+/*
+ * 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 java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import java.util.ArrayList;
+
+/**
+ * Class that represents what you see in an link or see tag.  This is
+ * factored out of SeeTagInfo so it can be used elsewhere (like AttrTagInfo).
+ */
+public class LinkReference {
+
+    /** The original text. */
+    public String text;
+    
+    /** The kind of this tag, if we have a new suggestion after parsing. */
+    public String kind;
+
+    /** The user visible text. */
+    public String label;
+
+    /** The link. */
+    public String href;
+
+    /** The {@link PackageInfo} if any. */
+    public PackageInfo packageInfo;
+
+    /** The {@link ClassInfo} if any. */
+    public ClassInfo classInfo;
+
+    /** The {@link MemberInfo} if any. */
+    public MemberInfo memberInfo;
+
+    /** The name of the referenced member PackageInfo} if any. */
+    public String referencedMemberName;
+
+    /** Set to true if everything is a-ok */
+    public boolean good;
+
+    /**
+     * regex pattern to use when matching explicit "<a href" reference text
+     */
+    private static final Pattern HREF_PATTERN
+            = Pattern.compile("^<a href=\"([^\"]*)\">([^<]*)</a>[ \n\r\t]*$",
+                              Pattern.CASE_INSENSITIVE);
+
+    /**
+     * Parse and resolve a link string.
+     *
+     * @param text the original text
+     * @param base the class or whatever that this link is on
+     * @param pos the original position in the source document
+     * @return a new link reference.  It always returns something.  If there was an
+     *         error, it logs it and fills in href and label with error text.
+     */
+    public static LinkReference parse(String text, ContainerInfo base, SourcePositionInfo pos,
+                                        boolean printOnErrors) {
+        LinkReference result = new LinkReference();
+        result.text = text;
+
+        int index;
+        int len = text.length();
+        int pairs = 0;
+        int pound = -1;
+        // split the string
+        done: {
+            for (index=0; index<len; index++) {
+                char c = text.charAt(index);
+                switch (c)
+                {
+                    case '(':
+                        pairs++;
+                        break;
+                    case '[':
+                        pairs++;
+                        break;
+                    case ')':
+                        pairs--;
+                        break;
+                    case ']':
+                        pairs--;
+                        break;
+                    case ' ':
+                    case '\t':
+                    case '\r':
+                    case '\n':
+                        if (pairs == 0) {
+                            break done;
+                        }
+                        break;
+                    case '#':
+                        if (pound < 0) {
+                            pound = index;
+                        }
+                        break;
+                }
+            }
+        }
+        if (index == len && pairs != 0) {
+            Errors.error(Errors.UNRESOLVED_LINK, pos,
+                        "unable to parse link/see tag: " + text.trim());
+            return result;
+        }
+
+        int linkend = index;
+
+        for (; index<len; index++) {
+            char c = text.charAt(index);
+            if (!(c == ' ' || c == '\t' || c == '\r' || c == '\n')) {
+                break;
+            }
+        }
+
+        result.label = text.substring(index);
+
+        String ref;
+        String mem;
+        if (pound == 0) {
+            ref = null;
+            mem = text.substring(1, linkend);
+        }
+        else if (pound > 0) {
+            ref = text.substring(0, pound);
+            mem = text.substring(pound+1, linkend);
+        }
+        else {
+            ref = text.substring(0, linkend);
+            mem = null;
+        }
+
+        // parse parameters, if any
+        String[] params = null;
+        String[] paramDimensions = null;
+        if (mem != null) {
+            index = mem.indexOf('(');
+            if (index > 0) {
+                ArrayList<String> paramList = new ArrayList<String>();
+                ArrayList<String> paramDimensionList = new ArrayList<String>();
+                len = mem.length();
+                int start = index+1;
+                final int START = 0;
+                final int TYPE = 1;
+                final int NAME = 2;
+                int dimension = 0;
+                int arraypair = 0;
+                int state = START;
+                int typestart = 0;
+                int typeend = -1;
+                for (int i=start; i<len; i++) {
+                    char c = mem.charAt(i);
+                    switch (state)
+                    {
+                        case START:
+                            if (c!=' ' && c!='\t' && c!='\r' && c!='\n') {
+                                state = TYPE;
+                                typestart = i;
+                            }
+                            break;
+                        case TYPE:
+                            if (c == '[') {
+                                if (typeend < 0) {
+                                    typeend = i;
+                                }
+                                dimension++;
+                                arraypair++;
+                            }
+                            else if (c == ']') {
+                                arraypair--;
+                            }
+                            else if (c==' ' || c=='\t' || c=='\r' || c=='\n') {
+                                if (typeend < 0) {
+                                    typeend = i;
+                                }
+                            }
+                            else {
+                                if (typeend >= 0 || c == ')' || c == ',') {
+                                    if (typeend < 0) {
+                                        typeend = i;
+                                    }
+                                    String s = mem.substring(typestart, typeend);
+                                    paramList.add(s);
+                                    s = "";
+                                    for (int j=0; j<dimension; j++) {
+                                        s += "[]";
+                                    }
+                                    paramDimensionList.add(s);
+                                    state = START;
+                                    typeend = -1;
+                                    dimension = 0;
+                                    if (c == ',' || c == ')') {
+                                        state = START;
+                                    } else {
+                                        state = NAME;
+                                    }
+                                }
+                            }
+                            break;
+                        case NAME:
+                            if (c == ',' || c == ')') {
+                                state = START;
+                            }
+                            break;
+                    }
+
+                }
+                params = paramList.toArray(new String[paramList.size()]);
+                paramDimensions = paramDimensionList.toArray(new String[paramList.size()]);
+                mem = mem.substring(0, index);
+            }
+        }
+
+        ClassInfo cl = null;
+        if (base instanceof ClassInfo) {
+            cl = (ClassInfo)base;
+        }
+
+        if (ref == null) {
+            // no class or package was provided, assume it's this class
+            if (cl != null) {
+                result.classInfo = cl;
+            }
+        } else {
+            // they provided something, maybe it's a class or a package
+            if (cl != null) {
+                result.classInfo = cl.extendedFindClass(ref);
+                if (result.classInfo == null) {
+                    result.classInfo = cl.findClass(ref);
+                }
+                if (result.classInfo == null) {
+                    result.classInfo = cl.findInnerClass(ref);
+                }
+            }
+            if (result.classInfo == null) {
+                result.classInfo = Converter.obtainClass(ref);
+            }
+            if (result.classInfo == null) {
+                result.packageInfo = Converter.obtainPackage(ref);
+            }
+        }
+
+        if (result.classInfo != null && mem != null) {
+            // it's either a field or a method, prefer a field
+            if (params == null) {
+                FieldInfo field = result.classInfo.findField(mem);
+                // findField looks in containing classes, so it might actually
+                // be somewhere else; link to where it really is, not what they
+                // typed.
+                if (field != null) {
+                    result.classInfo = field.containingClass();
+                    result.memberInfo = field;
+                }
+            }
+            if (result.memberInfo == null) {
+                MethodInfo method = result.classInfo.findMethod(mem, params, paramDimensions);
+                if (method != null) {
+                    result.classInfo = method.containingClass();
+                    result.memberInfo = method;
+                }
+            }
+        }
+
+        result.referencedMemberName = mem;
+        if (params != null) {
+            result.referencedMemberName = result.referencedMemberName + '(';
+            len = params.length;
+            if (len > 0) {
+                len--;
+                for (int i=0; i<len; i++) {
+                    result.referencedMemberName = result.referencedMemberName + params[i]
+                            + paramDimensions[i] + ", ";
+                }
+                result.referencedMemberName = result.referencedMemberName + params[len]
+                        + paramDimensions[len];
+            }
+            result.referencedMemberName = result.referencedMemberName + ")";
+        }
+
+        // debugging spew
+        if (false) {
+            result.label = result.label + "/" + ref + "/" + mem + '/';
+            if (params != null) {
+                for (int i=0; i<params.length; i++) {
+                    result.label += params[i] + "|";
+                }
+            }
+
+            FieldInfo f = (result.memberInfo instanceof FieldInfo)
+                        ? (FieldInfo)result.memberInfo
+                        : null;
+            MethodInfo m = (result.memberInfo instanceof MethodInfo)
+                        ? (MethodInfo)result.memberInfo
+                        : null;
+            result.label = result.label
+                        + "/package=" + (result.packageInfo!=null?result.packageInfo.name():"")
+                        + "/class=" + (result.classInfo!=null?result.classInfo.qualifiedName():"")
+                        + "/field=" + (f!=null?f.name():"")
+                        + "/method=" + (m!=null?m.name():"");
+            
+        }
+
+        MethodInfo method = null;
+        boolean skipHref = false;
+
+        if (result.memberInfo != null && result.memberInfo.isExecutable()) {
+           method = (MethodInfo)result.memberInfo;
+        }
+
+        if (text.startsWith("\"")) {
+            // literal quoted reference (e.g., a book title)
+            result.label = text.substring(1);
+            skipHref = true;
+            if (!result.label.endsWith("\"")) {
+                Errors.error(Errors.UNRESOLVED_LINK, pos,
+                        "unbalanced quoted link/see tag: " + text.trim());
+                result.makeError();
+                return result;
+            }
+            result.label = result.label.substring(0, result.label.length() - 1);
+            result.kind = "@seeJustLabel";
+        }
+        else if (text.startsWith("<")) {
+            // explicit "<a href" form
+            Matcher matcher = HREF_PATTERN.matcher(text);
+            if (! matcher.matches()) {
+                Errors.error(Errors.UNRESOLVED_LINK, pos,
+                        "invalid <a> link/see tag: " + text.trim());
+                result.makeError();
+                return result;
+            }
+            result.href = matcher.group(1);
+            result.label = matcher.group(2);
+            result.kind = "@seeHref";
+        }
+        else if (result.packageInfo != null) {
+            result.href = result.packageInfo.htmlPage();
+            if (result.label.length() == 0) {
+                result.href = result.packageInfo.htmlPage();
+                result.label = result.packageInfo.name();
+            }
+        }
+        else if (result.classInfo != null && result.referencedMemberName == null) {
+            // class reference
+            if (result.label.length() == 0) {
+                result.label = result.classInfo.name();
+            }
+            result.href = result.classInfo.htmlPage();
+        }
+        else if (result.memberInfo != null) {
+            // member reference
+            ClassInfo containing = result.memberInfo.containingClass();
+            if (result.memberInfo.isExecutable()) {
+                if (result.referencedMemberName.indexOf('(') < 0) {
+                    result.referencedMemberName += method.flatSignature();
+                }
+            } 
+            if (result.label.length() == 0) {
+                result.label = result.referencedMemberName;
+            }
+            result.href = containing.htmlPage() + '#' + result.memberInfo.anchor();
+        }
+
+        if (result.href == null && !skipHref) {
+            if (printOnErrors && (base == null || base.checkLevel())) {
+                Errors.error(Errors.UNRESOLVED_LINK, pos,
+                        "Unresolved link/see tag \"" + text.trim()
+                        + "\" in " + ((base != null) ? base.qualifiedName() : "[null]"));
+            }
+            result.makeError();
+        }
+        else if (result.memberInfo != null && !result.memberInfo.checkLevel()) {
+            if (printOnErrors && (base == null || base.checkLevel())) {
+                Errors.error(Errors.HIDDEN_LINK, pos,
+                        "Link to hidden member: " + text.trim());
+                result.href = null;
+            }
+            result.kind = "@seeJustLabel";
+        }
+        else if (result.classInfo != null && !result.classInfo.checkLevel()) {
+            if (printOnErrors && (base == null || base.checkLevel())) {
+                Errors.error(Errors.HIDDEN_LINK, pos,
+                        "Link to hidden class: " + text.trim() + " label=" + result.label);
+                result.href = null;
+            }
+            result.kind = "@seeJustLabel";
+        }
+        else if (result.packageInfo != null && !result.packageInfo.checkLevel()) {
+            if (printOnErrors && (base == null || base.checkLevel())) {
+                Errors.error(Errors.HIDDEN_LINK, pos,
+                        "Link to hidden package: " + text.trim());
+                result.href = null;
+            }
+            result.kind = "@seeJustLabel";
+        }
+
+        result.good = true;
+
+        return result;
+    }
+
+    public boolean checkLevel() {
+        if (memberInfo != null) {
+            return memberInfo.checkLevel();
+        }
+        if (classInfo != null) {
+            return classInfo.checkLevel();
+        }
+        if (packageInfo != null) {
+            return packageInfo.checkLevel();
+        }
+        return false;
+    }
+
+    /** turn this LinkReference into one with an error message */
+    private void makeError() {
+        //this.href = "ERROR(" + this.text.trim() + ")";
+        this.href = null;
+        if (this.label == null) {
+            this.label = "";
+        }
+        this.label = "ERROR(" + this.label + "/" + text.trim() + ")";
+    }
+
+    /** private. **/
+    private LinkReference() {
+    }
+}
diff --git a/tools/droiddoc/src/LiteralTagInfo.java b/tools/droiddoc/src/LiteralTagInfo.java
new file mode 100644
index 0000000..b39490d
--- /dev/null
+++ b/tools/droiddoc/src/LiteralTagInfo.java
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+public class LiteralTagInfo extends TagInfo
+{
+    private static String encode(String t)
+    {
+        t = t.replace("&", "&amp;");
+        t = t.replace("<", "&lt;");
+        t = t.replace(">", "&gt;");
+        return t;
+    }
+
+    public LiteralTagInfo(String n, String k, String t, SourcePositionInfo sp)
+    {
+        super("Text", "Text", encode(t), sp);
+    }
+}
diff --git a/tools/droiddoc/src/MemberInfo.java b/tools/droiddoc/src/MemberInfo.java
new file mode 100644
index 0000000..2a2572a
--- /dev/null
+++ b/tools/droiddoc/src/MemberInfo.java
@@ -0,0 +1,154 @@
+/*
+ * 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.
+ */
+
+public abstract class MemberInfo extends DocInfo implements Comparable, Scoped
+{
+    public MemberInfo(String rawCommentText, String name, String signature,
+                        ClassInfo containingClass, ClassInfo realContainingClass,
+                        boolean isPublic, boolean isProtected,
+                        boolean isPackagePrivate, boolean isPrivate,
+                        boolean isFinal, boolean isStatic, boolean isSynthetic,
+                        String kind,
+                        SourcePositionInfo position,
+                        AnnotationInstanceInfo[] annotations)
+    {
+        super(rawCommentText, position);
+        mName = name;
+        mSignature = signature;
+        mContainingClass = containingClass;
+        mRealContainingClass = realContainingClass;
+        mIsPublic = isPublic;
+        mIsProtected = isProtected;
+        mIsPackagePrivate = isPackagePrivate;
+        mIsPrivate = isPrivate;
+        mIsFinal = isFinal;
+        mIsStatic = isStatic;
+        mIsSynthetic = isSynthetic;
+        mKind = kind;
+        mAnnotations = annotations;
+    }
+
+    public abstract boolean isExecutable();
+
+    public String anchor()
+    {
+        if (mSignature != null) {
+            return mName + mSignature;
+        } else {
+            return mName;
+        }
+    }
+
+    public String htmlPage() {
+        return mContainingClass.htmlPage() + "#" + anchor();
+    }
+
+    public int compareTo(Object that) {
+        return this.htmlPage().compareTo(((MemberInfo)that).htmlPage());
+    }
+
+    public String name()
+    {
+        return mName;
+    }
+
+    public String signature()
+    {
+        return mSignature;
+    }
+
+    public ClassInfo realContainingClass()
+    {
+        return mRealContainingClass;
+    }
+
+    public ClassInfo containingClass()
+    {
+        return mContainingClass;
+    }
+
+    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 isFinal()
+    {
+        return mIsFinal;
+    }
+
+    public boolean isSynthetic()
+    {
+        return mIsSynthetic;
+    }
+
+    public ContainerInfo parent()
+    {
+        return mContainingClass;
+    }
+
+    public boolean checkLevel()
+    {
+        return DroidDoc.checkLevel(mIsPublic, mIsProtected,
+                mIsPackagePrivate, mIsPrivate, isHidden());
+    }
+
+    public String kind()
+    {
+        return mKind;
+    }
+    
+    public AnnotationInstanceInfo[] annotations()
+    {
+        return mAnnotations;
+    }
+
+    ClassInfo mContainingClass;
+    ClassInfo mRealContainingClass;
+    String mName;
+    String mSignature;
+    boolean mIsPublic;
+    boolean mIsProtected;
+    boolean mIsPackagePrivate;
+    boolean mIsPrivate;
+    boolean mIsFinal;
+    boolean mIsStatic;
+    boolean mIsSynthetic;
+    String mKind;
+    private AnnotationInstanceInfo[] mAnnotations;
+
+}
+
diff --git a/tools/droiddoc/src/MethodInfo.java b/tools/droiddoc/src/MethodInfo.java
new file mode 100644
index 0000000..ca30665
--- /dev/null
+++ b/tools/droiddoc/src/MethodInfo.java
@@ -0,0 +1,645 @@
+/*
+ * 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 org.clearsilver.HDF;
+import org.clearsilver.CS;
+import java.util.*;
+import java.io.*;
+
+public class MethodInfo extends MemberInfo
+{
+    public static final Comparator<MethodInfo> comparator = new Comparator<MethodInfo>() {
+        public int compare(MethodInfo a, MethodInfo b) {
+            return a.name().compareTo(b.name());
+        }
+    };
+    
+    private class InlineTags implements InheritedTags
+    { 
+        public TagInfo[] tags()
+        {
+            return comment().tags();
+        }
+        public InheritedTags inherited()
+        {
+            MethodInfo m = findOverriddenMethod(name(), signature());
+            if (m != null) {
+                return m.inlineTags();
+            } else {
+                return null;
+            }
+        }
+    }
+    
+    private static void addInterfaces(ClassInfo[] ifaces, ArrayList<ClassInfo> queue)
+    {
+        for (ClassInfo i: ifaces) {
+            queue.add(i);
+        }
+        for (ClassInfo i: ifaces) {
+            addInterfaces(i.interfaces(), queue);
+        }
+    }
+
+    // first looks for a superclass, and then does a breadth first search to
+    // find the least far away match
+    public MethodInfo findOverriddenMethod(String name, String signature)
+    {
+        if (mReturnType == null) {
+            // ctor
+            return null;
+        }
+        if (mOverriddenMethod != null) {
+            return mOverriddenMethod;
+        }
+
+        ArrayList<ClassInfo> queue = new ArrayList<ClassInfo>();
+        addInterfaces(containingClass().interfaces(), queue);
+        for (ClassInfo iface: queue) {
+            for (MethodInfo me: iface.methods()) {
+                if (me.name().equals(name)
+                        && me.signature().equals(signature)
+                        && me.inlineTags().tags() != null
+                        && me.inlineTags().tags().length > 0) {
+                    return me;
+                }
+            }
+        }
+        return null;
+    }
+    
+    private static void addRealInterfaces(ClassInfo[] ifaces, ArrayList<ClassInfo> queue)
+    {
+        for (ClassInfo i: ifaces) {
+            queue.add(i);
+            if (i.realSuperclass() != null &&  i.realSuperclass().isAbstract()) {
+                queue.add(i.superclass());
+            }
+        }
+        for (ClassInfo i: ifaces) {
+            addInterfaces(i.realInterfaces(), queue);
+        }
+    }
+    
+    public MethodInfo findRealOverriddenMethod(String name, String signature, HashSet notStrippable) {
+        if (mReturnType == null) {
+        // ctor
+        return null;
+        }
+        if (mOverriddenMethod != null) {
+            return mOverriddenMethod;
+        }
+
+        ArrayList<ClassInfo> queue = new ArrayList<ClassInfo>();
+        if (containingClass().realSuperclass() != null && 
+            containingClass().realSuperclass().isAbstract()) {
+            queue.add(containingClass());
+        }
+        addInterfaces(containingClass().realInterfaces(), queue);
+        for (ClassInfo iface: queue) {
+            for (MethodInfo me: iface.methods()) {
+                if (me.name().equals(name)
+                    && me.signature().equals(signature)
+                    && me.inlineTags().tags() != null
+                    && me.inlineTags().tags().length > 0
+                    && notStrippable.contains(me.containingClass())) {
+                return me;
+                }
+            }
+        }
+        return null;
+    }
+    
+    public MethodInfo findSuperclassImplementation(HashSet notStrippable) {
+        if (mReturnType == null) {
+            // ctor
+            return null;
+        }
+        if (mOverriddenMethod != null) {
+            // Even if we're told outright that this was the overridden method, we want to
+            // be conservative and ignore mismatches of parameter types -- they arise from
+            // extending generic specializations, and we want to consider the derived-class
+            // method to be a non-override.
+            if (this.signature().equals(mOverriddenMethod.signature())) {
+                return mOverriddenMethod;
+            }
+        }
+
+        ArrayList<ClassInfo> queue = new ArrayList<ClassInfo>();
+        if (containingClass().realSuperclass() != null && 
+                containingClass().realSuperclass().isAbstract()) {
+            queue.add(containingClass());
+        }
+        addInterfaces(containingClass().realInterfaces(), queue);
+        for (ClassInfo iface: queue) {
+            for (MethodInfo me: iface.methods()) {
+                if (me.name().equals(this.name())
+                        && me.signature().equals(this.signature())
+                        && notStrippable.contains(me.containingClass())) {
+                    return me;
+                }
+            }
+        }
+        return null;
+    }
+    
+    public ClassInfo findRealOverriddenClass(String name, String signature) {
+        if (mReturnType == null) {
+        // ctor
+        return null;
+        }
+        if (mOverriddenMethod != null) {
+            return mOverriddenMethod.mRealContainingClass;
+        }
+
+        ArrayList<ClassInfo> queue = new ArrayList<ClassInfo>();
+        if (containingClass().realSuperclass() != null && 
+            containingClass().realSuperclass().isAbstract()) {
+            queue.add(containingClass());
+        }
+        addInterfaces(containingClass().realInterfaces(), queue);
+        for (ClassInfo iface: queue) {
+            for (MethodInfo me: iface.methods()) {
+                if (me.name().equals(name)
+                    && me.signature().equals(signature)
+                    && me.inlineTags().tags() != null
+                    && me.inlineTags().tags().length > 0) {
+                return iface;
+                }
+            }
+        }
+        return null;
+    }
+
+    private class FirstSentenceTags implements InheritedTags
+    {
+        public TagInfo[] tags()
+        {
+            return comment().briefTags();
+        }
+        public InheritedTags inherited()
+        {
+            MethodInfo m = findOverriddenMethod(name(), signature());
+            if (m != null) {
+                return m.firstSentenceTags();
+            } else {
+                return null;
+            }
+        }
+    }
+    
+    private class ReturnTags implements InheritedTags {
+        public TagInfo[] tags() {
+            return comment().returnTags();
+        }
+        public InheritedTags inherited() {
+            MethodInfo m = findOverriddenMethod(name(), signature());
+            if (m != null) {
+                return m.returnTags();
+            } else {
+                return null;
+            }
+        }
+    }
+    
+    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(),
+                        "Method " + mContainingClass.qualifiedName() + "." + name()
+                        + ": @Deprecated annotation and @deprecated doc tag do not match");
+            }
+
+            mIsDeprecated = commentDeprecated | annotationDeprecated;
+            mDeprecatedKnown = true;
+        }
+        return mIsDeprecated;
+    }
+    
+    public TypeInfo[] getTypeParameters(){
+        return mTypeParameters;
+    }
+
+    public MethodInfo cloneForClass(ClassInfo newContainingClass) {
+        MethodInfo result =  new MethodInfo(getRawCommentText(), mTypeParameters,
+                name(), signature(), newContainingClass, realContainingClass(),
+                isPublic(), isProtected(), isPackagePrivate(), isPrivate(), isFinal(), isStatic(),
+                isSynthetic(), mIsAbstract, mIsSynchronized, mIsNative, mIsAnnotationElement,
+                kind(), mFlatSignature, mOverriddenMethod,
+                mReturnType, mParameters, mThrownExceptions, position(), annotations());
+        result.init(mDefaultAnnotationElementValue);
+        return result;
+    }
+
+    public MethodInfo(String rawCommentText, TypeInfo[] typeParameters, String name,
+                        String signature, ClassInfo containingClass, ClassInfo realContainingClass,
+                        boolean isPublic, boolean isProtected,
+                        boolean isPackagePrivate, boolean isPrivate,
+                        boolean isFinal, boolean isStatic, boolean isSynthetic,
+                        boolean isAbstract, boolean isSynchronized, boolean isNative,
+                        boolean isAnnotationElement, String kind,
+                        String flatSignature, MethodInfo overriddenMethod,
+                        TypeInfo returnType, ParameterInfo[] parameters,
+                        ClassInfo[] thrownExceptions, SourcePositionInfo position,
+                        AnnotationInstanceInfo[] annotations)
+    {
+        // Explicitly coerce 'final' state of Java6-compiled enum values() method, to match
+        // the Java5-emitted base API description.
+        super(rawCommentText, name, signature, containingClass, realContainingClass,
+                isPublic, isProtected, isPackagePrivate, isPrivate,
+                ((name.equals("values") && containingClass.isEnum()) ? true : isFinal),
+                isStatic, isSynthetic, kind, position, annotations);
+
+        // The underlying MethodDoc for an interface's declared methods winds up being marked
+        // non-abstract.  Correct that here by looking at the immediate-parent class, and marking
+        // this method abstract if it is an unimplemented interface method. 
+        if (containingClass.isInterface()) {
+            isAbstract = true;
+        }
+
+        mReasonOpened = "0:0";
+        mIsAnnotationElement = isAnnotationElement;
+        mTypeParameters = typeParameters;
+        mIsAbstract = isAbstract;
+        mIsSynchronized = isSynchronized;
+        mIsNative = isNative;
+        mFlatSignature = flatSignature;
+        mOverriddenMethod = overriddenMethod;
+        mReturnType = returnType;
+        mParameters = parameters;
+        mThrownExceptions = thrownExceptions;
+    }
+
+    public void init(AnnotationValueInfo defaultAnnotationElementValue)
+    {
+        mDefaultAnnotationElementValue = defaultAnnotationElementValue;
+    }
+
+    public boolean isAbstract()
+    {
+        return mIsAbstract;
+    }
+
+    public boolean isSynchronized()
+    {
+        return mIsSynchronized;
+    }
+
+    public boolean isNative()
+    {
+        return mIsNative;
+    }
+
+    public String flatSignature()
+    {
+        return mFlatSignature;
+    }
+
+    public InheritedTags inlineTags()
+    {
+        return new InlineTags();
+    }
+
+    public InheritedTags firstSentenceTags()
+    {
+        return new FirstSentenceTags();
+    }
+
+    public InheritedTags returnTags() {
+        return new ReturnTags();
+    }
+
+    public TypeInfo returnType()
+    {
+        return mReturnType;
+    }
+
+    public String prettySignature()
+    {
+        String s = "(";
+        int N = mParameters.length;
+        for (int i=0; i<N; i++) {
+            ParameterInfo p = mParameters[i];
+            TypeInfo t = p.type();
+            if (t.isPrimitive()) {
+                s += t.simpleTypeName();
+            } else {
+                s += t.asClassInfo().name();
+            }
+            if (i != N-1) {
+                s += ',';
+            }
+        }
+        s += ')';
+        return s;
+    }
+
+    private boolean inList(ClassInfo item, ThrowsTagInfo[] list)
+    {
+        int len = list.length;
+        String qn = item.qualifiedName();
+        for (int i=0; i<len; i++) {
+            ClassInfo ex = list[i].exception();
+            if (ex != null && ex.qualifiedName().equals(qn)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public ThrowsTagInfo[] throwsTags()
+    {
+        if (mThrowsTags == null) {
+            ThrowsTagInfo[] documented = comment().throwsTags();
+            ArrayList<ThrowsTagInfo> rv = new ArrayList<ThrowsTagInfo>();
+
+            int len = documented.length;
+            for (int i=0; i<len; i++) {
+                rv.add(documented[i]);
+            }
+
+            ClassInfo[] all = mThrownExceptions;
+            len = all.length;
+            for (int i=0; i<len; i++) {
+                ClassInfo cl = all[i];
+                if (documented == null || !inList(cl, documented)) {
+                    rv.add(new ThrowsTagInfo("@throws", "@throws",
+                                        cl.qualifiedName(), cl, "",
+                                        containingClass(), position()));
+                }
+            }
+            mThrowsTags = rv.toArray(new ThrowsTagInfo[rv.size()]);
+        }
+        return mThrowsTags;
+    }
+
+    private static int indexOfParam(String name, String[] list)
+    {
+        final int N = list.length;
+        for (int i=0; i<N; i++) {
+            if (name.equals(list[i])) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    public ParamTagInfo[] paramTags()
+    {
+        if (mParamTags == null) {
+            final int N = mParameters.length;
+
+            String[] names = new String[N];
+            String[] comments = new String[N];
+            SourcePositionInfo[] positions = new SourcePositionInfo[N];
+
+            // get the right names so we can handle our names being different from
+            // our parent's names.
+            for (int i=0; i<N; i++) {
+                names[i] = mParameters[i].name();
+                comments[i] = "";
+                positions[i] = mParameters[i].position();
+            }
+
+            // gather our comments, and complain about misnamed @param tags
+            for (ParamTagInfo tag: comment().paramTags()) {
+                int index = indexOfParam(tag.parameterName(), names);
+                if (index >= 0) {
+                    comments[index] = tag.parameterComment();
+                    positions[index] = tag.position();
+                } else {
+                    Errors.error(Errors.UNKNOWN_PARAM_TAG_NAME, tag.position(),
+                            "@param tag with name that doesn't match the parameter list: '"
+                            + tag.parameterName() + "'");
+                }
+            }
+             
+            // get our parent's tags to fill in the blanks
+            MethodInfo overridden = this.findOverriddenMethod(name(), signature());
+            if (overridden != null) {
+                ParamTagInfo[] maternal = overridden.paramTags();
+                for (int i=0; i<N; i++) {
+                    if (comments[i].equals("")) {
+                        comments[i] = maternal[i].parameterComment();
+                        positions[i] = maternal[i].position();
+                    }
+                }
+            }
+
+            // construct the results, and cache them for next time
+            mParamTags = new ParamTagInfo[N];
+            for (int i=0; i<N; i++) {
+                mParamTags[i] = new ParamTagInfo("@param", "@param", names[i] + " " + comments[i],
+                        parent(), positions[i]);
+
+                // while we're here, if we find any parameters that are still undocumented at this
+                // point, complain. (this warning is off by default, because it's really, really
+                // common; but, it's good to be able to enforce it)
+                if (comments[i].equals("")) {
+                    Errors.error(Errors.UNDOCUMENTED_PARAMETER, positions[i],
+                            "Undocumented parameter '" + names[i] + "' on method '"
+                            + name() + "'");
+                }
+            }
+        }
+        return mParamTags;
+    }
+
+    public SeeTagInfo[] seeTags()
+    {
+        SeeTagInfo[] result = comment().seeTags();
+        if (result == null) {
+            if (mOverriddenMethod != null) {
+                result = mOverriddenMethod.seeTags();
+            }
+        }
+        return result;
+    }
+
+    public TagInfo[] deprecatedTags()
+    {
+        TagInfo[] result = comment().deprecatedTags();
+        if (result.length == 0) {
+            if (comment().undeprecateTags().length == 0) {
+                if (mOverriddenMethod != null) {
+                    result = mOverriddenMethod.deprecatedTags();
+                }
+            }
+        }
+        return result;
+    }
+
+    public ParameterInfo[] parameters()
+    {
+        return mParameters;
+    }
+    
+
+    public boolean matchesParams(String[] params, String[] dimensions)
+    {
+        if (mParamStrings == null) {
+            ParameterInfo[] mine = mParameters;
+            int len = mine.length;
+            if (len != params.length) {
+                return false;
+            }
+            for (int i=0; i<len; i++) {
+                TypeInfo t = mine[i].type();
+                if (!t.dimension().equals(dimensions[i])) {
+                    return false;
+                }
+                String qn = t.qualifiedTypeName();
+                String s = params[i];
+                int slen = s.length();
+                int qnlen = qn.length();
+                if (!(qn.equals(s) ||
+                        ((slen+1)<qnlen && qn.charAt(qnlen-slen-1)=='.'
+                         && qn.endsWith(s)))) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    public void makeHDF(HDF data, String base)
+    {
+        data.setValue(base + ".kind", kind());
+        data.setValue(base + ".name", name());
+        data.setValue(base + ".href", htmlPage());
+        data.setValue(base + ".anchor", anchor());
+
+        if (mReturnType != null) {
+            returnType().makeHDF(data, base + ".returnType", false, typeVariables());
+            data.setValue(base + ".abstract", mIsAbstract ? "abstract" : "");
+        }
+
+        data.setValue(base + ".synchronized", mIsSynchronized ? "synchronized" : "");
+        data.setValue(base + ".final", isFinal() ? "final" : "");
+        data.setValue(base + ".static", isStatic() ? "static" : "");
+
+        TagInfo.makeHDF(data, base + ".shortDescr", firstSentenceTags());
+        TagInfo.makeHDF(data, base + ".descr", inlineTags());
+        TagInfo.makeHDF(data, base + ".deprecated", deprecatedTags());
+        TagInfo.makeHDF(data, base + ".seeAlso", seeTags());
+        ParamTagInfo.makeHDF(data, base + ".paramTags", paramTags());
+        AttrTagInfo.makeReferenceHDF(data, base + ".attrRefs", comment().attrTags());
+        ThrowsTagInfo.makeHDF(data, base + ".throws", throwsTags());
+        ParameterInfo.makeHDF(data, base + ".params", parameters(), isVarArgs(), typeVariables());
+        if (isProtected()) {
+            data.setValue(base + ".scope", "protected");
+        }
+        else if (isPublic()) {
+            data.setValue(base + ".scope", "public");
+        }
+        TagInfo.makeHDF(data, base + ".returns", returnTags());
+
+        if (mTypeParameters != null) {
+            TypeInfo.makeHDF(data, base + ".generic.typeArguments", mTypeParameters, false);
+        }
+    }
+
+    public HashSet<String> typeVariables()
+    {
+        HashSet<String> result = TypeInfo.typeVariables(mTypeParameters);
+        ClassInfo cl = containingClass();
+        while (cl != null) {
+            TypeInfo[] types = cl.asTypeInfo().typeArguments();
+            if (types != null) {
+                TypeInfo.typeVariables(types, result);
+            }
+            cl = cl.containingClass();
+        }
+        return result;
+    }
+
+    public boolean isExecutable()
+    {
+        return true;
+    }
+
+    public ClassInfo[] thrownExceptions()
+    {
+        return mThrownExceptions;
+    }
+
+    public String typeArgumentsName(HashSet<String> typeVars)
+    {
+        if (mTypeParameters == null || mTypeParameters.length == 0) {
+            return "";
+        } else {
+            return TypeInfo.typeArgumentsName(mTypeParameters, typeVars);
+        }
+    }
+
+    public boolean isAnnotationElement()
+    {
+        return mIsAnnotationElement;
+    }
+
+    public AnnotationValueInfo defaultAnnotationElementValue()
+    {
+        return mDefaultAnnotationElementValue;
+    }
+    
+    public void setVarargs(boolean set){
+        mIsVarargs = set;
+    }
+    public boolean isVarArgs(){
+      return mIsVarargs;
+    }
+    public String toString(){
+      return this.name();
+    }
+    
+    public void setReason(String reason) {
+        mReasonOpened = reason;
+    }
+    
+    public String getReason() {
+        return mReasonOpened;
+    }
+
+    private String mFlatSignature;
+    private MethodInfo mOverriddenMethod;
+    private TypeInfo mReturnType;
+    private boolean mIsAnnotationElement;
+    private boolean mIsAbstract;
+    private boolean mIsSynchronized;
+    private boolean mIsNative;
+    private boolean mIsVarargs;
+    private boolean mDeprecatedKnown;
+    private boolean mIsDeprecated;
+    private ParameterInfo[] mParameters;
+    private ClassInfo[] mThrownExceptions;
+    private String[] mParamStrings;
+    ThrowsTagInfo[] mThrowsTags;
+    private ParamTagInfo[] mParamTags;
+    private TypeInfo[] mTypeParameters;
+    private AnnotationValueInfo mDefaultAnnotationElementValue;
+    private String mReasonOpened;
+}
+
diff --git a/tools/droiddoc/src/NavTree.java b/tools/droiddoc/src/NavTree.java
new file mode 100644
index 0000000..9eef0ce
--- /dev/null
+++ b/tools/droiddoc/src/NavTree.java
@@ -0,0 +1,142 @@
+/*
+ * 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 org.clearsilver.HDF;
+
+import java.util.ArrayList;
+
+public class NavTree {
+
+    public static void writeNavTree(String dir) {
+        ArrayList<Node> children = new ArrayList();
+        for (PackageInfo pkg: DroidDoc.choosePackages()) {
+            children.add(makePackageNode(pkg));
+        }
+        Node node = new Node("Reference", dir + "packages.html", children);
+
+        StringBuilder buf = new StringBuilder();
+        if (false) {
+            // if you want a root node
+            buf.append("[");
+            node.render(buf);
+            buf.append("]");
+        } else {
+            // if you don't want a root node
+            node.renderChildren(buf);
+        }
+
+        HDF data = DroidDoc.makeHDF();
+        data.setValue("reference_tree", buf.toString());
+        ClearPage.write(data, "navtree_data.cs", "navtree_data.js");
+    }
+
+    private static Node makePackageNode(PackageInfo pkg) {
+        ArrayList<Node> children = new ArrayList();
+
+        children.add(new Node("Description", pkg.fullDescriptionHtmlPage(), null));
+
+        addClassNodes(children, "Interfaces", pkg.interfaces());
+        addClassNodes(children, "Classes", pkg.ordinaryClasses());
+        addClassNodes(children, "Enums", pkg.enums());
+        addClassNodes(children, "Exceptions", pkg.exceptions());
+        addClassNodes(children, "Errors", pkg.errors());
+
+        return new Node(pkg.name(), pkg.htmlPage(), children);
+    }
+
+    private static void addClassNodes(ArrayList<Node> parent, String label, ClassInfo[] classes) {
+        ArrayList<Node> children = new ArrayList();
+
+        for (ClassInfo cl: classes) {
+            if (cl.checkLevel()) {
+                children.add(new Node(cl.name(), cl.htmlPage(), null));
+            }
+        }
+
+        if (children.size() > 0) {
+            parent.add(new Node(label, null, children));
+        }
+    }
+
+    private static class Node {
+        private String mLabel;
+        private String mLink;
+        ArrayList<Node> mChildren;
+
+        Node(String label, String link, ArrayList<Node> children) {
+            mLabel = label;
+            mLink = link;
+            mChildren = children;
+        }
+
+        static void renderString(StringBuilder buf, String s) {
+            if (s == null) {
+                buf.append("null");
+            } else {
+                buf.append('"');
+                final int N = s.length();
+                for (int i=0; i<N; i++) {
+                    char c = s.charAt(i);
+                    if (c >= ' ' && c <= '~' && c != '"' && c != '\\') {
+                        buf.append(c);
+                    } else {
+                        buf.append("\\u");
+                        for (int j=0; i<4; i++) {
+                            char x = (char)(c & 0x000f);
+                            if (x > 10) {
+                                x = (char)(x - 10 + 'a');
+                            } else {
+                                x = (char)(x + '0');
+                            }
+                            buf.append(x);
+                            c >>= 4;
+                        }
+                    }
+                }
+                buf.append('"');
+            }
+        }
+
+        void renderChildren(StringBuilder buf) {
+            ArrayList<Node> list = mChildren;
+            if (list == null || list.size() == 0) {
+                // We output null for no children.  That way empty lists here can just
+                // be a byproduct of how we generate the lists.
+                buf.append("null");
+            } else {
+                buf.append("[ ");
+                final int N = list.size();
+                for (int i=0; i<N; i++) {
+                    list.get(i).render(buf);
+                    if (i != N-1) {
+                        buf.append(", ");
+                    }
+                }
+                buf.append(" ]\n");
+            }
+        }
+
+        void render(StringBuilder buf) {
+            buf.append("[ ");
+            renderString(buf, mLabel);
+            buf.append(", ");
+            renderString(buf, mLink);
+            buf.append(", ");
+            renderChildren(buf);
+            buf.append(" ]");
+        }
+    }
+}
diff --git a/tools/droiddoc/src/PackageInfo.java b/tools/droiddoc/src/PackageInfo.java
new file mode 100644
index 0000000..aac0def
--- /dev/null
+++ b/tools/droiddoc/src/PackageInfo.java
@@ -0,0 +1,185 @@
+/*
+ * 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 PackageInfo extends DocInfo implements ContainerInfo
+{
+    public static final Comparator<PackageInfo> comparator = new Comparator<PackageInfo>() {
+        public int compare(PackageInfo a, PackageInfo b) {
+            return a.name().compareTo(b.name());
+        }
+    };
+
+    public PackageInfo(PackageDoc pkg, String name, SourcePositionInfo position)
+    {
+        super(pkg.getRawCommentText(), position);
+        mName = name;
+
+        if (pkg == null) {
+            throw new RuntimeException("pkg is null");
+        }
+        mPackage = pkg;
+    }
+
+    public String htmlPage()
+    {
+        String s = mName;
+        s = s.replace('.', '/');
+        s += "/package-summary.html";
+        s = DroidDoc.javadocDir + s;
+        return s;
+    }
+
+    public String fullDescriptionHtmlPage() {
+        String s = mName;
+        s = s.replace('.', '/');
+        s += "/package-descr.html";
+        s = DroidDoc.javadocDir + s;
+        return s;
+    }
+
+    public ContainerInfo parent()
+    {
+        return null;
+    }
+
+    public boolean isHidden()
+    {
+        return comment().isHidden();
+    }
+
+    public boolean checkLevel() {
+        // TODO should return false if all classes are hidden but the package isn't.
+        // We don't have this so I'm not doing it now.
+        return !isHidden();
+    }
+
+    public String name()
+    {
+        return mName;
+    }
+
+    public String qualifiedName()
+    {
+        return mName;
+    }
+
+    public TagInfo[] inlineTags()
+    {
+        return comment().tags();
+    }
+
+    public TagInfo[] firstSentenceTags()
+    {
+        return comment().briefTags();
+    }
+
+    public static ClassInfo[] filterHidden(ClassInfo[] classes)
+    {
+        ArrayList<ClassInfo> out = new ArrayList<ClassInfo>();
+
+        for (ClassInfo cl: classes) {
+            if (!cl.isHidden()) {
+                out.add(cl);
+            }
+        }
+
+        return out.toArray(new ClassInfo[0]);
+    }
+
+    public void makeLink(HDF data, String base)
+    {
+        if (checkLevel()) {
+            data.setValue(base + ".link", htmlPage());
+        }
+        data.setValue(base + ".name", name());
+    }
+
+    public void makeClassLinkListHDF(HDF data, String base)
+    {
+        makeLink(data, base);
+        ClassInfo.makeLinkListHDF(data, base + ".interfaces", interfaces());
+        ClassInfo.makeLinkListHDF(data, base + ".classes", ordinaryClasses());
+        ClassInfo.makeLinkListHDF(data, base + ".enums", enums());
+        ClassInfo.makeLinkListHDF(data, base + ".exceptions", exceptions());
+        ClassInfo.makeLinkListHDF(data, base + ".errors", errors());
+    }
+
+    public ClassInfo[] interfaces()
+    {
+        if (mInterfaces == null) {
+            mInterfaces = ClassInfo.sortByName(filterHidden(Converter.convertClasses(
+                            mPackage.interfaces())));
+        }
+        return mInterfaces;
+    }
+
+    public ClassInfo[] ordinaryClasses()
+    {
+        if (mOrdinaryClasses == null) {
+            mOrdinaryClasses = ClassInfo.sortByName(filterHidden(Converter.convertClasses(
+                            mPackage.ordinaryClasses())));
+        }
+        return mOrdinaryClasses;
+    }
+
+    public ClassInfo[] enums()
+    {
+        if (mEnums == null) {
+            mEnums = ClassInfo.sortByName(filterHidden(Converter.convertClasses(mPackage.enums())));
+        }
+        return mEnums;
+    }
+
+    public ClassInfo[] exceptions()
+    {
+        if (mExceptions == null) {
+            mExceptions = ClassInfo.sortByName(filterHidden(Converter.convertClasses(
+                        mPackage.exceptions())));
+        }
+        return mExceptions;
+    }
+
+    public ClassInfo[] errors()
+    {
+        if (mErrors == null) {
+            mErrors = ClassInfo.sortByName(filterHidden(Converter.convertClasses(
+                        mPackage.errors())));
+        }
+        return mErrors;
+    }
+
+    // in hashed containers, treat the name as the key
+    @Override
+    public int hashCode() {
+        return mName.hashCode();
+    }
+
+    private String mName;
+    private PackageDoc mPackage;
+    private ClassInfo[] mInterfaces;
+    private ClassInfo[] mOrdinaryClasses;
+    private ClassInfo[] mEnums;
+    private ClassInfo[] mExceptions;
+    private ClassInfo[] mErrors;
+}
+
diff --git a/tools/droiddoc/src/ParamTagInfo.java b/tools/droiddoc/src/ParamTagInfo.java
new file mode 100644
index 0000000..c21ecd5
--- /dev/null
+++ b/tools/droiddoc/src/ParamTagInfo.java
@@ -0,0 +1,95 @@
+/*
+ * 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 java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import org.clearsilver.HDF;
+import org.clearsilver.CS;
+
+public class ParamTagInfo extends ParsedTagInfo
+{
+    static final Pattern PATTERN = Pattern.compile(
+                                "([^ \t\r\n]+)[ \t\r\n]+(.*)",
+                                Pattern.DOTALL);
+
+    private boolean mIsTypeParameter;
+    private String mParameterComment;
+    private String mParameterName;
+
+    ParamTagInfo(String name, String kind, String text, ContainerInfo base,
+            SourcePositionInfo sp)
+    {
+        super(name, kind, text, base, sp);
+
+        Matcher m = PATTERN.matcher(text);
+        if (m.matches()) {
+            mParameterName = m.group(1);
+            mParameterComment = m.group(2);
+            int len = mParameterName.length();
+            mIsTypeParameter = len > 2
+                                && mParameterName.charAt(0) == '<'
+                                && mParameterName.charAt(len-1) == '>';
+        } else {
+            mParameterName = text.trim();
+            mParameterComment = "";
+            mIsTypeParameter = false;
+        }
+        setCommentText(mParameterComment);
+    }
+
+    ParamTagInfo(String name, String kind, String text,
+                            boolean isTypeParameter, String parameterComment,
+                            String parameterName, ContainerInfo base,
+                            SourcePositionInfo sp)
+    {
+        super(name, kind, text, base, sp);
+        mIsTypeParameter = isTypeParameter;
+        mParameterComment = parameterComment;
+        mParameterName = parameterName;
+    }
+
+    public boolean isTypeParameter()
+    {
+        return mIsTypeParameter;
+    }
+
+    public String parameterComment()
+    {
+        return mParameterComment;
+    }
+
+    public String parameterName()
+    {
+        return mParameterName;
+    }
+
+    public void makeHDF(HDF data, String base)
+    {
+        data.setValue(base + ".name", parameterName());
+        data.setValue(base + ".isTypeParameter", isTypeParameter() ? "1" : "0");
+        TagInfo.makeHDF(data, base + ".comment", commentTags());
+    }
+
+    public static void makeHDF(HDF data, String base, ParamTagInfo[] tags)
+    {
+        for (int i=0; i<tags.length; i++) {
+            // don't output if the comment is ""
+            if (!"".equals(tags[i].parameterComment())) {
+                tags[i].makeHDF(data, base + "." + i);
+            }
+        }
+    }
+}
diff --git a/tools/droiddoc/src/ParameterInfo.java b/tools/droiddoc/src/ParameterInfo.java
new file mode 100644
index 0000000..44608be
--- /dev/null
+++ b/tools/droiddoc/src/ParameterInfo.java
@@ -0,0 +1,72 @@
+/*
+ * 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 org.clearsilver.HDF;
+import org.clearsilver.CS;
+import java.util.HashSet;
+
+public class ParameterInfo
+{
+    ParameterInfo(String name, String typeName, TypeInfo type, SourcePositionInfo position)
+    {
+        mName = name;
+        mTypeName = typeName;
+        mType = type;
+        mPosition = position;
+    }
+
+    TypeInfo type()
+    {
+        return mType;
+    }
+
+    String name()
+    {
+        return mName;
+    }
+
+    String typeName()
+    {
+        return mTypeName;
+    }
+
+    SourcePositionInfo position()
+    {
+        return mPosition;
+    }
+
+    public void makeHDF(HDF data, String base, boolean isLastVararg,
+            HashSet<String> typeVariables)
+    {
+        data.setValue(base + ".name", this.name());
+        type().makeHDF(data, base + ".type", isLastVararg, typeVariables);
+    }
+
+    public static void makeHDF(HDF data, String base, ParameterInfo[] params,
+            boolean isVararg, HashSet<String> typeVariables)
+    {
+        for (int i=0; i<params.length; i++) {
+            params[i].makeHDF(data, base + "." + i,
+                    isVararg && (i == params.length - 1), typeVariables);
+        }
+    }
+    
+    String mName;
+    String mTypeName;
+    TypeInfo mType;
+    SourcePositionInfo mPosition;
+}
+
diff --git a/tools/droiddoc/src/ParsedTagInfo.java b/tools/droiddoc/src/ParsedTagInfo.java
new file mode 100755
index 0000000..c2e4806
--- /dev/null
+++ b/tools/droiddoc/src/ParsedTagInfo.java
@@ -0,0 +1,61 @@
+/*
+ * 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 org.clearsilver.HDF;
+import org.clearsilver.CS;
+import java.util.ArrayList;
+
+public class ParsedTagInfo extends TagInfo
+{
+    private ContainerInfo mContainer;
+    private String mCommentText;
+    private Comment mComment;
+
+    ParsedTagInfo(String name, String kind, String text, ContainerInfo base, SourcePositionInfo sp)
+    {
+        super(name, kind, text, SourcePositionInfo.findBeginning(sp, text));
+        mContainer = base;
+        mCommentText = text;
+    }
+
+    public TagInfo[] commentTags()
+    {
+        if (mComment == null) {
+            mComment = new Comment(mCommentText, mContainer, position());
+        }
+        return mComment.tags();
+    }
+
+    protected void setCommentText(String comment)
+    {
+        mCommentText = comment;
+    }
+
+    public static <T extends ParsedTagInfo> TagInfo[]
+    joinTags(T[] tags)
+    {
+        ArrayList<TagInfo> list = new ArrayList<TagInfo>();
+        final int N = tags.length;
+        for (int i=0; i<N; i++) {
+            TagInfo[] t = tags[i].commentTags();
+            final int M = t.length;
+            for (int j=0; j<M; j++) {
+                list.add(t[j]);
+            }
+        }
+        return list.toArray(new TagInfo[list.size()]);
+    }
+}
diff --git a/tools/droiddoc/src/Proofread.java b/tools/droiddoc/src/Proofread.java
new file mode 100644
index 0000000..ec9f523
--- /dev/null
+++ b/tools/droiddoc/src/Proofread.java
@@ -0,0 +1,178 @@
+/*
+ * 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 java.io.IOException;
+import java.io.FileWriter;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+public class Proofread
+{
+    static FileWriter out = null;
+    static final Pattern WHITESPACE = Pattern.compile("\\r?\\n");
+    static final String INDENT = "        ";
+    static final String NEWLINE = "\n" + INDENT;
+
+    public static void initProofread(String filename)
+    {
+        try {
+            out = new FileWriter(filename);
+            out.write("javadoc proofread file: " + filename + "\n");
+        }
+        catch (IOException e) {
+            if (out != null) {
+                try {
+                    out.close();
+                }
+                catch (IOException ex) {
+                }
+                out = null;
+            }
+            System.err.println("error opening file: " + filename);
+        }
+    }
+
+    public static void finishProofread(String filename)
+    {
+        if (out == null) {
+            return;
+        }
+
+        try {
+            out.close();
+        }
+        catch (IOException e) {
+        }
+    }
+
+    public static void write(String s)
+    {
+        if (out == null) {
+            return ;
+        }
+        try {
+            out.write(s);
+        }
+        catch (IOException e) {
+        }
+    }
+
+    public static void writeIndented(String s)
+    {
+        s = s.trim();
+        Matcher m = WHITESPACE.matcher(s);
+        s = m.replaceAll(NEWLINE);
+        write(INDENT);
+        write(s);
+        write("\n");
+    }
+
+    public static void writeFileHeader(String filename)
+    {
+        write("\n\n=== ");
+        write(filename);
+        write(" ===\n");
+    }
+
+    public static void writeTagList(TagInfo[] tags)
+    {
+        if (out == null) {
+            return;
+        }
+
+        for (TagInfo t: tags) {
+            String k = t.kind();
+            if ("Text".equals(t.name())) {
+                writeIndented(t.text());
+            }
+            else if ("@more".equals(k)) {
+                writeIndented("");
+            }
+            else if ("@see".equals(k)) {
+                SeeTagInfo see = (SeeTagInfo)t;
+                String label = see.label();
+                if (label == null) {
+                    label = "";
+                }
+                writeIndented("{" + see.name() + " ... " + label + "}");
+            }
+            else if ("@code".equals(k)) {
+                writeIndented(t.text());
+            }
+            else if ("@samplecode".equals(k)) {
+                writeIndented(t.text());
+            }
+            else {
+                writeIndented("{" + (t.name() != null ? t.name() : "") + "/" +
+                        t.text() + "}");
+            }
+        }
+    }
+
+    public static void writePackages(String filename, TagInfo[] tags)
+    {
+        if (out == null) {
+            return;
+        }
+
+        writeFileHeader(filename);
+        writeTagList(tags);
+    }
+
+    public static void writePackage(String filename, TagInfo[] tags)
+    {
+        if (out == null) {
+            return;
+        }
+
+        writeFileHeader(filename);
+        writeTagList(tags);
+    }
+
+    public static void writeClass(String filename, ClassInfo cl)
+    {
+        if (out == null) {
+            return;
+        }
+
+        writeFileHeader(filename);
+        writeTagList(cl.inlineTags());
+
+        // enum constants
+        for (FieldInfo f: cl.enumConstants()) {
+            write("ENUM: " + f.name() + "\n");
+            writeTagList(f.inlineTags());
+        }
+
+        // fields
+        for (FieldInfo f: cl.selfFields()) {
+            write("FIELD: " + f.name() + "\n");
+            writeTagList(f.inlineTags());
+        }
+
+        // constructors
+        for (MethodInfo m: cl.constructors()) {
+            write("CONSTRUCTOR: " + m.name() + "\n");
+            writeTagList(m.inlineTags().tags());
+        }
+
+        // methods
+        for (MethodInfo m: cl.selfMethods()) {
+            write("METHOD: " + m.name() + "\n");
+            writeTagList(m.inlineTags().tags());
+        }
+    }
+}
diff --git a/tools/droiddoc/src/SampleCode.java b/tools/droiddoc/src/SampleCode.java
new file mode 100644
index 0000000..e2283bd
--- /dev/null
+++ b/tools/droiddoc/src/SampleCode.java
@@ -0,0 +1,161 @@
+/*
+ * 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 org.clearsilver.HDF;
+import org.clearsilver.CS;
+import java.util.*;
+import java.io.*;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+
+public class SampleCode {
+    String mSource;
+    String mDest;
+    String mTitle;
+
+    public SampleCode(String source, String dest, String title) {
+        mSource = source;
+        mTitle = title;
+        int len = dest.length();
+        if (len > 1 && dest.charAt(len-1) != '/') {
+            mDest = dest + '/';
+        } else {
+            mDest = dest;
+        }
+    }
+
+    public void write() {
+        File f = new File(mSource);
+        if (!f.isDirectory()) {
+            System.out.println("-samplecode not a directory: " + mSource);
+            return;
+        }
+        writeDirectory(f, mDest);
+    }
+
+    public static String convertExtension(String s, String ext) {
+        return s.substring(0, s.lastIndexOf('.')) + ext;
+    }
+
+    public static String[] IMAGES = { ".png", ".jpg", ".gif" };
+    public static String[] TEMPLATED = { ".java", ".xml" };
+
+    public static boolean inList(String s, String[] list) {
+        for (String t: list) {
+            if (s.endsWith(t)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public void writeDirectory(File dir, String relative) {
+        TreeSet<String> dirs = new TreeSet<String>();
+        TreeSet<String> files = new TreeSet<String>();
+
+        String subdir = relative; //.substring(mDest.length());
+
+        for (File f: dir.listFiles()) {
+            String name = f.getName();
+            if (name.startsWith(".") || name.startsWith("_")) {
+                continue;
+            }
+            if (f.isFile()) {
+                String out = relative + name;
+
+                if (inList(out, IMAGES)) {
+                    // copied directly
+                    ClearPage.copyFile(f, out);
+                    writeImagePage(f, convertExtension(out, DroidDoc.htmlExtension), subdir);
+                    files.add(name);
+                }
+                if (inList(out, TEMPLATED)) {
+                    // copied and goes through the template
+                    ClearPage.copyFile(f, out);
+                    writePage(f, convertExtension(out, DroidDoc.htmlExtension), subdir);
+                    files.add(name);
+                }
+                // else ignored
+            }
+            else if (f.isDirectory()) {
+                writeDirectory(f, relative + name + "/");
+                dirs.add(name);
+            }
+        }
+
+        // write the index page
+        int i;
+        HDF hdf = DroidDoc.makeHDF();
+
+        hdf.setValue("page.title", dir.getName() + " - " + mTitle);
+        hdf.setValue("projectTitle", mTitle);
+        hdf.setValue("subdir", subdir);
+        i=0;
+        for (String d: dirs) {
+            hdf.setValue("subdirs." + i + ".name", d);
+            i++;
+        }
+        i=0;
+        for (String f: files) {
+            hdf.setValue("files." + i + ".name", f);
+            hdf.setValue("files." + i + ".href", convertExtension(f, ".html"));
+            i++;
+        }
+        String filename = dir.getPath() + "/_index.html";
+        String summary = SampleTagInfo.readFile(new SourcePositionInfo(filename, -1,-1), filename,
+                                                "sample code", true, false, true);
+        if (summary == null) {
+            summary = "";
+        }
+        hdf.setValue("summary", summary);
+        
+        ClearPage.write(hdf, "sampleindex.cs", relative + "/index" + DroidDoc.htmlExtension);
+    }
+
+    public void writePage(File f, String out, String subdir) {
+        String name = f.getName();
+
+        String filename = f.getPath();
+        String data = SampleTagInfo.readFile(new SourcePositionInfo(filename, -1,-1), filename,
+                                                "sample code", true, true, true);
+        data = DroidDoc.escape(data);
+        
+        HDF hdf = DroidDoc.makeHDF();
+
+        hdf.setValue("page.title", name);
+        hdf.setValue("subdir", subdir);
+        hdf.setValue("realFile", name);
+        hdf.setValue("fileContents", data);
+
+        ClearPage.write(hdf, "sample.cs", out);
+    }
+
+    public void writeImagePage(File f, String out, String subdir) {
+        String name = f.getName();
+
+        String data = "<img src=\"" + name + "\" title=\"" + name + "\" />";
+        
+        HDF hdf = DroidDoc.makeHDF();
+
+        hdf.setValue("page.title", name);
+        hdf.setValue("subdir", subdir);
+        hdf.setValue("realFile", name);
+        hdf.setValue("fileContents", data);
+
+        ClearPage.write(hdf, "sample.cs", out);
+    }
+}
diff --git a/tools/droiddoc/src/SampleTagInfo.java b/tools/droiddoc/src/SampleTagInfo.java
new file mode 100644
index 0000000..c80083b
--- /dev/null
+++ b/tools/droiddoc/src/SampleTagInfo.java
@@ -0,0 +1,288 @@
+/*
+ * 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 org.clearsilver.HDF;
+import org.clearsilver.CS;
+
+import java.io.Reader;
+import java.io.IOException;
+import java.io.FileReader;
+import java.io.LineNumberReader;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+/*
+ * SampleTagInfo copies text from a given file into the javadoc comment.
+ *
+ * The @include tag copies the text verbatim from the given file.
+ *
+ * The @sample tag copies the text from the given file, stripping leading and
+ * trailing whitespace, and reducing the indent level of the text to the indent
+ * level of the first non-whitespace line.
+ *
+ * Both tags accept either a filename and an id or just a filename.  If no id
+ * is provided, the entire file is copied.  If an id is provided, the lines
+ * in the given file between the first two lines containing BEGIN_INCLUDE(id)
+ * and END_INCLUDE(id), for the given id, are copied.  The id may be only 
+ * letters, numbers and underscore (_).
+ *
+ * Four examples:
+ * {@include samples/ApiDemos/src/com/google/app/Notification1.java}
+ * {@sample samples/ApiDemos/src/com/google/app/Notification1.java}
+ * {@include samples/ApiDemos/src/com/google/app/Notification1.java Bleh}
+ * {@sample samples/ApiDemos/src/com/google/app/Notification1.java Bleh}
+ *
+ */
+public class SampleTagInfo extends TagInfo
+{
+    static final int STATE_BEGIN = 0;
+    static final int STATE_MATCHING = 1;
+
+    static final Pattern TEXT = Pattern.compile(
+                "[\r\n \t]*([^\r\n \t]*)[\r\n \t]*([0-9A-Za-z_]*)[\r\n \t]*",
+                Pattern.DOTALL);
+
+    private static final String BEGIN_INCLUDE = "BEGIN_INCLUDE";
+    private static final String END_INCLUDE = "END_INCLUDE";
+
+    private ContainerInfo mBase;
+    private String mIncluded;
+
+    public static String escapeHtml(String str) {
+        return str.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;");
+    }
+
+    private static boolean isIncludeLine(String str) {
+        return str.indexOf(BEGIN_INCLUDE)>=0 || str.indexOf(END_INCLUDE)>=0;
+    }
+
+    SampleTagInfo(String name, String kind, String text, ContainerInfo base,
+            SourcePositionInfo position)
+    {
+        super(name, kind, text, position);
+        mBase = base;
+
+        Matcher m = TEXT.matcher(text);
+        if (!m.matches()) {
+            Errors.error(Errors.BAD_INCLUDE_TAG, position, "Bad @include tag: "
+                    + text);
+            return;
+        }
+        String filename = m.group(1);
+        String id = m.group(2);
+        boolean trim = "@sample".equals(name);
+
+        if (id == null || "".equals(id)) {
+            mIncluded = readFile(position, filename, id, trim, true, false);
+        } else {
+            mIncluded = loadInclude(position, filename, id, trim);
+        }
+
+        if (mIncluded == null) {
+            Errors.error(Errors.BAD_INCLUDE_TAG, position, "include tag '" + id
+                    + "' not found in file: " + filename);
+        }
+    }
+
+    static String getTrimString(String line)
+    {
+        int i = 0;
+        int len = line.length();
+        for (; i<len; i++) {
+            char c = line.charAt(i);
+            if (c != ' ' && c != '\t') {
+                break;
+            }
+        }
+        if (i == len) {
+            return null;
+        } else {
+            return line.substring(0, i);
+        }
+    }
+
+    static String loadInclude(SourcePositionInfo pos, String filename,
+                                String id, boolean trim)
+    {
+        Reader input = null;
+        StringBuilder result = new StringBuilder();
+
+        String begin = BEGIN_INCLUDE + "(" + id + ")";
+        String end = END_INCLUDE + "(" + id + ")";
+
+        try {
+            input = new FileReader(filename);
+            LineNumberReader lines = new LineNumberReader(input);
+
+            int state = STATE_BEGIN;
+
+            int trimLength = -1;
+            String trimString = null;
+            int trailing = 0;
+
+            while (true) {
+                String line = lines.readLine();
+                if (line == null) {
+                    return null;
+                }
+                switch (state) {
+                case STATE_BEGIN:
+                    if (line.indexOf(begin) >= 0) {
+                        state = STATE_MATCHING;
+                    }
+                    break;
+                case STATE_MATCHING:
+                    if (line.indexOf(end) >= 0) {
+                        return result.substring(0);
+                    } else {
+                        boolean empty = "".equals(line.trim());
+                        if (trim) {
+                            if (isIncludeLine(line)) {
+                                continue;
+                            }
+                            if (trimLength < 0 && !empty) {
+                                trimString = getTrimString(line);
+                                if (trimString != null) {
+                                    trimLength = trimString.length();
+                                }
+                            }
+                            if (trimLength >= 0 && line.length() > trimLength) {
+                                boolean trimThisLine = true;
+                                for (int i=0; i<trimLength; i++) {
+                                    if (line.charAt(i) != trimString.charAt(i)){
+                                        trimThisLine = false;
+                                        break;
+                                    }
+                                }
+                                if (trimThisLine) {
+                                    line = line.substring(trimLength);
+                                }
+                            }
+                            if (trimLength >= 0) {
+                                if (!empty) {
+                                    for (int i=0; i<trailing; i++) {
+                                        result.append('\n');
+                                    }
+                                    line = escapeHtml(line);
+                                    result.append(line);
+                                    trailing = 1;  // add \n next time, maybe
+                                } else {
+                                    trailing++;
+                                }
+                            }
+                        } else {
+                            result.append(line);
+                            result.append('\n');
+                        }
+                    }
+                    break;
+                }
+            }
+        }
+        catch (IOException e) {
+            Errors.error(Errors.BAD_INCLUDE_TAG, pos, "Error reading file for"
+                    + " include \"" + id + "\" " + filename);
+        }
+        finally {
+            if (input != null) {
+                try {
+                    input.close();
+                }
+                catch (IOException ex) {
+                }
+            }
+        }
+        Errors.error(Errors.BAD_INCLUDE_TAG, pos, "Did not find " + end
+                + " in file " + filename);
+        return null;
+    }
+
+    static String readFile(SourcePositionInfo pos, String filename,
+                                String id, boolean trim, boolean escape,
+                                boolean errorOk)
+    {
+        Reader input = null;
+        StringBuilder result = new StringBuilder();
+        int trailing = 0;
+        boolean started = false;
+        try {
+            input = new FileReader(filename);
+            LineNumberReader lines = new LineNumberReader(input);
+
+            while (true) {
+                String line = lines.readLine();
+                if (line == null) {
+                    break;
+                }
+                if (trim) {
+                    if (isIncludeLine(line)) {
+                        continue;
+                    }
+                    if (!"".equals(line.trim())) {
+                        if (started) {
+                            for (int i=0; i<trailing; i++) {
+                                result.append('\n');
+                            }
+                        }
+                        if (escape) {
+                            line = escapeHtml(line);
+                        }
+                        result.append(line);
+                        trailing = 1;  // add \n next time, maybe
+                        started = true;
+                    } else {
+                        if (started) {
+                            trailing++;
+                        }
+                    }
+                } else {
+                    result.append(line);
+                    result.append('\n');
+                }
+            }
+        }
+        catch (IOException e) {
+            if (errorOk) {
+                return null;
+            } else {
+                Errors.error(Errors.BAD_INCLUDE_TAG, pos, "Error reading file for"
+                        + " include \"" + id + "\" " + filename);
+            }
+        }
+        finally {
+            if (input != null) {
+                try {
+                    input.close();
+                }
+                catch (IOException ex) {
+                }
+            }
+        }
+        return result.substring(0);
+    }
+
+    public void makeHDF(HDF data, String base)
+    {
+        data.setValue(base + ".name", name());
+        data.setValue(base + ".kind", kind());
+        if (mIncluded != null) {
+            data.setValue(base + ".text", mIncluded);
+        } else {
+            data.setValue(base + ".text", "INCLUDE_ERROR");
+        }
+    }
+}
+
diff --git a/tools/droiddoc/src/Scoped.java b/tools/droiddoc/src/Scoped.java
new file mode 100644
index 0000000..cca61ed
--- /dev/null
+++ b/tools/droiddoc/src/Scoped.java
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+public interface Scoped {
+    boolean isPublic();
+    boolean isProtected();
+    boolean isPackagePrivate();
+    boolean isPrivate();
+    boolean isHidden();
+}
diff --git a/tools/droiddoc/src/SeeTagInfo.java b/tools/droiddoc/src/SeeTagInfo.java
new file mode 100644
index 0000000..94863b5
--- /dev/null
+++ b/tools/droiddoc/src/SeeTagInfo.java
@@ -0,0 +1,79 @@
+/*
+ * 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 java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import org.clearsilver.HDF;
+import org.clearsilver.CS;
+import java.util.ArrayList;
+
+public class SeeTagInfo extends TagInfo
+{
+    private ContainerInfo mBase;
+    LinkReference mLink;
+
+    SeeTagInfo(String name, String kind, String text, ContainerInfo base,
+            SourcePositionInfo position)
+    {
+        super(name, kind, text, position);
+        mBase = base;
+    }
+
+    protected LinkReference linkReference() {
+        if (mLink == null) {
+            mLink = LinkReference.parse(text(), mBase, position(),
+                           (!"@see".equals(name())) && (mBase != null ? mBase.checkLevel() : true));
+        }
+        return mLink;
+    }
+
+    public String label()
+    {
+        return linkReference().label;
+    }
+
+    public void makeHDF(HDF data, String base)
+    {
+        LinkReference linkRef = linkReference();
+        if (linkRef.kind != null) {
+            // if they have a better suggestion about "kind" use that.
+            // do this before super.makeHDF() so it picks it up
+            setKind(linkRef.kind);
+        }
+
+        super.makeHDF(data, base);
+
+        data.setValue(base + ".label", linkRef.label);
+        if (linkRef.href != null) {
+            data.setValue(base + ".href", linkRef.href);
+        }
+    }
+
+    public boolean checkLevel() {
+        return linkReference().checkLevel();
+    }
+
+    public static void makeHDF(HDF data, String base, SeeTagInfo[] tags)
+    {
+        int j=0;
+        for (SeeTagInfo tag: tags) {
+            if (tag.mBase.checkLevel() && tag.checkLevel()) {
+                tag.makeHDF(data, base + "." + j);
+                j++;
+            }
+        }
+    }
+}
diff --git a/tools/droiddoc/src/Sorter.java b/tools/droiddoc/src/Sorter.java
new file mode 100644
index 0000000..92039d4
--- /dev/null
+++ b/tools/droiddoc/src/Sorter.java
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+public class Sorter implements Comparable
+{
+    public String label;
+    public Object data;
+
+    public Sorter(String l, Object d)
+    {
+        label = l;
+        data = d;
+    }
+
+    public int compareTo(Object other)
+    {
+        return label.compareToIgnoreCase(((Sorter)other).label);
+    }
+}
diff --git a/tools/droiddoc/src/SourcePositionInfo.java b/tools/droiddoc/src/SourcePositionInfo.java
new file mode 100644
index 0000000..6244803
--- /dev/null
+++ b/tools/droiddoc/src/SourcePositionInfo.java
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+public class SourcePositionInfo implements Comparable
+{
+    public SourcePositionInfo() {
+        this.file = "<unknown>";
+        this.line = 0;
+        this.column = 0;
+    }
+
+    public SourcePositionInfo(String file, int line, int column)
+    {
+        this.file = file;
+        this.line = line;
+        this.column = column;
+    }
+
+    public SourcePositionInfo(SourcePositionInfo that)
+    {
+        this.file = that.file;
+        this.line = that.line;
+        this.column = that.column;
+    }
+
+    /**
+     * Given this position and str which occurs at that position, as well as str an index into str,
+     * find the SourcePositionInfo.
+     *
+     * @throw StringIndexOutOfBoundsException if index &gt; str.length()
+     */
+    public static SourcePositionInfo add(SourcePositionInfo that, String str, int index)
+    {
+        if (that == null) {
+            return null;
+        }
+        int line = that.line;
+        char prev = 0;
+        for (int i=0; i<index; i++) {
+            char c = str.charAt(i);
+            if (c == '\r' || (c == '\n' && prev != '\r')) {
+                line++;
+            }
+            prev = c;
+        }
+        return new SourcePositionInfo(that.file, line, 0);
+    }
+
+    public static SourcePositionInfo findBeginning(SourcePositionInfo that, String str)
+    {
+        if (that == null) {
+            return null;
+        }
+        int line = that.line-1; // -1 because, well, it seems to work
+        int prev = 0;
+        for (int i=str.length()-1; i>=0; i--) {
+            char c = str.charAt(i);
+            if ((c == '\r' && prev != '\n') || (c == '\n')) {
+                line--;
+            }
+            prev = c;
+        }
+        return new SourcePositionInfo(that.file, line, 0);
+    }
+
+    public String toString()
+    {
+        return file + ':' + line;
+    }
+
+    public int compareTo(Object o) {
+        SourcePositionInfo that = (SourcePositionInfo)o;
+        int r = this.file.compareTo(that.file);
+        if (r != 0) return r;
+        return this.line - that.line;
+    }
+
+    public String file;
+    public int line;
+    public int column;
+}
diff --git a/tools/droiddoc/src/Stubs.java b/tools/droiddoc/src/Stubs.java
new file mode 100644
index 0000000..e1ec76a
--- /dev/null
+++ b/tools/droiddoc/src/Stubs.java
@@ -0,0 +1,988 @@
+/*
+ * 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 java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.Comparator;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.PrintStream;
+
+public class Stubs {
+    private static HashSet<ClassInfo> notStrippable;
+    public static void writeStubs(String stubsDir, Boolean writeXML, String xmlFile,
+            HashSet<String> stubPackages) {
+        // figure out which classes we need
+        notStrippable = new HashSet();
+        ClassInfo[] all = Converter.allClasses();
+        File  xml = new File(xmlFile);
+        xml.getParentFile().mkdirs();
+        PrintStream xmlWriter = null;
+        if (writeXML) {
+            try {
+                xmlWriter = new PrintStream(xml);
+            } catch (FileNotFoundException e) {
+                Errors.error(Errors.IO_ERROR, new SourcePositionInfo(xmlFile, 0, 0),
+                        "Cannot open file for write.");
+            }
+        }
+        // If a class is public or protected, not hidden, and marked as included,
+        // then we can't strip it
+        for (ClassInfo cl: all) {
+            if (cl.checkLevel() && cl.isIncluded()) {
+                cantStripThis(cl, notStrippable, "0:0");
+            }
+        }
+
+        // complain about anything that looks includeable but is not supposed to
+        // be written, e.g. hidden things
+        for (ClassInfo cl: notStrippable) {
+            if (!cl.isHidden()) {
+                MethodInfo[] methods = cl.selfMethods();
+                for (MethodInfo m: methods) {
+                    if (m.isHidden()) {
+                        Errors.error(Errors.UNAVAILABLE_SYMBOL,
+                                m.position(), "Reference to hidden method "
+                                + m.name());
+                    } else if (m.isDeprecated()) {
+                        // don't bother reporting deprecated methods
+                        // unless they are public
+                        Errors.error(Errors.DEPRECATED,
+                                m.position(), "Method "
+                                + cl.qualifiedName() + "." + m.name()
+                                + " is deprecated");
+                    }
+
+                    ClassInfo returnClass = m.returnType().asClassInfo();
+                    if (returnClass != null && returnClass.isHidden()) {
+                        Errors.error(Errors.UNAVAILABLE_SYMBOL, m.position(),
+                                "Method " + cl.qualifiedName() + "." + m.name()
+                                + " returns unavailable type " + returnClass.name());
+                    }
+
+                    ParameterInfo[] params = m.parameters();
+                    for (ParameterInfo p: params) {
+                        TypeInfo t = p.type();
+                        if (!t.isPrimitive()) {
+                            if (t.asClassInfo().isHidden()) {
+                                Errors.error(Errors.UNAVAILABLE_SYMBOL,
+                                        m.position(), "Parameter of hidden type "
+                                        + t.fullName() + " in "
+                                        + cl.qualifiedName() + "." + m.name() + "()");
+                            }
+                        }
+                    }
+                }
+
+                // annotations are handled like methods
+                methods = cl.annotationElements();
+                for (MethodInfo m: methods) {
+                    if (m.isHidden()) {
+                        Errors.error(Errors.UNAVAILABLE_SYMBOL,
+                                m.position(), "Reference to hidden annotation "
+                                + m.name());
+                    }
+
+                    ClassInfo returnClass = m.returnType().asClassInfo();
+                    if (returnClass != null && returnClass.isHidden()) {
+                        Errors.error(Errors.UNAVAILABLE_SYMBOL,
+                                m.position(), "Annotation '" + m.name()
+                                + "' returns unavailable type " + returnClass.name());
+                    }
+
+                    ParameterInfo[] params = m.parameters();
+                    for (ParameterInfo p: params) {
+                        TypeInfo t = p.type();
+                        if (!t.isPrimitive()) {
+                            if (t.asClassInfo().isHidden()) {
+                                Errors.error(Errors.UNAVAILABLE_SYMBOL,
+                                        p.position(), "Reference to unavailable annotation class "
+                                        + t.fullName());
+                            }
+                        }
+                    }
+                }
+            } else if (cl.isDeprecated()) {
+                // not hidden, but deprecated
+                Errors.error(Errors.DEPRECATED,
+                        cl.position(), "Class " + cl.qualifiedName()
+                        + " is deprecated");
+            }
+        }
+
+        // write out the stubs
+        HashMap<PackageInfo, List<ClassInfo>> packages = new HashMap<PackageInfo, List<ClassInfo>>();
+        for (ClassInfo cl: notStrippable) {
+            if (!cl.isDocOnly()) {
+                if (stubPackages == null || stubPackages.contains(cl.containingPackage().name())) {
+                    writeClassFile(stubsDir, cl);
+                    if (packages.containsKey(cl.containingPackage())) {
+                        packages.get(cl.containingPackage()).add(cl);
+                    } else {
+                        ArrayList<ClassInfo> classes = new ArrayList<ClassInfo>();
+                        classes.add(cl);
+                        packages.put(cl.containingPackage(), classes);
+                    }
+                }
+            }
+        }
+
+        // write out the XML
+        if (writeXML && xmlWriter != null) {
+            writeXML(xmlWriter, packages, notStrippable);
+        }
+
+        if (xmlWriter != null) {
+            xmlWriter.close();
+        }
+
+    }
+
+    public static void cantStripThis(ClassInfo cl, HashSet<ClassInfo> notStrippable, String why) {
+
+      if (!notStrippable.add(cl)) {
+        // slight optimization: if it already contains cl, it already contains
+        // all of cl's parents
+          return;
+      }
+      cl.setReasonIncluded(why);
+
+      // cant strip annotations
+      /*if (cl.annotations() != null){
+          for (AnnotationInstanceInfo ai : cl.annotations()){
+              if (ai.type() != null){
+                  cantStripThis(ai.type(), notStrippable, "1:" + cl.qualifiedName());
+              }
+          }
+      }*/
+      // cant strip any public fields or their generics
+      if (cl.allSelfFields() != null){
+          for (FieldInfo fInfo : cl.allSelfFields()){
+              if (fInfo.type() != null){
+                  if (fInfo.type().asClassInfo() != null){
+                      cantStripThis(fInfo.type().asClassInfo(), notStrippable,
+                          "2:" + cl.qualifiedName());
+                  }
+                  if (fInfo.type().typeArguments() != null){
+                      for (TypeInfo tTypeInfo : fInfo.type().typeArguments()){
+                          if (tTypeInfo.asClassInfo() != null){
+                              cantStripThis(tTypeInfo.asClassInfo(), notStrippable,
+                                  "3:" + cl.qualifiedName());
+                          }
+                      }
+                  }
+              }
+          }
+      }
+      //cant strip any of the type's generics
+      if (cl.asTypeInfo() != null){
+          if (cl.asTypeInfo().typeArguments() != null){
+              for (TypeInfo tInfo : cl.asTypeInfo().typeArguments()){
+                  if (tInfo.asClassInfo() != null){
+                      cantStripThis(tInfo.asClassInfo(), notStrippable, "4:" + cl.qualifiedName());
+                  }
+              }
+          }
+      }
+      //cant strip any of the annotation elements
+      //cantStripThis(cl.annotationElements(), notStrippable);
+      // take care of methods
+      cantStripThis(cl.allSelfMethods(), notStrippable);
+      cantStripThis(cl.allConstructors(), notStrippable);
+      // blow the outer class open if this is an inner class
+      if(cl.containingClass() != null){
+          cantStripThis(cl.containingClass(), notStrippable, "5:" + cl.qualifiedName());
+      }
+      // blow open super class and interfaces
+     ClassInfo supr = cl.realSuperclass();
+      if (supr != null) {
+          if (supr.isHidden()) {
+              // cl is a public class declared as extending a hidden superclass.
+              // this is not a desired practice but it's happened, so we deal
+              // with it by stripping off the superclass relation for purposes of
+              // generating the doc & stub information, and proceeding normally.
+              cl.init(cl.asTypeInfo(), cl.realInterfaces(), cl.realInterfaceTypes(),
+                      cl.innerClasses(), cl.allConstructors(), cl.allSelfMethods(),
+                      cl.annotationElements(), cl.allSelfFields(), cl.enumConstants(),
+                      cl.containingPackage(), cl.containingClass(),
+                      null, null, cl.annotations());
+              Errors.error(Errors.HIDDEN_SUPERCLASS,
+                      cl.position(), "Public class " + cl.qualifiedName()
+                      + " stripped of unavailable superclass "
+                      + supr.qualifiedName());
+          } else {
+              cantStripThis(supr, notStrippable, "6:" + cl.realSuperclass().name()
+                      + cl.qualifiedName());
+          }
+      }
+    }
+
+    private static void cantStripThis(MethodInfo[] mInfos , HashSet<ClassInfo> notStrippable) {
+      //for each method, blow open the parameters, throws and return types.  also blow open their generics
+      if (mInfos != null){
+          for (MethodInfo mInfo : mInfos){
+              if (mInfo.getTypeParameters() != null){
+                  for (TypeInfo tInfo : mInfo.getTypeParameters()){
+                      if (tInfo.asClassInfo() != null){
+                          cantStripThis(tInfo.asClassInfo(), notStrippable, "8:" +
+                                        mInfo.realContainingClass().qualifiedName() + ":" +
+                                        mInfo.name());
+                      }
+                  }
+              }
+              if (mInfo.parameters() != null){
+                  for (ParameterInfo pInfo : mInfo.parameters()){
+                      if (pInfo.type() != null && pInfo.type().asClassInfo() != null){
+                          cantStripThis(pInfo.type().asClassInfo(), notStrippable,
+                                        "9:"+  mInfo.realContainingClass().qualifiedName()
+                                        + ":" + mInfo.name());
+                          if (pInfo.type().typeArguments() != null){
+                              for (TypeInfo tInfoType : pInfo.type().typeArguments()){
+                                  if (tInfoType.asClassInfo() != null){
+                                      ClassInfo tcl = tInfoType.asClassInfo();
+                                      if (tcl.isHidden()) {
+                                          Errors.error(Errors.UNAVAILABLE_SYMBOL, mInfo.position(),
+                                                  "Parameter of hidden type "
+                                                  + tInfoType.fullName() + " in "
+                                                  + mInfo.containingClass().qualifiedName()
+                                                  + '.' + mInfo.name() + "()");
+                                      } else {
+                                          cantStripThis(tcl, notStrippable,
+                                                  "10:" +
+                                                  mInfo.realContainingClass().qualifiedName() + ":" +
+                                                  mInfo.name());
+                                      }
+                                  }
+                              }
+                          }
+                      }
+                  }
+              }
+              for (ClassInfo thrown : mInfo.thrownExceptions()){
+                  cantStripThis(thrown, notStrippable, "11:" +
+                                mInfo.realContainingClass().qualifiedName()
+                                +":" + mInfo.name());
+              }
+              if (mInfo.returnType() != null && mInfo.returnType().asClassInfo() != null){
+                  cantStripThis(mInfo.returnType().asClassInfo(), notStrippable,
+                                "12:" + mInfo.realContainingClass().qualifiedName() +
+                                ":" + mInfo.name());
+                  if (mInfo.returnType().typeArguments() != null){
+                      for (TypeInfo tyInfo: mInfo.returnType().typeArguments() ){
+                          if (tyInfo.asClassInfo() != null){
+                              cantStripThis(tyInfo.asClassInfo(), notStrippable,
+                                            "13:" +
+                                            mInfo.realContainingClass().qualifiedName()
+                                            + ":" + mInfo.name());
+                          }
+                      }
+                  }
+              }
+          }
+      }
+    }
+
+    static String javaFileName(ClassInfo cl) {
+        String dir = "";
+        PackageInfo pkg = cl.containingPackage();
+        if (pkg != null) {
+            dir = pkg.name();
+            dir = dir.replace('.', '/') + '/';
+        }
+        return dir + cl.name() + ".java";
+    }
+
+    static void writeClassFile(String stubsDir, ClassInfo cl) {
+        // inner classes are written by their containing class
+        if (cl.containingClass() != null) {
+            return;
+        }
+
+        String filename = stubsDir + '/' + javaFileName(cl);
+        File file = new File(filename);
+        ClearPage.ensureDirectory(file);
+
+        PrintStream stream = null;
+        try {
+            stream = new PrintStream(file);
+            writeClassFile(stream, cl);
+        }
+        catch (FileNotFoundException e) {
+            System.err.println("error writing file: " + filename);
+        }
+        finally {
+            if (stream != null) {
+                stream.close();
+            }
+        }
+    }
+
+    static void writeClassFile(PrintStream stream, ClassInfo cl) {
+        PackageInfo pkg = cl.containingPackage();
+        if (pkg != null) {
+            stream.println("package " + pkg.name() + ";");
+        }
+        writeClass(stream, cl);
+    }
+
+    static void writeClass(PrintStream stream, ClassInfo cl) {
+        writeAnnotations(stream, cl.annotations());
+
+        stream.print(DroidDoc.scope(cl) + " ");
+        if (cl.isAbstract() && !cl.isAnnotation() && !cl.isInterface()) {
+            stream.print("abstract ");
+        }
+        if (cl.isStatic()){
+            stream.print("static ");
+        }
+        if (cl.isFinal() && !cl.isEnum()) {
+            stream.print("final ");
+        }
+        if (false) {
+            stream.print("strictfp ");
+        }
+
+        HashSet<String> classDeclTypeVars = new HashSet();
+        String leafName = cl.asTypeInfo().fullName(classDeclTypeVars);
+        int bracket = leafName.indexOf('<');
+        if (bracket < 0) bracket = leafName.length() - 1;
+        int period = leafName.lastIndexOf('.', bracket);
+        if (period < 0) period = -1;
+        leafName = leafName.substring(period+1);
+
+        String kind = cl.kind();
+        stream.println(kind + " " + leafName);
+
+        TypeInfo base = cl.superclassType();
+
+        if (!"enum".equals(kind)) {
+            if (base != null && !"java.lang.Object".equals(base.qualifiedTypeName())) {
+                stream.println("  extends " + base.fullName(classDeclTypeVars));
+            }
+        }
+
+        TypeInfo[] interfaces = cl.realInterfaceTypes();
+        List<TypeInfo> usedInterfaces = new ArrayList<TypeInfo>();
+        for (TypeInfo iface : interfaces) {
+            if (notStrippable.contains(iface.asClassInfo())
+                    && !iface.asClassInfo().isDocOnly()) {
+                usedInterfaces.add(iface);
+            }
+        }
+        if (usedInterfaces.size() > 0 && !cl.isAnnotation()) {
+            // can java annotations extend other ones?
+            if (cl.isInterface() || cl.isAnnotation()) {
+                stream.print("  extends ");
+            } else {
+                stream.print("  implements ");
+            }
+            String comma = "";
+            for (TypeInfo iface: usedInterfaces) {
+                stream.print(comma + iface.fullName(classDeclTypeVars));
+                comma = ", ";
+            }
+            stream.println();
+        }
+
+        stream.println("{");
+
+        FieldInfo[] enumConstants = cl.enumConstants();
+        int N = enumConstants.length;
+        for (int i=0; i<N; i++) {
+            FieldInfo field = enumConstants[i];
+            if (!field.constantLiteralValue().equals("null")){
+            stream.println(field.name() + "(" + field.constantLiteralValue()
+                    + (i==N-1 ? ");" : "),"));
+            }else{
+              stream.println(field.name() + "(" + (i==N-1 ? ");" : "),"));
+            }
+        }
+
+        for (ClassInfo inner: cl.getRealInnerClasses()) {
+            if (notStrippable.contains(inner)
+                    && !inner.isDocOnly()){
+                writeClass(stream, inner);
+            }
+        }
+
+
+        for (MethodInfo method: cl.constructors()) {
+            if (!method.isDocOnly()) {
+                writeMethod(stream, method, true);
+            }
+        }
+
+        boolean fieldNeedsInitialization = false;
+        boolean staticFieldNeedsInitialization = false;
+        for (FieldInfo field: cl.allSelfFields()) {
+            if (!field.isDocOnly()) {
+                if (!field.isStatic() && field.isFinal() && !fieldIsInitialized(field)) {
+                    fieldNeedsInitialization = true;
+                }
+                if (field.isStatic() && field.isFinal() && !fieldIsInitialized(field)) {
+                    staticFieldNeedsInitialization = true;
+                }
+            }
+        }
+
+        // The compiler includes a default public constructor that calls the super classes
+        // default constructor in the case where there are no written constructors.
+        // So, if we hide all the constructors, java may put in a constructor
+        // that calls a nonexistent super class constructor.  So, if there are no constructors,
+        // and the super class doesn't have a default constructor, write in a private constructor
+        // that works.  TODO -- we generate this as protected, but we really should generate
+        // it as private unless it also exists in the real code.
+        if ((cl.constructors().length == 0 && (cl.getNonWrittenConstructors().length != 0
+                    || fieldNeedsInitialization))
+                && !cl.isAnnotation()
+                && !cl.isInterface()
+                && !cl.isEnum() ) {
+            //Errors.error(Errors.HIDDEN_CONSTRUCTOR,
+            //             cl.position(), "No constructors " +
+            //            "found and superclass has no parameterless constructor.  A constructor " +
+            //            "that calls an appropriate superclass constructor " +
+            //            "was automatically written to stubs.\n");
+            stream.println(cl.leafName()
+                    + "() { " + superCtorCall(cl,null)
+                    + "throw new" + " RuntimeException(\"Stub!\"); }");
+        }
+
+        for (MethodInfo method: cl.allSelfMethods()) {
+            if (cl.isEnum()) {
+                if (("values".equals(method.name())
+                            && "()".equals(method.signature()))
+                    || ("valueOf".equals(method.name())
+                            && "(java.lang.String)".equals(method.signature()))) {
+                    // skip these two methods on enums, because they're synthetic,
+                    // although for some reason javadoc doesn't mark them as synthetic,
+                    // maybe because they still want them documented
+                    continue;
+                }
+            }
+            if (!method.isDocOnly()) {
+                writeMethod(stream, method, false);
+            }
+        }
+        //Write all methods that are hidden, but override abstract methods or interface methods.
+        //These can't be hidden.
+        for (MethodInfo method : cl.getHiddenMethods()){
+            MethodInfo overriddenMethod = method.findRealOverriddenMethod(method.name(), method.signature(), notStrippable);
+            ClassInfo classContainingMethod = method.findRealOverriddenClass(method.name(),
+                                                                             method.signature());
+            if (overriddenMethod != null && !overriddenMethod.isHidden()
+                && !overriddenMethod.isDocOnly() &&
+                (overriddenMethod.isAbstract() ||
+                overriddenMethod.containingClass().isInterface())) {
+                method.setReason("1:" + classContainingMethod.qualifiedName());
+                cl.addMethod(method);
+                writeMethod(stream, method, false);
+            }
+        }
+
+        for (MethodInfo element: cl.annotationElements()) {
+            if (!element.isDocOnly()) {
+                writeAnnotationElement(stream, element);
+            }
+        }
+
+        for (FieldInfo field: cl.allSelfFields()) {
+            if (!field.isDocOnly()) {
+                writeField(stream, field);
+            }
+        }
+
+        if (staticFieldNeedsInitialization) {
+            stream.print("static { ");
+            for (FieldInfo field: cl.allSelfFields()) {
+                if (!field.isDocOnly() && field.isStatic() && field.isFinal()
+                        && !fieldIsInitialized(field) && field.constantValue() == null) {
+                    stream.print(field.name() + " = " + field.type().defaultValue()
+                            + "; ");
+                }
+            }
+            stream.println("}");
+        }
+
+        stream.println("}");
+    }
+
+
+    static void writeMethod(PrintStream stream, MethodInfo method, boolean isConstructor) {
+        String comma;
+
+        stream.print(DroidDoc.scope(method) + " ");
+        if (method.isStatic()) {
+            stream.print("static ");
+        }
+        if (method.isFinal()) {
+            stream.print("final ");
+        }
+        if (method.isAbstract()) {
+            stream.print("abstract ");
+        }
+        if (method.isSynchronized()) {
+            stream.print("synchronized ");
+        }
+        if (method.isNative()) {
+            stream.print("native ");
+        }
+        if (false /*method.isStictFP()*/) {
+            stream.print("strictfp ");
+        }
+
+        stream.print(method.typeArgumentsName(new HashSet()) + " ");
+
+        if (!isConstructor) {
+            stream.print(method.returnType().fullName(method.typeVariables()) + " ");
+        }
+        String n = method.name();
+        int pos = n.lastIndexOf('.');
+        if (pos >= 0) {
+            n = n.substring(pos + 1);
+        }
+        stream.print(n + "(");
+        comma = "";
+        int count = 1;
+        int size = method.parameters().length;
+        for (ParameterInfo param: method.parameters()) {
+            stream.print(comma + fullParameterTypeName(method, param.type(), count == size)
+                    + " " + param.name());
+            comma = ", ";
+            count++;
+        }
+        stream.print(")");
+
+        comma = "";
+        if (method.thrownExceptions().length > 0) {
+            stream.print(" throws ");
+            for (ClassInfo thrown: method.thrownExceptions()) {
+                stream.print(comma + thrown.qualifiedName());
+                comma = ", ";
+            }
+        }
+        if (method.isAbstract() || method.isNative() || method.containingClass().isInterface()) {
+            stream.println(";");
+        } else {
+            stream.print(" { ");
+            if (isConstructor) {
+                stream.print(superCtorCall(method.containingClass(), method.thrownExceptions()));
+            }
+            stream.println("throw new RuntimeException(\"Stub!\"); }");
+        }
+    }
+
+    static void writeField(PrintStream stream, FieldInfo field) {
+        stream.print(DroidDoc.scope(field) + " ");
+        if (field.isStatic()) {
+            stream.print("static ");
+        }
+        if (field.isFinal()) {
+            stream.print("final ");
+        }
+        if (field.isTransient()) {
+            stream.print("transient ");
+        }
+        if (field.isVolatile()) {
+            stream.print("volatile ");
+        }
+
+        stream.print(field.type().fullName());
+        stream.print(" ");
+        stream.print(field.name());
+
+        if (fieldIsInitialized(field)) {
+            stream.print(" = " + field.constantLiteralValue());
+        }
+
+        stream.println(";");
+    }
+
+    static boolean fieldIsInitialized(FieldInfo field) {
+        return (field.isFinal() && field.constantValue() != null)
+                || !field.type().dimension().equals("")
+                || field.containingClass().isInterface();
+    }
+
+    // Returns 'true' if the method is an @Override of a visible parent
+    // method implementation, and thus does not affect the API.
+    static boolean methodIsOverride(MethodInfo mi) {
+        // Abstract/static/final methods are always listed in the API description
+        if (mi.isAbstract() || mi.isStatic() || mi.isFinal()) {
+            return false;
+        }
+
+        // Find any relevant ancestor declaration and inspect it
+        MethodInfo om = mi.findSuperclassImplementation(notStrippable);
+        if (om != null) {
+            // Visibility mismatch is an API change, so check for it
+            if (mi.mIsPrivate == om.mIsPrivate
+                    && mi.mIsPublic == om.mIsPublic
+                    && mi.mIsProtected == om.mIsProtected) {
+                // Look only for overrides of an ancestor class implementation,
+                // not of e.g. an abstract or interface method declaration
+                if (!om.isAbstract()) {
+                    // If the parent is hidden, we can't rely on it to provide
+                    // the API
+                    if (!om.isHidden()) {
+                        // If the only "override" turns out to be in our own class
+                        // (which sometimes happens in concrete subclasses of
+                        // abstract base classes), it's not really an override
+                        if (!mi.mContainingClass.equals(om.mContainingClass)) {
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    static boolean canCallMethod(ClassInfo from, MethodInfo m) {
+        if (m.isPublic() || m.isProtected()) {
+            return true;
+        }
+        if (m.isPackagePrivate()) {
+            String fromPkg = from.containingPackage().name();
+            String pkg = m.containingClass().containingPackage().name();
+            if (fromPkg.equals(pkg)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    // call a constructor, any constructor on this class's superclass.
+    static String superCtorCall(ClassInfo cl, ClassInfo[] thrownExceptions) {
+        ClassInfo base = cl.realSuperclass();
+        if (base == null) {
+            return "";
+        }
+        HashSet<String> exceptionNames = new HashSet<String>();
+        if (thrownExceptions != null ){
+            for (ClassInfo thrown : thrownExceptions){
+              exceptionNames.add(thrown.name());
+            }
+        }
+        MethodInfo[] ctors = base.constructors();
+        MethodInfo ctor = null;
+        //bad exception indicates that the exceptions thrown by the super constructor
+        //are incompatible with the constructor we're using for the sub class.
+        Boolean badException = false;
+        for (MethodInfo m: ctors) {
+            if (canCallMethod(cl, m)) {
+                if (m.thrownExceptions() != null){
+                    for (ClassInfo thrown : m.thrownExceptions()){
+                        if (!exceptionNames.contains(thrown.name())){
+                            badException = true;
+                        }
+                    }
+                }
+                if (badException){
+                  badException = false;
+                  continue;
+                }
+                // if it has no args, we're done
+                if (m.parameters().length == 0) {
+                    return "";
+                }
+                ctor = m;
+            }
+        }
+        if (ctor != null) {
+            String result = "";
+            result+= "super(";
+            ParameterInfo[] params = ctor.parameters();
+            int N = params.length;
+            for (int i=0; i<N; i++) {
+                TypeInfo t = params[i].type();
+                if (t.isPrimitive() && t.dimension().equals("")) {
+                    String n = t.simpleTypeName();
+                    if (("byte".equals(n)
+                            || "short".equals(n)
+                            || "int".equals(n)
+                            || "long".equals(n)
+                            || "float".equals(n)
+                            || "double".equals(n)) && t.dimension().equals("")) {
+                        result += "0";
+                    }
+                    else if ("char".equals(n)) {
+                        result += "'\\0'";
+                    }
+                    else if ("boolean".equals(n)) {
+                        result += "false";
+                    }
+                    else {
+                        result += "<<unknown-" + n + ">>";
+                    }
+                } else {
+                    //put null in each super class method.  Cast null to the correct type
+                    //to avoid collisions with other constructors.  If the type is generic
+                    //don't cast it
+                    result += (!t.isTypeVariable() ? "(" + t.qualifiedTypeName() + t.dimension() +
+                              ")" : "") + "null";
+                }
+                if (i != N-1) {
+                    result += ",";
+                }
+            }
+            result += "); ";
+            return result;
+        } else {
+            return "";
+        }
+    }
+
+    static void writeAnnotations(PrintStream stream, AnnotationInstanceInfo[] annotations) {
+        for (AnnotationInstanceInfo ann: annotations) {
+            if (!ann.type().isHidden()) {
+                stream.println(ann.toString());
+            }
+        }
+    }
+
+    static void writeAnnotationElement(PrintStream stream, MethodInfo ann) {
+        stream.print(ann.returnType().fullName());
+        stream.print(" ");
+        stream.print(ann.name());
+        stream.print("()");
+        AnnotationValueInfo def = ann.defaultAnnotationElementValue();
+        if (def != null) {
+            stream.print(" default ");
+            stream.print(def.valueString());
+        }
+        stream.println(";");
+    }
+
+    static void writeXML(PrintStream xmlWriter, HashMap<PackageInfo, List<ClassInfo>> allClasses,
+                         HashSet notStrippable) {
+        // extract the set of packages, sort them by name, and write them out in that order
+        Set<PackageInfo> allClassKeys = allClasses.keySet();
+        PackageInfo[] allPackages = allClassKeys.toArray(new PackageInfo[allClassKeys.size()]);
+        Arrays.sort(allPackages, PackageInfo.comparator);
+
+        xmlWriter.println("<api>");
+        for (PackageInfo pack : allPackages) {
+            writePackageXML(xmlWriter, pack, allClasses.get(pack), notStrippable);
+        }
+        xmlWriter.println("</api>");
+    }
+
+    static void writePackageXML(PrintStream xmlWriter, PackageInfo pack, List<ClassInfo> classList,
+                                HashSet notStrippable) {
+        ClassInfo[] classes = classList.toArray(new ClassInfo[classList.size()]);
+        Arrays.sort(classes, ClassInfo.comparator);
+        xmlWriter.println("<package name=\"" + pack.name() + "\"\n"
+                //+ " source=\"" + pack.position() + "\"\n"
+                + ">");
+        for (ClassInfo cl : classes) {
+            writeClassXML(xmlWriter, cl, notStrippable);
+        }
+        xmlWriter.println("</package>");
+
+
+    }
+
+    static void writeClassXML(PrintStream xmlWriter, ClassInfo cl, HashSet notStrippable) {
+        String scope = DroidDoc.scope(cl);
+        String deprecatedString = "";
+        String declString = (cl.isInterface()) ? "interface" : "class";
+        if (cl.isDeprecated()) {
+            deprecatedString = "deprecated";
+        } else {
+            deprecatedString = "not deprecated";
+        }
+        xmlWriter.println("<" + declString + " name=\"" + cl.name() + "\"");
+        if (!cl.isInterface() && !cl.qualifiedName().equals("java.lang.Object")) {
+            xmlWriter.println(" extends=\"" + ((cl.realSuperclass() == null)
+                            ? "java.lang.Object"
+                            : cl.realSuperclass().qualifiedName()) + "\"");
+        }
+        xmlWriter.println(" abstract=\"" + cl.isAbstract() + "\"\n"
+                + " static=\"" + cl.isStatic() + "\"\n"
+                + " final=\"" + cl.isFinal() + "\"\n"
+                + " deprecated=\"" + deprecatedString + "\"\n"
+                + " visibility=\"" + scope + "\"\n"
+                //+ " source=\"" + cl.position() + "\"\n"
+                + ">");
+
+        ClassInfo[] interfaces = cl.realInterfaces();
+        Arrays.sort(interfaces, ClassInfo.comparator);
+        for (ClassInfo iface : interfaces) {
+            if (notStrippable.contains(iface)) {
+                xmlWriter.println("<implements name=\"" + iface.qualifiedName() + "\">");
+                xmlWriter.println("</implements>");
+            }
+        }
+
+        MethodInfo[] constructors = cl.constructors();
+        Arrays.sort(constructors, MethodInfo.comparator);
+        for (MethodInfo mi : constructors) {
+            writeConstructorXML(xmlWriter, mi);
+        }
+
+        MethodInfo[] methods = cl.allSelfMethods();
+        Arrays.sort(methods, MethodInfo.comparator);
+        for (MethodInfo mi : methods) {
+            if (!methodIsOverride(mi)) {
+                writeMethodXML(xmlWriter, mi);
+            }
+        }
+
+        FieldInfo[] fields = cl.allSelfFields();
+        Arrays.sort(fields, FieldInfo.comparator);
+        for (FieldInfo fi : fields) {
+            writeFieldXML(xmlWriter, fi);
+        }
+        xmlWriter.println("</" + declString + ">");
+
+    }
+
+    static void writeMethodXML(PrintStream xmlWriter, MethodInfo mi) {
+        String scope = DroidDoc.scope(mi);
+
+        String deprecatedString = "";
+        if (mi.isDeprecated()) {
+            deprecatedString = "deprecated";
+        } else {
+            deprecatedString = "not deprecated";
+        }
+        xmlWriter.println("<method name=\"" + mi.name() + "\"\n"
+                + ((mi.returnType() != null)
+                        ? " return=\"" + makeXMLcompliant(fullParameterTypeName(mi, mi.returnType(), false)) + "\"\n"
+                        : "")
+                + " abstract=\"" + mi.isAbstract() + "\"\n"
+                + " native=\"" + mi.isNative() + "\"\n"
+                + " synchronized=\"" + mi.isSynchronized() + "\"\n"
+                + " static=\"" + mi.isStatic() + "\"\n"
+                + " final=\"" + mi.isFinal() + "\"\n"
+                + " deprecated=\""+ deprecatedString + "\"\n"
+                + " visibility=\"" + scope + "\"\n"
+                //+ " source=\"" + mi.position() + "\"\n"
+                + ">");
+
+        // write parameters in declaration order
+        int numParameters = mi.parameters().length;
+        int count = 0;
+        for (ParameterInfo pi : mi.parameters()) {
+            count++;
+            writeParameterXML(xmlWriter, mi, pi, count == numParameters);
+        }
+
+        // but write exceptions in canonicalized order
+        ClassInfo[] exceptions = mi.thrownExceptions();
+        Arrays.sort(exceptions, ClassInfo.comparator);
+        for (ClassInfo pi : exceptions) {
+          xmlWriter.println("<exception name=\"" + pi.name() +"\" type=\"" + pi.qualifiedName()
+                            + "\">");
+          xmlWriter.println("</exception>");
+        }
+        xmlWriter.println("</method>");
+    }
+
+    static void writeConstructorXML(PrintStream xmlWriter, MethodInfo mi) {
+        String scope = DroidDoc.scope(mi);
+        String deprecatedString = "";
+        if (mi.isDeprecated()) {
+            deprecatedString = "deprecated";
+        } else {
+            deprecatedString = "not deprecated";
+        }
+        xmlWriter.println("<constructor name=\"" + mi.name() + "\"\n"
+                + " type=\"" + mi.containingClass().qualifiedName() + "\"\n"
+                + " static=\"" + mi.isStatic() + "\"\n"
+                + " final=\"" + mi.isFinal() + "\"\n"
+                + " deprecated=\"" + deprecatedString + "\"\n"
+                + " visibility=\"" + scope +"\"\n"
+                //+ " source=\"" + mi.position() + "\"\n"
+                + ">");
+
+        int numParameters = mi.parameters().length;
+        int count = 0;
+        for (ParameterInfo pi : mi.parameters()) {
+            count++;
+            writeParameterXML(xmlWriter, mi, pi, count == numParameters);
+        }
+
+        ClassInfo[] exceptions = mi.thrownExceptions();
+        Arrays.sort(exceptions, ClassInfo.comparator);
+        for (ClassInfo pi : exceptions) {
+            xmlWriter.println("<exception name=\"" + pi.name() +"\" type=\"" + pi.qualifiedName()
+                              + "\">");
+            xmlWriter.println("</exception>");
+        }
+        xmlWriter.println("</constructor>");
+  }
+
+    static void writeParameterXML(PrintStream xmlWriter, MethodInfo method,
+            ParameterInfo pi, boolean isLast) {
+        xmlWriter.println("<parameter name=\"" + pi.name() + "\" type=\"" +
+                makeXMLcompliant(fullParameterTypeName(method, pi.type(), isLast)) + "\">");
+        xmlWriter.println("</parameter>");
+    }
+
+    static void writeFieldXML(PrintStream xmlWriter, FieldInfo fi) {
+        String scope = DroidDoc.scope(fi);
+        String deprecatedString = "";
+        if (fi.isDeprecated()) {
+            deprecatedString = "deprecated";
+        } else {
+            deprecatedString = "not deprecated";
+        }
+        //need to make sure value is valid XML
+        String value  = makeXMLcompliant(fi.constantLiteralValue());
+
+        String fullTypeName = makeXMLcompliant(fi.type().qualifiedTypeName())
+                + fi.type().dimension();
+
+        xmlWriter.println("<field name=\"" + fi.name() +"\"\n"
+                          + " type=\"" + fullTypeName + "\"\n"
+                          + " transient=\"" + fi.isTransient() + "\"\n"
+                          + " volatile=\"" + fi.isVolatile() + "\"\n"
+                          + (fieldIsInitialized(fi) ? " value=\"" + value + "\"\n" : "")
+                          + " static=\"" + fi.isStatic() + "\"\n"
+                          + " final=\"" + fi.isFinal() + "\"\n"
+                          + " deprecated=\"" + deprecatedString + "\"\n"
+                          + " visibility=\"" + scope + "\"\n"
+                          //+ " source=\"" + fi.position() + "\"\n"
+                          + ">");
+        xmlWriter.println("</field>");
+    }
+
+    static String makeXMLcompliant(String s) {
+        String returnString = "";
+        returnString = s.replaceAll("&", "&amp;");
+        returnString = returnString.replaceAll("<", "&lt;");
+        returnString = returnString.replaceAll(">", "&gt;");
+        returnString = returnString.replaceAll("\"", "&quot;");
+        returnString = returnString.replaceAll("'", "&pos;");
+        return returnString;
+    }
+
+    static String fullParameterTypeName(MethodInfo method, TypeInfo type, boolean isLast) {
+        String fullTypeName = type.fullName(method.typeVariables());
+        if (isLast && method.isVarArgs()) {
+            // TODO: note that this does not attempt to handle hypothetical
+            // vararg methods whose last parameter is a list of arrays, e.g.
+            // "Object[]...".
+            fullTypeName = type.fullNameNoDimension(method.typeVariables()) + "...";
+        }
+        return fullTypeName;
+    }
+}
diff --git a/tools/droiddoc/src/TagInfo.java b/tools/droiddoc/src/TagInfo.java
new file mode 100644
index 0000000..d25c500
--- /dev/null
+++ b/tools/droiddoc/src/TagInfo.java
@@ -0,0 +1,100 @@
+/*
+ * 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 org.clearsilver.HDF;
+import org.clearsilver.CS;
+
+public class TagInfo
+{
+    private String mName;
+    private String mText;
+    private String mKind;
+    private SourcePositionInfo mPosition;
+
+    TagInfo(String n, String k, String t, SourcePositionInfo sp)
+    {
+        mName = n;
+        mText = t;
+        mKind = k;
+        mPosition = sp;
+    }
+
+    String name()
+    {
+        return mName;
+    }
+
+    String text()
+    {
+        return mText;
+    }
+
+    String kind()
+    {
+        return mKind;
+    }
+    
+    SourcePositionInfo position() {
+        return mPosition;
+    }
+
+    void setKind(String kind) {
+        mKind = kind;
+    }
+
+    public void makeHDF(HDF data, String base)
+    {
+        data.setValue(base + ".name", name());
+        data.setValue(base + ".text", text());
+        data.setValue(base + ".kind", kind());
+    }
+
+    public static void makeHDF(HDF data, String base, TagInfo[] tags)
+    {
+        makeHDF(data, base, tags, null, 0, 0);
+    }
+
+    public static void makeHDF(HDF data, String base, InheritedTags tags)
+    {
+        makeHDF(data, base, tags.tags(), tags.inherited(), 0, 0);
+    }
+
+    private static int makeHDF(HDF data, String base, TagInfo[] tags,
+                                InheritedTags inherited, int j, int depth)
+    {
+        int i;
+        int len = tags.length;
+        if (len == 0 && inherited != null) {
+            j = makeHDF(data, base, inherited.tags(), inherited.inherited(), j, depth+1);
+        } else {
+            for (i=0; i<len; i++, j++) {
+                TagInfo t = tags[i];
+                if (inherited != null && t.name().equals("@inheritDoc")) {
+                    j = makeHDF(data, base, inherited.tags(),
+                                    inherited.inherited(), j, depth+1);
+                } else {
+                    if (t.name().equals("@inheritDoc")) {
+                        Errors.error(Errors.BAD_INHERITDOC, t.mPosition,
+                                "@inheritDoc on class/method that is not inherited");
+                    }
+                    t.makeHDF(data, base + "." + j);
+                }
+            }
+        }
+        return j;
+    }
+}
+
diff --git a/tools/droiddoc/src/TextTagInfo.java b/tools/droiddoc/src/TextTagInfo.java
new file mode 100644
index 0000000..dcdfdd9
--- /dev/null
+++ b/tools/droiddoc/src/TextTagInfo.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+public class TextTagInfo extends TagInfo {
+    TextTagInfo(String n, String k, String t, SourcePositionInfo p) {
+        super(n, k, DroidDoc.escape(t), p);
+    }
+}
diff --git a/tools/droiddoc/src/ThrowsTagInfo.java b/tools/droiddoc/src/ThrowsTagInfo.java
new file mode 100644
index 0000000..318a57d
--- /dev/null
+++ b/tools/droiddoc/src/ThrowsTagInfo.java
@@ -0,0 +1,83 @@
+/*
+ * 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 org.clearsilver.HDF;
+import org.clearsilver.CS;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+public class ThrowsTagInfo extends ParsedTagInfo
+{
+    static final Pattern PATTERN = Pattern.compile(
+                                "(\\S+)\\s+(.*)",
+                                Pattern.DOTALL);
+    private ClassInfo mException;
+
+    public ThrowsTagInfo(String name, String kind, String text,
+            ContainerInfo base, SourcePositionInfo sp)
+    {
+        super(name, kind, text, base, sp);
+
+        Matcher m = PATTERN.matcher(text);
+        if (m.matches()) {
+            setCommentText(m.group(2));
+            String className = m.group(1);
+            if (base instanceof ClassInfo) {
+                mException = ((ClassInfo)base).findClass(className);
+            }
+            if (mException == null) {
+                mException = Converter.obtainClass(className);
+            }
+        }
+    }
+
+    public ThrowsTagInfo(String name, String kind, String text,
+                            ClassInfo exception, String exceptionComment,
+                            ContainerInfo base, SourcePositionInfo sp)
+    {
+        super(name, kind, text, base, sp);
+        mException = exception;
+        setCommentText(exceptionComment);
+    }
+
+    public ClassInfo exception()
+    {
+        return mException;
+    }
+
+    public TypeInfo exceptionType()
+    {
+        if (mException != null) {
+            return mException.asTypeInfo();
+        } else {
+            return null;
+        }
+    }
+
+    public static void makeHDF(HDF data, String base, ThrowsTagInfo[] tags)
+    {
+        for (int i=0; i<tags.length; i++) {
+            TagInfo.makeHDF(data, base + '.' + i + ".comment",
+                    tags[i].commentTags());
+            if (tags[i].exceptionType() != null) {
+                tags[i].exceptionType().makeHDF(data, base + "." + i + ".type");
+            }
+        }
+    }
+
+    
+}
+
diff --git a/tools/droiddoc/src/TodoFile.java b/tools/droiddoc/src/TodoFile.java
new file mode 100644
index 0000000..ebef27e
--- /dev/null
+++ b/tools/droiddoc/src/TodoFile.java
@@ -0,0 +1,195 @@
+/*
+ * 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 org.clearsilver.HDF;
+import org.clearsilver.CS;
+import java.util.*;
+import java.io.*;
+
+public class TodoFile {
+
+    public static final String MISSING = "No description text";
+
+    public static boolean areTagsUseful(InheritedTags tags) {
+        while (tags != null) {
+            if (areTagsUseful(tags.tags())) {
+                return true;
+            }
+            tags = tags.inherited();
+        }
+        return false;
+    }
+
+    public static boolean areTagsUseful(TagInfo[] tags) {
+        for (TagInfo t: tags) {
+            if ("Text".equals(t.name()) && t.text().trim().length() != 0) {
+                return true;
+            }
+            if ("@inheritDoc".equals(t.name())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public static void setHDF(HDF data, String base, SourcePositionInfo pos, String name,
+            String descr) {
+        data.setValue(base + ".pos", pos.toString());
+        data.setValue(base + ".name", name);
+        data.setValue(base + ".descr", descr);
+    }
+
+    static class PackageStats {
+        String name;
+        public int total;
+        public int errors;
+    }
+
+    public static String percent(int a, int b) {
+        return ""+Math.round((((b-a)/(float)b))*100) + "%";
+    }
+
+    public static void writeTodoFile(String filename) {
+        HDF data = DroidDoc.makeHDF();
+        DroidDoc.setPageTitle(data, "Missing Documentation");
+        TreeMap<String,PackageStats> packageStats = new TreeMap<String,PackageStats>();
+
+        ClassInfo[] classes = Converter.rootClasses();
+        Arrays.sort(classes);
+
+        int classIndex = 0;
+        
+        for (ClassInfo cl: classes) {
+            if (cl.isHidden()) {
+                continue;
+            }
+
+            String classBase = "classes." + classIndex;
+
+            String base = classBase + ".errors.";
+            int errors = 0;
+            int total = 1;
+
+            if (!areTagsUseful(cl.inlineTags())) {
+                setHDF(data, base + errors, cl.position(), "&lt;class comment&gt;", MISSING);
+                errors++;
+            }
+
+
+            for (MethodInfo m: cl.constructors()) {
+                boolean good = true;
+                total++;
+                if (m.checkLevel()) {
+                    if (!areTagsUseful(m.inlineTags())) {
+                        setHDF(data, base + errors, m.position(), m.name() + m.prettySignature(),
+                                MISSING);
+                        good = false;
+                    }
+                }
+                if (!good) {
+                    errors++;
+                }
+            }
+            
+            for (MethodInfo m: cl.selfMethods()) {
+                boolean good = true;
+                total++;
+                if (m.checkLevel()) {
+                    if (!areTagsUseful(m.inlineTags())) {
+                        setHDF(data, base + errors, m.position(), m.name() + m.prettySignature(),
+                                MISSING);
+                        good = false;
+                    }
+                }
+                if (!good) {
+                    errors++;
+                }
+            }
+            
+
+            for (FieldInfo f: cl.enumConstants()) {
+                boolean good = true;
+                total++;
+                if (f.checkLevel()) {
+                    if (!areTagsUseful(f.inlineTags())) {
+                        setHDF(data, base + errors, f.position(), f.name(), MISSING);
+                        good = false;
+                    }
+                }
+                if (!good) {
+                    errors++;
+                }
+            }
+            
+            for (FieldInfo f: cl.selfFields()) {
+                boolean good = true;
+                total++;
+                if (f.checkLevel()) {
+                    if (!areTagsUseful(f.inlineTags())) {
+                        setHDF(data, base + errors, f.position(), f.name(), MISSING);
+                        good = false;
+                    }
+                }
+                if (!good) {
+                    errors++;
+                }
+            }
+
+            if (errors > 0) {
+                data.setValue(classBase + ".qualified", cl.qualifiedName());
+                data.setValue(classBase + ".errorCount", ""+errors);
+                data.setValue(classBase + ".totalCount", ""+total);
+                data.setValue(classBase + ".percentGood", percent(errors, total));
+            }
+
+            PackageInfo pkg = cl.containingPackage();
+            String pkgName = pkg != null ? pkg.name() : "";
+            PackageStats ps = packageStats.get(pkgName);
+            if (ps == null) {
+                ps = new PackageStats();
+                ps.name = pkgName;
+                packageStats.put(pkgName, ps);
+            }
+            ps.total += total;
+            ps.errors += errors;
+
+            classIndex++;
+        }
+
+        int allTotal = 0;
+        int allErrors = 0;
+
+        int i = 0;
+        for (PackageStats ps: packageStats.values()) {
+            data.setValue("packages." + i + ".name", ""+ps.name);
+            data.setValue("packages." + i + ".errorCount", ""+ps.errors);
+            data.setValue("packages." + i + ".totalCount", ""+ps.total);
+            data.setValue("packages." + i + ".percentGood", percent(ps.errors, ps.total));
+
+            allTotal += ps.total;
+            allErrors += ps.errors;
+
+            i++;
+        }
+
+        data.setValue("all.errorCount", ""+allErrors);
+        data.setValue("all.totalCount", ""+allTotal);
+        data.setValue("all.percentGood", percent(allErrors, allTotal));
+
+        ClearPage.write(data, "todo.cs", filename, true);
+    }
+}
+
diff --git a/tools/droiddoc/src/TypeInfo.java b/tools/droiddoc/src/TypeInfo.java
new file mode 100644
index 0000000..c1119de
--- /dev/null
+++ b/tools/droiddoc/src/TypeInfo.java
@@ -0,0 +1,289 @@
+/*
+ * 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 org.clearsilver.HDF;
+import org.clearsilver.CS;
+import java.util.*;
+import java.io.*;
+
+public class TypeInfo
+{
+    public TypeInfo(boolean isPrimitive, String dimension,
+            String simpleTypeName, String qualifiedTypeName,
+            ClassInfo cl)
+    {
+        mIsPrimitive = isPrimitive;
+        mDimension = dimension;
+        mSimpleTypeName = simpleTypeName;
+        mQualifiedTypeName = qualifiedTypeName;
+        mClass = cl;
+    }
+
+    public ClassInfo asClassInfo()
+    {
+        return mClass;
+    }
+
+    public boolean isPrimitive()
+    {
+        return mIsPrimitive;
+    }
+
+    public String dimension()
+    {
+        return mDimension;
+    }
+
+    public String simpleTypeName()
+    {
+        return mSimpleTypeName;
+    }
+
+    public String qualifiedTypeName()
+    {
+        return mQualifiedTypeName;
+    }
+
+    public String fullName()
+    {
+        if (mFullName != null) {
+            return mFullName;
+        } else {
+            return fullName(new HashSet());
+        }
+    }
+
+    public static String typeArgumentsName(TypeInfo[] args, HashSet<String> typeVars)
+    {
+        String result = "<";
+        for (int i=0; i<args.length; i++) {
+            result += args[i].fullName(typeVars);
+            if (i != args.length-1) {
+                result += ", ";
+            }
+        }
+        result += ">";
+        return result;
+    }
+
+    public String fullName(HashSet<String> typeVars)
+    {
+        mFullName = fullNameNoDimension(typeVars) + mDimension;
+        return mFullName;
+    }
+
+    public String fullNameNoDimension(HashSet<String> typeVars)
+    {
+        String fullName = null;
+        if (mIsTypeVariable) {
+            if (typeVars.contains(mQualifiedTypeName)) {
+                // don't recurse forever with the parameters.  This handles
+                // Enum<K extends Enum<K>>
+                return mQualifiedTypeName;
+            }
+            typeVars.add(mQualifiedTypeName);
+        }
+/*
+        if (fullName != null) {
+            return fullName;
+        }
+*/
+        fullName = mQualifiedTypeName;
+        if (mTypeArguments != null && mTypeArguments.length > 0) {
+            fullName += typeArgumentsName(mTypeArguments, typeVars);
+        }
+        else if (mSuperBounds != null && mSuperBounds.length > 0) {
+            fullName += " super " + mSuperBounds[0].fullName(typeVars);
+            for (int i=1; i<mSuperBounds.length; i++) {
+                fullName += " & " + mSuperBounds[i].fullName(typeVars);
+            }
+        }
+        else if (mExtendsBounds != null && mExtendsBounds.length > 0) {
+            fullName += " extends " + mExtendsBounds[0].fullName(typeVars);
+            for (int i=1; i<mExtendsBounds.length; i++) {
+                fullName += " & " + mExtendsBounds[i].fullName(typeVars);
+            }
+        }
+        return fullName;
+    }
+
+    public TypeInfo[] typeArguments()
+    {
+        return mTypeArguments;
+    }
+
+    public void makeHDF(HDF data, String base)
+    {
+        makeHDFRecursive(data, base, false, false, new HashSet<String>());
+    }
+
+    public void makeQualifiedHDF(HDF data, String base)
+    {
+        makeHDFRecursive(data, base, true, false, new HashSet<String>());
+    }
+
+    public void makeHDF(HDF data, String base, boolean isLastVararg,
+            HashSet<String> typeVariables)
+    {
+        makeHDFRecursive(data, base, false, isLastVararg, typeVariables);
+    }
+
+    public void makeQualifiedHDF(HDF data, String base, HashSet<String> typeVariables)
+    {
+        makeHDFRecursive(data, base, true, false, typeVariables);
+    }
+
+    private void makeHDFRecursive(HDF data, String base, boolean qualified,
+            boolean isLastVararg, HashSet<String> typeVars)
+    {
+        String label = qualified ? qualifiedTypeName() : simpleTypeName();
+        label += (isLastVararg) ? "..." : dimension();
+        data.setValue(base + ".label", label);
+        ClassInfo cl = asClassInfo();
+        if (mIsTypeVariable || mIsWildcard) {
+            // could link to an @param tag on the class to describe this
+            // but for now, just don't make it a link
+        }
+        else if (!isPrimitive() && cl != null && cl.isIncluded()) {
+            data.setValue(base + ".link", cl.htmlPage());
+        }
+
+        if (mIsTypeVariable) {
+            if (typeVars.contains(qualifiedTypeName())) {
+                // don't recurse forever with the parameters.  This handles
+                // Enum<K extends Enum<K>>
+                return;
+            }
+            typeVars.add(qualifiedTypeName());
+        }
+        if (mTypeArguments != null) {
+            TypeInfo.makeHDF(data, base + ".typeArguments", mTypeArguments, qualified, typeVars);
+        }
+        if (mSuperBounds != null) {
+            TypeInfo.makeHDF(data, base + ".superBounds", mSuperBounds, qualified, typeVars);
+        }
+        if (mExtendsBounds != null) {
+            TypeInfo.makeHDF(data, base + ".extendsBounds", mExtendsBounds, qualified, typeVars);
+        }
+    }
+
+    public static void makeHDF(HDF data, String base, TypeInfo[] types, boolean qualified,
+            HashSet<String> typeVariables)
+    {
+        final int N = types.length;
+        for (int i=0; i<N; i++) {
+            types[i].makeHDFRecursive(data, base + "." + i, qualified, false, typeVariables);
+        }
+    }
+
+    public static void makeHDF(HDF data, String base, TypeInfo[] types, boolean qualified)
+    {
+        makeHDF(data, base, types, qualified, new HashSet<String>());
+    }
+
+    void setTypeArguments(TypeInfo[] args)
+    {
+        mTypeArguments = args;
+    }
+
+    void setBounds(TypeInfo[] superBounds, TypeInfo[] extendsBounds)
+    {
+        mSuperBounds = superBounds;
+        mExtendsBounds = extendsBounds;
+    }
+
+    void setIsTypeVariable(boolean b)
+    {
+        mIsTypeVariable = b;
+    }
+
+    void setIsWildcard(boolean b)
+    {
+        mIsWildcard = b;
+    }
+
+    static HashSet<String> typeVariables(TypeInfo[] params)
+    {
+        return typeVariables(params, new HashSet());
+    }
+
+    static HashSet<String> typeVariables(TypeInfo[] params, HashSet<String> result)
+    {
+        for (TypeInfo t: params) {
+            if (t.mIsTypeVariable) {
+                result.add(t.mQualifiedTypeName);
+            }
+        }
+        return result;
+    }
+
+
+    public boolean isTypeVariable()
+    {
+        return mIsTypeVariable;
+    }
+
+    public String defaultValue() {
+        if (mIsPrimitive) {
+            if ("boolean".equals(mSimpleTypeName)) {
+                return "false";
+            } else {
+                return "0";
+            }
+        } else {
+            return "null";
+        }
+    }
+
+    public String toString(){
+      String returnString = "";
+      returnString += "Primitive?: " + mIsPrimitive + " TypeVariable?: " +
+      mIsTypeVariable + " Wildcard?: " + mIsWildcard + " Dimension: " + mDimension
+      + " QualifedTypeName: " + mQualifiedTypeName;
+
+      if (mTypeArguments != null){
+        returnString += "\nTypeArguments: ";
+        for (TypeInfo tA : mTypeArguments){
+          returnString += tA.qualifiedTypeName() + "(" + tA + ") ";
+        }
+      }
+      if (mSuperBounds != null){
+        returnString += "\nSuperBounds: ";
+        for (TypeInfo tA : mSuperBounds){
+          returnString += tA.qualifiedTypeName() + "(" + tA + ") ";
+        }
+      }
+      if (mExtendsBounds != null){
+        returnString += "\nExtendsBounds: ";
+        for (TypeInfo tA : mExtendsBounds){
+          returnString += tA.qualifiedTypeName() + "(" + tA + ") ";
+        }
+      }
+      return returnString;
+    }
+
+    private boolean mIsPrimitive;
+    private boolean mIsTypeVariable;
+    private boolean mIsWildcard;
+    private String mDimension;
+    private String mSimpleTypeName;
+    private String mQualifiedTypeName;
+    private ClassInfo mClass;
+    private TypeInfo[] mTypeArguments;
+    private TypeInfo[] mSuperBounds;
+    private TypeInfo[] mExtendsBounds;
+    private String mFullName;
+}
