diff --git a/tools/droiddoc/src/Android.mk b/tools/droiddoc/src/Android.mk
new file mode 100644
index 0000000..c0c583d
--- /dev/null
+++ b/tools/droiddoc/src/Android.mk
@@ -0,0 +1,68 @@
+# 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 \
+	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..38ac55c
--- /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..b0412c9
--- /dev/null
+++ b/tools/droiddoc/src/DroidDoc.java
@@ -0,0 +1,1326 @@
+/*
+ * 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();
+        }
+
+        // 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 = 1;
+            ClassInfo[] classesToCheck = pkg.ordinaryClasses();
+            while (pass < 5 ) {
+                switch(pass) {
+                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.out.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;
+                    System.out.println("Writing CS:  " + filename);
+                    ClearPage.write(data, templ, filename);
+                }
+                else if (len > 3 && ".jd".equals(templ.substring(len-3))) {
+                    String filename = templ.substring(0,len-3) + htmlExtension;
+                    System.out.println("Writing JD:  " + filename);
+                    DocFile.writePage(f.getAbsolutePath(), relative, filename);
+                }
+                else {
+//                    System.out.println("relative=" + relative
+//                            + " f.getAbsolutePath()=" + f.getAbsolutePath()
+//                            + " templ=" + templ);
+                    System.out.println("Copying:     " + templ);
+                    ClearPage.copyFile(f, templ);
+                }
+            }
+            else if (f.isDirectory()) {
+                System.out.println("Writing dir: " + relative + f.getName() + "/");
+                writeDirectory(f, relative + f.getName() + "/");
+            }
+        }
+    }
+
+    public static void writeHTMLPages()
+    {
+        File f = new File(ClearPage.htmlDir);
+        if (!f.isDirectory()) {
+            System.out.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.out.println("error writing file: " + filename);
+        }
+        finally {
+            if (stream != null) {
+                stream.close();
+            }
+        }
+    }
+
+    public static void writePackages(String filename)
+    {
+        System.out.println("Writing packages...");
+        HDF data = makePackageHDF();
+
+        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 = 1;
+            ClassInfo[] classesToCheck = pkg.ordinaryClasses();
+            while (pass < 5 ) {
+                switch(pass) {
+                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.out.println("Error reading package: " + pkg.name());
+                    break;
+                }
+                for (ClassInfo cl : classesToCheck) {
+                    if (!cl.isHidden()) {
+                        allHidden = false;
+                        break;
+                    }
+                }
+                if (!allHidden) {
+                    break;
+                }
+                pass++;
+            }
+            if (allHidden) {
+                continue;
+            }
+
+            writePackage(pkg);
+
+            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();
+        System.out.println("Writing " + 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 = filename.substring(0, filename.lastIndexOf('/')+1)
+            + "package-descr" + htmlExtension;
+        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() + ")";
+                        }
+                    }
+                } else {
+                    //System.out.println("not duplicate: " + sorted[i].label);
+                }
+                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 = makePackageHDF();
+
+        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);
+
+        System.out.println("Writing " + cl.name());
+        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..1431314
--- /dev/null
+++ b/tools/droiddoc/src/Errors.java
@@ -0,0 +1,133 @@
+/*
+ * 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;
+        String msg;
+
+        Message(SourcePositionInfo p, String m) {
+            pos = p;
+            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;
+        }
+
+        String which = (!warningsAreErrors && error.level == WARNING) ? " warning " : " error ";
+        String message = which + error.code + ": " + text;
+
+        if (where == null) {
+            where = new SourcePositionInfo("unknown", 0, 0);
+        }
+
+        allErrors.add(new Message(where, message));
+
+        if (error.level == ERROR || (warningsAreErrors && error.level == WARNING)) {
+            hadError = true;
+        }
+    }
+
+    public static void printErrors() {
+        for (Message m: allErrors) {
+            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..fa821cf
--- /dev/null
+++ b/tools/droiddoc/src/LinkReference.java
@@ -0,0 +1,439 @@
+/*
+ * 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());
+            }
+            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..ed98378
--- /dev/null
+++ b/tools/droiddoc/src/MethodInfo.java
@@ -0,0 +1,642 @@
+/*
+ * 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)
+    {
+        super(rawCommentText, name, signature, containingClass, realContainingClass,
+                isPublic, isProtected, isPackagePrivate, isPrivate,
+                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/PackageInfo.java b/tools/droiddoc/src/PackageInfo.java
new file mode 100644
index 0000000..c696112
--- /dev/null
+++ b/tools/droiddoc/src/PackageInfo.java
@@ -0,0 +1,162 @@
+/*
+ * 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 htmlLinksPage()
+    {
+        String s = mName;
+        s = s.replace('.', '/');
+        s += "/package-links.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", ClassInfo.sortByName(interfaces()));
+        ClassInfo.makeLinkListHDF(data, base + ".classes", ClassInfo.sortByName(ordinaryClasses()));
+        ClassInfo.makeLinkListHDF(data, base + ".enums", ClassInfo.sortByName(enums()));
+        ClassInfo.makeLinkListHDF(data, base + ".exceptions", ClassInfo.sortByName(exceptions()));
+        ClassInfo.makeLinkListHDF(data, base + ".errors", ClassInfo.sortByName(errors()));
+    }
+
+    public ClassInfo[] interfaces()
+    {
+        return filterHidden(Converter.convertClasses(mPackage.interfaces()));
+    }
+
+    public ClassInfo[] ordinaryClasses()
+    {
+        return filterHidden(Converter.convertClasses(mPackage.ordinaryClasses()));
+    }
+
+    public ClassInfo[] enums()
+    {
+        return filterHidden(Converter.convertClasses(mPackage.enums()));
+    }
+
+    public ClassInfo[] exceptions()
+    {
+        return filterHidden(Converter.convertClasses(mPackage.exceptions()));
+    }
+
+    public ClassInfo[] errors()
+    {
+        return filterHidden(Converter.convertClasses(mPackage.errors()));
+    }
+
+    // in hashed containers, treat the name as the key
+    @Override
+    public int hashCode() {
+        return mName.hashCode();
+    }
+
+    private String mName;
+    private PackageDoc mPackage;
+}
+
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..a233d68
--- /dev/null
+++ b/tools/droiddoc/src/Stubs.java
@@ -0,0 +1,958 @@
+/*
+ * 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,
+                                        p.position(), "Reference to unavailable class "
+                                        + t.fullName());
+                            }
+                        }
+                    }
+                }
+                
+                // 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){
+                                      cantStripThis(tInfoType.asClassInfo(), 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()) {
+            String fullTypeName = param.type().fullName(method.typeVariables());
+            if (count == size && 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 = param.type().qualifiedTypeName() + "...";
+            }
+            stream.print(comma + fullTypeName + " " + 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=\"" + mi.returnType().qualifiedTypeName() + "\"\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
+        for (ParameterInfo pi : mi.parameters()) {
+            writeParameterXML(xmlWriter, pi);
+        }
+        
+        // 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"
+                + ">");
+
+        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, ParameterInfo pi) {
+        xmlWriter.println("<parameter name=\"" + pi.name() + "\" type=\"" +
+                          pi.type().qualifiedTypeName() + "\">");
+        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());
+        xmlWriter.println("<field name=\"" + fi.name() +"\"\n"
+                          + " type=\"" + fi.type().qualifiedTypeName() + "\"\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;
+    }
+}
+
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..68cdd8e
--- /dev/null
+++ b/tools/droiddoc/src/TypeInfo.java
@@ -0,0 +1,283 @@
+/*
+ * 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)
+    {
+        if (mIsTypeVariable) {
+            if (typeVars.contains(mQualifiedTypeName)) {
+                // don't recurse forever with the parameters.  This handles
+                // Enum<K extends Enum<K>>
+                return mQualifiedTypeName + mDimension;
+            }
+            typeVars.add(mQualifiedTypeName);
+        }
+/*
+        if (mFullName != null) {
+            return mFullName;
+        }
+*/
+        mFullName = mQualifiedTypeName;
+        if (mTypeArguments != null && mTypeArguments.length > 0) {
+            mFullName += typeArgumentsName(mTypeArguments, typeVars);
+        }
+        else if (mSuperBounds != null && mSuperBounds.length > 0) {
+            mFullName += " super " + mSuperBounds[0].fullName(typeVars);
+            for (int i=1; i<mSuperBounds.length; i++) {
+                mFullName += " & " + mSuperBounds[i].fullName(typeVars);
+            }
+        }
+        else if (mExtendsBounds != null && mExtendsBounds.length > 0) {
+            mFullName += " extends " + mExtendsBounds[0].fullName(typeVars);
+            for (int i=1; i<mExtendsBounds.length; i++) {
+                mFullName += " & " + mExtendsBounds[i].fullName(typeVars);
+            }
+        }
+        mFullName += mDimension;
+        return mFullName;
+    }
+
+    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;
+}
