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