diff --git a/core/main.mk b/core/main.mk
index da66c36..ded9d44 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -383,17 +383,18 @@
 	dalvik/libdex \
 	dalvik/tools/dmtracedump \
 	dalvik/tools/hprof-conv \
-	development/tools/line_endings \
-	development/tools/etc1tool \
-	sdk/emulator/mksdcard \
-	sdk/sdklauncher \
 	development/host \
+	development/tools/etc1tool \
+	development/tools/line_endings \
+	external/easymock \
 	external/expat \
 	external/libpng \
 	external/qemu \
 	external/sqlite/dist \
 	external/zlib \
 	frameworks/base \
+	sdk/emulator/mksdcard \
+	sdk/sdklauncher \
 	system/core/adb \
 	system/core/fastboot \
 	system/core/libcutils \
diff --git a/core/pathmap.mk b/core/pathmap.mk
index eae48af..428594f 100644
--- a/core/pathmap.mk
+++ b/core/pathmap.mk
@@ -82,6 +82,7 @@
 	    graphics \
 	    location \
 	    media \
+	    drm \
 	    opengl \
 	    sax \
 	    telephony \
diff --git a/core/prelink-linux-arm.map b/core/prelink-linux-arm.map
index b178242..df470a1 100644
--- a/core/prelink-linux-arm.map
+++ b/core/prelink-linux-arm.map
@@ -23,23 +23,25 @@
 #
 
 # core system libraries
-libdl.so                0xAFF00000 # [<64K]
-libc.so                 0xAFD00000 # [~2M]
-libstdc++.so            0xAFC00000 # [<64K]
-libm.so                 0xAFB00000 # [~1M]
-liblog.so               0xAFA00000 # [<64K]
-libcutils.so            0xAF900000 # [~1M]
-libthread_db.so         0xAF800000 # [<64K]
-libz.so                 0xAF700000 # [~1M]
-libevent.so             0xAF600000 # [???]
-libssl.so               0xAF400000 # [~2M]
-libcrypto.so            0xAF000000 # [~4M]
-libsysutils.so          0xAEF00000 # [~1M]
+libdl.so                0xB0100000 # [<64K]
+libc.so                 0xAFF00000 # [~2M]
+libstdc++.so            0xAFE00000 # [<64K]
+libm.so                 0xAFD00000 # [~1M]
+liblog.so               0xAFC00000 # [<64K]
+libcutils.so            0xAFB00000 # [~1M]
+libthread_db.so         0xAFA00000 # [<64K]
+libz.so                 0xAF900000 # [~1M]
+libevent.so             0xAF800000 # [???]
+libssl.so               0xAF600000 # [~2M]
+libcrypto.so            0xAF200000 # [~4M]
+libsysutils.so          0xAF100000 # [~1M]
 
 # bluetooth
-liba2dp.so              0xAEE00000 # [~1M]
-audio.so                0xAED00000 # [~1M]
-input.so                0xAEC00000 # [~1M]
+liba2dp.so              0xAF000000 # [~1M]
+input.so                0xAEF00000 # [~1M]
+audio.so                0xAEE00000 # [~1M]
+libglib.so              0xAED00000 # [~1M]
+network.so              0xAEC00000 # [~1M]
 libbluetoothd.so        0xAEA00000 # [~2M]
 libbluedroid.so         0xAE900000 # [<64K]
 libbluetooth.so         0xAE800000 # [~1M]
diff --git a/core/proguard.flags b/core/proguard.flags
index 06e32cc..447e7c5 100644
--- a/core/proguard.flags
+++ b/core/proguard.flags
@@ -44,6 +44,19 @@
 @com.google.common.annotations.VisibleForTesting *;
 }
 
+# Keep serializable classes and necessary members for serializable classes
+# Copied from the ProGuard manual at http://proguard.sourceforge.net.
+-keepnames class * implements java.io.Serializable
+-keepclassmembers class * implements java.io.Serializable {
+    static final long serialVersionUID;
+    private static final java.io.ObjectStreamField[] serialPersistentFields;
+    !static !transient <fields>;
+    private void writeObject(java.io.ObjectOutputStream);
+    private void readObject(java.io.ObjectInputStream);
+    java.lang.Object writeReplace();
+    java.lang.Object readResolve();
+}
+
 # Please specify classes to be kept explicitly in your package's configuration.
 # -keep class * extends android.app.Activity
 # -keep class * extends android.view.View
diff --git a/core/tasks/apicheck.mk b/core/tasks/apicheck.mk
index 740668c..99a3227 100644
--- a/core/tasks/apicheck.mk
+++ b/core/tasks/apicheck.mk
@@ -19,6 +19,10 @@
 
 ifneq ($(BUILD_TINY_ANDROID), true)
 
+APICHECK_CLASSPATH := $(HOST_JDK_TOOLS_JAR)
+APICHECK_CLASSPATH := $(APICHECK_CLASSPATH):$(HOST_OUT_JAVA_LIBRARIES)/doclava$(COMMON_JAVA_PACKAGE_SUFFIX)
+APICHECK_CLASSPATH := $(APICHECK_CLASSPATH):$(HOST_OUT_JAVA_LIBRARIES)/jsilver$(COMMON_JAVA_PACKAGE_SUFFIX)
+
 .PHONY: checkapi
 
 # eval this to define a rule that runs apicheck.
@@ -32,7 +36,7 @@
 define check-api
 $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/$(strip $(1))-timestamp: $(2) $(3) $(APICHECK)
 	@echo "Checking API:" $(1)
-	$(hide) ( $(APICHECK) $(4) $(2) $(3) || ( $(5) ; exit 38 ) )
+	$(hide) ( $(APICHECK) -JXmx1024m -J"classpath $(APICHECK_CLASSPATH)" $(4) $(2) $(3) || ( $(5) ; exit 38 ) )
 	$(hide) mkdir -p $$(dir $$@)
 	$(hide) touch $$@
 checkapi: $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/$(strip $(1))-timestamp
diff --git a/target/product/full.mk b/target/product/full.mk
index 8725804..77619a6 100644
--- a/target/product/full.mk
+++ b/target/product/full.mk
@@ -39,13 +39,11 @@
     development/data/etc/apns-conf.xml:system/etc/apns-conf.xml \
     development/data/etc/vold.conf:system/etc/vold.conf
 
-# Pick up some sounds - stick with the short list to save space
-# on smaller devices.
-$(call inherit-product, frameworks/base/data/sounds/OriginalAudio.mk)
+# Pick up some sounds.
+$(call inherit-product, frameworks/base/data/sounds/AudioPackage4.mk)
 
-# Get a list of languages. We use the small list to save space
-# on smaller devices.
-$(call inherit-product, build/target/product/languages_small.mk)
+# Get a list of languages.
+$(call inherit-product, build/target/product/locales_full.mk)
 
 $(call inherit-product, build/target/product/generic.mk)
 
diff --git a/tools/apicheck/Android.mk b/tools/apicheck/Android.mk
index a2ff8a2..24f697c 100644
--- a/tools/apicheck/Android.mk
+++ b/tools/apicheck/Android.mk
@@ -29,16 +29,10 @@
 
 include $(BUILD_SYSTEM)/base_rules.mk
 
-$(LOCAL_BUILT_MODULE): $(HOST_OUT_JAVA_LIBRARIES)/apicheck$(COMMON_JAVA_PACKAGE_SUFFIX)
+$(LOCAL_BUILT_MODULE): $(HOST_OUT_JAVA_LIBRARIES)/doclava$(COMMON_JAVA_PACKAGE_SUFFIX)
 $(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/etc/apicheck | $(ACP)
 	@echo "Copy: $(PRIVATE_MODULE) ($@)"
 	$(copy-file-to-new-target)
 	$(hide) chmod 755 $@
 
-# the other stuff
-# ============================================================
-subdirs := $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk, \
-		src \
-	))
-
-include $(subdirs)
+# Apicheck is now part of Doclava -- See external/doclava.
diff --git a/tools/apicheck/etc/apicheck b/tools/apicheck/etc/apicheck
index 5d0480c..c710c46 100644
--- a/tools/apicheck/etc/apicheck
+++ b/tools/apicheck/etc/apicheck
@@ -16,6 +16,10 @@
 
 # Set up prog to be the path of this script, including following symlinks,
 # and set up progdir to be the fully-qualified pathname of its directory.
+#
+# The classpath and other java options used in apicheck are specified in
+# build/core/tasks/apicheck.mk.
+
 prog="$0"
 while [ -h "${prog}" ]; do
     newProg=`/bin/ls -ld "${prog}"`
@@ -34,8 +38,6 @@
 prog="${progdir}"/`basename "${prog}"`
 cd "${oldwd}"
 
-libdir=`dirname $progdir`/framework
-
 javaOpts=""
 while expr "x$1" : 'x-J' >/dev/null; do
     opt=`expr "x$1" : 'x-J\(.*\)'`
@@ -43,4 +45,4 @@
     shift
 done
 
-exec java $javaOpts -jar $libdir/apicheck.jar "$@"
+exec java $javaOpts com.google.doclava.apicheck.ApiCheck "$@"
diff --git a/tools/apicheck/src/Android.mk b/tools/apicheck/src/Android.mk
deleted file mode 100644
index c4e7c6e..0000000
--- a/tools/apicheck/src/Android.mk
+++ /dev/null
@@ -1,28 +0,0 @@
-# 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)
-
-
-# apicheck java library
-# ============================================================
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_JAR_MANIFEST := MANIFEST.mf
-
-LOCAL_MODULE:= apicheck
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
diff --git a/tools/apicheck/src/MANIFEST.mf b/tools/apicheck/src/MANIFEST.mf
deleted file mode 100644
index e6dc263..0000000
--- a/tools/apicheck/src/MANIFEST.mf
+++ /dev/null
@@ -1,2 +0,0 @@
-Manifest-Version: 1.0
-Main-Class: com.android.apicheck.ApiCheck
diff --git a/tools/apicheck/src/com/android/apicheck/AbstractMethodInfo.java b/tools/apicheck/src/com/android/apicheck/AbstractMethodInfo.java
deleted file mode 100644
index ca90820..0000000
--- a/tools/apicheck/src/com/android/apicheck/AbstractMethodInfo.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.apicheck;
-
-public interface AbstractMethodInfo {
-  
-    public void addException(String exec);
-    public void addParameter(ParameterInfo p);
-
-}
diff --git a/tools/apicheck/src/com/android/apicheck/ApiCheck.java b/tools/apicheck/src/com/android/apicheck/ApiCheck.java
deleted file mode 100644
index b2f2265..0000000
--- a/tools/apicheck/src/com/android/apicheck/ApiCheck.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.apicheck;
-
-import org.xml.sax.*;
-import org.xml.sax.helpers.*;
-import java.io.*;
-import java.util.ArrayList;
-import java.util.Stack;
-
-public class ApiCheck {
-        // parse out and consume the -whatever command line flags
-        private static ArrayList<String[]> parseFlags(ArrayList<String> allArgs) {
-            ArrayList<String[]> ret = new ArrayList<String[]>();
-
-            int i;
-            for (i = 0; i < allArgs.size(); i++) {
-                // flags with one value attached
-                String flag = allArgs.get(i);
-                if (flag.equals("-error")
-                        || flag.equals("-warning")
-                        || flag.equals("-hide")) {
-                    String[] arg = new String[2];
-                    arg[0] = flag;
-                    arg[1] = allArgs.get(++i);
-                    ret.add(arg);
-                } else {
-                    // we've consumed all of the -whatever args, so we're done
-                    break;
-                }
-            }
-
-            // i now points to the first non-flag arg; strip what came before
-            for (; i > 0; i--) {
-                allArgs.remove(0);
-            }
-            return ret;
-        }
-
-        public static void main(String[] originalArgs) {
-            // translate to an ArrayList<String> for munging
-            ArrayList<String> args = new ArrayList<String>(originalArgs.length);
-            for (String a: originalArgs) {
-                args.add(a);
-            }
-
-            ArrayList<String[]> flags = ApiCheck.parseFlags(args);
-            for (String[] a: flags) {
-                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) {
-                        System.err.println("Bad argument: " + a[0] + " " + a[1]);
-                        System.exit(2);
-                    }
-                }
-            }
-
-            ApiCheck acheck = new ApiCheck();
-
-            ApiInfo oldApi = acheck.parseApi(args.get(0));
-            ApiInfo newApi = acheck.parseApi(args.get(1));
-
-            // only run the consistency check if we haven't had XML parse errors
-            if (!Errors.hadError) {
-                oldApi.isConsistent(newApi);
-            }
-
-            Errors.printErrors();
-            System.exit(Errors.hadError ? 1 : 0);
-        }
-
-    public ApiInfo parseApi(String xmlFile) {
-        FileReader fileReader = null;
-        try {
-            XMLReader xmlreader = XMLReaderFactory.createXMLReader();
-            MakeHandler handler = new MakeHandler();
-            xmlreader.setContentHandler(handler);
-            xmlreader.setErrorHandler(handler);
-            fileReader = new FileReader(xmlFile);
-            xmlreader.parse(new InputSource(fileReader));
-            ApiInfo apiInfo = handler.getApi();
-            apiInfo.resolveSuperclasses();
-            apiInfo.resolveInterfaces();
-            return apiInfo;
-        } catch (SAXParseException e) {
-            Errors.error(Errors.PARSE_ERROR,
-                    new SourcePositionInfo(xmlFile, e.getLineNumber(), 0),
-                    e.getMessage());
-        } catch (Exception e) {
-            e.printStackTrace();
-            Errors.error(Errors.PARSE_ERROR,
-                    new SourcePositionInfo(xmlFile, 0, 0), e.getMessage());
-        } finally {
-            if (fileReader != null) {
-                try {
-                    fileReader.close();
-                } catch (IOException ignored) {}
-            }
-        }
-        return null;
-    }
-
-    private static class MakeHandler extends DefaultHandler {
-
-            private ApiInfo mApi;
-            private PackageInfo mCurrentPackage;
-            private ClassInfo mCurrentClass;
-            private AbstractMethodInfo mCurrentMethod;
-            private Stack<ClassInfo> mClassScope = new Stack<ClassInfo>();
-
-
-            public MakeHandler() {
-                super();
-                mApi = new ApiInfo();
-            }
-
-            @Override
-            public void startElement(String uri, String localName, String qName,
-                                     Attributes attributes) {
-                if (qName.equals("package")) {
-                    mCurrentPackage = new PackageInfo(attributes.getValue("name"),
-                            SourcePositionInfo.fromXml(attributes.getValue("source")));
-                } else if (qName.equals("class")
-                        || qName.equals("interface")) {
-                    // push the old outer scope for later recovery, then set
-                    // up the new current class object
-                    mClassScope.push(mCurrentClass);
-                    mCurrentClass = new ClassInfo(attributes.getValue("name"),
-                                                  mCurrentPackage,
-                                                  attributes.getValue("extends") ,
-                                                  qName.equals("interface"),
-                                                  Boolean.valueOf(
-                                                      attributes.getValue("abstract")),
-                                                  Boolean.valueOf(
-                                                      attributes.getValue("static")),
-                                                  Boolean.valueOf(
-                                                      attributes.getValue("final")),
-                                                  attributes.getValue("deprecated"),
-                                                  attributes.getValue("visibility"),
-                                                  SourcePositionInfo.fromXml(attributes.getValue("source")),
-                                                  mCurrentClass);
-                } else if (qName.equals("method")) {
-                    mCurrentMethod = new MethodInfo(attributes.getValue("name"),
-                                                    attributes.getValue("return") ,
-                                                    Boolean.valueOf(
-                                                        attributes.getValue("abstract")),
-                                                    Boolean.valueOf(
-                                                        attributes.getValue("native")),
-                                                    Boolean.valueOf(
-                                                        attributes.getValue("synchronized")),
-                                                    Boolean.valueOf(
-                                                        attributes.getValue("static")),
-                                                    Boolean.valueOf(
-                                                        attributes.getValue("final")),
-                                                    attributes.getValue("deprecated"),
-                                                    attributes.getValue("visibility"),
-                                                    SourcePositionInfo.fromXml(attributes.getValue("source")),
-                                                    mCurrentClass);
-                } else if (qName.equals("constructor")) {
-                    mCurrentMethod = new ConstructorInfo(attributes.getValue("name"),
-                                                         attributes.getValue("type") ,
-                                                         Boolean.valueOf(
-                                                             attributes.getValue("static")),
-                                                         Boolean.valueOf(
-                                                             attributes.getValue("final")),
-                                                         attributes.getValue("deprecated"),
-                                                         attributes.getValue("visibility"),
-                                                         SourcePositionInfo.fromXml(attributes.getValue("source")),
-                                                         mCurrentClass);
-                } else if (qName.equals("field")) {
-                    FieldInfo fInfo = new FieldInfo(attributes.getValue("name"),
-                                                    attributes.getValue("type") ,
-                                                    Boolean.valueOf(
-                                                        attributes.getValue("transient")),
-                                                    Boolean.valueOf(
-                                                        attributes.getValue("volatile")),
-                                                    attributes.getValue("value"),
-                                                    Boolean.valueOf(
-                                                        attributes.getValue("static")),
-                                                    Boolean.valueOf(
-                                                        attributes.getValue("final")),
-                                                    attributes.getValue("deprecated"),
-                                                    attributes.getValue("visibility"),
-                                                    SourcePositionInfo.fromXml(attributes.getValue("source")),
-                                                    mCurrentClass);
-                    mCurrentClass.addField(fInfo);
-                } else if (qName.equals("parameter")) {
-                    mCurrentMethod.addParameter(new ParameterInfo(attributes.getValue("type"),
-                                                                  attributes.getValue("name")));
-                } else if (qName.equals("exception")) {
-                    mCurrentMethod.addException(attributes.getValue("type"));
-                } else if (qName.equals("implements")) {
-                    mCurrentClass.addInterface(attributes.getValue("name"));
-                }
-            }
-
-            @Override
-            public void endElement(String uri, String localName, String qName) {
-                if (qName.equals("method")) {
-                    mCurrentClass.addMethod((MethodInfo) mCurrentMethod);
-                } else if (qName.equals("constructor")) {
-                    mCurrentClass.addConstructor((ConstructorInfo) mCurrentMethod);
-                } else if (qName.equals("class")
-                        || qName.equals("interface")) {
-                    mCurrentPackage.addClass(mCurrentClass);
-                    mCurrentClass = mClassScope.pop();
-                } else if (qName.equals("package")){
-                    mApi.addPackage(mCurrentPackage);
-                }
-            }
-            public ApiInfo getApi() {
-                return mApi;
-            }
-        }
-}
diff --git a/tools/apicheck/src/com/android/apicheck/ApiInfo.java b/tools/apicheck/src/com/android/apicheck/ApiInfo.java
deleted file mode 100644
index 47b9a15..0000000
--- a/tools/apicheck/src/com/android/apicheck/ApiInfo.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.apicheck;
-import java.util.*;
-
-public class ApiInfo {
-  
-    private HashMap<String, PackageInfo> mPackages;
-    private HashMap<String, ClassInfo> mAllClasses;
-    
-    public ApiInfo() {
-        mPackages = new HashMap<String, PackageInfo>();
-        mAllClasses = new HashMap<String, ClassInfo>();
-    }
-
-    public ClassInfo findClass(String name) {
-        return mAllClasses.get(name);
-    }
-
-    public void resolveInterfaces() {
-        for (ClassInfo c : mAllClasses.values()) {
-            c.resolveInterfaces(this);
-        }
-    }
-    
-    public boolean isConsistent(ApiInfo otherApi) {
-        boolean consistent = true;
-        for (PackageInfo pInfo : mPackages.values()) {
-            if (otherApi.getPackages().containsKey(pInfo.name())) {
-                if (!pInfo.isConsistent(otherApi.getPackages().get(pInfo.name()))) {
-                    consistent = false;
-                }
-            } else {
-                Errors.error(Errors.REMOVED_PACKAGE, pInfo.position(),
-                        "Removed package " + pInfo.name());
-                consistent = false;
-            }
-        }
-        for (PackageInfo pInfo : otherApi.mPackages.values()) {
-            if (!pInfo.isInBoth()) {
-                Errors.error(Errors.ADDED_PACKAGE, pInfo.position(),
-                        "Added package " + pInfo.name());
-                consistent = false;
-            }
-        }
-        return consistent;
-    }
-    
-    public HashMap<String, PackageInfo> getPackages() {
-        return mPackages;
-    }
-    
-    public void addPackage(PackageInfo pInfo) {
-        // track the set of organized packages in the API
-        mPackages.put(pInfo.name(), pInfo);
-        
-        // accumulate a direct map of all the classes in the API
-        for (ClassInfo cl: pInfo.allClasses().values()) {
-            mAllClasses.put(cl.qualifiedName(), cl);
-        }
-    }
-
-    public void resolveSuperclasses() {
-        for (ClassInfo cl: mAllClasses.values()) {
-            // java.lang.Object has no superclass
-            if (!cl.qualifiedName().equals("java.lang.Object")) {
-                String scName = cl.superclassName();
-                if (scName == null) {
-                    scName = "java.lang.Object";
-                }
-
-                ClassInfo superclass = mAllClasses.get(scName);
-                cl.setSuperClass(superclass);
-            }
-        }
-    }
-}
diff --git a/tools/apicheck/src/com/android/apicheck/ClassInfo.java b/tools/apicheck/src/com/android/apicheck/ClassInfo.java
deleted file mode 100644
index 962a316..0000000
--- a/tools/apicheck/src/com/android/apicheck/ClassInfo.java
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.apicheck;
-import java.util.*;
-
-public class ClassInfo {
-    private String mName;
-    private String mSuperClassName;
-    private boolean mIsInterface;
-    private boolean mIsAbstract;
-    private boolean mIsStatic;
-    private boolean mIsFinal;
-    private String mDeprecated;
-    private String mScope;
-    private List<String> mInterfaceNames;
-    private List<ClassInfo> mInterfaces;
-    private HashMap<String, MethodInfo> mMethods;
-    private HashMap<String, FieldInfo> mFields;
-    private HashMap<String, ConstructorInfo> mConstructors;
-    private boolean mExistsInBoth;
-    private PackageInfo mPackage;
-    private SourcePositionInfo mSourcePosition;
-    private ClassInfo mSuperClass;
-    private ClassInfo mParentClass;
-
-    public ClassInfo(String name, PackageInfo pack, String superClass, boolean isInterface,
-                     boolean isAbstract, boolean isStatic, boolean isFinal, String deprecated,
-                     String visibility, SourcePositionInfo source, ClassInfo parent) {
-        mName = name;
-        mPackage = pack;
-        mSuperClassName = superClass;
-        mIsInterface = isInterface;
-        mIsAbstract = isAbstract;
-        mIsStatic = isStatic;
-        mIsFinal = isFinal;
-        mDeprecated = deprecated;
-        mScope = visibility;
-        mInterfaceNames = new ArrayList<String>();
-        mInterfaces = new ArrayList<ClassInfo>();
-        mMethods = new HashMap<String, MethodInfo>();
-        mFields = new HashMap<String, FieldInfo>();
-        mConstructors = new HashMap<String, ConstructorInfo>();
-        mExistsInBoth = false;
-        mSourcePosition = source;
-        mParentClass = parent;
-    }
-
-    public String name() {
-        return mName;
-    }
-
-    public String qualifiedName() {
-        String parentQName = (mParentClass != null)
-                ? (mParentClass.qualifiedName() + ".")
-                : "";
-        return mPackage.name() + "." + parentQName + name();
-    }
-
-    public String superclassName() {
-        return mSuperClassName;
-    }
-    
-    public SourcePositionInfo position() {
-        return mSourcePosition;
-    }
-
-    public boolean isInterface() {
-        return mIsInterface;
-    }
-
-    public boolean isFinal() {
-        return mIsFinal;
-    }
-    
-    // Find a superclass implementation of the given method.
-    public static MethodInfo overriddenMethod(MethodInfo candidate, ClassInfo newClassObj) {
-        if (newClassObj == null) {
-            return null;
-        }
-        for (MethodInfo mi : newClassObj.mMethods.values()) {
-            if (mi.matches(candidate)) {
-                // found it
-                return mi;
-            }
-        }
-
-        // not found here. recursively search ancestors
-        return ClassInfo.overriddenMethod(candidate, newClassObj.mSuperClass);
-    }
-    
-    // Find a superinterface declaration of the given method.
-    public static MethodInfo interfaceMethod(MethodInfo candidate, ClassInfo newClassObj) {
-        if (newClassObj == null) {
-            return null;
-        }
-        for (ClassInfo interfaceInfo : newClassObj.mInterfaces) {
-            for (MethodInfo mi : interfaceInfo.mMethods.values()) {
-                if (mi.matches(candidate)) {
-                    return mi;
-                }
-            }
-        }
-        return ClassInfo.interfaceMethod(candidate, newClassObj.mSuperClass);
-    }
-
-    public boolean isConsistent(ClassInfo cl) {
-        cl.mExistsInBoth = true;
-        mExistsInBoth = true;
-        boolean consistent = true;
-
-        if (isInterface() != cl.isInterface()) {
-            Errors.error(Errors.CHANGED_CLASS, cl.position(),
-                    "Class " + cl.qualifiedName()
-                    + " changed class/interface declaration");
-            consistent = false;
-        }
-        for (String iface : mInterfaceNames) {
-            if (!implementsInterface(cl, iface)) {
-                Errors.error(Errors.REMOVED_INTERFACE, cl.position(),
-                        "Class " + qualifiedName() + " no longer implements " + iface);
-            }
-        }
-        for (String iface : cl.mInterfaceNames) {
-          if (!mInterfaceNames.contains(iface)) {
-              Errors.error(Errors.ADDED_INTERFACE, cl.position(),
-                      "Added interface " + iface + " to class "
-                      + qualifiedName());
-              consistent = false;
-            }
-        }
-        
-        for (MethodInfo mInfo : mMethods.values()) {
-            if (cl.mMethods.containsKey(mInfo.getHashableName())) {
-                if (!mInfo.isConsistent(cl.mMethods.get(mInfo.getHashableName()))) {
-                    consistent = false;
-                }
-            } else {
-                /* This class formerly provided this method directly, and now does not.
-                 * Check our ancestry to see if there's an inherited version that still
-                 * fulfills the API requirement.
-                 */
-                MethodInfo mi = ClassInfo.overriddenMethod(mInfo, cl);
-                if (mi == null) {
-                    mi = ClassInfo.interfaceMethod(mInfo, cl);
-                }
-                if (mi == null) {
-                    Errors.error(Errors.REMOVED_METHOD, mInfo.position(),
-                            "Removed public method " + mInfo.qualifiedName());
-                    consistent = false;
-                }
-            }
-        }
-        for (MethodInfo mInfo : cl.mMethods.values()) {
-            if (!mInfo.isInBoth()) {
-                /* Similarly to the above, do not fail if this "new" method is
-                 * really an override of an existing superclass method.
-                 */
-                MethodInfo mi = ClassInfo.overriddenMethod(mInfo, cl);
-                if (mi == null) {
-                    Errors.error(Errors.ADDED_METHOD, mInfo.position(),
-                            "Added public method " + mInfo.qualifiedName());
-                    consistent = false;
-                }
-            }
-        }
-        
-        for (ConstructorInfo mInfo : mConstructors.values()) {
-          if (cl.mConstructors.containsKey(mInfo.getHashableName())) {
-              if (!mInfo.isConsistent(cl.mConstructors.get(mInfo.getHashableName()))) {
-                  consistent = false;
-              }
-          } else {
-              Errors.error(Errors.REMOVED_METHOD, mInfo.position(),
-                      "Removed public constructor " + mInfo.prettySignature());
-              consistent = false;
-          }
-        }
-        for (ConstructorInfo mInfo : cl.mConstructors.values()) {
-            if (!mInfo.isInBoth()) {
-                Errors.error(Errors.ADDED_METHOD, mInfo.position(),
-                        "Added public constructor " + mInfo.prettySignature());
-                consistent = false;
-            }
-        }
-        
-        for (FieldInfo mInfo : mFields.values()) {
-          if (cl.mFields.containsKey(mInfo.name())) {
-              if (!mInfo.isConsistent(cl.mFields.get(mInfo.name()))) {
-                  consistent = false;
-              }
-          } else {
-              Errors.error(Errors.REMOVED_FIELD, mInfo.position(),
-                      "Removed field " + mInfo.qualifiedName());
-              consistent = false;
-          }
-        }
-        for (FieldInfo mInfo : cl.mFields.values()) {
-            if (!mInfo.isInBoth()) {
-                Errors.error(Errors.ADDED_FIELD, mInfo.position(),
-                        "Added public field " + mInfo.qualifiedName());
-                consistent = false;
-            }
-        }
-        
-        if (mIsAbstract != cl.mIsAbstract) {
-            consistent = false;
-            Errors.error(Errors.CHANGED_ABSTRACT, cl.position(),
-                    "Class " + cl.qualifiedName() + " changed abstract qualifier");
-        }
-      
-        if (mIsFinal != cl.mIsFinal) {
-            consistent = false;
-            Errors.error(Errors.CHANGED_FINAL, cl.position(),
-                    "Class " + cl.qualifiedName() + " changed final qualifier");
-        }
-      
-        if (mIsStatic != cl.mIsStatic) {
-            consistent = false;
-            Errors.error(Errors.CHANGED_STATIC, cl.position(),
-                    "Class " + cl.qualifiedName() + " changed static qualifier");
-        }
-     
-        if (!mScope.equals(cl.mScope)) {
-            consistent = false;
-            Errors.error(Errors.CHANGED_SCOPE, cl.position(),
-                    "Class " + cl.qualifiedName() + " scope changed from "
-                    + mScope + " to " + cl.mScope);
-        }
-        
-        if (!mDeprecated.equals(cl.mDeprecated)) {
-            consistent = false;
-            Errors.error(Errors.CHANGED_DEPRECATED, cl.position(),
-                    "Class " + cl.qualifiedName() + " has changed deprecation state");
-        }
-        
-        if (mSuperClassName != null) {
-            if (cl.mSuperClassName == null || !mSuperClassName.equals(cl.mSuperClassName)) {
-                consistent = false;
-                Errors.error(Errors.CHANGED_SUPERCLASS, cl.position(),
-                        "Class " + qualifiedName() + " superclass changed from "
-                        + mSuperClassName + " to " + cl.mSuperClassName);
-            }
-        } else if (cl.mSuperClassName != null) {
-            consistent = false;
-            Errors.error(Errors.CHANGED_SUPERCLASS, cl.position(),
-                    "Class " + qualifiedName() + " superclass changed from "
-                    + "null to " + cl.mSuperClassName);
-        }
-        
-        return consistent;
-    }
-
-    /**
-     * Returns true if {@code cl} implements the interface {@code iface} either
-     * by either being that interface, implementing that interface or extending
-     * a type that implements the interface.
-     */
-    private boolean implementsInterface(ClassInfo cl, String iface) {
-        if (cl.qualifiedName().equals(iface)) {
-            return true;
-        }
-        for (ClassInfo clImplements : cl.mInterfaces) {
-            if (implementsInterface(clImplements, iface)) {
-                return true;
-            }
-        }
-        if (cl.mSuperClass != null && implementsInterface(cl.mSuperClass, iface)) {
-            return true;
-        }
-        return false;
-    }
-
-    public void resolveInterfaces(ApiInfo apiInfo) {
-        for (String interfaceName : mInterfaceNames) {
-            mInterfaces.add(apiInfo.findClass(interfaceName));
-        }
-    }
-    
-    public void addInterface(String name) {
-        mInterfaceNames.add(name);
-    }
-    
-    public void addMethod(MethodInfo mInfo) {
-        mMethods.put(mInfo.getHashableName(), mInfo);
-    }
-    
-    public void addConstructor(ConstructorInfo cInfo) {
-        mConstructors.put(cInfo.getHashableName(), cInfo);
-        
-    }
-    
-    public void addField(FieldInfo fInfo) {
-        mFields.put(fInfo.name(), fInfo);
-      
-    }
-    
-    public void setSuperClass(ClassInfo superclass) {
-        mSuperClass = superclass;
-    }
-    
-    public boolean isInBoth() {
-        return mExistsInBoth;
-    }
-
-    public Map<String, ConstructorInfo> allConstructors() {
-        return mConstructors;
-    }
-
-    public Map<String, FieldInfo> allFields() {
-        return mFields;
-    }
-
-    public Map<String, MethodInfo> allMethods() {
-        return mMethods;
-    }
-
-    /**
-     * Returns the class hierarchy for this class, starting with this class.
-     */
-    public Iterable<ClassInfo> hierarchy() {
-        List<ClassInfo> result = new ArrayList<ClassInfo>(4);
-        for (ClassInfo c  = this; c != null; c = c.mSuperClass) {
-            result.add(c);
-        }
-        return result;
-    }
-}
diff --git a/tools/apicheck/src/com/android/apicheck/ConstructorInfo.java b/tools/apicheck/src/com/android/apicheck/ConstructorInfo.java
deleted file mode 100644
index f36c7cd..0000000
--- a/tools/apicheck/src/com/android/apicheck/ConstructorInfo.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.apicheck;
-import java.util.*;
-
-public class ConstructorInfo implements AbstractMethodInfo {
-    
-    private String mName;
-    private String mType;
-    private boolean mIsStatic;
-    private boolean mIsFinal;
-    private String mDeprecated;
-    private String mScope;
-    private List<String> mExceptions;
-    private List<ParameterInfo> mParameters;
-    private boolean mExistsInBoth;
-    private SourcePositionInfo mSourcePosition;
-    private ClassInfo mClass;
-    
-    public ConstructorInfo(String name, String type, boolean isStatic, boolean isFinal,
-                           String deprecated, String scope, SourcePositionInfo pos, ClassInfo clazz) {
-        mName = name;
-        mType = type;
-        mIsStatic = isStatic;
-        mIsFinal = isFinal;
-        mDeprecated= deprecated;
-        mScope = scope;
-        mExistsInBoth = false;
-        mExceptions = new ArrayList<String>();
-        mParameters = new ArrayList<ParameterInfo>();
-        mSourcePosition = pos;
-        mClass = clazz;
-    }
-    
-    public void addParameter(ParameterInfo pInfo) {
-        mParameters.add(pInfo);
-    }
-    
-    public void addException(String exec) {
-        mExceptions.add(exec);
-    }
-    
-    public String getHashableName() {
-      StringBuilder result = new StringBuilder();
-      result.append(name());
-      for (ParameterInfo pInfo : mParameters) {
-          result.append(":").append(pInfo.getType());
-      }
-      return result.toString();
-    }
-    
-    public boolean isInBoth() {
-        return mExistsInBoth;
-    }
-    
-    public SourcePositionInfo position() {
-        return mSourcePosition;
-    }
-    
-    public String name() {
-        return mName;
-    }
-    
-    public String qualifiedName() {
-        String baseName = (mClass != null)
-                ? (mClass.qualifiedName() + ".")
-                : "";
-        return baseName + name();
-    }
-    
-    public String prettySignature() {
-        String params = "";
-        for (ParameterInfo pInfo : mParameters) {
-            if (params.length() > 0) {
-                params += ", ";
-            }
-            params += pInfo.getType();
-        }
-        return qualifiedName() + '(' + params + ')';
-    }
-    
-    public boolean isConsistent(ConstructorInfo mInfo) {
-      mInfo.mExistsInBoth = true;
-      mExistsInBoth = true;
-      boolean consistent = true;
-      
-      if (mIsFinal != mInfo.mIsFinal) {
-          consistent = false;
-          Errors.error(Errors.CHANGED_FINAL, mInfo.position(),
-                  "Constructor " + mInfo.qualifiedName() + " has changed 'final' qualifier");
-      }
-      
-      if (mIsStatic != mInfo.mIsStatic) {
-          consistent = false;
-          Errors.error(Errors.CHANGED_FINAL, mInfo.position(),
-                  "Constructor " + mInfo.qualifiedName() + " has changed 'static' qualifier");
-      }
-     
-      if (!mScope.equals(mInfo.mScope)) {
-          consistent = false;
-          Errors.error(Errors.CHANGED_SCOPE, mInfo.position(),
-                  "Constructor " + mInfo.qualifiedName() + " changed scope from "
-                  + mScope + " to " + mInfo.mScope);
-      }
-      
-      if (!mDeprecated.equals(mInfo.mDeprecated)) {
-          consistent = false;
-          Errors.error(Errors.CHANGED_DEPRECATED, mInfo.position(),
-                  "Constructor " + mInfo.qualifiedName() + " has changed deprecation state");
-      }
-      
-      for (String exec : mExceptions) {
-          if (!mInfo.mExceptions.contains(exec)) {
-              Errors.error(Errors.CHANGED_THROWS, mInfo.position(),
-                      "Constructor " + mInfo.qualifiedName() + " no longer throws exception "
-                      + exec);
-              consistent = false;
-          }
-      }
-      
-      for (String exec : mInfo.mExceptions) {
-          if (!mExceptions.contains(exec)) {
-              Errors.error(Errors.CHANGED_THROWS, mInfo.position(),
-                      "Constructor " + mInfo.qualifiedName() + " added thrown exception "
-                      + exec);
-            consistent = false;
-          }
-      }
-      
-      return consistent;
-  }
-    
-
-}
diff --git a/tools/apicheck/src/com/android/apicheck/Errors.java b/tools/apicheck/src/com/android/apicheck/Errors.java
deleted file mode 100644
index b0b620e..0000000
--- a/tools/apicheck/src/com/android/apicheck/Errors.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.apicheck;
-
-import java.lang.Comparable;
-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);
-        }
-
-        @Override
-        public String toString() {
-            return this.pos.toString() + 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 PARSE_ERROR = new Error(1, ERROR);
-    public static Error ADDED_PACKAGE = new Error(2, WARNING);
-    public static Error ADDED_CLASS = new Error(3, WARNING);
-    public static Error ADDED_METHOD = new Error(4, WARNING);
-    public static Error ADDED_FIELD = new Error(5, WARNING);
-    public static Error ADDED_INTERFACE = new Error(6, WARNING);
-    public static Error REMOVED_PACKAGE = new Error(7, WARNING);
-    public static Error REMOVED_CLASS = new Error(8, WARNING);
-    public static Error REMOVED_METHOD = new Error(9, WARNING);
-    public static Error REMOVED_FIELD = new Error(10, WARNING);
-    public static Error REMOVED_INTERFACE = new Error(11, WARNING);
-    public static Error CHANGED_STATIC = new Error(12, WARNING);
-    public static Error CHANGED_FINAL = new Error(13, WARNING);
-    public static Error CHANGED_TRANSIENT = new Error(14, WARNING);
-    public static Error CHANGED_VOLATILE = new Error(15, WARNING);
-    public static Error CHANGED_TYPE = new Error(16, WARNING);
-    public static Error CHANGED_VALUE = new Error(17, WARNING);
-    public static Error CHANGED_SUPERCLASS = new Error(18, WARNING);
-    public static Error CHANGED_SCOPE = new Error(19, WARNING);
-    public static Error CHANGED_ABSTRACT = new Error(20, WARNING);
-    public static Error CHANGED_THROWS = new Error(21, WARNING);
-    public static Error CHANGED_NATIVE = new Error(22, HIDDEN);
-    public static Error CHANGED_CLASS = new Error(23, WARNING);
-    public static Error CHANGED_DEPRECATED = new Error(24, WARNING);
-    public static Error CHANGED_SYNCHRONIZED = new Error(25, ERROR);
-
-    public static Error[] ERRORS = {
-        PARSE_ERROR,
-        ADDED_PACKAGE,
-        ADDED_CLASS,
-        ADDED_METHOD,
-        ADDED_FIELD,
-        ADDED_INTERFACE,
-        REMOVED_PACKAGE,
-        REMOVED_CLASS,
-        REMOVED_METHOD,
-        REMOVED_FIELD,
-        REMOVED_INTERFACE,
-        CHANGED_STATIC,
-        CHANGED_FINAL,
-        CHANGED_TRANSIENT,
-        CHANGED_VOLATILE,
-        CHANGED_TYPE,
-        CHANGED_VALUE,
-        CHANGED_SUPERCLASS,
-        CHANGED_SCOPE,
-        CHANGED_ABSTRACT,
-        CHANGED_THROWS,
-        CHANGED_NATIVE,
-        CHANGED_CLASS,
-        CHANGED_DEPRECATED,
-        CHANGED_SYNCHRONIZED,
-        };
-
-    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/apicheck/src/com/android/apicheck/FieldInfo.java b/tools/apicheck/src/com/android/apicheck/FieldInfo.java
deleted file mode 100644
index d80d9f6..0000000
--- a/tools/apicheck/src/com/android/apicheck/FieldInfo.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.apicheck;
-
-public class FieldInfo {
-  
-    private String mName;
-    private String mType;
-    private boolean mIsTransient;
-    private boolean mIsVolatile;
-    private String mValue;
-    private boolean mIsStatic;
-    private boolean mIsFinal;
-    private String mDeprecated;
-    private String mScope;
-    private boolean mExistsInBoth;
-    private SourcePositionInfo mSourcePosition;
-    private ClassInfo mClass;
-    
-    public FieldInfo (String name, String type, boolean isTransient, boolean isVolatile,
-                       String value, boolean isStatic, boolean isFinal, String deprecated,
-                       String scope, SourcePositionInfo source, ClassInfo parent) {
-        mName = name;
-        mType = type;
-        mIsTransient = isTransient;
-        mIsVolatile = isVolatile;
-        mValue = value;
-        mIsStatic = isStatic;
-        mIsFinal = isFinal;
-        mDeprecated = deprecated;
-        mScope = scope;
-        mExistsInBoth = false;
-        mSourcePosition = source;
-        mClass = parent;
-    }
-    
-    public boolean isInBoth() {
-        return mExistsInBoth;
-    }
-    public SourcePositionInfo position() {
-        return mSourcePosition;
-    }
-    
-    public String name() {
-        return mName;
-    }
-    
-    public String qualifiedName() {
-        String parentQName = (mClass != null)
-                ? (mClass.qualifiedName() + ".")
-                : "";
-        return parentQName + name();
-    }
-    
-    // Check the declared value with a typed comparison, not a string comparison,
-    // to accommodate toolchains with different fp -> string conversions.
-    public boolean valueEquals(FieldInfo other) {
-        // Type mismatch means nonequal, as does a null/non-null mismatch
-        if (!mType.equals(other.mType)
-                || ((mValue == null) != (other.mValue == null))) {
-            return false;
-        }
-
-        // Null values are considered equal
-        if (mValue == null) {
-            return true;
-        }
-
-        // Floating point gets an implementation-type comparison; all others just use the string
-        // If float/double parse fails, fall back to string comparison -- it means that it's a
-        // canonical droiddoc-generated constant expression that represents a NaN.
-        try {
-            if (mType.equals("float")) {
-                float val = Float.parseFloat(mValue);
-                float otherVal = Float.parseFloat(other.mValue);
-                return (val == otherVal);
-            } else if (mType.equals("double")) {
-                double val = Double.parseDouble(mValue);
-                double otherVal = Double.parseDouble(other.mValue);
-                return (val == otherVal);
-            }
-        } catch (NumberFormatException e) {
-            // fall through
-        }
-        
-        return mValue.equals(other.mValue);
-    }
-
-    public boolean isConsistent(FieldInfo fInfo) {
-      fInfo.mExistsInBoth = true;
-      mExistsInBoth = true;
-      boolean consistent = true;
-      if (!mType.equals(fInfo.mType)) {
-          Errors.error(Errors.CHANGED_TYPE, fInfo.position(),
-                  "Field " + fInfo.qualifiedName() + " has changed type");
-          consistent = false;
-      }
-
-      if (!this.valueEquals(fInfo)) {
-          Errors.error(Errors.CHANGED_VALUE, fInfo.position(),
-                  "Field " + fInfo.qualifiedName() + " has changed value from "
-                  + mValue + " to " + fInfo.mValue);
-          consistent = false;
-      }
-      
-      if (!mScope.equals(fInfo.mScope)) {
-          Errors.error(Errors.CHANGED_SCOPE, fInfo.position(),
-                  "Method " + fInfo.qualifiedName() + " changed scope from "
-                  + mScope + " to " + fInfo.mScope);
-          consistent = false;
-      }
-      
-      if (mIsStatic != fInfo.mIsStatic) {
-          Errors.error(Errors.CHANGED_STATIC, fInfo.position(),
-                  "Field " + fInfo.qualifiedName() + " has changed 'static' qualifier");
-          consistent = false;
-      }
-      
-      if (mIsFinal != fInfo.mIsFinal) {
-          Errors.error(Errors.CHANGED_FINAL, fInfo.position(),
-                  "Field " + fInfo.qualifiedName() + " has changed 'final' qualifier");
-          consistent = false;
-      }
-      
-      if (mIsTransient != fInfo.mIsTransient) {
-          Errors.error(Errors.CHANGED_TRANSIENT, fInfo.position(),
-                  "Field " + fInfo.qualifiedName() + " has changed 'transient' qualifier");
-          consistent = false;
-      }
-      
-      if (mIsVolatile != fInfo.mIsVolatile) {
-          Errors.error(Errors.CHANGED_VOLATILE, fInfo.position(),
-                  "Field " + fInfo.qualifiedName() + " has changed 'volatile' qualifier");
-          consistent = false;
-      }
-      
-      if (!mDeprecated.equals(fInfo.mDeprecated)) {
-          Errors.error(Errors.CHANGED_DEPRECATED, fInfo.position(),
-                  "Field " + fInfo.qualifiedName() + " has changed deprecation state");
-          consistent = false;
-      }
-      
-      return consistent;
-    }
-
-}
diff --git a/tools/apicheck/src/com/android/apicheck/MethodInfo.java b/tools/apicheck/src/com/android/apicheck/MethodInfo.java
deleted file mode 100644
index e4e4537..0000000
--- a/tools/apicheck/src/com/android/apicheck/MethodInfo.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.apicheck;
-import java.util.*;
-
-public class MethodInfo implements AbstractMethodInfo {
-  
-    private String mName;
-    private String mReturn;
-    private boolean mIsAbstract;
-    private boolean mIsNative;
-    private boolean mIsSynchronized;
-    private boolean mIsStatic;
-    private boolean mIsFinal;
-    private String mDeprecated;
-    private String mScope;
-    private boolean mExistsInBoth;
-    private List<ParameterInfo> mParameters;
-    private List<String> mExceptions;
-    private SourcePositionInfo mSourcePosition;
-    private ClassInfo mClass;
-    
-    public MethodInfo (String name, String returnType, boolean isAbstract, boolean isNative,
-                        boolean isSynchronized, boolean isStatic, boolean isFinal, String deprecated
-                        , String scope, SourcePositionInfo source, ClassInfo parent) {
-        
-        mName = name;
-        mReturn = returnType;
-        mIsAbstract = isAbstract;
-        mIsNative = isNative;
-        mIsSynchronized = isSynchronized;
-        mIsStatic = isStatic;
-        mIsFinal = isFinal;
-        mDeprecated = deprecated;
-        mScope = scope;
-        mParameters = new ArrayList<ParameterInfo>();
-        mExceptions = new ArrayList<String>();
-        mExistsInBoth = false;
-        mSourcePosition = source;
-        mClass = parent;
-    }
-    
-    
-    public String name() {
-        return mName;
-    }
-    
-    public String qualifiedName() {
-        String parentQName = (mClass != null)
-                ? (mClass.qualifiedName() + ".")
-                : "";
-        return parentQName + name();
-    }
-    
-    public String prettySignature() {
-        String params = "";
-        for (ParameterInfo pInfo : mParameters) {
-            if (params.length() > 0) {
-                params += ", ";
-            }
-            params += pInfo.getType();
-        }
-        return qualifiedName() + '(' + params + ')';
-    }
-    
-    public SourcePositionInfo position() {
-        return mSourcePosition;
-    }
-    
-    public ClassInfo containingClass() {
-        return mClass;
-    }
-
-    public boolean matches(MethodInfo other) {
-        return getSignature().equals(other.getSignature());
-    }
-    
-    public boolean isConsistent(MethodInfo mInfo) {
-        mInfo.mExistsInBoth = true;
-        mExistsInBoth = true;
-        boolean consistent = true;
-        if (!mReturn.equals(mInfo.mReturn)) {
-            consistent = false;
-            Errors.error(Errors.CHANGED_TYPE, mInfo.position(),
-                    "Method " + mInfo.qualifiedName() + " has changed return type from "
-                    + mReturn + " to " + mInfo.mReturn);
-        }
-        
-        if (mIsAbstract != mInfo.mIsAbstract) {
-            consistent = false;
-            Errors.error(Errors.CHANGED_ABSTRACT, mInfo.position(),
-                    "Method " + mInfo.qualifiedName() + " has changed 'abstract' qualifier");
-        }
-        
-        if (mIsNative != mInfo.mIsNative) {
-            consistent = false;
-            Errors.error(Errors.CHANGED_NATIVE, mInfo.position(),
-                    "Method " + mInfo.qualifiedName() + " has changed 'native' qualifier");
-        }
-        
-        if (mIsFinal != mInfo.mIsFinal) {
-            // Compiler-generated methods vary in their 'final' qual between versions of
-            // the compiler, so this check needs to be quite narrow.  A change in 'final'
-            // status of a method is only relevant if (a) the method is not declared 'static'
-            // and (b) the method's class is not itself 'final'.
-            if (!mIsStatic) {
-                if ((mClass == null) || (!mClass.isFinal())) {
-                    consistent = false;
-                    Errors.error(Errors.CHANGED_FINAL, mInfo.position(),
-                            "Method " + mInfo.qualifiedName() + " has changed 'final' qualifier");
-                }
-            }
-        }
-        
-        if (mIsStatic != mInfo.mIsStatic) {
-            consistent = false;
-            Errors.error(Errors.CHANGED_STATIC, mInfo.position(),
-                    "Method " + mInfo.qualifiedName() + " has changed 'static' qualifier");
-        }
-       
-        if (!mScope.equals(mInfo.mScope)) {
-            consistent = false;
-            Errors.error(Errors.CHANGED_SCOPE, mInfo.position(),
-                    "Method " + mInfo.qualifiedName() + " changed scope from "
-                    + mScope + " to " + mInfo.mScope);
-        }
-        
-        if (!mDeprecated.equals(mInfo.mDeprecated)) {
-            Errors.error(Errors.CHANGED_DEPRECATED, mInfo.position(),
-                    "Method " + mInfo.qualifiedName() + " has changed deprecation state");
-            consistent = false;
-        }
-        
-        if (mIsSynchronized != mInfo.mIsSynchronized) {
-            Errors.error(Errors.CHANGED_SYNCHRONIZED, mInfo.position(),
-                    "Method " + mInfo.qualifiedName() + " has changed 'synchronized' qualifier from " + mIsSynchronized + " to " + mInfo.mIsSynchronized);
-            consistent = false;
-        }
-        
-        for (String exec : mExceptions) {
-            if (!mInfo.mExceptions.contains(exec)) {
-                // exclude 'throws' changes to finalize() overrides with no arguments
-                if (!name().equals("finalize") || (mParameters.size() > 0)) {
-                    Errors.error(Errors.CHANGED_THROWS, mInfo.position(),
-                            "Method " + mInfo.qualifiedName() + " no longer throws exception "
-                            + exec);
-                    consistent = false;
-                }
-            }
-        }
-        
-        for (String exec : mInfo.mExceptions) {
-            // exclude 'throws' changes to finalize() overrides with no arguments
-            if (!mExceptions.contains(exec)) {
-                if (!name().equals("finalize") || (mParameters.size() > 0)) {
-                    Errors.error(Errors.CHANGED_THROWS, mInfo.position(),
-                            "Method " + mInfo.qualifiedName() + " added thrown exception "
-                            + exec);
-                    consistent = false;
-                }
-            }
-        }
-        
-        return consistent;
-    }
-    
-    public void addParameter(ParameterInfo pInfo) {
-        mParameters.add(pInfo);
-    }
-    
-    public void addException(String exc) {
-        mExceptions.add(exc);
-    }
-    
-    public String getParameterHash() {
-        String hash = "";
-        for (ParameterInfo pInfo : mParameters) {
-            hash += ":" + pInfo.getType();
-        }
-        return hash;
-    }
-    
-    public String getHashableName() {
-        return name() + getParameterHash();
-    }
-    
-    public String getSignature() {
-        return name() + getParameterHash();
-    }
-    
-    public boolean isInBoth() {
-        return mExistsInBoth;
-    }
-
-}
diff --git a/tools/apicheck/src/com/android/apicheck/PackageInfo.java b/tools/apicheck/src/com/android/apicheck/PackageInfo.java
deleted file mode 100644
index 2262f21..0000000
--- a/tools/apicheck/src/com/android/apicheck/PackageInfo.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.apicheck;
-import java.util.*;
-
-public class PackageInfo {
-    private String mName;
-    private HashMap<String, ClassInfo> mClasses;
-    private boolean mExistsInBoth;
-    private SourcePositionInfo mPosition;
-    
-    public PackageInfo(String name, SourcePositionInfo position) {
-        mName = name;
-        mClasses = new HashMap<String, ClassInfo>();
-        mExistsInBoth = false;
-        mPosition = position;
-    }
-    
-    public void addClass(ClassInfo cl) {
-        mClasses.put(cl.name() , cl);
-    }
-    
-    public HashMap<String, ClassInfo> allClasses() {
-        return mClasses;
-    }
-    
-    public String name() {
-        return mName;
-    }
-    
-    public SourcePositionInfo position() {
-        return mPosition;
-    }
-    
-    public boolean isConsistent(PackageInfo pInfo) {
-        mExistsInBoth = true;
-        pInfo.mExistsInBoth = true;
-        boolean consistent = true;
-        for (ClassInfo cInfo : mClasses.values()) {
-            if (pInfo.mClasses.containsKey(cInfo.name())) {
-                if (!cInfo.isConsistent(pInfo.mClasses.get(cInfo.name()))) {
-                    consistent = false;
-                }
-            } else {
-                Errors.error(Errors.REMOVED_CLASS, cInfo.position(),
-                        "Removed public class " + cInfo.qualifiedName());
-                consistent = false;
-            }
-        }
-        for (ClassInfo cInfo : pInfo.mClasses.values()) {
-            if (!cInfo.isInBoth()) {
-                Errors.error(Errors.ADDED_CLASS, cInfo.position(),
-                        "Added class " + cInfo.name() + " to package "
-                        + pInfo.name());
-                consistent = false;
-            }
-        }
-        return consistent;
-    }
-    
-    public boolean isInBoth() {
-        return mExistsInBoth;
-    }
-}
diff --git a/tools/apicheck/src/com/android/apicheck/ParameterInfo.java b/tools/apicheck/src/com/android/apicheck/ParameterInfo.java
deleted file mode 100644
index 5788814..0000000
--- a/tools/apicheck/src/com/android/apicheck/ParameterInfo.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.apicheck;
-
-public class ParameterInfo {
-    private String mType;
-    private String mName;
-    
-    public ParameterInfo(String type, String name) {
-        mType = type;
-        mName = name;
-    }
-    
-    public String getType() {
-        return mType;
-    }
-    
-    public String getName() {
-        return mName;
-    }
-}
diff --git a/tools/apicheck/src/com/android/apicheck/SourcePositionInfo.java b/tools/apicheck/src/com/android/apicheck/SourcePositionInfo.java
deleted file mode 100644
index 276771b..0000000
--- a/tools/apicheck/src/com/android/apicheck/SourcePositionInfo.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.apicheck;
-
-import java.lang.Comparable;
-
-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);
-    }
-
-    @Override
-    public String toString()
-    {
-        if (this.file == null) {
-            return "(unknown)";
-        } else {
-            if (this.line == 0) {
-                return this.file + ':';
-            } else {
-                return this.file + ':' + this.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;
-    }
-
-    /**
-     * Build a SourcePositionInfo from the XML source= notation
-     */
-    public static SourcePositionInfo fromXml(String source) {
-        if (source != null) {
-            for (int i = 0; i < source.length(); i++) {
-                if (source.charAt(i) == ':') {
-                    return new SourcePositionInfo(source.substring(0, i),
-                            Integer.parseInt(source.substring(i+1)), 0);
-                }
-            }
-        }
-
-        return new SourcePositionInfo("(unknown)", 0, 0);
-    }
-
-    public String file;
-    public int line;
-    public int column;
-}
diff --git a/tools/apriori/apriori.c b/tools/apriori/apriori.c
index b25ac2b..0e5b5d2 100644
--- a/tools/apriori/apriori.c
+++ b/tools/apriori/apriori.c
@@ -62,7 +62,7 @@
 
 // We will store retouch entries into this buffer, then dump them at the
 // end of the .so file before setup_prelink_info().
-#define RETOUCH_MAX_SIZE 500000
+#define RETOUCH_MAX_SIZE 550000
 static char *retouch_buf;
 static unsigned int retouch_byte_cnt;
 // Compression state.
diff --git a/tools/droiddoc/NOTICE b/tools/droiddoc/NOTICE
deleted file mode 100644
index 3f1b1bb..0000000
--- a/tools/droiddoc/NOTICE
+++ /dev/null
@@ -1,45 +0,0 @@
-
-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.
-
-
-======================================================================
-
-jQuery 1.2.6 - New Wave Javascript
-
-Copyright (c) 2008 John Resig (jquery.com)
-Dual licensed under the MIT (MIT-LICENSE.txt)
-and GPL (GPL-LICENSE.txt) licenses.
-
-Copyright (c) 2009 John Resig, http://jquery.com/
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
diff --git a/tools/droiddoc/src/Android.mk b/tools/droiddoc/src/Android.mk
deleted file mode 100644
index 30270b5..0000000
--- a/tools/droiddoc/src/Android.mk
+++ /dev/null
@@ -1,69 +0,0 @@
-# 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_SRC_FILES := \
-    AnnotationInstanceInfo.java \
-    AnnotationValueInfo.java \
-	AttributeInfo.java \
-	AttrTagInfo.java \
-	ClassInfo.java \
-	DroidDoc.java \
-	ClearPage.java \
-	Comment.java \
-	ContainerInfo.java \
-	Converter.java \
-	DocFile.java \
-	DocInfo.java \
-	Errors.java \
-	FieldInfo.java \
-	Hierarchy.java \
-	InheritedTags.java \
-	KeywordEntry.java \
-    LinkReference.java \
-	LiteralTagInfo.java \
-	MemberInfo.java \
-	MethodInfo.java \
-	NavTree.java \
-	PackageInfo.java \
-	ParamTagInfo.java \
-	ParameterInfo.java \
-	ParsedTagInfo.java \
-	Proofread.java \
-	SampleCode.java \
-	SampleTagInfo.java \
-    Scoped.java \
-	SeeTagInfo.java \
-	SinceTagger.java \
-	Sorter.java \
-	SourcePositionInfo.java \
-    Stubs.java \
-	TagInfo.java \
-    TextTagInfo.java \
-	ThrowsTagInfo.java \
-	TodoFile.java \
-	TypeInfo.java
-
-LOCAL_JAVA_LIBRARIES := \
-	apicheck \
-	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
deleted file mode 100644
index c4abc7e..0000000
--- a/tools/droiddoc/src/AnnotationInstanceInfo.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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;
-    }
-
-    @Override
-    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
deleted file mode 100644
index a2d869a..0000000
--- a/tools/droiddoc/src/AnnotationValueInfo.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 7f1b4d9..0000000
--- a/tools/droiddoc/src/AttrTagInfo.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * 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;
-    }
-
-    @Override
-    public String name() {
-        return NAME_COMMAND.equals(mCommand) ? mAttrName : null;
-    }
-
-    public Comment description() {
-        return DESCRIPTION_COMMAND.equals(mCommand) ? mDescrComment : null;
-    }
-
-    @Override
-    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
deleted file mode 100644
index a24106b..0000000
--- a/tools/droiddoc/src/AttributeInfo.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * 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
deleted file mode 100644
index f3f11de..0000000
--- a/tools/droiddoc/src/ClassInfo.java
+++ /dev/null
@@ -1,1464 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import com.sun.javadoc.*;
-import com.sun.tools.doclets.*;
-import org.clearsilver.HDF;
-import org.clearsilver.CS;
-import java.util.*;
-import java.io.*;
-
-public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Scoped
-{
-    public static final Comparator<ClassInfo> comparator = new Comparator<ClassInfo>() {
-        public int compare(ClassInfo a, ClassInfo b) {
-            return a.name().compareTo(b.name());
-        }
-    };
-
-    public static final Comparator<ClassInfo> qualifiedComparator = new Comparator<ClassInfo>() {
-        public int compare(ClassInfo a, ClassInfo b) {
-            return a.qualifiedName().compareTo(b.qualifiedName());
-        }
-    };
-
-    public ClassInfo(
-            ClassDoc cl,
-            String rawCommentText, SourcePositionInfo position,
-            boolean isPublic, boolean isProtected, boolean isPackagePrivate,
-            boolean isPrivate, boolean isStatic,
-            boolean isInterface, boolean isAbstract, boolean isOrdinaryClass,
-            boolean isException, boolean isError, boolean isEnum, boolean isAnnotation,
-            boolean isFinal, boolean isIncluded, String name,
-            String qualifiedName, String qualifiedTypeName, boolean isPrimitive)
-    {
-        super(rawCommentText, position);
-
-        mClass = cl;
-        mIsPublic = isPublic;
-        mIsProtected = isProtected;
-        mIsPackagePrivate = isPackagePrivate;
-        mIsPrivate = isPrivate;
-        mIsStatic = isStatic;
-        mIsInterface = isInterface;
-        mIsAbstract = isAbstract;
-        mIsOrdinaryClass = isOrdinaryClass;
-        mIsException = isException;
-        mIsError = isError;
-        mIsEnum = isEnum;
-        mIsAnnotation = isAnnotation;
-        mIsFinal = isFinal;
-        mIsIncluded = isIncluded;
-        mName = name;
-        mQualifiedName = qualifiedName;
-        mQualifiedTypeName = qualifiedTypeName;
-        mIsPrimitive = isPrimitive;
-        mNameParts = name.split("\\.");
-    }
-
-    public void init(TypeInfo typeInfo, ClassInfo[] interfaces, TypeInfo[] interfaceTypes,
-            ClassInfo[] innerClasses,
-            MethodInfo[] constructors, MethodInfo[] methods, MethodInfo[] annotationElements,
-            FieldInfo[] fields, FieldInfo[] enumConstants,
-            PackageInfo containingPackage, ClassInfo containingClass,
-            ClassInfo superclass, TypeInfo superclassType, AnnotationInstanceInfo[] annotations)
-    {
-        mTypeInfo = typeInfo;
-        mRealInterfaces = interfaces;
-        mRealInterfaceTypes = interfaceTypes;
-        mInnerClasses = innerClasses;
-        mAllConstructors = constructors;
-        mAllSelfMethods = methods;
-        mAnnotationElements = annotationElements;
-        mAllSelfFields = fields;
-        mEnumConstants = enumConstants;
-        mContainingPackage = containingPackage;
-        mContainingClass = containingClass;
-        mRealSuperclass = superclass;
-        mRealSuperclassType = superclassType;
-        mAnnotations = annotations;
-
-        // after providing new methods and new superclass info,clear any cached
-        // lists of self + superclass methods, ctors, etc.
-        mSuperclassInit = false;
-        mConstructors = null;
-        mMethods = null;
-        mSelfMethods = null;
-        mFields = null;
-        mSelfFields = null;
-        mSelfAttributes = null;
-        mDeprecatedKnown = false;
-
-        Arrays.sort(mEnumConstants, FieldInfo.comparator);
-        Arrays.sort(mInnerClasses, ClassInfo.comparator);
-    }
-
-    public void init2() {
-        // calling this here forces the AttrTagInfo objects to be linked to the AttribtueInfo
-        // objects
-        selfAttributes();
-    }
-
-    public void init3(TypeInfo[] types, ClassInfo[] realInnerClasses){
-      mTypeParameters = types;
-      mRealInnerClasses = realInnerClasses;
-    }
-
-    public ClassInfo[] getRealInnerClasses(){
-      return mRealInnerClasses;
-    }
-
-    public TypeInfo[] getTypeParameters(){
-      return mTypeParameters;
-    }
-
-    public boolean checkLevel()
-    {
-        int val = mCheckLevel;
-        if (val >= 0) {
-            return val != 0;
-        } else {
-            boolean v = DroidDoc.checkLevel(mIsPublic, mIsProtected,
-                                                mIsPackagePrivate, mIsPrivate, isHidden());
-            mCheckLevel = v ? 1 : 0;
-            return v;
-        }
-    }
-
-    public int compareTo(Object that) {
-        if (that instanceof ClassInfo) {
-            return mQualifiedName.compareTo(((ClassInfo)that).mQualifiedName);
-        } else {
-            return this.hashCode() - that.hashCode();
-        }
-    }
-
-    @Override
-    public ContainerInfo parent()
-    {
-        return this;
-    }
-
-    public boolean isPublic()
-    {
-        return mIsPublic;
-    }
-
-    public boolean isProtected()
-    {
-        return mIsProtected;
-    }
-
-    public boolean isPackagePrivate()
-    {
-        return mIsPackagePrivate;
-    }
-
-    public boolean isPrivate()
-    {
-        return mIsPrivate;
-    }
-
-    public boolean isStatic()
-    {
-        return mIsStatic;
-    }
-
-    public boolean isInterface()
-    {
-        return mIsInterface;
-    }
-
-    public boolean isAbstract()
-    {
-        return mIsAbstract;
-    }
-
-    public PackageInfo containingPackage()
-    {
-        return mContainingPackage;
-    }
-
-    public ClassInfo containingClass()
-    {
-        return mContainingClass;
-    }
-
-    public boolean isOrdinaryClass()
-    {
-        return mIsOrdinaryClass;
-    }
-
-    public boolean isException()
-    {
-        return mIsException;
-    }
-
-    public boolean isError()
-    {
-        return mIsError;
-    }
-
-    public boolean isEnum()
-    {
-        return mIsEnum;
-    }
-
-    public boolean isAnnotation()
-    {
-        return mIsAnnotation;
-    }
-
-    public boolean isFinal()
-    {
-        return mIsFinal;
-    }
-
-    public boolean isIncluded()
-    {
-        return mIsIncluded;
-    }
-
-    public HashSet<String> typeVariables()
-    {
-        HashSet<String> result = TypeInfo.typeVariables(mTypeInfo.typeArguments());
-        ClassInfo cl = containingClass();
-        while (cl != null) {
-            TypeInfo[] types = cl.asTypeInfo().typeArguments();
-            if (types != null) {
-                TypeInfo.typeVariables(types, result);
-            }
-            cl = cl.containingClass();
-        }
-        return result;
-    }
-
-    private static void gatherHiddenInterfaces(ClassInfo cl, HashSet<ClassInfo> interfaces) {
-        for (ClassInfo iface: cl.mRealInterfaces) {
-            if (iface.checkLevel()) {
-                interfaces.add(iface);
-            } else {
-                gatherHiddenInterfaces(iface, interfaces);
-            }
-        }
-    }
-
-    public ClassInfo[] interfaces()
-    {
-        if (mInterfaces == null) {
-            if (checkLevel()) {
-                HashSet<ClassInfo> interfaces = new HashSet<ClassInfo>();
-                ClassInfo superclass = mRealSuperclass;
-                while (superclass != null && !superclass.checkLevel()) {
-                    gatherHiddenInterfaces(superclass, interfaces);
-                    superclass = superclass.mRealSuperclass;
-                }
-                gatherHiddenInterfaces(this, interfaces);
-                mInterfaces = interfaces.toArray(new ClassInfo[interfaces.size()]);
-            } else {
-                // put something here in case someone uses it
-                mInterfaces = mRealInterfaces;
-            }
-            Arrays.sort(mInterfaces, ClassInfo.qualifiedComparator);
-        }
-        return mInterfaces;
-    }
-
-    public ClassInfo[] realInterfaces()
-    {
-        return mRealInterfaces;
-    }
-
-    TypeInfo[] realInterfaceTypes()
-    {
-        return mRealInterfaceTypes;
-    }
-
-    public String name()
-    {
-        return mName;
-    }
-
-    public String[] nameParts()
-    {
-        return mNameParts;
-    }
-
-    public String leafName()
-    {
-        return mNameParts[mNameParts.length-1];
-    }
-
-    public String qualifiedName()
-    {
-        return mQualifiedName;
-    }
-
-    public String qualifiedTypeName()
-    {
-        return mQualifiedTypeName;
-    }
-
-    public boolean isPrimitive()
-    {
-        return mIsPrimitive;
-    }
-
-    public MethodInfo[] allConstructors() {
-        return mAllConstructors;
-    }
-
-    public MethodInfo[] constructors()
-    {
-        if (mConstructors == null) {
-            MethodInfo[] methods = mAllConstructors;
-            ArrayList<MethodInfo> ctors = new ArrayList<MethodInfo>();
-            for (int i=0; i<methods.length; i++) {
-                MethodInfo m = methods[i];
-                if (!m.isHidden()) {
-                    ctors.add(m);
-                }
-            }
-            mConstructors = ctors.toArray(new MethodInfo[ctors.size()]);
-            Arrays.sort(mConstructors, MethodInfo.comparator);
-        }
-        return mConstructors;
-    }
-
-    public ClassInfo[] innerClasses()
-    {
-        return mInnerClasses;
-    }
-
-    public TagInfo[] inlineTags()
-    {
-        return comment().tags();
-    }
-
-    public TagInfo[] firstSentenceTags()
-    {
-        return comment().briefTags();
-    }
-
-    public boolean isDeprecated() {
-        boolean deprecated = false;
-        if (!mDeprecatedKnown) {
-            boolean commentDeprecated = (comment().deprecatedTags().length > 0);
-            boolean annotationDeprecated = false;
-            for (AnnotationInstanceInfo annotation : annotations()) {
-                if (annotation.type().qualifiedName().equals("java.lang.Deprecated")) {
-                    annotationDeprecated = true;
-                    break;
-                }
-            }
-
-            if (commentDeprecated != annotationDeprecated) {
-                Errors.error(Errors.DEPRECATION_MISMATCH, position(),
-                        "Class " + qualifiedName()
-                        + ": @Deprecated annotation and @deprecated comment do not match");
-            }
-
-            mIsDeprecated = commentDeprecated | annotationDeprecated;
-            mDeprecatedKnown = true;
-        }
-        return mIsDeprecated;
-    }
-
-    public TagInfo[] deprecatedTags()
-    {
-        // Should we also do the interfaces?
-        return comment().deprecatedTags();
-    }
-
-    public MethodInfo[] methods()
-    {
-        if (mMethods == null) {
-            TreeMap<String,MethodInfo> all = new TreeMap<String,MethodInfo>();
-
-            ClassInfo[] ifaces = interfaces();
-            for (ClassInfo iface: ifaces) {
-                if (iface != null) {
-                    MethodInfo[] inhereted = iface.methods();
-                    for (MethodInfo method: inhereted) {
-                        String key = method.name() + method.signature();
-                        all.put(key, method);
-                    }
-                }
-            }
-
-            ClassInfo superclass = superclass();
-            if (superclass != null) {
-                MethodInfo[] inhereted = superclass.methods();
-                for (MethodInfo method: inhereted) {
-                    String key = method.name() + method.signature();
-                    all.put(key, method);
-                }
-            }
-
-            MethodInfo[] methods = selfMethods();
-            for (MethodInfo method: methods) {
-                String key = method.name() + method.signature();
-                MethodInfo old = all.put(key, method);
-            }
-
-            mMethods = all.values().toArray(new MethodInfo[all.size()]);
-        }
-        return mMethods;
-    }
-
-    public MethodInfo[] annotationElements()
-    {
-        return mAnnotationElements;
-    }
-
-    public AnnotationInstanceInfo[] annotations()
-    {
-        return mAnnotations;
-    }
-
-    private static void addFields(ClassInfo cl, TreeMap<String,FieldInfo> all)
-    {
-        FieldInfo[] fields = cl.fields();
-        int N = fields.length;
-        for (int i=0; i<N; i++) {
-            FieldInfo f = fields[i];
-            all.put(f.name(), f);
-        }
-    }
-
-    public FieldInfo[] fields()
-    {
-        if (mFields == null) {
-            int N;
-            TreeMap<String,FieldInfo> all = new TreeMap<String,FieldInfo>();
-
-            ClassInfo[] interfaces = interfaces();
-            N = interfaces.length;
-            for (int i=0; i<N; i++) {
-                addFields(interfaces[i], all);
-            }
-
-            ClassInfo superclass = superclass();
-            if (superclass != null) {
-                addFields(superclass, all);
-            }
-
-            FieldInfo[] fields = selfFields();
-            N = fields.length;
-            for (int i=0; i<N; i++) {
-                FieldInfo f = fields[i];
-                if (!f.isHidden()) {
-                    String key = f.name();
-                    all.put(key, f);
-                }
-            }
-
-            mFields = all.values().toArray(new FieldInfo[0]);
-        }
-        return mFields;
-    }
-
-    public void gatherFields(ClassInfo owner, ClassInfo cl, HashMap<String,FieldInfo> fields) {
-        FieldInfo[] flds = cl.selfFields();
-        for (FieldInfo f: flds) {
-            if (f.checkLevel()) {
-                fields.put(f.name(), f.cloneForClass(owner));
-            }
-        }
-    }
-
-    public FieldInfo[] selfFields()
-    {
-        if (mSelfFields == null) {
-            HashMap<String,FieldInfo> fields = new HashMap<String,FieldInfo>();
-            // our hidden parents
-            if (mRealSuperclass != null && !mRealSuperclass.checkLevel()) {
-                gatherFields(this, mRealSuperclass, fields);
-            }
-            for (ClassInfo iface: mRealInterfaces) {
-                if (!iface.checkLevel()) {
-                    gatherFields(this, iface, fields);
-                }
-            }
-            // mine
-            FieldInfo[] selfFields = mAllSelfFields;
-            for (int i=0; i<selfFields.length; i++) {
-                FieldInfo f = selfFields[i];
-                if (!f.isHidden()) {
-                    fields.put(f.name(), f);
-                }
-            }
-            // combine and return in
-            mSelfFields = fields.values().toArray(new FieldInfo[fields.size()]);
-            Arrays.sort(mSelfFields, FieldInfo.comparator);
-        }
-        return mSelfFields;
-    }
-
-    public FieldInfo[] allSelfFields() {
-        return mAllSelfFields;
-    }
-
-    public void gatherMethods(ClassInfo owner, ClassInfo cl, HashMap<String,MethodInfo> methods) {
-        MethodInfo[] meth = cl.selfMethods();
-        for (MethodInfo m: meth) {
-            if (m.checkLevel()) {
-                methods.put(m.name()+m.signature(), m.cloneForClass(owner));
-            }
-        }
-    }
-
-    public MethodInfo[] selfMethods()
-    {
-        if (mSelfMethods == null) {
-            HashMap<String,MethodInfo> methods = new HashMap<String,MethodInfo>();
-            // our hidden parents
-            if (mRealSuperclass != null && !mRealSuperclass.checkLevel()) {
-                gatherMethods(this, mRealSuperclass, methods);
-            }
-            for (ClassInfo iface: mRealInterfaces) {
-                if (!iface.checkLevel()) {
-                    gatherMethods(this, iface, methods);
-                }
-            }
-            // mine
-            MethodInfo[] selfMethods = mAllSelfMethods;
-            for (int i=0; i<selfMethods.length; i++) {
-                MethodInfo m = selfMethods[i];
-                if (m.checkLevel()) {
-                    methods.put(m.name()+m.signature(), m);
-                }
-            }
-            // combine and return it
-            mSelfMethods = methods.values().toArray(new MethodInfo[methods.size()]);
-            Arrays.sort(mSelfMethods, MethodInfo.comparator);
-        }
-        return mSelfMethods;
-    }
-
-    public MethodInfo[] allSelfMethods() {
-        return mAllSelfMethods;
-    }
-
-    public void addMethod(MethodInfo method) {
-        MethodInfo[] methods = new MethodInfo[mAllSelfMethods.length + 1];
-        int i = 0;
-        for (MethodInfo m : mAllSelfMethods) {
-            methods[i] = m;
-            i++;
-        }
-        methods[i] = method;
-        mAllSelfMethods = methods;
-    }
-
-    public AttributeInfo[] selfAttributes()
-    {
-        if (mSelfAttributes == null) {
-            TreeMap<FieldInfo,AttributeInfo> attrs = new TreeMap<FieldInfo,AttributeInfo>();
-
-            // the ones in the class comment won't have any methods
-            for (AttrTagInfo tag: comment().attrTags()) {
-                FieldInfo field = tag.reference();
-                if (field != null) {
-                    AttributeInfo attr = attrs.get(field);
-                    if (attr == null) {
-                        attr = new AttributeInfo(this, field);
-                        attrs.put(field, attr);
-                    }
-                    tag.setAttribute(attr);
-                }
-            }
-
-            // in the methods
-            for (MethodInfo m: selfMethods()) {
-                for (AttrTagInfo tag: m.comment().attrTags()) {
-                    FieldInfo field = tag.reference();
-                    if (field != null) {
-                        AttributeInfo attr = attrs.get(field);
-                        if (attr == null) {
-                            attr = new AttributeInfo(this, field);
-                            attrs.put(field, attr);
-                        }
-                        tag.setAttribute(attr);
-                        attr.methods.add(m);
-                    }
-                }
-            }
-
-            //constructors too
-           for (MethodInfo m: constructors()) {
-              for (AttrTagInfo tag: m.comment().attrTags()) {
-                  FieldInfo field = tag.reference();
-                  if (field != null) {
-                      AttributeInfo attr = attrs.get(field);
-                      if (attr == null) {
-                          attr = new AttributeInfo(this, field);
-                          attrs.put(field, attr);
-                      }
-                      tag.setAttribute(attr);
-                      attr.methods.add(m);
-                  }
-              }
-          }
-
-            mSelfAttributes = attrs.values().toArray(new AttributeInfo[attrs.size()]);
-            Arrays.sort(mSelfAttributes, AttributeInfo.comparator);
-        }
-        return mSelfAttributes;
-    }
-
-    public FieldInfo[] enumConstants()
-    {
-        return mEnumConstants;
-    }
-
-    public ClassInfo superclass()
-    {
-        if (!mSuperclassInit) {
-            if (this.checkLevel()) {
-                // rearrange our little inheritance hierarchy, because we need to hide classes that
-                // don't pass checkLevel
-                ClassInfo superclass = mRealSuperclass;
-                while (superclass != null && !superclass.checkLevel()) {
-                    superclass = superclass.mRealSuperclass;
-                }
-                mSuperclass = superclass;
-            } else {
-                mSuperclass = mRealSuperclass;
-            }
-        }
-        return mSuperclass;
-    }
-
-    public ClassInfo realSuperclass()
-    {
-        return mRealSuperclass;
-    }
-
-    /** always the real superclass, not the collapsed one we get through superclass(),
-     * also has the type parameter info if it's generic.
-     */
-    public TypeInfo superclassType()
-    {
-        return mRealSuperclassType;
-    }
-
-    public TypeInfo asTypeInfo()
-    {
-        return mTypeInfo;
-    }
-
-    TypeInfo[] interfaceTypes()
-    {
-        ClassInfo[] infos = interfaces();
-        int len = infos.length;
-        TypeInfo[] types = new TypeInfo[len];
-        for (int i=0; i<len; i++) {
-            types[i] = infos[i].asTypeInfo();
-        }
-        return types;
-    }
-
-    public String htmlPage()
-    {
-        String s = containingPackage().name();
-        s = s.replace('.', '/');
-        s += '/';
-        s += name();
-        s += ".html";
-        s = DroidDoc.javadocDir + s;
-        return s;
-    }
-
-    /** Even indirectly */
-    public boolean isDerivedFrom(ClassInfo cl)
-    {
-        ClassInfo dad = this.superclass();
-        if (dad != null) {
-            if (dad.equals(cl)) {
-                return true;
-            } else {
-                if (dad.isDerivedFrom(cl)) {
-                    return true;
-                }
-            }
-        }
-        for (ClassInfo iface: interfaces()) {
-            if (iface.equals(cl)) {
-                return true;
-            } else {
-                if (iface.isDerivedFrom(cl)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    public void makeKeywordEntries(List<KeywordEntry> keywords)
-    {
-        if (!checkLevel()) {
-            return;
-        }
-
-        String htmlPage = htmlPage();
-        String qualifiedName = qualifiedName();
-
-        keywords.add(new KeywordEntry(name(), htmlPage,
-                "class in " + containingPackage().name()));
-
-        FieldInfo[] fields = selfFields();
-        FieldInfo[] enumConstants = enumConstants();
-        MethodInfo[] ctors = constructors();
-        MethodInfo[] methods = selfMethods();
-
-        // enum constants
-        for (FieldInfo field: enumConstants()) {
-            if (field.checkLevel()) {
-                keywords.add(new KeywordEntry(field.name(),
-                            htmlPage + "#" + field.anchor(),
-                            "enum constant in " + qualifiedName));
-            }
-        }
-
-        // constants
-        for (FieldInfo field: fields) {
-            if (field.isConstant() && field.checkLevel()) {
-                keywords.add(new KeywordEntry(field.name(),
-                            htmlPage + "#" + field.anchor(),
-                            "constant in " + qualifiedName));
-            }
-        }
-
-        // fields
-        for (FieldInfo field: fields) {
-            if (!field.isConstant() && field.checkLevel()) {
-                keywords.add(new KeywordEntry(field.name(),
-                            htmlPage + "#" + field.anchor(),
-                            "field in " + qualifiedName));
-            }
-        }
-
-        // public constructors
-        for (MethodInfo m: ctors) {
-            if (m.isPublic() && m.checkLevel()) {
-                keywords.add(new KeywordEntry(m.name() + m.prettySignature(),
-                            htmlPage + "#" + m.anchor(),
-                            "constructor in " + qualifiedName));
-            }
-        }
-
-        // protected constructors
-        if (DroidDoc.checkLevel(DroidDoc.SHOW_PROTECTED)) {
-            for (MethodInfo m: ctors) {
-                if (m.isProtected() && m.checkLevel()) {
-                    keywords.add(new KeywordEntry(m.name() + m.prettySignature(),
-                                htmlPage + "#" + m.anchor(),
-                                "constructor in " + qualifiedName));
-                }
-            }
-        }
-
-        // package private constructors
-        if (DroidDoc.checkLevel(DroidDoc.SHOW_PACKAGE)) {
-            for (MethodInfo m: ctors) {
-                if (m.isPackagePrivate() && m.checkLevel()) {
-                    keywords.add(new KeywordEntry(m.name() + m.prettySignature(),
-                                htmlPage + "#" + m.anchor(),
-                                "constructor in " + qualifiedName));
-                }
-            }
-        }
-
-        // private constructors
-        if (DroidDoc.checkLevel(DroidDoc.SHOW_PRIVATE)) {
-            for (MethodInfo m: ctors) {
-                if (m.isPrivate() && m.checkLevel()) {
-                    keywords.add(new KeywordEntry(m.name() + m.prettySignature(),
-                                htmlPage + "#" + m.anchor(),
-                                "constructor in " + qualifiedName));
-                }
-            }
-        }
-
-        // public methods
-        for (MethodInfo m: methods) {
-            if (m.isPublic() && m.checkLevel()) {
-                keywords.add(new KeywordEntry(m.name() + m.prettySignature(),
-                            htmlPage + "#" + m.anchor(),
-                            "method in " + qualifiedName));
-            }
-        }
-
-        // protected methods
-        if (DroidDoc.checkLevel(DroidDoc.SHOW_PROTECTED)) {
-            for (MethodInfo m: methods) {
-                if (m.isProtected() && m.checkLevel()) {
-                    keywords.add(new KeywordEntry(m.name() + m.prettySignature(),
-                                htmlPage + "#" + m.anchor(),
-                                "method in " + qualifiedName));
-                }
-            }
-        }
-
-        // package private methods
-        if (DroidDoc.checkLevel(DroidDoc.SHOW_PACKAGE)) {
-            for (MethodInfo m: methods) {
-                if (m.isPackagePrivate() && m.checkLevel()) {
-                    keywords.add(new KeywordEntry(m.name() + m.prettySignature(),
-                                htmlPage + "#" + m.anchor(),
-                                "method in " + qualifiedName));
-                }
-            }
-        }
-
-        // private methods
-        if (DroidDoc.checkLevel(DroidDoc.SHOW_PRIVATE)) {
-            for (MethodInfo m: methods) {
-                if (m.isPrivate() && m.checkLevel()) {
-                    keywords.add(new KeywordEntry(m.name() + m.prettySignature(),
-                                htmlPage + "#" + m.anchor(),
-                                "method in " + qualifiedName));
-                }
-            }
-        }
-    }
-
-    public void makeLink(HDF data, String base)
-    {
-        data.setValue(base + ".label", this.name());
-        if (!this.isPrimitive() && this.isIncluded() && this.checkLevel()) {
-            data.setValue(base + ".link", this.htmlPage());
-        }
-    }
-
-    public static void makeLinkListHDF(HDF data, String base, ClassInfo[] classes) {
-        final int N = classes.length;
-        for (int i=0; i<N; i++) {
-            ClassInfo cl = classes[i];
-            if (cl.checkLevel()) {
-                cl.asTypeInfo().makeHDF(data, base + "." + i);
-            }
-        }
-    }
-
-    /**
-     * Used in lists of this class (packages, nested classes, known subclasses)
-     */
-    public void makeShortDescrHDF(HDF data, String base)
-    {
-        mTypeInfo.makeHDF(data, base + ".type");
-        data.setValue(base + ".kind", this.kind());
-        TagInfo.makeHDF(data, base + ".shortDescr", this.firstSentenceTags());
-        TagInfo.makeHDF(data, base + ".deprecated", deprecatedTags());
-        data.setValue(base + ".since", getSince());
-    }
-
-    /**
-     * Turns into the main class page
-     */
-    public void makeHDF(HDF data)
-    {
-        int i, j, n;
-        String name = name();
-        String qualified = qualifiedName();
-        AttributeInfo[] selfAttributes = selfAttributes();
-        MethodInfo[] methods = selfMethods();
-        FieldInfo[] fields = selfFields();
-        FieldInfo[] enumConstants = enumConstants();
-        MethodInfo[] ctors = constructors();
-        ClassInfo[] inners = innerClasses();
-
-        // class name
-        mTypeInfo.makeHDF(data, "class.type");
-        mTypeInfo.makeQualifiedHDF(data, "class.qualifiedType");
-        data.setValue("class.name", name);
-        data.setValue("class.qualified", qualified);
-        String scope = "";
-        if (isProtected()) {
-            data.setValue("class.scope", "protected");
-        }
-        else if (isPublic()) {
-            data.setValue("class.scope", "public");
-        }
-        if (isStatic()) {
-            data.setValue("class.static", "static");
-        }
-        if (isFinal()) {
-            data.setValue("class.final", "final");
-        }
-        if (isAbstract() && !isInterface()) {
-            data.setValue("class.abstract", "abstract");
-        }
-
-        // class info
-        String kind = kind();
-        if (kind != null) {
-            data.setValue("class.kind", kind);
-        }
-        data.setValue("class.since", getSince());
-
-        // the containing package -- note that this can be passed to type_link,
-        // but it also contains the list of all of the packages
-        containingPackage().makeClassLinkListHDF(data, "class.package");
-
-        // inheritance hierarchy
-        Vector<ClassInfo> superClasses = new Vector<ClassInfo>();
-        superClasses.add(this);
-        ClassInfo supr = superclass();
-        while (supr != null) {
-            superClasses.add(supr);
-            supr = supr.superclass();
-        }
-        n = superClasses.size();
-        for (i=0; i<n; i++) {
-            supr = superClasses.elementAt(n-i-1);
-
-            supr.asTypeInfo().makeQualifiedHDF(data, "class.inheritance." + i + ".class");
-            supr.asTypeInfo().makeHDF(data, "class.inheritance." + i + ".short_class");
-            j = 0;
-            for (TypeInfo t: supr.interfaceTypes()) {
-                t.makeHDF(data, "class.inheritance." + i + ".interfaces." + j);
-                j++;
-            }
-        }
-
-        // class description
-        TagInfo.makeHDF(data, "class.descr", inlineTags());
-        TagInfo.makeHDF(data, "class.seeAlso", comment().seeTags());
-        TagInfo.makeHDF(data, "class.deprecated", deprecatedTags());
-
-        // known subclasses
-        TreeMap<String, ClassInfo> direct = new TreeMap<String, ClassInfo>();
-        TreeMap<String, ClassInfo> indirect = new TreeMap<String, ClassInfo>();
-        ClassInfo[] all = Converter.rootClasses();
-        for (ClassInfo cl: all) {
-            if (cl.superclass() != null && cl.superclass().equals(this)) {
-                direct.put(cl.name(), cl);
-            }
-            else if (cl.isDerivedFrom(this)) {
-                indirect.put(cl.name(), cl);
-            }
-        }
-        // direct
-        i = 0;
-        for (ClassInfo cl: direct.values()) {
-            if (cl.checkLevel()) {
-                cl.makeShortDescrHDF(data, "class.subclasses.direct." + i);
-            }
-            i++;
-        }
-        // indirect
-        i = 0;
-        for (ClassInfo cl: indirect.values()) {
-            if (cl.checkLevel()) {
-                cl.makeShortDescrHDF(data, "class.subclasses.indirect." + i);
-            }
-            i++;
-        }
-
-        // nested classes
-        i=0;
-        for (ClassInfo inner: inners) {
-            if (inner.checkLevel()) {
-                inner.makeShortDescrHDF(data, "class.inners." + i);
-            }
-            i++;
-        }
-
-        // enum constants
-        i=0;
-        for (FieldInfo field: enumConstants) {
-            if (field.isConstant()) {
-                field.makeHDF(data, "class.enumConstants." + i);
-                i++;
-            }
-        }
-
-        // constants
-        i=0;
-        for (FieldInfo field: fields) {
-            if (field.isConstant()) {
-                field.makeHDF(data, "class.constants." + i);
-                i++;
-            }
-        }
-
-        // fields
-        i=0;
-        for (FieldInfo field: fields) {
-            if (!field.isConstant()) {
-                field.makeHDF(data, "class.fields." + i);
-                i++;
-            }
-        }
-
-        // public constructors
-        i=0;
-        for (MethodInfo ctor: ctors) {
-            if (ctor.isPublic()) {
-                ctor.makeHDF(data, "class.ctors.public." + i);
-                i++;
-            }
-        }
-
-        // protected constructors
-        if (DroidDoc.checkLevel(DroidDoc.SHOW_PROTECTED)) {
-            i=0;
-            for (MethodInfo ctor: ctors) {
-                if (ctor.isProtected()) {
-                    ctor.makeHDF(data, "class.ctors.protected." + i);
-                    i++;
-                }
-            }
-        }
-
-        // package private constructors
-        if (DroidDoc.checkLevel(DroidDoc.SHOW_PACKAGE)) {
-            i=0;
-            for (MethodInfo ctor: ctors) {
-                if (ctor.isPackagePrivate()) {
-                    ctor.makeHDF(data, "class.ctors.package." + i);
-                    i++;
-                }
-            }
-        }
-
-        // private constructors
-        if (DroidDoc.checkLevel(DroidDoc.SHOW_PRIVATE)) {
-            i=0;
-            for (MethodInfo ctor: ctors) {
-                if (ctor.isPrivate()) {
-                    ctor.makeHDF(data, "class.ctors.private." + i);
-                    i++;
-                }
-            }
-        }
-
-        // public methods
-        i=0;
-        for (MethodInfo method: methods) {
-            if (method.isPublic()) {
-                method.makeHDF(data, "class.methods.public." + i);
-                i++;
-            }
-        }
-
-        // protected methods
-        if (DroidDoc.checkLevel(DroidDoc.SHOW_PROTECTED)) {
-            i=0;
-            for (MethodInfo method: methods) {
-                if (method.isProtected()) {
-                    method.makeHDF(data, "class.methods.protected." + i);
-                    i++;
-                }
-            }
-        }
-
-        // package private methods
-        if (DroidDoc.checkLevel(DroidDoc.SHOW_PACKAGE)) {
-            i=0;
-            for (MethodInfo method: methods) {
-                if (method.isPackagePrivate()) {
-                    method.makeHDF(data, "class.methods.package." + i);
-                    i++;
-                }
-            }
-        }
-
-        // private methods
-        if (DroidDoc.checkLevel(DroidDoc.SHOW_PRIVATE)) {
-            i=0;
-            for (MethodInfo method: methods) {
-                if (method.isPrivate()) {
-                    method.makeHDF(data, "class.methods.private." + i);
-                    i++;
-                }
-            }
-        }
-
-        // xml attributes
-        i=0;
-        for (AttributeInfo attr: selfAttributes) {
-            if (attr.checkLevel()) {
-                attr.makeHDF(data, "class.attrs." + i);
-                i++;
-            }
-        }
-
-        // inherited methods
-        Set<ClassInfo> interfaces = new TreeSet<ClassInfo>();
-        addInterfaces(interfaces(), interfaces);
-        ClassInfo cl = superclass();
-        i=0;
-        while (cl != null) {
-            addInterfaces(cl.interfaces(), interfaces);
-            makeInheritedHDF(data, i, cl);
-            cl = cl.superclass();
-            i++;
-        }
-        for (ClassInfo iface: interfaces) {
-            makeInheritedHDF(data, i, iface);
-            i++;
-        }
-    }
-
-    private static void addInterfaces(ClassInfo[] ifaces, Set<ClassInfo> out)
-    {
-        for (ClassInfo cl: ifaces) {
-            out.add(cl);
-            addInterfaces(cl.interfaces(), out);
-        }
-    }
-
-    private static void makeInheritedHDF(HDF data, int index, ClassInfo cl)
-    {
-        int i;
-
-        String base = "class.inherited." + index;
-        data.setValue(base + ".qualified", cl.qualifiedName());
-        if (cl.checkLevel()) {
-            data.setValue(base + ".link", cl.htmlPage());
-        }
-        String kind = cl.kind();
-        if (kind != null) {
-            data.setValue(base + ".kind", kind);
-        }
-
-        if (cl.mIsIncluded) {
-            data.setValue(base + ".included", "true");
-        }
-
-        // xml attributes
-        i=0;
-        for (AttributeInfo attr: cl.selfAttributes()) {
-            attr.makeHDF(data, base + ".attrs." + i);
-            i++;
-        }
-
-        // methods
-        i=0;
-        for (MethodInfo method: cl.selfMethods()) {
-            method.makeHDF(data, base + ".methods." + i);
-            i++;
-        }
-
-        // fields
-        i=0;
-        for (FieldInfo field: cl.selfFields()) {
-            if (!field.isConstant()) {
-                field.makeHDF(data, base + ".fields." + i);
-                i++;
-            }
-        }
-
-        // constants
-        i=0;
-        for (FieldInfo field: cl.selfFields()) {
-            if (field.isConstant()) {
-                field.makeHDF(data, base + ".constants." + i);
-                i++;
-            }
-        }
-    }
-
-    @Override
-    public boolean isHidden()
-    {
-        int val = mHidden;
-        if (val >= 0) {
-            return val != 0;
-        } else {
-            boolean v = isHiddenImpl();
-            mHidden = v ? 1 : 0;
-            return v;
-        }
-    }
-
-    public boolean isHiddenImpl()
-    {
-        ClassInfo cl = this;
-        while (cl != null) {
-            PackageInfo pkg = cl.containingPackage();
-            if (pkg != null && pkg.isHidden()) {
-                return true;
-            }
-            if (cl.comment().isHidden()) {
-                return true;
-            }
-            cl = cl.containingClass();
-        }
-        return false;
-    }
-
-    private MethodInfo matchMethod(MethodInfo[] methods, String name,
-                                    String[] params, String[] dimensions)
-    {
-        int len = methods.length;
-        for (int i=0; i<len; i++) {
-            MethodInfo method = methods[i];
-            if (method.name().equals(name)) {
-                if (params == null) {
-                    return method;
-                } else {
-                    if (method.matchesParams(params, dimensions)) {
-                        return method;
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    public MethodInfo findMethod(String name,
-                                    String[] params, String[] dimensions)
-    {
-        // first look on our class, and our superclasses
-
-        // for methods
-        MethodInfo rv;
-        rv = matchMethod(methods(), name, params, dimensions);
-
-        if (rv != null) {
-            return rv;
-        }
-
-        // for constructors
-        rv = matchMethod(constructors(), name, params, dimensions);
-        if (rv != null) {
-            return rv;
-        }
-
-        // then recursively look at our containing class
-        ClassInfo containing = containingClass();
-        if (containing != null) {
-            return containing.findMethod(name, params, dimensions);
-        }
-
-        return null;
-    }
-
-    private ClassInfo searchInnerClasses(String[] nameParts, int index)
-    {
-        String part = nameParts[index];
-
-        ClassInfo[] inners = mInnerClasses;
-        for (ClassInfo in: inners) {
-            String[] innerParts = in.nameParts();
-            if (part.equals(innerParts[innerParts.length-1])) {
-                if (index == nameParts.length-1) {
-                    return in;
-                } else {
-                    return in.searchInnerClasses(nameParts, index+1);
-                }
-            }
-        }
-        return null;
-    }
-
-    public ClassInfo extendedFindClass(String className)
-    {
-        // ClassDoc.findClass has this bug that we're working around here:
-        // If you have a class PackageManager with an inner class PackageInfo
-        // and you call it with "PackageInfo" it doesn't find it.
-        return searchInnerClasses(className.split("\\."), 0);
-    }
-
-    public ClassInfo findClass(String className)
-    {
-        return Converter.obtainClass(mClass.findClass(className));
-    }
-
-    public ClassInfo findInnerClass(String className)
-    {
-        // ClassDoc.findClass won't find inner classes.  To deal with that,
-        // we try what they gave us first, but if that didn't work, then
-        // we see if there are any periods in className, and start searching
-        // from there.
-        String[] nodes = className.split("\\.");
-        ClassDoc cl = mClass;
-        for (String n: nodes) {
-            cl = cl.findClass(n);
-            if (cl == null) {
-                return null;
-            }
-        }
-        return Converter.obtainClass(cl);
-    }
-
-    public FieldInfo findField(String name)
-    {
-        // first look on our class, and our superclasses
-        for (FieldInfo f: fields()) {
-            if (f.name().equals(name)) {
-                return f;
-            }
-        }
-
-        // then look at our enum constants (these are really fields, maybe
-        // they should be mixed into fields().  not sure)
-        for (FieldInfo f: enumConstants()) {
-            if (f.name().equals(name)) {
-                return f;
-            }
-        }
-
-        // then recursively look at our containing class
-        ClassInfo containing = containingClass();
-        if (containing != null) {
-            return containing.findField(name);
-        }
-
-        return null;
-    }
-
-    public static ClassInfo[] sortByName(ClassInfo[] classes)
-    {
-        int i;
-        Sorter[] sorted = new Sorter[classes.length];
-        for (i=0; i<sorted.length; i++) {
-            ClassInfo cl = classes[i];
-            sorted[i] = new Sorter(cl.name(), cl);
-        }
-
-        Arrays.sort(sorted);
-
-        ClassInfo[] rv = new ClassInfo[classes.length];
-        for (i=0; i<rv.length; i++) {
-            rv[i] = (ClassInfo)sorted[i].data;
-        }
-
-        return rv;
-    }
-
-    public boolean equals(ClassInfo that)
-    {
-        if (that != null) {
-            return this.qualifiedName().equals(that.qualifiedName());
-        } else {
-            return false;
-        }
-    }
-
-    public void setNonWrittenConstructors(MethodInfo[] nonWritten) {
-        mNonWrittenConstructors = nonWritten;
-    }
-
-    public MethodInfo[] getNonWrittenConstructors() {
-        return mNonWrittenConstructors;
-    }
-
-    public String kind()
-    {
-        if (isOrdinaryClass()) {
-            return "class";
-        }
-        else if (isInterface()) {
-            return "interface";
-        }
-        else if (isEnum()) {
-            return "enum";
-        }
-        else if (isError()) {
-            return "class";
-        }
-        else if (isException()) {
-            return "class";
-        }
-        else if (isAnnotation()) {
-            return "@interface";
-        }
-        return null;
-    }
-
-    public void setHiddenMethods(MethodInfo[] mInfo){
-        mHiddenMethods = mInfo;
-    }
-    public MethodInfo[] getHiddenMethods(){
-        return mHiddenMethods;
-    }
-    @Override
-    public String toString(){
-        return this.qualifiedName();
-    }
-
-    public void setReasonIncluded(String reason) {
-        mReasonIncluded = reason;
-    }
-
-    public String getReasonIncluded() {
-        return mReasonIncluded;
-    }
-
-    private ClassDoc mClass;
-
-    // ctor
-    private boolean mIsPublic;
-    private boolean mIsProtected;
-    private boolean mIsPackagePrivate;
-    private boolean mIsPrivate;
-    private boolean mIsStatic;
-    private boolean mIsInterface;
-    private boolean mIsAbstract;
-    private boolean mIsOrdinaryClass;
-    private boolean mIsException;
-    private boolean mIsError;
-    private boolean mIsEnum;
-    private boolean mIsAnnotation;
-    private boolean mIsFinal;
-    private boolean mIsIncluded;
-    private String mName;
-    private String mQualifiedName;
-    private String mQualifiedTypeName;
-    private boolean mIsPrimitive;
-    private TypeInfo mTypeInfo;
-    private String[] mNameParts;
-
-    // init
-    private ClassInfo[] mRealInterfaces;
-    private ClassInfo[] mInterfaces;
-    private TypeInfo[] mRealInterfaceTypes;
-    private ClassInfo[] mInnerClasses;
-    private MethodInfo[] mAllConstructors;
-    private MethodInfo[] mAllSelfMethods;
-    private MethodInfo[] mAnnotationElements; // if this class is an annotation
-    private FieldInfo[] mAllSelfFields;
-    private FieldInfo[] mEnumConstants;
-    private PackageInfo mContainingPackage;
-    private ClassInfo mContainingClass;
-    private ClassInfo mRealSuperclass;
-    private TypeInfo mRealSuperclassType;
-    private ClassInfo mSuperclass;
-    private AnnotationInstanceInfo[] mAnnotations;
-    private boolean mSuperclassInit;
-    private boolean mDeprecatedKnown;
-
-    // lazy
-    private MethodInfo[] mConstructors;
-    private ClassInfo[] mRealInnerClasses;
-    private MethodInfo[] mSelfMethods;
-    private FieldInfo[] mSelfFields;
-    private AttributeInfo[] mSelfAttributes;
-    private MethodInfo[] mMethods;
-    private FieldInfo[] mFields;
-    private TypeInfo[] mTypeParameters;
-    private MethodInfo[] mHiddenMethods;
-    private int mHidden = -1;
-    private int mCheckLevel = -1;
-    private String mReasonIncluded;
-    private MethodInfo[] mNonWrittenConstructors;
-    private boolean mIsDeprecated;
-}
diff --git a/tools/droiddoc/src/ClearPage.java b/tools/droiddoc/src/ClearPage.java
deleted file mode 100644
index 184c8b8..0000000
--- a/tools/droiddoc/src/ClearPage.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * 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), "UTF-8");
-            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
deleted file mode 100644
index 553cdf2..0000000
--- a/tools/droiddoc/src/Comment.java
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * 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",
-            "@sdkCurrent",
-            "@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("@pending") || 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 || mText.indexOf("@pending") >= 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
deleted file mode 100644
index b8a3e10..0000000
--- a/tools/droiddoc/src/ContainerInfo.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * 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
deleted file mode 100644
index ee911f4..0000000
--- a/tools/droiddoc/src/Converter.java
+++ /dev/null
@@ -1,755 +0,0 @@
-/*
- * 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()
-    {
-        @Override
-        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;
-        }
-        @Override
-        protected void made(Object o, Object r)
-        {
-            if (mClassesNeedingInit == null) {
-                initClass((ClassDoc)o, (ClassInfo)r);
-                ((ClassInfo)r).init2();
-            }
-        }
-        @Override
-        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()
-    {
-        @Override
-        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()
-    {
-        @Override
-        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()
-    {
-        @Override
-        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()
-    {
-       @Override
-    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;
-       }
-        @Override
-        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()));
-            }
-        }
-        @Override
-        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()
-    {
-        @Override
-        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()
-    {
-        @Override
-        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
deleted file mode 100644
index cc7a8cf..0000000
--- a/tools/droiddoc/src/DocFile.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * 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();
-            FileInputStream is = new FileInputStream(f);
-            InputStreamReader reader = new InputStreamReader(is, "UTF-8");
-            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);
-
-        // write the page using the appropriate root template, based on the 
-        // whichdoc value supplied by build
-        String fromWhichmodule = hdf.getValue("android.whichmodule", "");
-        if (fromWhichmodule.equals("online-pdk")) {
-            //leaving this in just for temporary compatibility with pdk doc
-            hdf.setValue("online-pdk", "true");
-            // add any conditional login for root template here (such as 
-            // for custom left nav based on tab etc. 
-            ClearPage.write(hdf, "docpage.cs", outfile);
-        } else {
-            if (outfile.indexOf("sdk/") != -1) {
-                hdf.setValue("sdk", "true");
-                if ((outfile.indexOf("index.html") != -1) || (outfile.indexOf("features.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("resources/") != -1) {
-                hdf.setValue("resources", "true");
-                ClearPage.write(hdf, "docpage.cs", outfile);
-            } else {
-                ClearPage.write(hdf, "nosidenavpage.cs", outfile);
-            }
-        }
-    } //writePage
-}
diff --git a/tools/droiddoc/src/DocInfo.java b/tools/droiddoc/src/DocInfo.java
deleted file mode 100644
index 3abb367..0000000
--- a/tools/droiddoc/src/DocInfo.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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();
-
-    public void setSince(String since) {
-        mSince = since;
-    }
-
-    public String getSince() {
-        return mSince;
-    }
-
-    private String mRawCommentText;
-    Comment mComment;
-    SourcePositionInfo mPosition;
-    private String mSince;
-}
-
diff --git a/tools/droiddoc/src/DroidDoc.java b/tools/droiddoc/src/DroidDoc.java
deleted file mode 100644
index 4e9d6b1..0000000
--- a/tools/droiddoc/src/DroidDoc.java
+++ /dev/null
@@ -1,1385 +0,0 @@
-/*
- * 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_CONSTANT_TYPE_FEATURE = "android.annotation.SdkConstant.SdkConstantType.FEATURE";
-    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 SinceTagger sinceTagger = new SinceTagger();
-
-    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;
-        boolean noDocs = false;
-        boolean offlineMode = 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];
-            }
-            else if (a[0].equals("-nodocs")) {
-                noDocs = true;
-            }
-            else if (a[0].equals("-since")) {
-                sinceTagger.addVersion(a[1], a[2]);
-            }
-            else if (a[0].equals("-offlinemode")) {
-                offlineMode = true;
-            }
-        }
-
-        // read some prefs from the template
-        if (!readTemplateSettings()) {
-            return false;
-        }
-
-        // Set up the data structures
-        Converter.makeInfo(r);
-
-        if (!noDocs) {
-            long startTime = System.nanoTime();
-
-            // Apply @since tags from the XML file
-            sinceTagger.tagAll(Converter.rootClasses());
-
-            // Files for proofreading
-            if (proofreadFile != null) {
-                Proofread.initProofread(proofreadFile);
-            }
-            if (todoFile != null) {
-                TodoFile.writeTodoFile(todoFile);
-            }
-
-            // HTML Pages
-            if (ClearPage.htmlDir != null) {
-                writeHTMLPages();
-            }
-
-            // Navigation tree
-            NavTree.writeNavTree(javadocDir);
-
-            // Packages Pages
-            writePackages(javadocDir
-                            + (ClearPage.htmlDir!=null
-                                ? "packages" + htmlExtension
-                                : "index" + htmlExtension));
-
-            // Classes
-            writeClassLists();
-            writeClasses();
-            writeHierarchy();
-     //      writeKeywords();
-
-            // Lists for JavaScript
-            writeLists();
-            if (keepListFile != null) {
-                writeKeepList(keepListFile);
-            }
-
-            // Sample Code
-            for (SampleCode sc: sampleCodes) {
-                sc.write(offlineMode);
-            }
-
-            // Index page
-            writeIndex();
-
-            Proofread.finishProofread(proofreadFile);
-
-            if (sdkValuePath != null) {
-                writeSdkValues(sdkValuePath);
-            }
-
-            long time = System.nanoTime() - startTime;
-            System.out.println("DroidDoc took " + (time / 1000000000) + " sec. to write docs to "
-                    + ClearPage.outputDir);
-        }
-
-        // Stubs
-        if (stubsDir != null) {
-            Stubs.writeStubs(stubsDir, apiXML, apiFile, stubPackages);
-        }
-
-        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;
-        }
-        if (option.equals("-nodocs")) {
-            return 1;
-        }
-        if (option.equals("-since")) {
-            return 3;
-        }
-        if (option.equals("-offlinemode")) {
-            return 1;
-        }
-        return 0;
-    }
-
-    public static boolean validOptions(String[][] options, DocErrorReporter r)
-    {
-        for (String[] a: options) {
-            if (a[0].equals("-error") || a[0].equals("-warning")
-                    || a[0].equals("-hide")) {
-                try {
-                    Integer.parseInt(a[1]);
-                }
-                catch (NumberFormatException e) {
-                    r.printError("bad -" + a[0] + " value must be a number: "
-                            + a[1]);
-                    return false;
-                }
-            }
-        }
-
-        return true;
-    }
-
-    public static HDF makeHDF()
-    {
-        HDF data = new HDF();
-
-        for (String[] p: mHDFData) {
-            data.setValue(p[0], p[1]);
-        }
-
-        try {
-            for (String p: ClearPage.hdfFiles) {
-                data.readFile(p);
-            }
-        }
-        catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-
-        return data;
-    }
-
-    public static HDF makePackageHDF()
-    {
-        HDF data = makeHDF();
-        ClassInfo[] classes = Converter.rootClasses();
-
-        SortedMap<String, PackageInfo> sorted = new TreeMap<String, PackageInfo>();
-        for (ClassInfo cl: classes) {
-            PackageInfo pkg = cl.containingPackage();
-            String name;
-            if (pkg == null) {
-                name = "";
-            } else {
-                name = pkg.name();
-            }
-            sorted.put(name, pkg);
-        }
-
-        int i = 0;
-        for (String s: sorted.keySet()) {
-            PackageInfo pkg = sorted.get(s);
-
-            if (pkg.isHidden()) {
-                continue;
-            }
-            Boolean allHidden = true;
-            int pass = 0;
-            ClassInfo[] classesToCheck = null;
-            while (pass < 5 ) {
-                switch(pass) {
-                case 0:
-                    classesToCheck = pkg.ordinaryClasses();
-                    break;
-                case 1:
-                    classesToCheck = pkg.enums();
-                    break;
-                case 2:
-                    classesToCheck = pkg.errors();
-                    break;
-                case 3:
-                    classesToCheck = pkg.exceptions();
-                    break;
-                case 4:
-                    classesToCheck = pkg.interfaces();
-                    break;
-                default:
-                    System.err.println("Error reading package: " + pkg.name());
-                    break;
-                }
-                for (ClassInfo cl : classesToCheck) {
-                    if (!cl.isHidden()) {
-                        allHidden = false;
-                        break;
-                    }
-                }
-                if (!allHidden) {
-                    break;
-                }
-                pass++;
-            }
-            if (allHidden) {
-                continue;
-            }
-
-            data.setValue("reference", "true");
-            data.setValue("docs.packages." + i + ".name", s);
-            data.setValue("docs.packages." + i + ".link", pkg.htmlPage());
-            data.setValue("docs.packages." + i + ".since", pkg.getSince());
-            TagInfo.makeHDF(data, "docs.packages." + i + ".shortDescr",
-                                               pkg.firstSentenceTags());
-            i++;
-        }
-
-        sinceTagger.writeVersionNames(data);
-        return data;
-    }
-
-    public static void writeDirectory(File dir, String relative)
-    {
-        File[] files = dir.listFiles();
-        int i, count = files.length;
-        for (i=0; i<count; i++) {
-            File f = files[i];
-            if (f.isFile()) {
-                String templ = relative + f.getName();
-                int len = templ.length();
-                if (len > 3 && ".cs".equals(templ.substring(len-3))) {
-                    HDF data = makeHDF();
-                    String filename = templ.substring(0,len-3) + htmlExtension;
-                    ClearPage.write(data, templ, filename);
-                }
-                else if (len > 3 && ".jd".equals(templ.substring(len-3))) {
-                    String filename = templ.substring(0,len-3) + htmlExtension;
-                    DocFile.writePage(f.getAbsolutePath(), relative, filename);
-                }
-                else {
-                    ClearPage.copyFile(f, templ);
-                }
-            }
-            else if (f.isDirectory()) {
-                writeDirectory(f, relative + f.getName() + "/");
-            }
-        }
-    }
-
-    public static void writeHTMLPages()
-    {
-        File f = new File(ClearPage.htmlDir);
-        if (!f.isDirectory()) {
-            System.err.println("htmlDir not a directory: " + ClearPage.htmlDir);
-        }
-        writeDirectory(f, "");
-    }
-
-    public static void writeLists()
-    {
-        HDF data = makeHDF();
-
-        ClassInfo[] classes = Converter.rootClasses();
-
-        SortedMap<String, Object> sorted = new TreeMap<String, Object>();
-        for (ClassInfo cl: classes) {
-            if (cl.isHidden()) {
-                continue;
-            }
-            sorted.put(cl.qualifiedName(), cl);
-            PackageInfo pkg = cl.containingPackage();
-            String name;
-            if (pkg == null) {
-                name = "";
-            } else {
-                name = pkg.name();
-            }
-            sorted.put(name, pkg);
-        }
-
-        int i = 0;
-        for (String s: sorted.keySet()) {
-            data.setValue("docs.pages." + i + ".id" , ""+i);
-            data.setValue("docs.pages." + i + ".label" , s);
-
-            Object o = sorted.get(s);
-            if (o instanceof PackageInfo) {
-                PackageInfo pkg = (PackageInfo)o;
-                data.setValue("docs.pages." + i + ".link" , pkg.htmlPage());
-                data.setValue("docs.pages." + i + ".type" , "package");
-            }
-            else if (o instanceof ClassInfo) {
-                ClassInfo cl = (ClassInfo)o;
-                data.setValue("docs.pages." + i + ".link" , cl.htmlPage());
-                data.setValue("docs.pages." + i + ".type" , "class");
-            }
-            i++;
-        }
-
-        ClearPage.write(data, "lists.cs", javadocDir + "lists.js");
-    }
-
-    public static void cantStripThis(ClassInfo cl, HashSet<ClassInfo> notStrippable) {
-        if (!notStrippable.add(cl)) {
-            // slight optimization: if it already contains cl, it already contains
-            // all of cl's parents
-            return;
-        }
-        ClassInfo supr = cl.superclass();
-        if (supr != null) {
-            cantStripThis(supr, notStrippable);
-        }
-        for (ClassInfo iface: cl.interfaces()) {
-            cantStripThis(iface, notStrippable);
-        }
-    }
-
-    private static String getPrintableName(ClassInfo cl) {
-        ClassInfo containingClass = cl.containingClass();
-        if (containingClass != null) {
-            // This is an inner class.
-            String baseName = cl.name();
-            baseName = baseName.substring(baseName.lastIndexOf('.') + 1);
-            return getPrintableName(containingClass) + '$' + baseName;
-        }
-        return cl.qualifiedName();
-    }
-
-    /**
-     * Writes the list of classes that must be present in order to
-     * provide the non-hidden APIs known to javadoc.
-     *
-     * @param filename the path to the file to write the list to
-     */
-    public static void writeKeepList(String filename) {
-        HashSet<ClassInfo> notStrippable = new HashSet<ClassInfo>();
-        ClassInfo[] all = Converter.allClasses();
-        Arrays.sort(all); // just to make the file a little more readable
-
-        // If a class is public and not hidden, then it and everything it derives
-        // from cannot be stripped.  Otherwise we can strip it.
-        for (ClassInfo cl: all) {
-            if (cl.isPublic() && !cl.isHidden()) {
-                cantStripThis(cl, notStrippable);
-            }
-        }
-        PrintStream stream = null;
-        try {
-            stream = new PrintStream(filename);
-            for (ClassInfo cl: notStrippable) {
-                stream.println(getPrintableName(cl));
-            }
-        }
-        catch (FileNotFoundException e) {
-            System.err.println("error writing file: " + filename);
-        }
-        finally {
-            if (stream != null) {
-                stream.close();
-            }
-        }
-    }
-
-    private static PackageInfo[] sVisiblePackages = null;
-    public static PackageInfo[] choosePackages() {
-        if (sVisiblePackages != null) {
-            return sVisiblePackages;
-        }
-
-        ClassInfo[] classes = Converter.rootClasses();
-        SortedMap<String, PackageInfo> sorted = new TreeMap<String, PackageInfo>();
-        for (ClassInfo cl: classes) {
-            PackageInfo pkg = cl.containingPackage();
-            String name;
-            if (pkg == null) {
-                name = "";
-            } else {
-                name = pkg.name();
-            }
-            sorted.put(name, pkg);
-        }
-
-        ArrayList<PackageInfo> result = new ArrayList();
-
-        for (String s: sorted.keySet()) {
-            PackageInfo pkg = sorted.get(s);
-
-            if (pkg.isHidden()) {
-                continue;
-            }
-            Boolean allHidden = true;
-            int pass = 0;
-            ClassInfo[] classesToCheck = null;
-            while (pass < 5 ) {
-                switch(pass) {
-                case 0:
-                    classesToCheck = pkg.ordinaryClasses();
-                    break;
-                case 1:
-                    classesToCheck = pkg.enums();
-                    break;
-                case 2:
-                    classesToCheck = pkg.errors();
-                    break;
-                case 3:
-                    classesToCheck = pkg.exceptions();
-                    break;
-                case 4:
-                    classesToCheck = pkg.interfaces();
-                    break;
-                default:
-                    System.err.println("Error reading package: " + pkg.name());
-                    break;
-                }
-                for (ClassInfo cl : classesToCheck) {
-                    if (!cl.isHidden()) {
-                        allHidden = false;
-                        break;
-                    }
-                }
-                if (!allHidden) {
-                    break;
-                }
-                pass++;
-            }
-            if (allHidden) {
-                continue;
-            }
-
-            result.add(pkg);
-        }
-
-        sVisiblePackages = result.toArray(new PackageInfo[result.size()]);
-        return sVisiblePackages;
-    }
-
-    public static void writePackages(String filename)
-    {
-        HDF data = makePackageHDF();
-
-        int i = 0;
-        for (PackageInfo pkg: choosePackages()) {
-            writePackage(pkg);
-
-            data.setValue("docs.packages." + i + ".name", pkg.name());
-            data.setValue("docs.packages." + i + ".link", pkg.htmlPage());
-            TagInfo.makeHDF(data, "docs.packages." + i + ".shortDescr",
-                            pkg.firstSentenceTags());
-
-            i++;
-        }
-
-        setPageTitle(data, "Package Index");
-
-        TagInfo.makeHDF(data, "root.descr",
-                Converter.convertTags(root.inlineTags(), null));
-
-        ClearPage.write(data, "packages.cs", filename);
-        ClearPage.write(data, "package-list.cs", javadocDir + "package-list");
-
-        Proofread.writePackages(filename,
-                Converter.convertTags(root.inlineTags(), null));
-    }
-
-    public static void writePackage(PackageInfo pkg)
-    {
-        // these this and the description are in the same directory,
-        // so it's okay
-        HDF data = makePackageHDF();
-
-        String name = pkg.name();
-
-        data.setValue("package.name", name);
-        data.setValue("package.since", pkg.getSince());
-        data.setValue("package.descr", "...description...");
-
-        makeClassListHDF(data, "package.interfaces",
-                         ClassInfo.sortByName(pkg.interfaces()));
-        makeClassListHDF(data, "package.classes",
-                         ClassInfo.sortByName(pkg.ordinaryClasses()));
-        makeClassListHDF(data, "package.enums",
-                         ClassInfo.sortByName(pkg.enums()));
-        makeClassListHDF(data, "package.exceptions",
-                         ClassInfo.sortByName(pkg.exceptions()));
-        makeClassListHDF(data, "package.errors",
-                         ClassInfo.sortByName(pkg.errors()));
-        TagInfo.makeHDF(data, "package.shortDescr",
-                         pkg.firstSentenceTags());
-        TagInfo.makeHDF(data, "package.descr", pkg.inlineTags());
-
-        String filename = pkg.htmlPage();
-        setPageTitle(data, name);
-        ClearPage.write(data, "package.cs", filename);
-
-        filename = pkg.fullDescriptionHtmlPage();
-        setPageTitle(data, name + " Details");
-        ClearPage.write(data, "package-descr.cs", filename);
-
-        Proofread.writePackage(filename, pkg.inlineTags());
-    }
-
-    public static void writeClassLists()
-    {
-        int i;
-        HDF data = makePackageHDF();
-
-        ClassInfo[] classes = PackageInfo.filterHidden(
-                                    Converter.convertClasses(root.classes()));
-        if (classes.length == 0) {
-            return ;
-        }
-
-        Sorter[] sorted = new Sorter[classes.length];
-        for (i=0; i<sorted.length; i++) {
-            ClassInfo cl = classes[i];
-            String name = cl.name();
-            sorted[i] = new Sorter(name, cl);
-        }
-
-        Arrays.sort(sorted);
-
-        // make a pass and resolve ones that have the same name
-        int firstMatch = 0;
-        String lastName = sorted[0].label;
-        for (i=1; i<sorted.length; i++) {
-            String s = sorted[i].label;
-            if (!lastName.equals(s)) {
-                if (firstMatch != i-1) {
-                    // there were duplicates
-                    for (int j=firstMatch; j<i; j++) {
-                        PackageInfo pkg = ((ClassInfo)sorted[j].data).containingPackage();
-                        if (pkg != null) {
-                            sorted[j].label = sorted[j].label + " (" + pkg.name() + ")";
-                        }
-                    }
-                }
-                firstMatch = i;
-                lastName = s;
-            }
-        }
-
-        // and sort again
-        Arrays.sort(sorted);
-
-        for (i=0; i<sorted.length; i++) {
-            String s = sorted[i].label;
-            ClassInfo cl = (ClassInfo)sorted[i].data;
-            char first = Character.toUpperCase(s.charAt(0));
-            cl.makeShortDescrHDF(data, "docs.classes." + first + '.' + i);
-        }
-
-        setPageTitle(data, "Class Index");
-        ClearPage.write(data, "classes.cs", javadocDir + "classes" + htmlExtension);
-    }
-
-    // we use the word keywords because "index" means something else in html land
-    // the user only ever sees the word index
-/*    public static void writeKeywords()
-    {
-        ArrayList<KeywordEntry> keywords = new ArrayList<KeywordEntry>();
-
-        ClassInfo[] classes = PackageInfo.filterHidden(Converter.convertClasses(root.classes()));
-
-        for (ClassInfo cl: classes) {
-            cl.makeKeywordEntries(keywords);
-        }
-
-        HDF data = makeHDF();
-
-        Collections.sort(keywords);
-
-        int i=0;
-        for (KeywordEntry entry: keywords) {
-            String base = "keywords." + entry.firstChar() + "." + i;
-            entry.makeHDF(data, base);
-            i++;
-        }
-
-        setPageTitle(data, "Index");
-        ClearPage.write(data, "keywords.cs", javadocDir + "keywords" + htmlExtension);
-    } */
-
-    public static void writeHierarchy()
-    {
-        ClassInfo[] classes = Converter.rootClasses();
-        ArrayList<ClassInfo> info = new ArrayList<ClassInfo>();
-        for (ClassInfo cl: classes) {
-            if (!cl.isHidden()) {
-                info.add(cl);
-            }
-        }
-        HDF data = makePackageHDF();
-        Hierarchy.makeHierarchy(data, info.toArray(new ClassInfo[info.size()]));
-        setPageTitle(data, "Class Hierarchy");
-        ClearPage.write(data, "hierarchy.cs", javadocDir + "hierarchy" + htmlExtension);
-    }
-
-    public static void writeClasses()
-    {
-        ClassInfo[] classes = Converter.rootClasses();
-
-        for (ClassInfo cl: classes) {
-            HDF data = makePackageHDF();
-            if (!cl.isHidden()) {
-                writeClass(cl, data);
-            }
-        }
-    }
-
-    public static void writeClass(ClassInfo cl, HDF data)
-    {
-        cl.makeHDF(data);
-
-        setPageTitle(data, cl.name());
-        ClearPage.write(data, "class.cs", cl.htmlPage());
-
-        Proofread.writeClass(cl.htmlPage(), cl);
-    }
-
-    public static void makeClassListHDF(HDF data, String base,
-            ClassInfo[] classes)
-    {
-        for (int i=0; i<classes.length; i++) {
-            ClassInfo cl = classes[i];
-            if (!cl.isHidden()) {
-                cl.makeShortDescrHDF(data, base + "." + i);
-            }
-        }
-    }
-
-    public static String linkTarget(String source, String target)
-    {
-        String[] src = source.split("/");
-        String[] tgt = target.split("/");
-
-        int srclen = src.length;
-        int tgtlen = tgt.length;
-
-        int same = 0;
-        while (same < (srclen-1)
-                && same < (tgtlen-1)
-                && (src[same].equals(tgt[same]))) {
-            same++;
-        }
-
-        String s = "";
-
-        int up = srclen-same-1;
-        for (int i=0; i<up; i++) {
-            s += "../";
-        }
-
-
-        int N = tgtlen-1;
-        for (int i=same; i<N; i++) {
-            s += tgt[i] + '/';
-        }
-        s += tgt[tgtlen-1];
-
-        return s;
-    }
-
-    /**
-     * Returns true if the given element has an @hide or @pending annotation.
-     */
-    private static boolean hasHideAnnotation(Doc doc) {
-        String comment = doc.getRawCommentText();
-        return comment.indexOf("@hide") != -1 || comment.indexOf("@pending") != -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<String> features = 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());
-                                    } else if (SDK_CONSTANT_TYPE_FEATURE.equals(type)) {
-                                        features.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);
-
-        Collections.sort(features);
-        writeValues(output + "/features.txt", features);
-
-        // 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
deleted file mode 100644
index 7ba5623..0000000
--- a/tools/droiddoc/src/Errors.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-public class Errors
-{
-    public static boolean hadError = false;
-    private static boolean warningsAreErrors = false;
-    private static TreeSet<Message> allErrors = new TreeSet<Message>();
-
-    private static class Message implements Comparable {
-        SourcePositionInfo pos;
-        int level;
-        String msg;
-
-        Message(SourcePositionInfo p, int l, String m) {
-            pos = p;
-            level = l;
-            msg = m;
-        }
-
-        public int compareTo(Object o) {
-            Message that = (Message)o;
-            int r = this.pos.compareTo(that.pos);
-            if (r != 0) return r;
-            return this.msg.compareTo(that.msg);
-        }
-
-        @Override
-        public String toString() {
-            String whereText = this.pos == null ? "unknown: " : this.pos.toString() + ':';
-            return whereText + this.msg;
-        }
-    }
-
-    public static void error(Error error, SourcePositionInfo where, String text) {
-        if (error.level == HIDDEN) {
-            return;
-        }
-
-        int level = (!warningsAreErrors && error.level == WARNING) ? WARNING : ERROR;
-        String which = level == WARNING ? " warning " : " error ";
-        String message = which + error.code + ": " + text;
-
-        if (where == null) {
-            where = new SourcePositionInfo("unknown", 0, 0);
-        }
-
-        allErrors.add(new Message(where, level, message));
-
-        if (error.level == ERROR || (warningsAreErrors && error.level == WARNING)) {
-            hadError = true;
-        }
-    }
-
-    public static void printErrors() {
-        for (Message m: allErrors) {
-            if (m.level == WARNING) {
-                System.err.println(m.toString());
-            }
-        }
-        for (Message m: allErrors) {
-            if (m.level == ERROR) {
-                System.err.println(m.toString());
-            }
-        }
-    }
-
-    public static int HIDDEN = 0;
-    public static int WARNING = 1;
-    public static int ERROR = 2;
-
-    public static void setWarningsAreErrors(boolean val) {
-        warningsAreErrors = val;
-    }
-
-    public static class Error {
-        public int code;
-        public int level;
-
-        public Error(int code, int level)
-        {
-            this.code = code;
-            this.level = level;
-        }
-    }
-
-    public static Error UNRESOLVED_LINK = new Error(1, WARNING);
-    public static Error BAD_INCLUDE_TAG = new Error(2, WARNING);
-    public static Error UNKNOWN_TAG = new Error(3, WARNING);
-    public static Error UNKNOWN_PARAM_TAG_NAME = new Error(4, WARNING);
-    public static Error UNDOCUMENTED_PARAMETER = new Error(5, HIDDEN);
-    public static Error BAD_ATTR_TAG = new Error(6, ERROR);
-    public static Error BAD_INHERITDOC = new Error(7, HIDDEN);
-    public static Error HIDDEN_LINK = new Error(8, WARNING);
-    public static Error HIDDEN_CONSTRUCTOR = new Error(9, WARNING);
-    public static Error UNAVAILABLE_SYMBOL = new Error(10, ERROR);
-    public static Error HIDDEN_SUPERCLASS = new Error(11, WARNING);
-    public static Error DEPRECATED = new Error(12, HIDDEN);
-    public static Error DEPRECATION_MISMATCH = new Error(13, WARNING);
-    public static Error MISSING_COMMENT = new Error(14, WARNING);
-    public static Error IO_ERROR = new Error(15, HIDDEN);
-    public static Error NO_SINCE_DATA = new Error(16, 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,
-            NO_SINCE_DATA,
-        };
-
-    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
deleted file mode 100644
index d9371e8..0000000
--- a/tools/droiddoc/src/FieldInfo.java
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * 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 + ".since", getSince());
-        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");
-            }
-        }
-    }
-
-    @Override
-    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
deleted file mode 100755
index ac5e1dc..0000000
--- a/tools/droiddoc/src/Hierarchy.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 242170c..0000000
--- a/tools/droiddoc/src/InheritedTags.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 7e5e357..0000000
--- a/tools/droiddoc/src/KeywordEntry.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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
deleted file mode 100644
index b1f998a..0000000
--- a/tools/droiddoc/src/LinkReference.java
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * 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);
-
-    /**
-     * regex pattern to use when matching double-quoted reference text
-     */
-    private static final Pattern QUOTE_PATTERN
-            = Pattern.compile("^\"([^\"]*)\"[ \n\r\t]*$");
-
-    /**
-     * 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)
-            Matcher matcher = QUOTE_PATTERN.matcher(text);
-            if (! matcher.matches()) {
-                Errors.error(Errors.UNRESOLVED_LINK, pos,
-                        "unbalanced quoted link/see tag: " + text.trim());
-                result.makeError();
-                return result;
-            }
-            skipHref = true;
-            result.label = matcher.group(1);
-            result.kind = "@seeJustLabel";
-        }
-        else if (text.startsWith("<")) {
-            // explicit "<a href" form
-            Matcher matcher = HREF_PATTERN.matcher(text);
-            if (! matcher.matches()) {
-                Errors.error(Errors.UNRESOLVED_LINK, pos,
-                        "invalid <a> link/see tag: " + text.trim());
-                result.makeError();
-                return result;
-            }
-            result.href = matcher.group(1);
-            result.label = matcher.group(2);
-            result.kind = "@seeHref";
-        }
-        else if (result.packageInfo != null) {
-            result.href = result.packageInfo.htmlPage();
-            if (result.label.length() == 0) {
-                result.href = result.packageInfo.htmlPage();
-                result.label = result.packageInfo.name();
-            }
-        }
-        else if (result.classInfo != null && result.referencedMemberName == null) {
-            // class reference
-            if (result.label.length() == 0) {
-                result.label = result.classInfo.name();
-            }
-            result.href = result.classInfo.htmlPage();
-        }
-        else if (result.memberInfo != null) {
-            // member reference
-            ClassInfo containing = result.memberInfo.containingClass();
-            if (result.memberInfo.isExecutable()) {
-                if (result.referencedMemberName.indexOf('(') < 0) {
-                    result.referencedMemberName += method.flatSignature();
-                }
-            } 
-            if (result.label.length() == 0) {
-                result.label = result.referencedMemberName;
-            }
-            result.href = containing.htmlPage() + '#' + result.memberInfo.anchor();
-        }
-
-        if (result.href == null && !skipHref) {
-            if (printOnErrors && (base == null || base.checkLevel())) {
-                Errors.error(Errors.UNRESOLVED_LINK, pos,
-                        "Unresolved link/see tag \"" + text.trim()
-                        + "\" in " + ((base != null) ? base.qualifiedName() : "[null]"));
-            }
-            result.makeError();
-        }
-        else if (result.memberInfo != null && !result.memberInfo.checkLevel()) {
-            if (printOnErrors && (base == null || base.checkLevel())) {
-                Errors.error(Errors.HIDDEN_LINK, pos,
-                        "Link to hidden member: " + text.trim());
-                result.href = null;
-            }
-            result.kind = "@seeJustLabel";
-        }
-        else if (result.classInfo != null && !result.classInfo.checkLevel()) {
-            if (printOnErrors && (base == null || base.checkLevel())) {
-                Errors.error(Errors.HIDDEN_LINK, pos,
-                        "Link to hidden class: " + text.trim() + " label=" + result.label);
-                result.href = null;
-            }
-            result.kind = "@seeJustLabel";
-        }
-        else if (result.packageInfo != null && !result.packageInfo.checkLevel()) {
-            if (printOnErrors && (base == null || base.checkLevel())) {
-                Errors.error(Errors.HIDDEN_LINK, pos,
-                        "Link to hidden package: " + text.trim());
-                result.href = null;
-            }
-            result.kind = "@seeJustLabel";
-        }
-
-        result.good = true;
-
-        return result;
-    }
-
-    public boolean checkLevel() {
-        if (memberInfo != null) {
-            return memberInfo.checkLevel();
-        }
-        if (classInfo != null) {
-            return classInfo.checkLevel();
-        }
-        if (packageInfo != null) {
-            return packageInfo.checkLevel();
-        }
-        return false;
-    }
-
-    /** turn this LinkReference into one with an error message */
-    private void makeError() {
-        //this.href = "ERROR(" + this.text.trim() + ")";
-        this.href = null;
-        if (this.label == null) {
-            this.label = "";
-        }
-        this.label = "ERROR(" + this.label + "/" + text.trim() + ")";
-    }
-
-    /** private. **/
-    private LinkReference() {
-    }
-}
diff --git a/tools/droiddoc/src/LiteralTagInfo.java b/tools/droiddoc/src/LiteralTagInfo.java
deleted file mode 100644
index b39490d..0000000
--- a/tools/droiddoc/src/LiteralTagInfo.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 05da583..0000000
--- a/tools/droiddoc/src/MemberInfo.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * 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;
-    }
-
-    @Override
-    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
deleted file mode 100644
index 7f96b80..0000000
--- a/tools/droiddoc/src/MethodInfo.java
+++ /dev/null
@@ -1,670 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import org.clearsilver.HDF;
-
-import java.util.*;
-
-public class MethodInfo extends MemberInfo
-{
-    public static final Comparator<MethodInfo> comparator = new Comparator<MethodInfo>() {
-        public int compare(MethodInfo a, MethodInfo b) {
-            return a.name().compareTo(b.name());
-        }
-    };
-
-    private class InlineTags implements InheritedTags
-    {
-        public TagInfo[] tags()
-        {
-            return comment().tags();
-        }
-        public InheritedTags inherited()
-        {
-            MethodInfo m = findOverriddenMethod(name(), signature());
-            if (m != null) {
-                return m.inlineTags();
-            } else {
-                return null;
-            }
-        }
-    }
-
-    private static void addInterfaces(ClassInfo[] ifaces, ArrayList<ClassInfo> queue)
-    {
-        for (ClassInfo i: ifaces) {
-            queue.add(i);
-        }
-        for (ClassInfo i: ifaces) {
-            addInterfaces(i.interfaces(), queue);
-        }
-    }
-
-    // first looks for a superclass, and then does a breadth first search to
-    // find the least far away match
-    public MethodInfo findOverriddenMethod(String name, String signature)
-    {
-        if (mReturnType == null) {
-            // ctor
-            return null;
-        }
-        if (mOverriddenMethod != null) {
-            return mOverriddenMethod;
-        }
-
-        ArrayList<ClassInfo> queue = new ArrayList<ClassInfo>();
-        addInterfaces(containingClass().interfaces(), queue);
-        for (ClassInfo iface: queue) {
-            for (MethodInfo me: iface.methods()) {
-                if (me.name().equals(name)
-                        && me.signature().equals(signature)
-                        && me.inlineTags().tags() != null
-                        && me.inlineTags().tags().length > 0) {
-                    return me;
-                }
-            }
-        }
-        return null;
-    }
-
-    private static void addRealInterfaces(ClassInfo[] ifaces, ArrayList<ClassInfo> queue)
-    {
-        for (ClassInfo i: ifaces) {
-            queue.add(i);
-            if (i.realSuperclass() != null &&  i.realSuperclass().isAbstract()) {
-                queue.add(i.superclass());
-            }
-        }
-        for (ClassInfo i: ifaces) {
-            addInterfaces(i.realInterfaces(), queue);
-        }
-    }
-
-    public MethodInfo findRealOverriddenMethod(String name, String signature, HashSet notStrippable) {
-        if (mReturnType == null) {
-        // ctor
-        return null;
-        }
-        if (mOverriddenMethod != null) {
-            return mOverriddenMethod;
-        }
-
-        ArrayList<ClassInfo> queue = new ArrayList<ClassInfo>();
-        if (containingClass().realSuperclass() != null &&
-            containingClass().realSuperclass().isAbstract()) {
-            queue.add(containingClass());
-        }
-        addInterfaces(containingClass().realInterfaces(), queue);
-        for (ClassInfo iface: queue) {
-            for (MethodInfo me: iface.methods()) {
-                if (me.name().equals(name)
-                    && me.signature().equals(signature)
-                    && me.inlineTags().tags() != null
-                    && me.inlineTags().tags().length > 0
-                    && notStrippable.contains(me.containingClass())) {
-                return me;
-                }
-            }
-        }
-        return null;
-    }
-
-    public MethodInfo findSuperclassImplementation(HashSet notStrippable) {
-        if (mReturnType == null) {
-            // ctor
-            return null;
-        }
-        if (mOverriddenMethod != null) {
-            // Even if we're told outright that this was the overridden method, we want to
-            // be conservative and ignore mismatches of parameter types -- they arise from
-            // extending generic specializations, and we want to consider the derived-class
-            // method to be a non-override.
-            if (this.signature().equals(mOverriddenMethod.signature())) {
-                return mOverriddenMethod;
-            }
-        }
-
-        ArrayList<ClassInfo> queue = new ArrayList<ClassInfo>();
-        if (containingClass().realSuperclass() != null &&
-                containingClass().realSuperclass().isAbstract()) {
-            queue.add(containingClass());
-        }
-        addInterfaces(containingClass().realInterfaces(), queue);
-        for (ClassInfo iface: queue) {
-            for (MethodInfo me: iface.methods()) {
-                if (me.name().equals(this.name())
-                        && me.signature().equals(this.signature())
-                        && notStrippable.contains(me.containingClass())) {
-                    return me;
-                }
-            }
-        }
-        return null;
-    }
-
-    public ClassInfo findRealOverriddenClass(String name, String signature) {
-        if (mReturnType == null) {
-        // ctor
-        return null;
-        }
-        if (mOverriddenMethod != null) {
-            return mOverriddenMethod.mRealContainingClass;
-        }
-
-        ArrayList<ClassInfo> queue = new ArrayList<ClassInfo>();
-        if (containingClass().realSuperclass() != null &&
-            containingClass().realSuperclass().isAbstract()) {
-            queue.add(containingClass());
-        }
-        addInterfaces(containingClass().realInterfaces(), queue);
-        for (ClassInfo iface: queue) {
-            for (MethodInfo me: iface.methods()) {
-                if (me.name().equals(name)
-                    && me.signature().equals(signature)
-                    && me.inlineTags().tags() != null
-                    && me.inlineTags().tags().length > 0) {
-                return iface;
-                }
-            }
-        }
-        return null;
-    }
-
-    private class FirstSentenceTags implements InheritedTags
-    {
-        public TagInfo[] tags()
-        {
-            return comment().briefTags();
-        }
-        public InheritedTags inherited()
-        {
-            MethodInfo m = findOverriddenMethod(name(), signature());
-            if (m != null) {
-                return m.firstSentenceTags();
-            } else {
-                return null;
-            }
-        }
-    }
-
-    private class ReturnTags implements InheritedTags {
-        public TagInfo[] tags() {
-            return comment().returnTags();
-        }
-        public InheritedTags inherited() {
-            MethodInfo m = findOverriddenMethod(name(), signature());
-            if (m != null) {
-                return m.returnTags();
-            } else {
-                return null;
-            }
-        }
-    }
-
-    public boolean isDeprecated() {
-        boolean deprecated = false;
-        if (!mDeprecatedKnown) {
-            boolean commentDeprecated = (comment().deprecatedTags().length > 0);
-            boolean annotationDeprecated = false;
-            for (AnnotationInstanceInfo annotation : annotations()) {
-                if (annotation.type().qualifiedName().equals("java.lang.Deprecated")) {
-                    annotationDeprecated = true;
-                    break;
-                }
-            }
-
-            if (commentDeprecated != annotationDeprecated) {
-                Errors.error(Errors.DEPRECATION_MISMATCH, position(),
-                        "Method " + mContainingClass.qualifiedName() + "." + name()
-                        + ": @Deprecated annotation and @deprecated doc tag do not match");
-            }
-
-            mIsDeprecated = commentDeprecated | annotationDeprecated;
-            mDeprecatedKnown = true;
-        }
-        return mIsDeprecated;
-    }
-
-    public TypeInfo[] getTypeParameters(){
-        return mTypeParameters;
-    }
-
-    public MethodInfo cloneForClass(ClassInfo newContainingClass) {
-        MethodInfo result =  new MethodInfo(getRawCommentText(), mTypeParameters,
-                name(), signature(), newContainingClass, realContainingClass(),
-                isPublic(), isProtected(), isPackagePrivate(), isPrivate(), isFinal(), isStatic(),
-                isSynthetic(), mIsAbstract, mIsSynchronized, mIsNative, mIsAnnotationElement,
-                kind(), mFlatSignature, mOverriddenMethod,
-                mReturnType, mParameters, mThrownExceptions, position(), annotations());
-        result.init(mDefaultAnnotationElementValue);
-        return result;
-    }
-
-    public MethodInfo(String rawCommentText, TypeInfo[] typeParameters, String name,
-                        String signature, ClassInfo containingClass, ClassInfo realContainingClass,
-                        boolean isPublic, boolean isProtected,
-                        boolean isPackagePrivate, boolean isPrivate,
-                        boolean isFinal, boolean isStatic, boolean isSynthetic,
-                        boolean isAbstract, boolean isSynchronized, boolean isNative,
-                        boolean isAnnotationElement, String kind,
-                        String flatSignature, MethodInfo overriddenMethod,
-                        TypeInfo returnType, ParameterInfo[] parameters,
-                        ClassInfo[] thrownExceptions, SourcePositionInfo position,
-                        AnnotationInstanceInfo[] annotations)
-    {
-        // Explicitly coerce 'final' state of Java6-compiled enum values() method, to match
-        // the Java5-emitted base API description.
-        super(rawCommentText, name, signature, containingClass, realContainingClass,
-                isPublic, isProtected, isPackagePrivate, isPrivate,
-                ((name.equals("values") && containingClass.isEnum()) ? true : isFinal),
-                isStatic, isSynthetic, kind, position, annotations);
-
-        // The underlying MethodDoc for an interface's declared methods winds up being marked
-        // non-abstract.  Correct that here by looking at the immediate-parent class, and marking
-        // this method abstract if it is an unimplemented interface method.
-        if (containingClass.isInterface()) {
-            isAbstract = true;
-        }
-
-        mReasonOpened = "0:0";
-        mIsAnnotationElement = isAnnotationElement;
-        mTypeParameters = typeParameters;
-        mIsAbstract = isAbstract;
-        mIsSynchronized = isSynchronized;
-        mIsNative = isNative;
-        mFlatSignature = flatSignature;
-        mOverriddenMethod = overriddenMethod;
-        mReturnType = returnType;
-        mParameters = parameters;
-        mThrownExceptions = thrownExceptions;
-    }
-
-    public void init(AnnotationValueInfo defaultAnnotationElementValue)
-    {
-        mDefaultAnnotationElementValue = defaultAnnotationElementValue;
-    }
-
-    public boolean isAbstract()
-    {
-        return mIsAbstract;
-    }
-
-    public boolean isSynchronized()
-    {
-        return mIsSynchronized;
-    }
-
-    public boolean isNative()
-    {
-        return mIsNative;
-    }
-
-    public String flatSignature()
-    {
-        return mFlatSignature;
-    }
-
-    public InheritedTags inlineTags()
-    {
-        return new InlineTags();
-    }
-
-    public InheritedTags firstSentenceTags()
-    {
-        return new FirstSentenceTags();
-    }
-
-    public InheritedTags returnTags() {
-        return new ReturnTags();
-    }
-
-    public TypeInfo returnType()
-    {
-        return mReturnType;
-    }
-
-    public String prettySignature()
-    {
-        String s = "(";
-        int N = mParameters.length;
-        for (int i=0; i<N; i++) {
-            ParameterInfo p = mParameters[i];
-            TypeInfo t = p.type();
-            if (t.isPrimitive()) {
-                s += t.simpleTypeName();
-            } else {
-                s += t.asClassInfo().name();
-            }
-            if (i != N-1) {
-                s += ',';
-            }
-        }
-        s += ')';
-        return s;
-    }
-
-    /**
-     * Returns a name consistent with the {@link
-     * com.android.apicheck.MethodInfo#getHashableName()}.
-     */
-    public String getHashableName() {
-        StringBuilder result = new StringBuilder();
-        result.append(name());
-        for (int p = 0; p < mParameters.length; p++) {
-            result.append(":");
-            if (p == mParameters.length - 1 && isVarArgs()) {
-                // TODO: note that this does not attempt to handle hypothetical
-                // vararg methods whose last parameter is a list of arrays, e.g.
-                // "Object[]...".
-                result.append(mParameters[p].type().fullNameNoDimension(typeVariables()))
-                        .append("...");
-            } else {
-                result.append(mParameters[p].type().fullName(typeVariables()));
-            }
-        }
-        return result.toString();
-    }
-
-    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());
-        data.setValue(base + ".since", getSince());
-        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;
-    }
-
-    @Override
-    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;
-    }
-
-    @Override
-    public String toString(){
-      return this.name();
-    }
-
-    public void setReason(String reason) {
-        mReasonOpened = reason;
-    }
-
-    public String getReason() {
-        return mReasonOpened;
-    }
-
-    private String mFlatSignature;
-    private MethodInfo mOverriddenMethod;
-    private TypeInfo mReturnType;
-    private boolean mIsAnnotationElement;
-    private boolean mIsAbstract;
-    private boolean mIsSynchronized;
-    private boolean mIsNative;
-    private boolean mIsVarargs;
-    private boolean mDeprecatedKnown;
-    private boolean mIsDeprecated;
-    private ParameterInfo[] mParameters;
-    private ClassInfo[] mThrownExceptions;
-    private String[] mParamStrings;
-    ThrowsTagInfo[] mThrowsTags;
-    private ParamTagInfo[] mParamTags;
-    private TypeInfo[] mTypeParameters;
-    private AnnotationValueInfo mDefaultAnnotationElementValue;
-    private String mReasonOpened;
-}
-
diff --git a/tools/droiddoc/src/NavTree.java b/tools/droiddoc/src/NavTree.java
deleted file mode 100644
index 0469fdc..0000000
--- a/tools/droiddoc/src/NavTree.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import org.clearsilver.HDF;
-
-import java.util.ArrayList;
-
-public class NavTree {
-
-    public static void writeNavTree(String dir) {
-        ArrayList<Node> children = new ArrayList();
-        for (PackageInfo pkg: DroidDoc.choosePackages()) {
-            children.add(makePackageNode(pkg));
-        }
-        Node node = new Node("Reference", dir + "packages.html", children, null);
-
-        StringBuilder buf = new StringBuilder();
-        if (false) {
-            // if you want a root node
-            buf.append("[");
-            node.render(buf);
-            buf.append("]");
-        } else {
-            // if you don't want a root node
-            node.renderChildren(buf);
-        }
-
-        HDF data = DroidDoc.makeHDF();
-        data.setValue("reference_tree", buf.toString());
-        ClearPage.write(data, "navtree_data.cs", "navtree_data.js");
-    }
-
-    private static Node makePackageNode(PackageInfo pkg) {
-        ArrayList<Node> children = new ArrayList();
-
-        children.add(new Node("Description", pkg.fullDescriptionHtmlPage(), null, null));
-
-        addClassNodes(children, "Interfaces", pkg.interfaces());
-        addClassNodes(children, "Classes", pkg.ordinaryClasses());
-        addClassNodes(children, "Enums", pkg.enums());
-        addClassNodes(children, "Exceptions", pkg.exceptions());
-        addClassNodes(children, "Errors", pkg.errors());
-
-        return new Node(pkg.name(), pkg.htmlPage(), children, pkg.getSince());
-    }
-
-    private static void addClassNodes(ArrayList<Node> parent, String label, ClassInfo[] classes) {
-        ArrayList<Node> children = new ArrayList();
-
-        for (ClassInfo cl: classes) {
-            if (cl.checkLevel()) {
-                children.add(new Node(cl.name(), cl.htmlPage(), null, cl.getSince()));
-            }
-        }
-
-        if (children.size() > 0) {
-            parent.add(new Node(label, null, children, null));
-        }
-    }
-
-    private static class Node {
-        private String mLabel;
-        private String mLink;
-        ArrayList<Node> mChildren;
-        private String mSince;
-
-        Node(String label, String link, ArrayList<Node> children, String since) {
-            mLabel = label;
-            mLink = link;
-            mChildren = children;
-            mSince = since;
-        }
-
-        static void renderString(StringBuilder buf, String s) {
-            if (s == null) {
-                buf.append("null");
-            } else {
-                buf.append('"');
-                final int N = s.length();
-                for (int i=0; i<N; i++) {
-                    char c = s.charAt(i);
-                    if (c >= ' ' && c <= '~' && c != '"' && c != '\\') {
-                        buf.append(c);
-                    } else {
-                        buf.append("\\u");
-                        for (int j=0; i<4; i++) {
-                            char x = (char)(c & 0x000f);
-                            if (x > 10) {
-                                x = (char)(x - 10 + 'a');
-                            } else {
-                                x = (char)(x + '0');
-                            }
-                            buf.append(x);
-                            c >>= 4;
-                        }
-                    }
-                }
-                buf.append('"');
-            }
-        }
-
-        void renderChildren(StringBuilder buf) {
-            ArrayList<Node> list = mChildren;
-            if (list == null || list.size() == 0) {
-                // We output null for no children.  That way empty lists here can just
-                // be a byproduct of how we generate the lists.
-                buf.append("null");
-            } else {
-                buf.append("[ ");
-                final int N = list.size();
-                for (int i=0; i<N; i++) {
-                    list.get(i).render(buf);
-                    if (i != N-1) {
-                        buf.append(", ");
-                    }
-                }
-                buf.append(" ]\n");
-            }
-        }
-
-        void render(StringBuilder buf) {
-            buf.append("[ ");
-            renderString(buf, mLabel);
-            buf.append(", ");
-            renderString(buf, mLink);
-            buf.append(", ");
-            renderChildren(buf);
-            buf.append(", ");
-            renderString(buf, mSince);
-            buf.append(" ]");
-        }
-    }
-}
diff --git a/tools/droiddoc/src/PackageInfo.java b/tools/droiddoc/src/PackageInfo.java
deleted file mode 100644
index 17ad1b7..0000000
--- a/tools/droiddoc/src/PackageInfo.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import com.sun.javadoc.*;
-import com.sun.tools.doclets.*;
-import org.clearsilver.HDF;
-import org.clearsilver.CS;
-import java.util.*;
-import java.io.*;
-
-public class PackageInfo extends DocInfo implements ContainerInfo
-{
-    public static final Comparator<PackageInfo> comparator = new Comparator<PackageInfo>() {
-        public int compare(PackageInfo a, PackageInfo b) {
-            return a.name().compareTo(b.name());
-        }
-    };
-
-    public PackageInfo(PackageDoc pkg, String name, SourcePositionInfo position)
-    {
-        super(pkg.getRawCommentText(), position);
-        mName = name;
-
-        if (pkg == null) {
-            throw new RuntimeException("pkg is null");
-        }
-        mPackage = pkg;
-    }
-
-    public String htmlPage()
-    {
-        String s = mName;
-        s = s.replace('.', '/');
-        s += "/package-summary.html";
-        s = DroidDoc.javadocDir + s;
-        return s;
-    }
-
-    public String fullDescriptionHtmlPage() {
-        String s = mName;
-        s = s.replace('.', '/');
-        s += "/package-descr.html";
-        s = DroidDoc.javadocDir + s;
-        return s;
-    }
-
-    @Override
-    public ContainerInfo parent()
-    {
-        return null;
-    }
-
-    @Override
-    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());
-        data.setValue(base + ".since", getSince());
-    }
-
-    public void makeClassLinkListHDF(HDF data, String base)
-    {
-        makeLink(data, base);
-        ClassInfo.makeLinkListHDF(data, base + ".interfaces", interfaces());
-        ClassInfo.makeLinkListHDF(data, base + ".classes", ordinaryClasses());
-        ClassInfo.makeLinkListHDF(data, base + ".enums", enums());
-        ClassInfo.makeLinkListHDF(data, base + ".exceptions", exceptions());
-        ClassInfo.makeLinkListHDF(data, base + ".errors", errors());
-        data.setValue(base + ".since", getSince());
-    }
-
-    public ClassInfo[] interfaces()
-    {
-        if (mInterfaces == null) {
-            mInterfaces = ClassInfo.sortByName(filterHidden(Converter.convertClasses(
-                            mPackage.interfaces())));
-        }
-        return mInterfaces;
-    }
-
-    public ClassInfo[] ordinaryClasses()
-    {
-        if (mOrdinaryClasses == null) {
-            mOrdinaryClasses = ClassInfo.sortByName(filterHidden(Converter.convertClasses(
-                            mPackage.ordinaryClasses())));
-        }
-        return mOrdinaryClasses;
-    }
-
-    public ClassInfo[] enums()
-    {
-        if (mEnums == null) {
-            mEnums = ClassInfo.sortByName(filterHidden(Converter.convertClasses(mPackage.enums())));
-        }
-        return mEnums;
-    }
-
-    public ClassInfo[] exceptions()
-    {
-        if (mExceptions == null) {
-            mExceptions = ClassInfo.sortByName(filterHidden(Converter.convertClasses(
-                        mPackage.exceptions())));
-        }
-        return mExceptions;
-    }
-
-    public ClassInfo[] errors()
-    {
-        if (mErrors == null) {
-            mErrors = ClassInfo.sortByName(filterHidden(Converter.convertClasses(
-                        mPackage.errors())));
-        }
-        return mErrors;
-    }
-
-    // in hashed containers, treat the name as the key
-    @Override
-    public int hashCode() {
-        return mName.hashCode();
-    }
-
-    private String mName;
-    private PackageDoc mPackage;
-    private ClassInfo[] mInterfaces;
-    private ClassInfo[] mOrdinaryClasses;
-    private ClassInfo[] mEnums;
-    private ClassInfo[] mExceptions;
-    private ClassInfo[] mErrors;
-}
-
diff --git a/tools/droiddoc/src/ParamTagInfo.java b/tools/droiddoc/src/ParamTagInfo.java
deleted file mode 100644
index d6f2b6b..0000000
--- a/tools/droiddoc/src/ParamTagInfo.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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;
-    }
-
-    @Override
-    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
deleted file mode 100644
index 44608be..0000000
--- a/tools/droiddoc/src/ParameterInfo.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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
deleted file mode 100755
index c2e4806..0000000
--- a/tools/droiddoc/src/ParsedTagInfo.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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
deleted file mode 100644
index ec9f523..0000000
--- a/tools/droiddoc/src/Proofread.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * 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
deleted file mode 100644
index bf54445..0000000
--- a/tools/droiddoc/src/SampleCode.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * 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(boolean offlineMode) {
-        File f = new File(mSource);
-        if (!f.isDirectory()) {
-            System.out.println("-samplecode not a directory: " + mSource);
-            return;
-        }
-        if (offlineMode) writeIndexOnly(f, mDest, offlineMode);
-        else 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 = writeIndex(dir);
-        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++;
-        }
-        
-        ClearPage.write(hdf, "sampleindex.cs", relative + "/index" + DroidDoc.htmlExtension);
-    }
-
-    public void writeIndexOnly(File dir, String relative, Boolean offline) {
-        HDF hdf = writeIndex(dir);
-        if (!offline) relative = "/" + relative;
-        ClearPage.write(hdf, "sampleindex.cs", relative + "index" +
-                        DroidDoc.htmlExtension);
-    }
-
-    public HDF writeIndex(File dir) {
-        HDF hdf = DroidDoc.makeHDF();
-
-        hdf.setValue("page.title", dir.getName() + " - " + mTitle);
-        hdf.setValue("projectTitle", mTitle);
-
-        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);
-
-        return hdf;
-    }
-
-    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
deleted file mode 100644
index c7ad1cc..0000000
--- a/tools/droiddoc/src/SampleTagInfo.java
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * 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);
-    }
-
-    @Override
-    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
deleted file mode 100644
index cca61ed..0000000
--- a/tools/droiddoc/src/Scoped.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 8420ed3..0000000
--- a/tools/droiddoc/src/SeeTagInfo.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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;
-    }
-
-    @Override
-    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/SinceTagger.java b/tools/droiddoc/src/SinceTagger.java
deleted file mode 100644
index a1bce55..0000000
--- a/tools/droiddoc/src/SinceTagger.java
+++ /dev/null
@@ -1,237 +0,0 @@
-// Copyright 2009 Google Inc. All Rights Reserved.
-
-import com.android.apicheck.ApiCheck;
-import com.android.apicheck.ApiInfo;
-
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Collections;
-
-import org.clearsilver.HDF;
-
-/**
- * Applies version information to the DroidDoc class model from apicheck XML
- * files. Sample usage:
- * <pre>
- *   ClassInfo[] classInfos = ...
- *
- *   SinceTagger sinceTagger = new SinceTagger()
- *   sinceTagger.addVersion("frameworks/base/api/1.xml", "Android 1.0")
- *   sinceTagger.addVersion("frameworks/base/api/2.xml", "Android 1.5")
- *   sinceTagger.tagAll(...);
- * </pre>
- */
-public class SinceTagger {
-
-    private final Map<String, String> xmlToName
-            = new LinkedHashMap<String, String>();
-
-    /**
-     * Specifies the apicheck XML file and the API version it holds. Calls to
-     * this method should be called in order from oldest version to newest.
-     */
-    public void addVersion(String file, String name) {
-        xmlToName.put(file, name);
-    }
-
-    public void tagAll(ClassInfo[] classDocs) {
-        // read through the XML files in order, applying their since information
-        // to the Javadoc models
-        for (Map.Entry<String, String> versionSpec : xmlToName.entrySet()) {
-            String xmlFile = versionSpec.getKey();
-            String versionName = versionSpec.getValue();
-            ApiInfo specApi = new ApiCheck().parseApi(xmlFile);
-
-            applyVersionsFromSpec(versionName, specApi, classDocs);
-        }
-
-        if (!xmlToName.isEmpty()) {
-            warnForMissingVersions(classDocs);
-        }
-    }
-
-    /**
-     * Writes an index of the version names to {@code data}. 
-     */
-    public void writeVersionNames(HDF data) {
-        int index = 1;
-        for (String version : xmlToName.values()) {
-            data.setValue("since." + index + ".name", version);
-            index++;
-        }
-    }
-
-    /**
-     * Applies the version information to {@code classDocs} where not already
-     * present.
-     *
-     * @param versionName the version name
-     * @param specApi the spec for this version. If a symbol is in this spec, it
-     *      was present in the named version
-     * @param classDocs the doc model to update
-     */
-    private void applyVersionsFromSpec(String versionName,
-            ApiInfo specApi, ClassInfo[] classDocs) {
-        for (ClassInfo classDoc : classDocs) {
-            com.android.apicheck.PackageInfo packageSpec
-                    = specApi.getPackages().get(classDoc.containingPackage().name());
-
-            if (packageSpec == null) {
-                continue;
-            }
-
-            com.android.apicheck.ClassInfo classSpec
-                    = packageSpec.allClasses().get(classDoc.name());
-
-            if (classSpec == null) {
-                continue;
-            }
-
-            versionPackage(versionName, classDoc.containingPackage());
-            versionClass(versionName, classDoc);
-            versionConstructors(versionName, classSpec, classDoc);
-            versionFields(versionName, classSpec, classDoc);
-            versionMethods(versionName, classSpec, classDoc);
-        }
-    }
-
-    /**
-     * Applies version information to {@code doc} where not already present.
-     */
-    private void versionPackage(String versionName, PackageInfo doc) {
-        if (doc.getSince() == null) {
-            doc.setSince(versionName);
-        }
-    }
-
-    /**
-     * Applies version information to {@code doc} where not already present.
-     */
-    private void versionClass(String versionName, ClassInfo doc) {
-        if (doc.getSince() == null) {
-            doc.setSince(versionName);
-        }
-    }
-
-    /**
-     * Applies version information from {@code spec} to {@code doc} where not
-     * already present.
-     */
-    private void versionConstructors(String versionName,
-            com.android.apicheck.ClassInfo spec, ClassInfo doc) {
-        for (MethodInfo constructor : doc.constructors()) {
-            if (constructor.getSince() == null
-                    && spec.allConstructors().containsKey(constructor.getHashableName())) {
-                constructor.setSince(versionName);
-            }
-        }
-    }
-
-    /**
-     * Applies version information from {@code spec} to {@code doc} where not
-     * already present.
-     */
-    private void versionFields(String versionName,
-            com.android.apicheck.ClassInfo spec, ClassInfo doc) {
-        for (FieldInfo field : doc.fields()) {
-            if (field.getSince() == null
-                    && spec.allFields().containsKey(field.name())) {
-                field.setSince(versionName);
-            }
-        }
-    }
-
-    /**
-     * Applies version information from {@code spec} to {@code doc} where not
-     * already present.
-     */
-    private void versionMethods(String versionName,
-            com.android.apicheck.ClassInfo spec, ClassInfo doc) {
-        for (MethodInfo method : doc.methods()) {
-            if (method.getSince() != null) {
-                continue;
-            }
-
-            for (com.android.apicheck.ClassInfo superclass : spec.hierarchy()) {
-                if (superclass.allMethods().containsKey(method.getHashableName())) {
-                    method.setSince(versionName);
-                    break;
-                }
-            }
-        }
-    }
-
-    /**
-     * Warns if any symbols are missing version information. When configured
-     * properly, this will yield zero warnings because {@code apicheck}
-     * guarantees that all symbols are present in the most recent API.
-     */
-    private void warnForMissingVersions(ClassInfo[] classDocs) {
-        for (ClassInfo claz : classDocs) {
-            if (!checkLevelRecursive(claz)) {
-                continue;
-            }
-
-            if (claz.getSince() == null) {
-                Errors.error(Errors.NO_SINCE_DATA, claz.position(),
-                        "XML missing class " + claz.qualifiedName());
-            }
-            
-            for (FieldInfo field : missingVersions(claz.fields())) {
-                Errors.error(Errors.NO_SINCE_DATA, field.position(),
-                        "XML missing field " + claz.qualifiedName()
-                                + "#" + field.name());
-            }
-
-            for (MethodInfo constructor : missingVersions(claz.constructors())) {
-                Errors.error(Errors.NO_SINCE_DATA, constructor.position(),
-                        "XML missing constructor " + claz.qualifiedName()
-                                + "#" + constructor.getHashableName());
-            }
-
-            for (MethodInfo method : missingVersions(claz.methods())) {
-                Errors.error(Errors.NO_SINCE_DATA, method.position(),
-                        "XML missing method " + claz.qualifiedName()
-                                + "#" + method.getHashableName());
-            }
-        }
-    }
-
-    /**
-     * Returns the DocInfos in {@code all} that are documented but do not have
-     * since tags.
-     */
-    private <T extends MemberInfo> Iterable<T> missingVersions(T[] all) {
-        List<T> result = Collections.emptyList();
-        for (T t : all) {
-            // if this member has version info or isn't documented, skip it
-            if (t.getSince() != null
-                    || t.isHidden()
-                    || !checkLevelRecursive(t.realContainingClass())) {
-                continue;
-            }
-
-            if (result.isEmpty()) {
-                result = new ArrayList<T>(); // lazily construct a mutable list
-            }
-            result.add(t);
-        }
-        return result;
-    }
-
-    /**
-     * Returns true if {@code claz} and all containing classes are documented.
-     * The result may be used to filter out members that exist in the API
-     * data structure but aren't a part of the API.
-     */
-    private boolean checkLevelRecursive(ClassInfo claz) {
-        for (ClassInfo c = claz; c != null; c = c.containingClass()) {
-            if (!c.checkLevel()) {
-                return false;
-            }
-        }
-        return true;
-    }
-}
diff --git a/tools/droiddoc/src/Sorter.java b/tools/droiddoc/src/Sorter.java
deleted file mode 100644
index 92039d4..0000000
--- a/tools/droiddoc/src/Sorter.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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
deleted file mode 100644
index ac605ec..0000000
--- a/tools/droiddoc/src/SourcePositionInfo.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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);
-    }
-
-    @Override
-    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
deleted file mode 100644
index b988ef5..0000000
--- a/tools/droiddoc/src/Stubs.java
+++ /dev/null
@@ -1,999 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Set;
-import java.util.Comparator;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.PrintStream;
-
-public class Stubs {
-    private static HashSet<ClassInfo> notStrippable;
-    public static void writeStubs(String stubsDir, Boolean writeXML, String xmlFile,
-            HashSet<String> stubPackages) {
-        // figure out which classes we need
-        notStrippable = new HashSet();
-        ClassInfo[] all = Converter.allClasses();
-        File  xml = new File(xmlFile);
-        xml.getParentFile().mkdirs();
-        PrintStream xmlWriter = null;
-        if (writeXML) {
-            try {
-                xmlWriter = new PrintStream(xml);
-            } catch (FileNotFoundException e) {
-                Errors.error(Errors.IO_ERROR, new SourcePositionInfo(xmlFile, 0, 0),
-                        "Cannot open file for write.");
-            }
-        }
-        // If a class is public or protected, not hidden, and marked as included,
-        // then we can't strip it
-        for (ClassInfo cl: all) {
-            if (cl.checkLevel() && cl.isIncluded()) {
-                cantStripThis(cl, notStrippable, "0:0");
-            }
-        }
-
-        // complain about anything that looks includeable but is not supposed to
-        // be written, e.g. hidden things
-        for (ClassInfo cl: notStrippable) {
-            if (!cl.isHidden()) {
-                MethodInfo[] methods = cl.selfMethods();
-                for (MethodInfo m: methods) {
-                    if (m.isHidden()) {
-                        Errors.error(Errors.UNAVAILABLE_SYMBOL,
-                                m.position(), "Reference to hidden method "
-                                + m.name());
-                    } else if (m.isDeprecated()) {
-                        // don't bother reporting deprecated methods
-                        // unless they are public
-                        Errors.error(Errors.DEPRECATED,
-                                m.position(), "Method "
-                                + cl.qualifiedName() + "." + m.name()
-                                + " is deprecated");
-                    }
-
-                    ClassInfo returnClass = m.returnType().asClassInfo();
-                    if (returnClass != null && returnClass.isHidden()) {
-                        Errors.error(Errors.UNAVAILABLE_SYMBOL, m.position(),
-                                "Method " + cl.qualifiedName() + "." + m.name()
-                                + " returns unavailable type " + returnClass.name());
-                    }
-
-                    ParameterInfo[] params = m.parameters();
-                    for (ParameterInfo p: params) {
-                        TypeInfo t = p.type();
-                        if (!t.isPrimitive()) {
-                            if (t.asClassInfo().isHidden()) {
-                                Errors.error(Errors.UNAVAILABLE_SYMBOL,
-                                        m.position(), "Parameter of hidden type "
-                                        + t.fullName() + " in "
-                                        + cl.qualifiedName() + "." + m.name() + "()");
-                            }
-                        }
-                    }
-                }
-
-                // annotations are handled like methods
-                methods = cl.annotationElements();
-                for (MethodInfo m: methods) {
-                    if (m.isHidden()) {
-                        Errors.error(Errors.UNAVAILABLE_SYMBOL,
-                                m.position(), "Reference to hidden annotation "
-                                + m.name());
-                    }
-
-                    ClassInfo returnClass = m.returnType().asClassInfo();
-                    if (returnClass != null && returnClass.isHidden()) {
-                        Errors.error(Errors.UNAVAILABLE_SYMBOL,
-                                m.position(), "Annotation '" + m.name()
-                                + "' returns unavailable type " + returnClass.name());
-                    }
-
-                    ParameterInfo[] params = m.parameters();
-                    for (ParameterInfo p: params) {
-                        TypeInfo t = p.type();
-                        if (!t.isPrimitive()) {
-                            if (t.asClassInfo().isHidden()) {
-                                Errors.error(Errors.UNAVAILABLE_SYMBOL,
-                                        p.position(), "Reference to unavailable annotation class "
-                                        + t.fullName());
-                            }
-                        }
-                    }
-                }
-            } else if (cl.isDeprecated()) {
-                // not hidden, but deprecated
-                Errors.error(Errors.DEPRECATED,
-                        cl.position(), "Class " + cl.qualifiedName()
-                        + " is deprecated");
-            }
-        }
-
-        // write out the stubs
-        HashMap<PackageInfo, List<ClassInfo>> packages = new HashMap<PackageInfo, List<ClassInfo>>();
-        for (ClassInfo cl: notStrippable) {
-            if (!cl.isDocOnly()) {
-                if (stubPackages == null || stubPackages.contains(cl.containingPackage().name())) {
-                    writeClassFile(stubsDir, cl);
-                    if (packages.containsKey(cl.containingPackage())) {
-                        packages.get(cl.containingPackage()).add(cl);
-                    } else {
-                        ArrayList<ClassInfo> classes = new ArrayList<ClassInfo>();
-                        classes.add(cl);
-                        packages.put(cl.containingPackage(), classes);
-                    }
-                }
-            }
-        }
-
-        // write out the XML
-        if (writeXML && xmlWriter != null) {
-            writeXML(xmlWriter, packages, notStrippable);
-        }
-
-        if (xmlWriter != null) {
-            xmlWriter.close();
-        }
-
-    }
-
-    public static void cantStripThis(ClassInfo cl, HashSet<ClassInfo> notStrippable, String why) {
-
-      if (!notStrippable.add(cl)) {
-        // slight optimization: if it already contains cl, it already contains
-        // all of cl's parents
-          return;
-      }
-      cl.setReasonIncluded(why);
-
-      // cant strip annotations
-      /*if (cl.annotations() != null){
-          for (AnnotationInstanceInfo ai : cl.annotations()){
-              if (ai.type() != null){
-                  cantStripThis(ai.type(), notStrippable, "1:" + cl.qualifiedName());
-              }
-          }
-      }*/
-      // cant strip any public fields or their generics
-      if (cl.allSelfFields() != null){
-          for (FieldInfo fInfo : cl.allSelfFields()){
-              if (fInfo.type() != null){
-                  if (fInfo.type().asClassInfo() != null){
-                      cantStripThis(fInfo.type().asClassInfo(), notStrippable,
-                          "2:" + cl.qualifiedName());
-                  }
-                  if (fInfo.type().typeArguments() != null){
-                      for (TypeInfo tTypeInfo : fInfo.type().typeArguments()){
-                          if (tTypeInfo.asClassInfo() != null){
-                              cantStripThis(tTypeInfo.asClassInfo(), notStrippable,
-                                  "3:" + cl.qualifiedName());
-                          }
-                      }
-                  }
-              }
-          }
-      }
-      //cant strip any of the type's generics
-      if (cl.asTypeInfo() != null){
-          if (cl.asTypeInfo().typeArguments() != null){
-              for (TypeInfo tInfo : cl.asTypeInfo().typeArguments()){
-                  if (tInfo.asClassInfo() != null){
-                      cantStripThis(tInfo.asClassInfo(), notStrippable, "4:" + cl.qualifiedName());
-                  }
-              }
-          }
-      }
-      //cant strip any of the annotation elements
-      //cantStripThis(cl.annotationElements(), notStrippable);
-      // take care of methods
-      cantStripThis(cl.allSelfMethods(), notStrippable);
-      cantStripThis(cl.allConstructors(), notStrippable);
-      // blow the outer class open if this is an inner class
-      if(cl.containingClass() != null){
-          cantStripThis(cl.containingClass(), notStrippable, "5:" + cl.qualifiedName());
-      }
-      // blow open super class and interfaces
-     ClassInfo supr = cl.realSuperclass();
-      if (supr != null) {
-          if (supr.isHidden()) {
-              // cl is a public class declared as extending a hidden superclass.
-              // this is not a desired practice but it's happened, so we deal
-              // with it by stripping off the superclass relation for purposes of
-              // generating the doc & stub information, and proceeding normally.
-              cl.init(cl.asTypeInfo(), cl.realInterfaces(), cl.realInterfaceTypes(),
-                      cl.innerClasses(), cl.allConstructors(), cl.allSelfMethods(),
-                      cl.annotationElements(), cl.allSelfFields(), cl.enumConstants(),
-                      cl.containingPackage(), cl.containingClass(),
-                      null, null, cl.annotations());
-              Errors.error(Errors.HIDDEN_SUPERCLASS,
-                      cl.position(), "Public class " + cl.qualifiedName()
-                      + " stripped of unavailable superclass "
-                      + supr.qualifiedName());
-          } else {
-              cantStripThis(supr, notStrippable, "6:" + cl.realSuperclass().name()
-                      + cl.qualifiedName());
-          }
-      }
-    }
-
-    private static void cantStripThis(MethodInfo[] mInfos , HashSet<ClassInfo> notStrippable) {
-      //for each method, blow open the parameters, throws and return types.  also blow open their generics
-      if (mInfos != null){
-          for (MethodInfo mInfo : mInfos){
-              if (mInfo.getTypeParameters() != null){
-                  for (TypeInfo tInfo : mInfo.getTypeParameters()){
-                      if (tInfo.asClassInfo() != null){
-                          cantStripThis(tInfo.asClassInfo(), notStrippable, "8:" +
-                                        mInfo.realContainingClass().qualifiedName() + ":" +
-                                        mInfo.name());
-                      }
-                  }
-              }
-              if (mInfo.parameters() != null){
-                  for (ParameterInfo pInfo : mInfo.parameters()){
-                      if (pInfo.type() != null && pInfo.type().asClassInfo() != null){
-                          cantStripThis(pInfo.type().asClassInfo(), notStrippable,
-                                        "9:"+  mInfo.realContainingClass().qualifiedName()
-                                        + ":" + mInfo.name());
-                          if (pInfo.type().typeArguments() != null){
-                              for (TypeInfo tInfoType : pInfo.type().typeArguments()){
-                                  if (tInfoType.asClassInfo() != null){
-                                      ClassInfo tcl = tInfoType.asClassInfo();
-                                      if (tcl.isHidden()) {
-                                          Errors.error(Errors.UNAVAILABLE_SYMBOL, mInfo.position(),
-                                                  "Parameter of hidden type "
-                                                  + tInfoType.fullName() + " in "
-                                                  + mInfo.containingClass().qualifiedName()
-                                                  + '.' + mInfo.name() + "()");
-                                      } else {
-                                          cantStripThis(tcl, notStrippable,
-                                                  "10:" +
-                                                  mInfo.realContainingClass().qualifiedName() + ":" +
-                                                  mInfo.name());
-                                      }
-                                  }
-                              }
-                          }
-                      }
-                  }
-              }
-              for (ClassInfo thrown : mInfo.thrownExceptions()){
-                  cantStripThis(thrown, notStrippable, "11:" +
-                                mInfo.realContainingClass().qualifiedName()
-                                +":" + mInfo.name());
-              }
-              if (mInfo.returnType() != null && mInfo.returnType().asClassInfo() != null){
-                  cantStripThis(mInfo.returnType().asClassInfo(), notStrippable,
-                                "12:" + mInfo.realContainingClass().qualifiedName() +
-                                ":" + mInfo.name());
-                  if (mInfo.returnType().typeArguments() != null){
-                      for (TypeInfo tyInfo: mInfo.returnType().typeArguments() ){
-                          if (tyInfo.asClassInfo() != null){
-                              cantStripThis(tyInfo.asClassInfo(), notStrippable,
-                                            "13:" +
-                                            mInfo.realContainingClass().qualifiedName()
-                                            + ":" + mInfo.name());
-                          }
-                      }
-                  }
-              }
-          }
-      }
-    }
-
-    static String javaFileName(ClassInfo cl) {
-        String dir = "";
-        PackageInfo pkg = cl.containingPackage();
-        if (pkg != null) {
-            dir = pkg.name();
-            dir = dir.replace('.', '/') + '/';
-        }
-        return dir + cl.name() + ".java";
-    }
-
-    static void writeClassFile(String stubsDir, ClassInfo cl) {
-        // inner classes are written by their containing class
-        if (cl.containingClass() != null) {
-            return;
-        }
-
-        // Work around the bogus "Array" class we invent for
-        // Arrays.copyOf's Class<? extends T[]> newType parameter. (http://b/2715505)
-        if (cl.containingPackage() != null && cl.containingPackage().name().equals("")) {
-            return;
-        }
-
-        String filename = stubsDir + '/' + javaFileName(cl);
-        File file = new File(filename);
-        ClearPage.ensureDirectory(file);
-
-        PrintStream stream = null;
-        try {
-            stream = new PrintStream(file);
-            writeClassFile(stream, cl);
-        }
-        catch (FileNotFoundException e) {
-            System.err.println("error writing file: " + filename);
-        }
-        finally {
-            if (stream != null) {
-                stream.close();
-            }
-        }
-    }
-
-    static void writeClassFile(PrintStream stream, ClassInfo cl) {
-        PackageInfo pkg = cl.containingPackage();
-        if (pkg != null) {
-            stream.println("package " + pkg.name() + ";");
-        }
-        writeClass(stream, cl);
-    }
-
-    static void writeClass(PrintStream stream, ClassInfo cl) {
-        writeAnnotations(stream, cl.annotations());
-
-        stream.print(DroidDoc.scope(cl) + " ");
-        if (cl.isAbstract() && !cl.isAnnotation() && !cl.isInterface()) {
-            stream.print("abstract ");
-        }
-        if (cl.isStatic()){
-            stream.print("static ");
-        }
-        if (cl.isFinal() && !cl.isEnum()) {
-            stream.print("final ");
-        }
-        if (false) {
-            stream.print("strictfp ");
-        }
-
-        HashSet<String> classDeclTypeVars = new HashSet();
-        String leafName = cl.asTypeInfo().fullName(classDeclTypeVars);
-        int bracket = leafName.indexOf('<');
-        if (bracket < 0) bracket = leafName.length() - 1;
-        int period = leafName.lastIndexOf('.', bracket);
-        if (period < 0) period = -1;
-        leafName = leafName.substring(period+1);
-
-        String kind = cl.kind();
-        stream.println(kind + " " + leafName);
-
-        TypeInfo base = cl.superclassType();
-
-        if (!"enum".equals(kind)) {
-            if (base != null && !"java.lang.Object".equals(base.qualifiedTypeName())) {
-                stream.println("  extends " + base.fullName(classDeclTypeVars));
-            }
-        }
-
-        TypeInfo[] interfaces = cl.realInterfaceTypes();
-        List<TypeInfo> usedInterfaces = new ArrayList<TypeInfo>();
-        for (TypeInfo iface : interfaces) {
-            if (notStrippable.contains(iface.asClassInfo())
-                    && !iface.asClassInfo().isDocOnly()) {
-                usedInterfaces.add(iface);
-            }
-        }
-        if (usedInterfaces.size() > 0 && !cl.isAnnotation()) {
-            // can java annotations extend other ones?
-            if (cl.isInterface() || cl.isAnnotation()) {
-                stream.print("  extends ");
-            } else {
-                stream.print("  implements ");
-            }
-            String comma = "";
-            for (TypeInfo iface: usedInterfaces) {
-                stream.print(comma + iface.fullName(classDeclTypeVars));
-                comma = ", ";
-            }
-            stream.println();
-        }
-
-        stream.println("{");
-
-        FieldInfo[] enumConstants = cl.enumConstants();
-        int N = enumConstants.length;
-        for (int i=0; i<N; i++) {
-            FieldInfo field = enumConstants[i];
-            if (!field.constantLiteralValue().equals("null")){
-            stream.println(field.name() + "(" + field.constantLiteralValue()
-                    + (i==N-1 ? ");" : "),"));
-            }else{
-              stream.println(field.name() + "(" + (i==N-1 ? ");" : "),"));
-            }
-        }
-
-        for (ClassInfo inner: cl.getRealInnerClasses()) {
-            if (notStrippable.contains(inner)
-                    && !inner.isDocOnly()){
-                writeClass(stream, inner);
-            }
-        }
-
-
-        for (MethodInfo method: cl.constructors()) {
-            if (!method.isDocOnly()) {
-                writeMethod(stream, method, true);
-            }
-        }
-
-        boolean fieldNeedsInitialization = false;
-        boolean staticFieldNeedsInitialization = false;
-        for (FieldInfo field: cl.allSelfFields()) {
-            if (!field.isDocOnly()) {
-                if (!field.isStatic() && field.isFinal() && !fieldIsInitialized(field)) {
-                    fieldNeedsInitialization = true;
-                }
-                if (field.isStatic() && field.isFinal() && !fieldIsInitialized(field)) {
-                    staticFieldNeedsInitialization = true;
-                }
-            }
-        }
-
-        // The compiler includes a default public constructor that calls the super classes
-        // default constructor in the case where there are no written constructors.
-        // So, if we hide all the constructors, java may put in a constructor
-        // that calls a nonexistent super class constructor.  So, if there are no constructors,
-        // and the super class doesn't have a default constructor, write in a private constructor
-        // that works.  TODO -- we generate this as protected, but we really should generate
-        // it as private unless it also exists in the real code.
-        if ((cl.constructors().length == 0 && (cl.getNonWrittenConstructors().length != 0
-                    || fieldNeedsInitialization))
-                && !cl.isAnnotation()
-                && !cl.isInterface()
-                && !cl.isEnum() ) {
-            //Errors.error(Errors.HIDDEN_CONSTRUCTOR,
-            //             cl.position(), "No constructors " +
-            //            "found and superclass has no parameterless constructor.  A constructor " +
-            //            "that calls an appropriate superclass constructor " +
-            //            "was automatically written to stubs.\n");
-            stream.println(cl.leafName()
-                    + "() { " + superCtorCall(cl,null)
-                    + "throw new" + " RuntimeException(\"Stub!\"); }");
-        }
-
-        for (MethodInfo method: cl.allSelfMethods()) {
-            if (cl.isEnum()) {
-                if (("values".equals(method.name())
-                            && "()".equals(method.signature()))
-                    || ("valueOf".equals(method.name())
-                            && "(java.lang.String)".equals(method.signature()))) {
-                    // skip these two methods on enums, because they're synthetic,
-                    // although for some reason javadoc doesn't mark them as synthetic,
-                    // maybe because they still want them documented
-                    continue;
-                }
-            }
-            if (!method.isDocOnly()) {
-                writeMethod(stream, method, false);
-            }
-        }
-        //Write all methods that are hidden, but override abstract methods or interface methods.
-        //These can't be hidden.
-        for (MethodInfo method : cl.getHiddenMethods()){
-            MethodInfo overriddenMethod = method.findRealOverriddenMethod(method.name(), method.signature(), notStrippable);
-            ClassInfo classContainingMethod = method.findRealOverriddenClass(method.name(),
-                                                                             method.signature());
-            if (overriddenMethod != null && !overriddenMethod.isHidden()
-                && !overriddenMethod.isDocOnly() &&
-                (overriddenMethod.isAbstract() ||
-                overriddenMethod.containingClass().isInterface())) {
-                method.setReason("1:" + classContainingMethod.qualifiedName());
-                cl.addMethod(method);
-                writeMethod(stream, method, false);
-            }
-        }
-
-        for (MethodInfo element: cl.annotationElements()) {
-            if (!element.isDocOnly()) {
-                writeAnnotationElement(stream, element);
-            }
-        }
-
-        for (FieldInfo field: cl.allSelfFields()) {
-            if (!field.isDocOnly()) {
-                writeField(stream, field);
-            }
-        }
-
-        if (staticFieldNeedsInitialization) {
-            stream.print("static { ");
-            for (FieldInfo field: cl.allSelfFields()) {
-                if (!field.isDocOnly() && field.isStatic() && field.isFinal()
-                        && !fieldIsInitialized(field) && field.constantValue() == null) {
-                    stream.print(field.name() + " = " + field.type().defaultValue()
-                            + "; ");
-                }
-            }
-            stream.println("}");
-        }
-
-        stream.println("}");
-    }
-
-
-    static void writeMethod(PrintStream stream, MethodInfo method, boolean isConstructor) {
-        String comma;
-
-        stream.print(DroidDoc.scope(method) + " ");
-        if (method.isStatic()) {
-            stream.print("static ");
-        }
-        if (method.isFinal()) {
-            stream.print("final ");
-        }
-        if (method.isAbstract()) {
-            stream.print("abstract ");
-        }
-        if (method.isSynchronized()) {
-            stream.print("synchronized ");
-        }
-        if (method.isNative()) {
-            stream.print("native ");
-        }
-        if (false /*method.isStictFP()*/) {
-            stream.print("strictfp ");
-        }
-
-        stream.print(method.typeArgumentsName(new HashSet()) + " ");
-
-        if (!isConstructor) {
-            stream.print(method.returnType().fullName(method.typeVariables()) + " ");
-        }
-        String n = method.name();
-        int pos = n.lastIndexOf('.');
-        if (pos >= 0) {
-            n = n.substring(pos + 1);
-        }
-        stream.print(n + "(");
-        comma = "";
-        int count = 1;
-        int size = method.parameters().length;
-        for (ParameterInfo param: method.parameters()) {
-            stream.print(comma + fullParameterTypeName(method, param.type(), count == size)
-                    + " " + param.name());
-            comma = ", ";
-            count++;
-        }
-        stream.print(")");
-
-        comma = "";
-        if (method.thrownExceptions().length > 0) {
-            stream.print(" throws ");
-            for (ClassInfo thrown: method.thrownExceptions()) {
-                stream.print(comma + thrown.qualifiedName());
-                comma = ", ";
-            }
-        }
-        if (method.isAbstract() || method.isNative() || method.containingClass().isInterface()) {
-            stream.println(";");
-        } else {
-            stream.print(" { ");
-            if (isConstructor) {
-                stream.print(superCtorCall(method.containingClass(), method.thrownExceptions()));
-            }
-            stream.println("throw new RuntimeException(\"Stub!\"); }");
-        }
-    }
-
-    static void writeField(PrintStream stream, FieldInfo field) {
-        stream.print(DroidDoc.scope(field) + " ");
-        if (field.isStatic()) {
-            stream.print("static ");
-        }
-        if (field.isFinal()) {
-            stream.print("final ");
-        }
-        if (field.isTransient()) {
-            stream.print("transient ");
-        }
-        if (field.isVolatile()) {
-            stream.print("volatile ");
-        }
-
-        stream.print(field.type().fullName());
-        stream.print(" ");
-        stream.print(field.name());
-
-        if (fieldIsInitialized(field)) {
-            stream.print(" = " + field.constantLiteralValue());
-        }
-
-        stream.println(";");
-    }
-
-    static boolean fieldIsInitialized(FieldInfo field) {
-        return (field.isFinal() && field.constantValue() != null)
-                || !field.type().dimension().equals("")
-                || field.containingClass().isInterface();
-    }
-
-    // Returns 'true' if the method is an @Override of a visible parent
-    // method implementation, and thus does not affect the API.
-    static boolean methodIsOverride(MethodInfo mi) {
-        // Abstract/static/final methods are always listed in the API description
-        if (mi.isAbstract() || mi.isStatic() || mi.isFinal()) {
-            return false;
-        }
-
-        // Find any relevant ancestor declaration and inspect it
-        MethodInfo om = mi.findSuperclassImplementation(notStrippable);
-        if (om != null) {
-            // Visibility mismatch is an API change, so check for it
-            if (mi.mIsPrivate == om.mIsPrivate
-                    && mi.mIsPublic == om.mIsPublic
-                    && mi.mIsProtected == om.mIsProtected) {
-                // Look only for overrides of an ancestor class implementation,
-                // not of e.g. an abstract or interface method declaration
-                if (!om.isAbstract()) {
-                    // If the parent is hidden, we can't rely on it to provide
-                    // the API
-                    if (!om.isHidden()) {
-                        // If the only "override" turns out to be in our own class
-                        // (which sometimes happens in concrete subclasses of
-                        // abstract base classes), it's not really an override
-                        if (!mi.mContainingClass.equals(om.mContainingClass)) {
-                            return true;
-                        }
-                    }
-                }
-            }
-        }
-        return false;
-    }
-
-    static boolean canCallMethod(ClassInfo from, MethodInfo m) {
-        if (m.isPublic() || m.isProtected()) {
-            return true;
-        }
-        if (m.isPackagePrivate()) {
-            String fromPkg = from.containingPackage().name();
-            String pkg = m.containingClass().containingPackage().name();
-            if (fromPkg.equals(pkg)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    // call a constructor, any constructor on this class's superclass.
-    static String superCtorCall(ClassInfo cl, ClassInfo[] thrownExceptions) {
-        ClassInfo base = cl.realSuperclass();
-        if (base == null) {
-            return "";
-        }
-        HashSet<String> exceptionNames = new HashSet<String>();
-        if (thrownExceptions != null ){
-            for (ClassInfo thrown : thrownExceptions){
-              exceptionNames.add(thrown.name());
-            }
-        }
-        MethodInfo[] ctors = base.constructors();
-        MethodInfo ctor = null;
-        //bad exception indicates that the exceptions thrown by the super constructor
-        //are incompatible with the constructor we're using for the sub class.
-        Boolean badException = false;
-        for (MethodInfo m: ctors) {
-            if (canCallMethod(cl, m)) {
-                if (m.thrownExceptions() != null){
-                    for (ClassInfo thrown : m.thrownExceptions()){
-                        if (!exceptionNames.contains(thrown.name())){
-                            badException = true;
-                        }
-                    }
-                }
-                if (badException){
-                  badException = false;
-                  continue;
-                }
-                // if it has no args, we're done
-                if (m.parameters().length == 0) {
-                    return "";
-                }
-                ctor = m;
-            }
-        }
-        if (ctor != null) {
-            String result = "";
-            result+= "super(";
-            ParameterInfo[] params = ctor.parameters();
-            int N = params.length;
-            for (int i=0; i<N; i++) {
-                TypeInfo t = params[i].type();
-                if (t.isPrimitive() && t.dimension().equals("")) {
-                    String n = t.simpleTypeName();
-                    if (("byte".equals(n)
-                            || "short".equals(n)
-                            || "int".equals(n)
-                            || "long".equals(n)
-                            || "float".equals(n)
-                            || "double".equals(n)) && t.dimension().equals("")) {
-                        result += "0";
-                    }
-                    else if ("char".equals(n)) {
-                        result += "'\\0'";
-                    }
-                    else if ("boolean".equals(n)) {
-                        result += "false";
-                    }
-                    else {
-                        result += "<<unknown-" + n + ">>";
-                    }
-                } else {
-                    //put null in each super class method.  Cast null to the correct type
-                    //to avoid collisions with other constructors.  If the type is generic
-                    //don't cast it
-                    result += (!t.isTypeVariable() ? "(" + t.qualifiedTypeName() + t.dimension() +
-                              ")" : "") + "null";
-                }
-                if (i != N-1) {
-                    result += ",";
-                }
-            }
-            result += "); ";
-            return result;
-        } else {
-            return "";
-        }
-    }
-
-    static void writeAnnotations(PrintStream stream, AnnotationInstanceInfo[] annotations) {
-        for (AnnotationInstanceInfo ann: annotations) {
-            if (!ann.type().isHidden()) {
-                stream.println(ann.toString());
-            }
-        }
-    }
-
-    static void writeAnnotationElement(PrintStream stream, MethodInfo ann) {
-        stream.print(ann.returnType().fullName());
-        stream.print(" ");
-        stream.print(ann.name());
-        stream.print("()");
-        AnnotationValueInfo def = ann.defaultAnnotationElementValue();
-        if (def != null) {
-            stream.print(" default ");
-            stream.print(def.valueString());
-        }
-        stream.println(";");
-    }
-
-    static void writeXML(PrintStream xmlWriter, HashMap<PackageInfo, List<ClassInfo>> allClasses,
-                         HashSet notStrippable) {
-        // extract the set of packages, sort them by name, and write them out in that order
-        Set<PackageInfo> allClassKeys = allClasses.keySet();
-        PackageInfo[] allPackages = allClassKeys.toArray(new PackageInfo[allClassKeys.size()]);
-        Arrays.sort(allPackages, PackageInfo.comparator);
-
-        xmlWriter.println("<api>");
-        for (PackageInfo pack : allPackages) {
-            writePackageXML(xmlWriter, pack, allClasses.get(pack), notStrippable);
-        }
-        xmlWriter.println("</api>");
-    }
-
-    static void writePackageXML(PrintStream xmlWriter, PackageInfo pack, List<ClassInfo> classList,
-                                HashSet notStrippable) {
-        ClassInfo[] classes = classList.toArray(new ClassInfo[classList.size()]);
-        Arrays.sort(classes, ClassInfo.comparator);
-        // Work around the bogus "Array" class we invent for
-        // Arrays.copyOf's Class<? extends T[]> newType parameter. (http://b/2715505)
-        if (pack.name().equals("")) {
-            return;
-        }
-        xmlWriter.println("<package name=\"" + pack.name() + "\"\n"
-                //+ " source=\"" + pack.position() + "\"\n"
-                + ">");
-        for (ClassInfo cl : classes) {
-            writeClassXML(xmlWriter, cl, notStrippable);
-        }
-        xmlWriter.println("</package>");
-
-
-    }
-
-    static void writeClassXML(PrintStream xmlWriter, ClassInfo cl, HashSet notStrippable) {
-        String scope = DroidDoc.scope(cl);
-        String deprecatedString = "";
-        String declString = (cl.isInterface()) ? "interface" : "class";
-        if (cl.isDeprecated()) {
-            deprecatedString = "deprecated";
-        } else {
-            deprecatedString = "not deprecated";
-        }
-        xmlWriter.println("<" + declString + " name=\"" + cl.name() + "\"");
-        if (!cl.isInterface() && !cl.qualifiedName().equals("java.lang.Object")) {
-            xmlWriter.println(" extends=\"" + ((cl.realSuperclass() == null)
-                            ? "java.lang.Object"
-                            : cl.realSuperclass().qualifiedName()) + "\"");
-        }
-        xmlWriter.println(" abstract=\"" + cl.isAbstract() + "\"\n"
-                + " static=\"" + cl.isStatic() + "\"\n"
-                + " final=\"" + cl.isFinal() + "\"\n"
-                + " deprecated=\"" + deprecatedString + "\"\n"
-                + " visibility=\"" + scope + "\"\n"
-                //+ " source=\"" + cl.position() + "\"\n"
-                + ">");
-
-        ClassInfo[] interfaces = cl.realInterfaces();
-        Arrays.sort(interfaces, ClassInfo.comparator);
-        for (ClassInfo iface : interfaces) {
-            if (notStrippable.contains(iface)) {
-                xmlWriter.println("<implements name=\"" + iface.qualifiedName() + "\">");
-                xmlWriter.println("</implements>");
-            }
-        }
-
-        MethodInfo[] constructors = cl.constructors();
-        Arrays.sort(constructors, MethodInfo.comparator);
-        for (MethodInfo mi : constructors) {
-            writeConstructorXML(xmlWriter, mi);
-        }
-
-        MethodInfo[] methods = cl.allSelfMethods();
-        Arrays.sort(methods, MethodInfo.comparator);
-        for (MethodInfo mi : methods) {
-            if (!methodIsOverride(mi)) {
-                writeMethodXML(xmlWriter, mi);
-            }
-        }
-
-        FieldInfo[] fields = cl.allSelfFields();
-        Arrays.sort(fields, FieldInfo.comparator);
-        for (FieldInfo fi : fields) {
-            writeFieldXML(xmlWriter, fi);
-        }
-        xmlWriter.println("</" + declString + ">");
-
-    }
-
-    static void writeMethodXML(PrintStream xmlWriter, MethodInfo mi) {
-        String scope = DroidDoc.scope(mi);
-
-        String deprecatedString = "";
-        if (mi.isDeprecated()) {
-            deprecatedString = "deprecated";
-        } else {
-            deprecatedString = "not deprecated";
-        }
-        xmlWriter.println("<method name=\"" + mi.name() + "\"\n"
-                + ((mi.returnType() != null)
-                        ? " return=\"" + makeXMLcompliant(fullParameterTypeName(mi, mi.returnType(), false)) + "\"\n"
-                        : "")
-                + " abstract=\"" + mi.isAbstract() + "\"\n"
-                + " native=\"" + mi.isNative() + "\"\n"
-                + " synchronized=\"" + mi.isSynchronized() + "\"\n"
-                + " static=\"" + mi.isStatic() + "\"\n"
-                + " final=\"" + mi.isFinal() + "\"\n"
-                + " deprecated=\""+ deprecatedString + "\"\n"
-                + " visibility=\"" + scope + "\"\n"
-                //+ " source=\"" + mi.position() + "\"\n"
-                + ">");
-
-        // write parameters in declaration order
-        int numParameters = mi.parameters().length;
-        int count = 0;
-        for (ParameterInfo pi : mi.parameters()) {
-            count++;
-            writeParameterXML(xmlWriter, mi, pi, count == numParameters);
-        }
-
-        // but write exceptions in canonicalized order
-        ClassInfo[] exceptions = mi.thrownExceptions();
-        Arrays.sort(exceptions, ClassInfo.comparator);
-        for (ClassInfo pi : exceptions) {
-          xmlWriter.println("<exception name=\"" + pi.name() +"\" type=\"" + pi.qualifiedName()
-                            + "\">");
-          xmlWriter.println("</exception>");
-        }
-        xmlWriter.println("</method>");
-    }
-
-    static void writeConstructorXML(PrintStream xmlWriter, MethodInfo mi) {
-        String scope = DroidDoc.scope(mi);
-        String deprecatedString = "";
-        if (mi.isDeprecated()) {
-            deprecatedString = "deprecated";
-        } else {
-            deprecatedString = "not deprecated";
-        }
-        xmlWriter.println("<constructor name=\"" + mi.name() + "\"\n"
-                + " type=\"" + mi.containingClass().qualifiedName() + "\"\n"
-                + " static=\"" + mi.isStatic() + "\"\n"
-                + " final=\"" + mi.isFinal() + "\"\n"
-                + " deprecated=\"" + deprecatedString + "\"\n"
-                + " visibility=\"" + scope +"\"\n"
-                //+ " source=\"" + mi.position() + "\"\n"
-                + ">");
-
-        int numParameters = mi.parameters().length;
-        int count = 0;
-        for (ParameterInfo pi : mi.parameters()) {
-            count++;
-            writeParameterXML(xmlWriter, mi, pi, count == numParameters);
-        }
-
-        ClassInfo[] exceptions = mi.thrownExceptions();
-        Arrays.sort(exceptions, ClassInfo.comparator);
-        for (ClassInfo pi : exceptions) {
-            xmlWriter.println("<exception name=\"" + pi.name() +"\" type=\"" + pi.qualifiedName()
-                              + "\">");
-            xmlWriter.println("</exception>");
-        }
-        xmlWriter.println("</constructor>");
-  }
-
-    static void writeParameterXML(PrintStream xmlWriter, MethodInfo method,
-            ParameterInfo pi, boolean isLast) {
-        xmlWriter.println("<parameter name=\"" + pi.name() + "\" type=\"" +
-                makeXMLcompliant(fullParameterTypeName(method, pi.type(), isLast)) + "\">");
-        xmlWriter.println("</parameter>");
-    }
-
-    static void writeFieldXML(PrintStream xmlWriter, FieldInfo fi) {
-        String scope = DroidDoc.scope(fi);
-        String deprecatedString = "";
-        if (fi.isDeprecated()) {
-            deprecatedString = "deprecated";
-        } else {
-            deprecatedString = "not deprecated";
-        }
-        //need to make sure value is valid XML
-        String value  = makeXMLcompliant(fi.constantLiteralValue());
-
-        String fullTypeName = makeXMLcompliant(fi.type().qualifiedTypeName())
-                + fi.type().dimension();
-
-        xmlWriter.println("<field name=\"" + fi.name() +"\"\n"
-                          + " type=\"" + fullTypeName + "\"\n"
-                          + " transient=\"" + fi.isTransient() + "\"\n"
-                          + " volatile=\"" + fi.isVolatile() + "\"\n"
-                          + (fieldIsInitialized(fi) ? " value=\"" + value + "\"\n" : "")
-                          + " static=\"" + fi.isStatic() + "\"\n"
-                          + " final=\"" + fi.isFinal() + "\"\n"
-                          + " deprecated=\"" + deprecatedString + "\"\n"
-                          + " visibility=\"" + scope + "\"\n"
-                          //+ " source=\"" + fi.position() + "\"\n"
-                          + ">");
-        xmlWriter.println("</field>");
-    }
-
-    static String makeXMLcompliant(String s) {
-        String returnString = "";
-        returnString = s.replaceAll("&", "&amp;");
-        returnString = returnString.replaceAll("<", "&lt;");
-        returnString = returnString.replaceAll(">", "&gt;");
-        returnString = returnString.replaceAll("\"", "&quot;");
-        returnString = returnString.replaceAll("'", "&pos;");
-        return returnString;
-    }
-
-    static String fullParameterTypeName(MethodInfo method, TypeInfo type, boolean isLast) {
-        String fullTypeName = type.fullName(method.typeVariables());
-        if (isLast && method.isVarArgs()) {
-            // TODO: note that this does not attempt to handle hypothetical
-            // vararg methods whose last parameter is a list of arrays, e.g.
-            // "Object[]...".
-            fullTypeName = type.fullNameNoDimension(method.typeVariables()) + "...";
-        }
-        return fullTypeName;
-    }
-}
diff --git a/tools/droiddoc/src/TagInfo.java b/tools/droiddoc/src/TagInfo.java
deleted file mode 100644
index d25c500..0000000
--- a/tools/droiddoc/src/TagInfo.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * 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
deleted file mode 100644
index dcdfdd9..0000000
--- a/tools/droiddoc/src/TextTagInfo.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 318a57d..0000000
--- a/tools/droiddoc/src/ThrowsTagInfo.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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
deleted file mode 100644
index ebef27e..0000000
--- a/tools/droiddoc/src/TodoFile.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 45e9db9..0000000
--- a/tools/droiddoc/src/TypeInfo.java
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import org.clearsilver.HDF;
-import org.clearsilver.CS;
-import java.util.*;
-import java.io.*;
-
-public class TypeInfo
-{
-    public TypeInfo(boolean isPrimitive, String dimension,
-            String simpleTypeName, String qualifiedTypeName,
-            ClassInfo cl)
-    {
-        mIsPrimitive = isPrimitive;
-        mDimension = dimension;
-        mSimpleTypeName = simpleTypeName;
-        mQualifiedTypeName = qualifiedTypeName;
-        mClass = cl;
-    }
-
-    public ClassInfo asClassInfo()
-    {
-        return mClass;
-    }
-
-    public boolean isPrimitive()
-    {
-        return mIsPrimitive;
-    }
-
-    public String dimension()
-    {
-        return mDimension;
-    }
-
-    public String simpleTypeName()
-    {
-        return mSimpleTypeName;
-    }
-
-    public String qualifiedTypeName()
-    {
-        return mQualifiedTypeName;
-    }
-
-    public String fullName()
-    {
-        if (mFullName != null) {
-            return mFullName;
-        } else {
-            return fullName(new HashSet());
-        }
-    }
-
-    public static String typeArgumentsName(TypeInfo[] args, HashSet<String> typeVars)
-    {
-        String result = "<";
-        for (int i=0; i<args.length; i++) {
-            result += args[i].fullName(typeVars);
-            if (i != args.length-1) {
-                result += ", ";
-            }
-        }
-        result += ">";
-        return result;
-    }
-
-    public String fullName(HashSet<String> typeVars)
-    {
-        mFullName = fullNameNoDimension(typeVars) + mDimension;
-        return mFullName;
-    }
-
-    public String fullNameNoDimension(HashSet<String> typeVars)
-    {
-        String fullName = null;
-        if (mIsTypeVariable) {
-            if (typeVars.contains(mQualifiedTypeName)) {
-                // don't recurse forever with the parameters.  This handles
-                // Enum<K extends Enum<K>>
-                return mQualifiedTypeName;
-            }
-            typeVars.add(mQualifiedTypeName);
-        }
-/*
-        if (fullName != null) {
-            return fullName;
-        }
-*/
-        fullName = mQualifiedTypeName;
-        if (mTypeArguments != null && mTypeArguments.length > 0) {
-            fullName += typeArgumentsName(mTypeArguments, typeVars);
-        }
-        else if (mSuperBounds != null && mSuperBounds.length > 0) {
-            fullName += " super " + mSuperBounds[0].fullName(typeVars);
-            for (int i=1; i<mSuperBounds.length; i++) {
-                fullName += " & " + mSuperBounds[i].fullName(typeVars);
-            }
-        }
-        else if (mExtendsBounds != null && mExtendsBounds.length > 0) {
-            fullName += " extends " + mExtendsBounds[0].fullName(typeVars);
-            for (int i=1; i<mExtendsBounds.length; i++) {
-                fullName += " & " + mExtendsBounds[i].fullName(typeVars);
-            }
-        }
-        return fullName;
-    }
-
-    public TypeInfo[] typeArguments()
-    {
-        return mTypeArguments;
-    }
-
-    public void makeHDF(HDF data, String base)
-    {
-        makeHDFRecursive(data, base, false, false, new HashSet<String>());
-    }
-
-    public void makeQualifiedHDF(HDF data, String base)
-    {
-        makeHDFRecursive(data, base, true, false, new HashSet<String>());
-    }
-
-    public void makeHDF(HDF data, String base, boolean isLastVararg,
-            HashSet<String> typeVariables)
-    {
-        makeHDFRecursive(data, base, false, isLastVararg, typeVariables);
-    }
-
-    public void makeQualifiedHDF(HDF data, String base, HashSet<String> typeVariables)
-    {
-        makeHDFRecursive(data, base, true, false, typeVariables);
-    }
-
-    private void makeHDFRecursive(HDF data, String base, boolean qualified,
-            boolean isLastVararg, HashSet<String> typeVars)
-    {
-        String label = qualified ? qualifiedTypeName() : simpleTypeName();
-        label += (isLastVararg) ? "..." : dimension();
-        data.setValue(base + ".label", label);
-        ClassInfo cl = asClassInfo();
-        if (mIsTypeVariable || mIsWildcard) {
-            // could link to an @param tag on the class to describe this
-            // but for now, just don't make it a link
-        }
-        else if (!isPrimitive() && cl != null && cl.isIncluded()) {
-            data.setValue(base + ".link", cl.htmlPage());
-            data.setValue(base + ".since", cl.getSince());
-        }
-
-        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";
-        }
-    }
-
-    @Override
-    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;
-}
diff --git a/tools/droiddoc/templates-sdk/customization.cs b/tools/droiddoc/templates-sdk/customization.cs
deleted file mode 100644
index 34f5595..0000000
--- a/tools/droiddoc/templates-sdk/customization.cs
+++ /dev/null
@@ -1,252 +0,0 @@
-<?cs # This default template file is meant to be replaced. ?>
-<?cs # Use the -tempatedir arg to javadoc to set your own directory with a replacement for this file in it. ?>
-
-
-<?cs # The default search box that goes in the header ?><?cs 
-def:default_search_box() ?>
-  <div id="search" >
-      <div id="searchForm">
-          <form accept-charset="utf-8" class="gsc-search-box" 
-                onsubmit="return submit_search()">
-            <table class="gsc-search-box" cellpadding="0" cellspacing="0"><tbody>
-                <tr>
-                  <td class="gsc-input">
-                    <input id="search_autocomplete" class="gsc-input" type="text" size="33" autocomplete="off"
-                      title="search developer docs" name="q"
-                      value="search developer docs"
-                      onFocus="search_focus_changed(this, true)"
-                      onBlur="search_focus_changed(this, false)"
-                      onkeydown="return search_changed(event, true, '<?cs var:toroot?>')"
-                      onkeyup="return search_changed(event, false, '<?cs var:toroot?>')" />
-                  <div id="search_filtered_div" class="no-display">
-                      <table id="search_filtered" cellspacing=0>
-                      </table>
-                  </div>
-                  </td>
-                  <td class="gsc-search-button">
-                    <input type="submit" value="Search" title="search" id="search-button" class="gsc-search-button" />
-                  </td>
-                  <td class="gsc-clear-button">
-                    <div title="clear results" class="gsc-clear-button">&nbsp;</div>
-                  </td>
-                </tr></tbody>
-              </table>
-          </form>
-      </div><!-- searchForm -->
-  </div><!-- search --><?cs 
-/def ?>
-
-<?cs 
-def:custom_masthead() ?>
-  <div id="header">
-      <div id="headerLeft">
-          <a href="<?cs var:toroot ?>index.html" tabindex="-1"><img
-              src="<?cs var:toroot ?>assets/images/bg_logo.png" alt="Android Developers" /></a>
-          <?cs include:"header_tabs.cs" ?>     <?cs # The links are extracted so we can better manage localization ?>
-      </div>
-      <div id="headerRight">
-          <div id="headerLinks">
-          <?cs if:template.showLanguageMenu ?>
-            <img src="<?cs var:toroot ?>assets/images/icon_world.jpg" alt="Language:" /> 
-            <span id="language">
-             	<select name="language" onChange="changeLangPref(this.value, true)">
-          			<option value="en">English&nbsp;&nbsp;&nbsp;</option>
-          			<option value="ja">日本語</option>
-          			<?cs # 
-      			    <option value="de">Deutsch</option> 
-          			<option value="es">Español</option>
-          			<option value="fr">Français</option>
-          			<option value="it">Italiano</option>
-          			<option value="zh-CN">中文 (简体)</option>
-          			<option value="zh-TW">中文 (繁體)</option>
-      			    ?>
-             	</select>	
-             	<script type="text/javascript">
-             	  <!--  
-                  loadLangPref();  
-             	   //-->
-             	</script>
-            </span>
-          <?cs /if ?>
-          <a href="http://www.android.com">Android.com</a>
-          </div><?cs 
-          call:default_search_box() ?><?cs 
-    	 	  if:reference ?>
-    			  <div id="api-level-toggle">
-    			    <input type="checkbox" id="apiLevelCheckbox" onclick="toggleApiLevelSelector(this)" />
-    			    <label for="apiLevelCheckbox" class="disabled">Filter by API Level: </label>
-    			    <select id="apiLevelSelector">
-    			      <!-- option elements added by buildApiLevelSelector() -->
-    			    </select>
-    			  </div>
-    	 	    <script>
-              var SINCE_DATA = [ <?cs 
-                each:since = since ?>'<?cs 
-                  var:since.name ?>'<?cs 
-                  if:!last(since) ?>, <?cs /if ?><?cs
-                /each 
-              ?> ];
-              buildApiLevelSelector();
-            </script><?cs 
-    			/if ?>
-      </div><!-- headerRight -->
-      <script type="text/javascript">
-        <!--  
-        changeTabLang(getLangPref());
-        //-->
-      </script>
-  </div><!-- header --><?cs 
-/def ?>
-
-<?cs 
-def:sdk_nav() ?>
-  <div class="g-section g-tpl-240" id="body-content">
-    <div class="g-unit g-first not-resizable" id="side-nav">
-      <div id="devdoc-nav"><?cs 
-        include:"../../../../frameworks/base/docs/html/sdk/sdk_toc.cs" ?>
-      </div>
-    </div> <!-- end side-nav -->
-<?cs /def ?>
-
-<?cs 
-def:resources_tab_nav() ?>
-  <div class="g-section g-tpl-240" id="body-content">
-    <div class="g-unit g-first side-nav-resizable" id="side-nav">
-      <div id="devdoc-nav"><?cs 
-        include:"../../../../frameworks/base/docs/html/resources/resources_toc.cs" ?>
-      </div>
-    </div> <!-- end side-nav -->
-    <script>
-      addLoadEvent(function() {
-        scrollIntoView("devdoc-nav");
-        });
-    </script>
-<?cs /def ?>
-
-<?cs 
-def:guide_nav() ?>
-  <div class="g-section g-tpl-240" id="body-content">
-    <div class="g-unit g-first side-nav-resizable" id="side-nav">
-      <div id="devdoc-nav"><?cs 
-        include:"../../../../frameworks/base/docs/html/guide/guide_toc.cs" ?>
-      </div>
-    </div> <!-- end side-nav -->
-    <script>
-      addLoadEvent(function() {
-        scrollIntoView("devdoc-nav");
-        });
-    </script>
-<?cs /def ?>
-
-<?cs # The default side navigation for the reference docs ?><?cs 
-def:default_left_nav() ?>
-  <div class="g-section g-tpl-240" id="body-content">
-    <div class="g-unit g-first side-nav-resizable" id="side-nav">
-      <div id="swapper">
-        <div id="nav-panels">
-          <div id="resize-packages-nav">
-            <div id="packages-nav">
-              <div id="index-links"><nobr>
-                <a href="<?cs var:toroot ?>reference/packages.html" <?cs if:(page.title == "Package Index") ?>class="selected"<?cs /if ?> >Package Index</a> | 
-                <a href="<?cs var:toroot ?>reference/classes.html" <?cs if:(page.title == "Class Index") ?>class="selected"<?cs /if ?>>Class Index</a></nobr>
-              </div>
-              <ul>
-              	<?cs call:package_link_list(docs.packages) ?>
-              </ul><br/>
-            </div> <!-- end packages -->
-          </div> <!-- end resize-packages -->
-          <div id="classes-nav"><?cs 
-            if:subcount(class.package) ?>
-            <ul>
-              <?cs call:list("Interfaces", class.package.interfaces) ?>
-              <?cs call:list("Classes", class.package.classes) ?>
-              <?cs call:list("Enums", class.package.enums) ?>
-              <?cs call:list("Exceptions", class.package.exceptions) ?>
-              <?cs call:list("Errors", class.package.errors) ?>
-            </ul><?cs 
-            elif:subcount(package) ?>
-            <ul>
-              <?cs call:class_link_list("Interfaces", package.interfaces) ?>
-              <?cs call:class_link_list("Classes", package.classes) ?>
-              <?cs call:class_link_list("Enums", package.enums) ?>
-              <?cs call:class_link_list("Exceptions", package.exceptions) ?>
-              <?cs call:class_link_list("Errors", package.errors) ?>
-            </ul><?cs 
-            else ?>
-              <script>
-                /*addLoadEvent(maxPackageHeight);*/
-              </script>
-              <p style="padding:10px">Select a package to view its members</p><?cs 
-            /if ?><br/>
-          </div><!-- end classes -->
-        </div><!-- end nav-panels -->
-        <div id="nav-tree" style="display:none">
-          <div id="index-links"><nobr>
-            <a href="<?cs var:toroot ?>reference/packages.html" <?cs if:(page.title == "Package Index") ?>class="selected"<?cs /if ?> >Package Index</a> | 
-            <a href="<?cs var:toroot ?>reference/classes.html" <?cs if:(page.title == "Class Index") ?>class="selected"<?cs /if ?>>Class Index</a></nobr>
-          </div>
-        </div><!-- end nav-tree -->
-      </div><!-- end swapper -->
-    </div> <!-- end side-nav -->
-    <script>
-      if (!isMobile) {
-        $("<a href='#' id='nav-swap' onclick='swapNav();return false;' style='font-size:10px;line-height:9px;margin-left:1em;text-decoration:none;'><span id='tree-link'>Use Tree Navigation</span><span id='panel-link' style='display:none'>Use Panel Navigation</span></a>").appendTo("#side-nav");
-        chooseDefaultNav();
-        if ($("#nav-tree").is(':visible')) {
-          init_default_navtree("<?cs var:toroot ?>");
-        } else {
-          addLoadEvent(function() {
-            scrollIntoView("packages-nav");
-            scrollIntoView("classes-nav");
-          });
-        }
-        $("#swapper").css({borderBottom:"2px solid #aaa"});
-      } else {
-        swapNav(); // tree view should be used on mobile
-      }
-    </script><?cs 
-/def ?>
-
-<?cs 
-def:custom_left_nav() ?><?cs 
-  if:guide ?><?cs 
-    call:guide_nav() ?><?cs 
-  elif:resources ?><?cs 
-    call:resources_tab_nav() ?><?cs 
-  elif:sdk ?><?cs 
-    call:sdk_nav() ?><?cs 
-  else ?><?cs 
-    call:default_left_nav() ?><?cs 
-  /if ?><?cs 
-/def ?>
-
-<?cs # appears at the bottom of every page ?><?cs 
-def:custom_cc_copyright() ?>
-  Except as noted, this content is 
-  licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
-  Creative Commons Attribution 2.5</a>. For details and 
-  restrictions, see the <a href="<?cs var:toroot ?>license.html">Content 
-  License</a>.<?cs 
-/def ?>
-
-<?cs 
-def:custom_copyright() ?>
-  Except as noted, this content is licensed under <a
-  href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a>. 
-  For details and restrictions, see the <a href="<?cs var:toroot ?>license.html">
-  Content License</a>.<?cs 
-/def ?>
-
-<?cs 
-def:custom_footerlinks() ?>
-  <p>
-    <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
-    <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
-    <a href="http://www.android.com/branding.html">Brand Guidelines</a>
-  </p><?cs 
-/def ?>
-
-<?cs # appears on the right side of the blue bar at the bottom off every page ?><?cs 
-def:custom_buildinfo() ?>
-  Android <?cs var:sdk.version ?>&nbsp;r<?cs var:sdk.rel.id ?> - <?cs var:page.now ?>
-<?cs /def ?>
diff --git a/tools/droiddoc/templates-sdk/customizations.cs b/tools/droiddoc/templates-sdk/customizations.cs
new file mode 100644
index 0000000..48ed591
--- /dev/null
+++ b/tools/droiddoc/templates-sdk/customizations.cs
@@ -0,0 +1,151 @@
+<?cs 
+def:sdk_nav() ?>
+  <div class="g-section g-tpl-240" id="body-content">
+    <div class="g-unit g-first not-resizable" id="side-nav">
+      <div id="devdoc-nav"><?cs 
+        include:"../../../../frameworks/base/docs/html/sdk/sdk_toc.cs" ?>
+      </div>
+    </div> <!-- end side-nav -->
+<?cs /def ?>
+<?cs 
+def:resources_tab_nav() ?>
+  <div class="g-section g-tpl-240" id="body-content">
+    <div class="g-unit g-first side-nav-resizable" id="side-nav">
+      <div id="devdoc-nav"><?cs 
+        include:"../../../../frameworks/base/docs/html/resources/resources_toc.cs" ?>
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      addLoadEvent(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+<?cs /def ?>
+<?cs 
+def:guide_nav() ?>
+  <div class="g-section g-tpl-240" id="body-content">
+    <div class="g-unit g-first side-nav-resizable" id="side-nav">
+      <div id="devdoc-nav"><?cs 
+        include:"../../../../frameworks/base/docs/html/guide/guide_toc.cs" ?>
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      addLoadEvent(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+<?cs /def ?>
+
+<?cs # The default side navigation for the reference docs ?><?cs 
+def:default_left_nav() ?>
+  <div class="g-section g-tpl-240" id="body-content">
+    <div class="g-unit g-first side-nav-resizable" id="side-nav">
+      <div id="swapper">
+        <div id="nav-panels">
+          <div id="resize-packages-nav">
+            <div id="packages-nav">
+              <div id="index-links"><nobr>
+                <a href="<?cs var:toroot ?>reference/packages.html" <?cs if:(page.title == "Package Index") ?>class="selected"<?cs /if ?> >Package Index</a> | 
+                <a href="<?cs var:toroot ?>reference/classes.html" <?cs if:(page.title == "Class Index") ?>class="selected"<?cs /if ?>>Class Index</a></nobr>
+              </div>
+              <ul>
+              	<?cs call:package_link_list(docs.packages) ?>
+              </ul><br/>
+            </div> <!-- end packages -->
+          </div> <!-- end resize-packages -->
+          <div id="classes-nav"><?cs 
+            if:subcount(class.package) ?>
+            <ul>
+              <?cs call:list("Interfaces", class.package.interfaces) ?>
+              <?cs call:list("Classes", class.package.classes) ?>
+              <?cs call:list("Enums", class.package.enums) ?>
+              <?cs call:list("Exceptions", class.package.exceptions) ?>
+              <?cs call:list("Errors", class.package.errors) ?>
+            </ul><?cs 
+            elif:subcount(package) ?>
+            <ul>
+              <?cs call:class_link_list("Interfaces", package.interfaces) ?>
+              <?cs call:class_link_list("Classes", package.classes) ?>
+              <?cs call:class_link_list("Enums", package.enums) ?>
+              <?cs call:class_link_list("Exceptions", package.exceptions) ?>
+              <?cs call:class_link_list("Errors", package.errors) ?>
+            </ul><?cs 
+            else ?>
+              <script>
+                /*addLoadEvent(maxPackageHeight);*/
+              </script>
+              <p style="padding:10px">Select a package to view its members</p><?cs 
+            /if ?><br/>
+          </div><!-- end classes -->
+        </div><!-- end nav-panels -->
+        <div id="nav-tree" style="display:none">
+          <div id="index-links"><nobr>
+            <a href="<?cs var:toroot ?>reference/packages.html" <?cs if:(page.title == "Package Index") ?>class="selected"<?cs /if ?> >Package Index</a> | 
+            <a href="<?cs var:toroot ?>reference/classes.html" <?cs if:(page.title == "Class Index") ?>class="selected"<?cs /if ?>>Class Index</a></nobr>
+          </div>
+        </div><!-- end nav-tree -->
+      </div><!-- end swapper -->
+    </div> <!-- end side-nav -->
+    <script>
+      if (!isMobile) {
+        $("<a href='#' id='nav-swap' onclick='swapNav();return false;' style='font-size:10px;line-height:9px;margin-left:1em;text-decoration:none;'><span id='tree-link'>Use Tree Navigation</span><span id='panel-link' style='display:none'>Use Panel Navigation</span></a>").appendTo("#side-nav");
+        chooseDefaultNav();
+        if ($("#nav-tree").is(':visible')) {
+          init_default_navtree("<?cs var:toroot ?>");
+        } else {
+          addLoadEvent(function() {
+            scrollIntoView("packages-nav");
+            scrollIntoView("classes-nav");
+          });
+        }
+        $("#swapper").css({borderBottom:"2px solid #aaa"});
+      } else {
+        swapNav(); // tree view should be used on mobile
+      }
+    </script><?cs 
+/def ?>
+
+<?cs 
+def:custom_left_nav() ?><?cs 
+  if:guide ?><?cs 
+    call:guide_nav() ?><?cs 
+  elif:resources ?><?cs 
+    call:resources_tab_nav() ?><?cs 
+  elif:sdk ?><?cs 
+    call:sdk_nav() ?><?cs 
+  else ?><?cs 
+    call:default_left_nav() ?><?cs 
+  /if ?><?cs 
+/def ?>
+
+<?cs # appears at the bottom of every page ?><?cs 
+def:custom_cc_copyright() ?>
+  Except as noted, this content is 
+  licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
+  Creative Commons Attribution 2.5</a>. For details and 
+  restrictions, see the <a href="<?cs var:toroot ?>license.html">Content 
+  License</a>.<?cs 
+/def ?>
+
+<?cs 
+def:custom_copyright() ?>
+  Except as noted, this content is licensed under <a
+  href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a>. 
+  For details and restrictions, see the <a href="<?cs var:toroot ?>license.html">
+  Content License</a>.<?cs 
+/def ?>
+
+<?cs 
+def:custom_footerlinks() ?>
+  <p>
+    <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+    <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+    <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+  </p><?cs 
+/def ?>
+
+<?cs # appears on the right side of the blue bar at the bottom off every page ?><?cs 
+def:custom_buildinfo() ?>
+  Android <?cs var:sdk.version ?>&nbsp;r<?cs var:sdk.rel.id ?> - <?cs var:page.now ?>
+<?cs /def ?>
+
diff --git a/tools/droiddoc/templates/class.cs b/tools/droiddoc/templates/class.cs
deleted file mode 100644
index d2add18..0000000
--- a/tools/droiddoc/templates/class.cs
+++ /dev/null
@@ -1,623 +0,0 @@
-<?cs include:"doctype.cs" ?>
-<?cs include:"macros.cs" ?>
-<html>
-<?cs include:"head_tag.cs" ?>
-<body class="<?cs var:class.since ?>">
-<?cs include:"header.cs" ?>
-
-<div class="g-unit" id="doc-content">
-
-<div id="api-info-block">
-
-<?cs # are there inherited members ?>
-<?cs each:cl=class.inherited ?>
-  <?cs if:subcount(cl.methods) ?>
-   <?cs set:inhmethods = #1 ?>
-  <?cs /if ?>
-  <?cs if:subcount(cl.constants) ?>
-   <?cs set:inhconstants = #1 ?>
-  <?cs /if ?>
-  <?cs if:subcount(cl.fields) ?>
-   <?cs set:inhfields = #1 ?>
-  <?cs /if ?>
-  <?cs if:subcount(cl.attrs) ?>
-   <?cs set:inhattrs = #1 ?>
-  <?cs /if ?>
-<?cs /each ?>
-
-<div class="sum-details-links">
-Summary:
-<?cs if:subcount(class.inners) ?>
-  <a href="#nestedclasses">Nested Classes</a>
-  <?cs set:linkcount = #1 ?>
-<?cs /if ?>
-<?cs if:subcount(class.attrs) ?>
-  <?cs if:linkcount ?>&#124; <?cs /if ?><a href="#lattrs">XML Attrs</a>
-  <?cs set:linkcount = #1 ?>
-<?cs /if ?>
-<?cs if:inhattrs ?>
-  <?cs if:linkcount ?>&#124; <?cs /if ?><a href="#inhattrs">Inherited XML Attrs</a>
-  <?cs set:linkcount = #1 ?>
-<?cs /if ?>
-<?cs if:subcount(class.enumConstants) ?>
-  <?cs if:linkcount ?>&#124; <?cs /if ?><a href="#enumconstants">Enums</a>
-  <?cs set:linkcount = #1 ?>
-<?cs /if ?>
-<?cs if:subcount(class.constants) ?>
-  <?cs if:linkcount ?>&#124; <?cs /if ?><a href="#constants">Constants</a>
-  <?cs set:linkcount = #1 ?>
-<?cs /if ?>
-<?cs if:inhconstants ?>
-  <?cs if:linkcount ?>&#124; <?cs /if ?><a href="#inhconstants">Inherited Constants</a>
-  <?cs set:linkcount = #1 ?>
-<?cs /if ?>
-<?cs if:subcount(class.fields) ?>
-  <?cs if:linkcount ?>&#124; <?cs /if ?><a href="#lfields">Fields</a>
-  <?cs set:linkcount = #1 ?>
-<?cs /if ?>
-<?cs if:inhfields ?>
-  <?cs if:linkcount ?>&#124; <?cs /if ?><a href="#inhfields">Inherited Fields</a>
-  <?cs set:linkcount = #1 ?>
-<?cs /if ?>
-<?cs if:subcount(class.ctors.public) ?>
-  <?cs if:linkcount ?>&#124; <?cs /if ?><a href="#pubctors">Ctors</a>
-  <?cs set:linkcount = #1 ?>
-<?cs /if ?>
-<?cs if:subcount(class.ctors.protected) ?>
-  <?cs if:linkcount ?>&#124; <?cs /if ?><a href="#proctors">Protected Ctors</a>
-  <?cs set:linkcount = #1 ?>
-<?cs /if ?>
-<?cs if:subcount(class.methods.public) ?>
-  <?cs if:linkcount ?>&#124; <?cs /if ?><a href="#pubmethods">Methods</a>
-  <?cs set:linkcount = #1 ?>
-<?cs /if ?>
-<?cs if:subcount(class.methods.protected) ?>
-  <?cs if:linkcount ?>&#124; <?cs /if ?><a href="#promethods">Protected Methods</a>
-  <?cs set:linkcount = #1 ?>
-<?cs /if ?>
-<?cs if:inhmethods ?>
-  <?cs if:linkcount ?>&#124; <?cs /if ?><a href="#inhmethods">Inherited Methods</a>
-<?cs /if ?>
-<?cs if:inhattrs || inhconstants || inhfields || inhmethods || subcount(class.subclasses.direct) || subcount(class.subclasses.indirect) ?>
-&#124; <a href="#" onclick="return toggleAllClassInherited()" id="toggleAllClassInherited">[Expand All]</a>
-<?cs /if ?>
-</div><!-- end sum-details-links -->
-<div class="api-level">
-  <?cs call:since_tags(class) ?>
-</div>
-</div><!-- end api-info-block -->
-
-<?cs # this next line must be exactly like this to be parsed by eclipse ?>
-<!-- ======== START OF CLASS DATA ======== -->
-
-<div id="jd-header">
-    <?cs var:class.scope ?>
-    <?cs var:class.static ?> 
-    <?cs var:class.final ?> 
-    <?cs var:class.abstract ?>
-    <?cs var:class.kind ?>
-<h1><?cs var:class.name ?></h1>
-
-<?cs set:colspan = subcount(class.inheritance) ?>
-<?cs each:supr = class.inheritance ?>
-  <?cs if:colspan == 2 ?>
-    extends <?cs call:type_link(supr.short_class) ?><br/>
-  <?cs /if ?>
-  <?cs if:last(supr) && subcount(supr.interfaces) ?>
-      implements 
-      <?cs each:t=supr.interfaces ?>
-        <?cs call:type_link(t) ?> 
-      <?cs /each ?>
-  <?cs /if ?>
-  <?cs set:colspan = colspan-1 ?>
-<?cs /each ?>
-
-</div><!-- end header -->
-
-<div id="naMessage"></div>
-
-<div id="jd-content" class="api apilevel-<?cs var:class.since ?>">
-<table class="jd-inheritance-table">
-<?cs set:colspan = subcount(class.inheritance) ?>
-<?cs each:supr = class.inheritance ?>
-    <tr>
-        <?cs loop:i = 1, (subcount(class.inheritance)-colspan), 1 ?>
-            <td class="jd-inheritance-space">&nbsp;<?cs if:(subcount(class.inheritance)-colspan) == i ?>&nbsp;&nbsp;&#x21b3;<?cs /if ?></td>
-        <?cs /loop ?> 	
-        <td colspan="<?cs var:colspan ?>" class="jd-inheritance-class-cell"><?cs
-            if:colspan == 1
-                ?><?cs call:class_name(class.qualifiedType) ?><?cs 
-            else 
-                ?><?cs call:type_link(supr.class) ?><?cs
-            /if ?></td>
-    </tr>
-    <?cs set:colspan = colspan-1 ?>
-<?cs /each ?>
-</table>
-
-<?cs # this next line must be exactly like this to be parsed by eclipse ?>
-
-<?cs if:subcount(class.subclasses.direct) ?>
-<table class="jd-sumtable jd-sumtable-subclasses"><tr><td colspan="12" style="border:none;margin:0;padding:0;">
-<?cs call:expando_trigger("subclasses-direct", "closed") ?>Known Direct Subclasses
-<?cs call:expandable_class_list("subclasses-direct", class.subclasses.direct, "list") ?>
-</td></tr></table>
-<?cs /if ?>
-
-<?cs if:subcount(class.subclasses.indirect) ?>
-<table class="jd-sumtable jd-sumtable-subclasses"><tr><td colspan="12" style="border:none;margin:0;padding:0;">
-<?cs call:expando_trigger("subclasses-indirect", "closed") ?>Known Indirect Subclasses
-<?cs call:expandable_class_list("subclasses-indirect", class.subclasses.indirect, "list") ?>
-</td></tr></table>
-<?cs /if ?>
-
-<div class="jd-descr">
-<?cs call:deprecated_warning(class) ?>
-<?cs if:subcount(class.descr) ?>
-<h2>Class Overview</h2>
-<p><?cs call:tag_list(class.descr) ?></p>
-<?cs /if ?>
-
-<?cs call:see_also_tags(class.seeAlso) ?>
-
-</div><!-- jd-descr -->
-
-
-<?cs # summary macros ?>
-
-<?cs def:write_method_summary(methods, included) ?>
-<?cs set:count = #1 ?>
-<?cs each:method = methods ?>
-	 <?cs # The apilevel-N class MUST BE LAST in the sequence of class names ?>
-    <tr class="<?cs if:count % #2 ?>alt-color<?cs /if ?> api apilevel-<?cs var:method.since ?>" >
-        <td class="jd-typecol"><nobr>
-            <?cs var:method.abstract ?>
-            <?cs var:method.synchronized ?>
-            <?cs var:method.final ?>
-            <?cs var:method.static ?>
-            <?cs call:type_link(method.generic) ?>
-            <?cs call:type_link(method.returnType) ?></nobr>
-        </td>
-        <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad"><?cs call:cond_link(method.name, toroot, method.href, included) ?></span>(<?cs call:parameter_list(method.params) ?>)</nobr>
-        <?cs if:subcount(method.shortDescr) || subcount(method.deprecated) ?>
-        <div class="jd-descrdiv"><?cs call:short_descr(method) ?></div>
-  <?cs /if ?>
-  </td></tr>
-<?cs set:count = count + #1 ?>
-<?cs /each ?>
-<?cs /def ?>
-
-<?cs def:write_field_summary(fields, included) ?>
-<?cs set:count = #1 ?>
-    <?cs each:field=fields ?>
-      <tr class="<?cs if:count % #2 ?>alt-color<?cs /if ?> api apilevel-<?cs var:field.since ?>" >
-          <td class="jd-typecol"><nobr>
-          <?cs var:field.scope ?>
-          <?cs var:field.static ?>
-          <?cs var:field.final ?>
-          <?cs call:type_link(field.type) ?></nobr></td>
-          <td class="jd-linkcol"><?cs call:cond_link(field.name, toroot, field.href, included) ?></td>
-          <td class="jd-descrcol" width="100%"><?cs call:short_descr(field) ?></td>
-      </tr>
-      <?cs set:count = count + #1 ?>
-    <?cs /each ?>
-<?cs /def ?>
-
-<?cs def:write_constant_summary(fields, included) ?>
-<?cs set:count = #1 ?>
-    <?cs each:field=fields ?>
-    <tr class="<?cs if:count % #2 ?>alt-color<?cs /if ?> api apilevel-<?cs var:field.since ?>" >
-        <td class="jd-typecol"><?cs call:type_link(field.type) ?></td>
-        <td class="jd-linkcol"><?cs call:cond_link(field.name, toroot, field.href, included) ?></td>
-        <td class="jd-descrcol" width="100%"><?cs call:short_descr(field) ?></td>
-    </tr>
-    <?cs set:count = count + #1 ?>
-    <?cs /each ?>
-<?cs /def ?>
-
-<?cs def:write_attr_summary(attrs, included) ?>
-<?cs set:count = #1 ?>
-    <tr>
-        <td><nobr><em>Attribute Name</em></nobr></td>
-        <td><nobr><em>Related Method</em></nobr></td>
-        <td><nobr><em>Description</em></nobr></td>
-    </tr>
-    <?cs each:attr=attrs ?>
-    <tr class="<?cs if:count % #2 ?>alt-color<?cs /if ?> api apilevel-<?cs var:attr.since ?>" >
-        <td class="jd-linkcol"><?cs if:included ?><a href="<?cs var:toroot ?><?cs var:attr.href ?>"><?cs /if ?><?cs var:attr.name ?><?cs if:included ?></a><?cs /if ?></td>
-        <td class="jd-linkcol"><?cs each:m=attr.methods ?>
-            <?cs call:cond_link(m.name, toroot, m.href, included) ?>
-            <?cs /each ?>
-        </td>
-        <td class="jd-descrcol" width="100%"><?cs call:short_descr(attr) ?>&nbsp;</td>
-    </tr>
-    <?cs set:count = count + #1 ?>
-    <?cs /each ?>
-<?cs /def ?>
-
-<?cs def:write_inners_summary(classes) ?>
-<?cs set:count = #1 ?>
-  <?cs each:cl=class.inners ?>
-    <tr class="<?cs if:count % #2 ?>alt-color<?cs /if ?> api apilevel-<?cs var:cl.since ?>" >
-      <td class="jd-typecol"><nobr>
-        <?cs var:cl.scope ?>
-        <?cs var:cl.static ?> 
-        <?cs var:cl.final ?> 
-        <?cs var:cl.abstract ?>
-        <?cs var:cl.kind ?></nobr></td>
-      <td class="jd-linkcol"><?cs call:type_link(cl.type) ?></td>
-      <td class="jd-descrcol" width="100%"><?cs call:short_descr(cl) ?>&nbsp;</td>
-    </tr>
-    <?cs set:count = count + #1 ?>
-    <?cs /each ?>
-<?cs /def ?>
-
-<?cs # end macros ?>
-
-<div class="jd-descr">
-<h2>Summary</h2>
-
-<?cs if:subcount(class.inners) ?>
-<?cs # this next line must be exactly like this to be parsed by eclipse ?>
-<!-- ======== NESTED CLASS SUMMARY ======== -->
-<table id="nestedclasses" class="jd-sumtable"><tr><th colspan="12">Nested Classes</th></tr>
-<?cs call:write_inners_summary(class.inners) ?>
-<?cs /if ?>
-
-<?cs # this next line must be exactly like this to be parsed by eclipse ?>
-<?cs if:subcount(class.attrs) ?>
-<!-- =========== FIELD SUMMARY =========== -->
-<table id="lattrs" class="jd-sumtable"><tr><th colspan="12">XML Attributes</th></tr>
-<?cs call:write_attr_summary(class.attrs, 1) ?>
-<?cs /if ?>
-
-<?cs # if there are inherited attrs, write the table ?>
-<?cs if:inhattrs ?>
-<?cs # this next line must be exactly like this to be parsed by eclipse ?>
-<!-- =========== FIELD SUMMARY =========== -->
-<table id="inhattrs" class="jd-sumtable"><tr><th>
-  <a href="#" class="toggle-all" onclick="return toggleAllInherited(this, null)">[Expand]</a>
-  <div style="clear:left;">Inherited XML Attributes</div></th></tr>
-<?cs each:cl=class.inherited ?>
-<?cs if:subcount(cl.attrs) ?>
-<tr class="api apilevel-<?cs var:cl.since ?>" >
-<td colspan="12">
-<?cs call:expando_trigger("inherited-attrs-"+cl.qualified, "closed") ?>From <?cs var:cl.kind ?>
-<?cs call:cond_link(cl.qualified, toroot, cl.link, cl.included) ?>
-<div id="inherited-attrs-<?cs var:cl.qualified ?>">
-  <div id="inherited-attrs-<?cs var:cl.qualified ?>-list"
-        class="jd-inheritedlinks">
-  </div>
-  <div id="inherited-attrs-<?cs var:cl.qualified ?>-summary" style="display: none;">
-    <table class="jd-sumtable-expando">
-    <?cs call:write_attr_summary(cl.attrs, cl.included) ?></table>
-  </div>
-</div>
-</td></tr>
-<?cs /if ?>
-<?cs /each ?>
-</table>
-<?cs /if ?>
-
-<?cs if:subcount(class.enumConstants) ?>
-<?cs # this next line must be exactly like this to be parsed by eclipse ?>
-<!-- =========== ENUM CONSTANT SUMMARY =========== -->
-<table id="enumconstants" class="jd-sumtable"><tr><th colspan="12">Enum Values</th></tr>
-<?cs set:count = #1 ?>
-    <?cs each:field=class.enumConstants ?>
-    <tr class="<?cs if:count % #2 ?>alt-color<?cs /if ?> api apilevel-<?cs var:field.since ?>" >
-        <td class="jd-descrcol"><?cs call:type_link(field.type) ?>&nbsp;</td>
-        <td class="jd-linkcol"><?cs call:cond_link(field.name, toroot, field.href, cl.included) ?>&nbsp;</td>
-        <td class="jd-descrcol" width="100%"><?cs call:short_descr(field) ?>&nbsp;</td>
-    </tr>
-    <?cs set:count = count + #1 ?>
-    <?cs /each ?>
-<?cs /if ?>
-
-<?cs if:subcount(class.constants) ?>
-<?cs # this next line must be exactly like this to be parsed by eclipse ?>
-<!-- =========== ENUM CONSTANT SUMMARY =========== -->
-<table id="constants" class="jd-sumtable"><tr><th colspan="12">Constants</th></tr>
-<?cs call:write_constant_summary(class.constants, 1) ?>
-</table>
-<?cs /if ?>
-
-<?cs # if there are inherited constants, write the table ?>
-<?cs if:inhconstants ?>
-<?cs # this next line must be exactly like this to be parsed by eclipse ?>
-<!-- =========== ENUM CONSTANT SUMMARY =========== -->
-<table id="inhconstants" class="jd-sumtable"><tr><th>
-  <a href="#" class="toggle-all" onclick="return toggleAllInherited(this, null)">[Expand]</a>
-  <div style="clear:left;">Inherited Constants</div></th></tr>
-<?cs each:cl=class.inherited ?>
-<?cs if:subcount(cl.constants) ?>
-<tr class="api apilevel-<?cs var:cl.since ?>" >
-<td colspan="12">
-<?cs call:expando_trigger("inherited-constants-"+cl.qualified, "closed") ?>From <?cs var:cl.kind ?>
-<?cs call:cond_link(cl.qualified, toroot, cl.link, cl.included) ?>
-<div id="inherited-constants-<?cs var:cl.qualified ?>">
-  <div id="inherited-constants-<?cs var:cl.qualified ?>-list"
-        class="jd-inheritedlinks">
-  </div>
-  <div id="inherited-constants-<?cs var:cl.qualified ?>-summary" style="display: none;">
-    <table class="jd-sumtable-expando">
-    <?cs call:write_constant_summary(cl.constants, cl.included) ?></table>
-  </div>
-</div>
-</td></tr>
-<?cs /if ?>
-<?cs /each ?>
-</table>
-<?cs /if ?>
-
-<?cs if:subcount(class.fields) ?>
-<?cs # this next line must be exactly like this to be parsed by eclipse ?>
-<!-- =========== FIELD SUMMARY =========== -->
-<table id="lfields" class="jd-sumtable"><tr><th colspan="12">Fields</th></tr>
-<?cs call:write_field_summary(class.fields, 1) ?>
-</table>
-<?cs /if ?>
-
-<?cs # if there are inherited fields, write the table ?>
-<?cs if:inhfields ?>
-<?cs # this next line must be exactly like this to be parsed by eclipse ?>
-<!-- =========== FIELD SUMMARY =========== -->
-<table id="inhfields" class="jd-sumtable"><tr><th>
-  <a href="#" class="toggle-all" onclick="return toggleAllInherited(this, null)">[Expand]</a>
-  <div style="clear:left;">Inherited Fields</div></th></tr>
-<?cs each:cl=class.inherited ?>
-<?cs if:subcount(cl.fields) ?>
-<tr class="api apilevel-<?cs var:cl.since ?>" >
-<td colspan="12">
-<?cs call:expando_trigger("inherited-fields-"+cl.qualified, "closed") ?>From <?cs var:cl.kind ?>
-<?cs call:cond_link(cl.qualified, toroot, cl.link, cl.included) ?>
-<div id="inherited-fields-<?cs var:cl.qualified ?>">
-  <div id="inherited-fields-<?cs var:cl.qualified ?>-list"
-        class="jd-inheritedlinks">
-  </div>
-  <div id="inherited-fields-<?cs var:cl.qualified ?>-summary" style="display: none;">
-    <table class="jd-sumtable-expando">
-    <?cs call:write_field_summary(cl.fields, cl.included) ?></table>
-  </div>
-</div>
-</td></tr>
-<?cs /if ?>
-<?cs /each ?>
-</table>
-<?cs /if ?>
-
-<?cs if:subcount(class.ctors.public) ?>
-<?cs # this next line must be exactly like this to be parsed by eclipse ?>
-<!-- ======== CONSTRUCTOR SUMMARY ======== -->
-<table id="pubctors" class="jd-sumtable"><tr><th colspan="12">Public Constructors</th></tr>
-<?cs call:write_method_summary(class.ctors.public, 1) ?>
-</table>
-<?cs /if ?>
-
-<?cs if:subcount(class.ctors.protected) ?>
-<?cs # this next line must be exactly like this to be parsed by eclipse ?>
-<!-- ======== CONSTRUCTOR SUMMARY ======== -->
-<table id="proctors" class="jd-sumtable"><tr><th colspan="12">Protected Constructors</th></tr>
-<?cs call:write_method_summary(class.ctors.protected, 1) ?>
-</table>
-<?cs /if ?>
-
-<?cs if:subcount(class.methods.public) ?>
-<?cs # this next line must be exactly like this to be parsed by eclipse ?>
-<!-- ========== METHOD SUMMARY =========== -->
-<table id="pubmethods" class="jd-sumtable"><tr><th colspan="12">Public Methods</th></tr>
-<?cs call:write_method_summary(class.methods.public, 1) ?>
-</table>
-<?cs /if ?>
-
-<?cs if:subcount(class.methods.protected) ?>
-<?cs # this next line must be exactly like this to be parsed by eclipse ?>
-<!-- ========== METHOD SUMMARY =========== -->
-<table id="promethods" class="jd-sumtable"><tr><th colspan="12">Protected Methods</th></tr>
-<?cs call:write_method_summary(class.methods.protected, 1) ?>
-</table>
-<?cs /if ?>
-
-<?cs # if there are inherited methods, write the table ?>
-<?cs if:inhmethods ?>
-<?cs # this next line must be exactly like this to be parsed by eclipse ?>
-<!-- ========== METHOD SUMMARY =========== -->
-<table id="inhmethods" class="jd-sumtable"><tr><th>
-  <a href="#" class="toggle-all" onclick="return toggleAllInherited(this, null)">[Expand]</a>
-  <div style="clear:left;">Inherited Methods</div></th></tr>
-<?cs each:cl=class.inherited ?>
-<?cs if:subcount(cl.methods) ?>
-<tr class="api apilevel-<?cs var:cl.since ?>" >
-<td colspan="12"><?cs call:expando_trigger("inherited-methods-"+cl.qualified, "closed") ?>
-From <?cs var:cl.kind ?> <?cs call:cond_link(cl.qualified, toroot, cl.link, cl.included) ?>
-<div id="inherited-methods-<?cs var:cl.qualified ?>">
-  <div id="inherited-methods-<?cs var:cl.qualified ?>-list"
-        class="jd-inheritedlinks">
-  </div>
-  <div id="inherited-methods-<?cs var:cl.qualified ?>-summary" style="display: none;">
-    <table class="jd-sumtable-expando">
-    <?cs call:write_method_summary(cl.methods, cl.included) ?></table>
-  </div>
-</div>
-</td></tr>
-<?cs /if ?>
-<?cs /each ?>
-</table>
-<?cs /if ?>
-
-</div><!-- jd-descr (summary) -->
-
-<!-- Details -->
-
-<?cs def:write_field_details(fields) ?>
-<?cs each:field=fields ?>
-<?cs # this next line must be exactly like this to be parsed by eclipse ?>
-<?cs # the A tag in the next line must remain where it is, so that Eclipse can parse the docs ?>
-<A NAME="<?cs var:field.anchor ?>"></A>
-<?cs # The apilevel-N class MUST BE LAST in the sequence of class names ?>
-<div class="jd-details api apilevel-<?cs var:field.since ?>"> 
-    <h4 class="jd-details-title">
-      <span class="normal">
-        <?cs var:field.scope ?> 
-        <?cs var:field.static ?> 
-        <?cs var:field.final ?> 
-        <?cs call:type_link(field.type) ?>
-      </span>
-        <?cs var:field.name ?>
-    </h4>
-      <div class="api-level">
-        <?cs call:since_tags(field) ?>
-      </div>
-    <div class="jd-details-descr">
-      <?cs call:description(field) ?>
-    <?cs if:subcount(field.constantValue) ?>
-        <div class="jd-tagdata">
-        <span class="jd-tagtitle">Constant Value: </span>
-        <span>
-            <?cs if:field.constantValue.isString ?>
-                <?cs var:field.constantValue.str ?>
-            <?cs else ?>
-                <?cs var:field.constantValue.dec ?>
-                (<?cs var:field.constantValue.hex ?>)
-            <?cs /if ?>
-        </span>
-        </div>
-    <?cs /if ?>
-    </div>
-</div>
-<?cs /each ?>
-<?cs /def ?>
-
-<?cs def:write_method_details(methods) ?>
-<?cs each:method=methods ?>
-<?cs # the A tag in the next line must remain where it is, so that Eclipse can parse the docs ?>
-<A NAME="<?cs var:method.anchor ?>"></A>
-<?cs # The apilevel-N class MUST BE LAST in the sequence of class names ?>
-<div class="jd-details api apilevel-<?cs var:method.since ?>"> 
-    <h4 class="jd-details-title">
-      <span class="normal">
-        <?cs var:method.scope ?> 
-        <?cs var:method.static ?> 
-        <?cs var:method.final ?> 
-        <?cs var:method.abstract ?> 
-        <?cs var:method.synchronized ?> 
-        <?cs call:type_link(method.returnType) ?>
-      </span>
-      <span class="sympad"><?cs var:method.name ?></span>
-      <span class="normal">(<?cs call:parameter_list(method.params) ?>)</span>
-    </h4>
-      <div class="api-level">
-        <?cs call:since_tags(method) ?>
-      </div>
-    <div class="jd-details-descr">
-      <?cs call:description(method) ?>
-    </div>
-</div>
-<?cs /each ?>
-<?cs /def ?>
-
-<?cs def:write_attr_details(attrs) ?>
-<?cs each:attr=attrs ?>
-<?cs # the A tag in the next line must remain where it is, so that Eclipse can parse the docs ?>
-<A NAME="<?cs var:attr.anchor ?>"></A>
-<?cs # The apilevel-N class MUST BE LAST in the sequence of class names ?>
-<div class="jd-details api apilevel-<?cs var:attr.since ?>"> 
-    <h4 class="jd-details-title"><?cs var:attr.name ?>
-    </h4>
-      <div class="api-level">
-        <?cs call:since_tags(attr) ?>
-      </div>
-    <div class="jd-details-descr">
-        <?cs call:description(attr) ?>
-
-        <div class="jd-tagdata">
-            <h5 class="jd-tagtitle">Related Methods</h5>
-            <ul class="nolist">
-            <?cs each:m=attr.methods ?>
-                <li><a href="<?cs var:toroot ?><?cs var:m.href ?>"><?cs var:m.name ?></a></li>
-            <?cs /each ?>
-            </ul>
-        </div>
-    </div>
-</div>
-<?cs /each ?>
-<?cs /def ?>
-
-
-<!-- XML Attributes -->
-<?cs if:subcount(class.attrs) ?>
-<?cs # this next line must be exactly like this to be parsed by eclipse ?>
-<!-- ========= FIELD DETAIL ======== -->
-<h2>XML Attributes</h2>
-<?cs call:write_attr_details(class.attrs) ?>
-<?cs /if ?>
-
-<!-- Enum Values -->
-<?cs if:subcount(class.enumConstants) ?>
-<?cs # this next line must be exactly like this to be parsed by eclipse ?>
-<!-- ========= ENUM CONSTANTS DETAIL ======== -->
-<h2>Enum Values</h2>
-<?cs call:write_field_details(class.enumConstants) ?>
-<?cs /if ?>
-
-<!-- Constants -->
-<?cs if:subcount(class.constants) ?>
-<?cs # this next line must be exactly like this to be parsed by eclipse ?>
-<!-- ========= ENUM CONSTANTS DETAIL ======== -->
-<h2>Constants</h2>
-<?cs call:write_field_details(class.constants) ?>
-<?cs /if ?>
-
-<!-- Fields -->
-<?cs if:subcount(class.fields) ?>
-<?cs # this next line must be exactly like this to be parsed by eclipse ?>
-<!-- ========= FIELD DETAIL ======== -->
-<h2>Fields</h2>
-<?cs call:write_field_details(class.fields) ?>
-<?cs /if ?>
-
-<!-- Public ctors -->
-<?cs if:subcount(class.ctors.public) ?>
-<?cs # this next line must be exactly like this to be parsed by eclipse ?>
-<!-- ========= CONSTRUCTOR DETAIL ======== -->
-<h2>Public Constructors</h2>
-<?cs call:write_method_details(class.ctors.public) ?>
-<?cs /if ?>
-
-<?cs # this next line must be exactly like this to be parsed by eclipse ?>
-<!-- ========= CONSTRUCTOR DETAIL ======== -->
-<!-- Protected ctors -->
-<?cs if:subcount(class.ctors.protected) ?>
-<h2>Protected Constructors</h2>
-<?cs call:write_method_details(class.ctors.protected) ?>
-<?cs /if ?>
-
-<?cs # this next line must be exactly like this to be parsed by eclipse ?>
-<!-- ========= METHOD DETAIL ======== -->
-<!-- Public methdos -->
-<?cs if:subcount(class.methods.public) ?>
-<h2>Public Methods</h2>
-<?cs call:write_method_details(class.methods.public) ?>
-<?cs /if ?>
-
-<?cs # this next line must be exactly like this to be parsed by eclipse ?>
-<!-- ========= METHOD DETAIL ======== -->
-<?cs if:subcount(class.methods.protected) ?>
-<h2>Protected Methods</h2>
-<?cs call:write_method_details(class.methods.protected) ?>
-<?cs /if ?>
-
-<?cs # the next two lines must be exactly like this to be parsed by eclipse ?>
-<!-- ========= END OF CLASS DATA ========= -->
-<A NAME="navbar_top"></A>
-
-<?cs include:"footer.cs" ?>
-</div> <!-- jd-content -->
-
-</div><!-- end doc-content -->
-
-<?cs include:"trailer.cs" ?>
-
-</body>
-</html>
diff --git a/tools/droiddoc/templates/classes.cs b/tools/droiddoc/templates/classes.cs
deleted file mode 100644
index 5a8315f..0000000
--- a/tools/droiddoc/templates/classes.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-<?cs include:"doctype.cs" ?>
-<?cs include:"macros.cs" ?>
-<html>
-<?cs include:"head_tag.cs" ?>
-<?cs include:"header.cs" ?>
-
-<div class="g-unit" id="doc-content">
-
-<div id="jd-header">
-<h1><?cs var:page.title ?></h1>
-</div>
-
-<div id="jd-content">
-
-<div class="jd-letterlist"><?cs each:letter=docs.classes ?>
-    <a href="#letter_<?cs name:letter ?>"><?cs name:letter ?></a><?cs /each?>
-</div>
-
-<?cs each:letter=docs.classes ?>
-<?cs set:count = #1 ?>
-<h2 id="letter_<?cs name:letter ?>"><?cs name:letter ?></h2>
-<table class="jd-sumtable">
-    <?cs set:cur_row = #0 ?>
-    <?cs each:cl = letter ?>
-        <tr class="<?cs if:count % #2 ?>alt-color<?cs /if ?> api apilevel-<?cs var:cl.since ?>" >
-            <td class="jd-linkcol"><?cs call:type_link(cl.type) ?></td>
-            <td class="jd-descrcol" width="100%"><?cs call:short_descr(cl) ?>&nbsp;</td>
-        </tr>
-    <?cs set:count = count + #1 ?>
-    <?cs /each ?>
-</table>
-<?cs /each ?>
-
-<?cs include:"footer.cs" ?>
-</div><!-- end jd-content -->
-</div><!-- end doc-content -->
-
-<?cs include:"trailer.cs" ?>
-
-</body>
-</html>
\ No newline at end of file
diff --git a/tools/droiddoc/templates/components/masthead.cs b/tools/droiddoc/templates/components/masthead.cs
new file mode 100644
index 0000000..e521489
--- /dev/null
+++ b/tools/droiddoc/templates/components/masthead.cs
@@ -0,0 +1,60 @@
+<?cs def:custom_masthead() ?>
+  <div id="header">
+      <div id="headerLeft">
+          <a href="<?cs var:toroot ?>index.html" tabindex="-1"><img
+              src="<?cs var:toroot ?>assets/images/bg_logo.png" alt="Android Developers" /></a>
+          <?cs include:"header_tabs.cs" ?>     <?cs # The links are extracted so we can better manage localization ?>
+      </div>
+      <div id="headerRight">
+          <div id="headerLinks">
+          <?cs if:template.showLanguageMenu ?>
+            <img src="<?cs var:toroot ?>assets/images/icon_world.jpg" alt="Language:" /> 
+            <span id="language">
+             	<select name="language" onChange="changeLangPref(this.value, true)">
+          			<option value="en">English&nbsp;&nbsp;&nbsp;</option>
+          			<option value="ja">日本語</option>
+          			<?cs # 
+      			    <option value="de">Deutsch</option> 
+          			<option value="es">Español</option>
+          			<option value="fr">Français</option>
+          			<option value="it">Italiano</option>
+          			<option value="zh-CN">中文 (简体)</option>
+          			<option value="zh-TW">中文 (繁體)</option>
+      			    ?>
+             	</select>	
+             	<script type="text/javascript">
+             	  <!--  
+                  loadLangPref();  
+             	   //-->
+             	</script>
+            </span>
+          <?cs /if ?>
+          <a href="http://www.android.com">Android.com</a>
+          </div><?cs 
+          call:default_search_box() ?><?cs 
+    	 	  if:reference ?>
+    			  <div id="api-level-toggle">
+    			    <input type="checkbox" id="apiLevelCheckbox" onclick="toggleApiLevelSelector(this)" />
+    			    <label for="apiLevelCheckbox" class="disabled">Filter by API Level: </label>
+    			    <select id="apiLevelSelector">
+    			      <!-- option elements added by buildApiLevelSelector() -->
+    			    </select>
+    			  </div>
+    	 	    <script>
+              var SINCE_DATA = [ <?cs 
+                each:since = since ?>'<?cs 
+                  var:since.name ?>'<?cs 
+                  if:!last(since) ?>, <?cs /if ?><?cs
+                /each 
+              ?> ];
+              buildApiLevelSelector();
+            </script><?cs 
+    			/if ?>
+      </div><!-- headerRight -->
+      <script type="text/javascript">
+        <!--  
+        changeTabLang(getLangPref());
+        //-->
+      </script>
+  </div><!-- header --><?cs 
+/def ?>
\ No newline at end of file
diff --git a/tools/droiddoc/templates/customization.cs b/tools/droiddoc/templates/customization.cs
deleted file mode 100644
index f6a5c1a..0000000
--- a/tools/droiddoc/templates/customization.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-<?cs # This default template file is meant to be replaced.                      ?>
-<?cs # Use the -templatedir arg to javadoc to set your own directory with a     ?>
-<?cs # replacement for this file in it. ?>
-
-
-<?cs def:default_search_box() ?><?cs /def ?>
-<?cs def:default_left_nav() ?><?cs /def ?>
-
-<?cs # appears at the top of every page ?><?cs 
-def:custom_masthead() ?>
-  <div id="header">
-      <div id="headerLeft">
-          <a href="<?cs var:toroot ?>index.html" tabindex="-1"><?cs var:page.title ?></a>
-      </div>
-      <div id="headerRight">
-          <?cs if:!online-pdk ?>
-            <?cs call:default_search_box() ?>
-          <?cs /if ?>
-      </div><!-- headerRight -->
-  </div><!-- header --><?cs 
-/def ?>
-
-<?cs # appear at the bottom of every page ?>
-<?cs def:custom_copyright() ?><?cs /def ?>
-<?cs def:custom_cc_copyright() ?><?cs /def ?>
-<?cs def:custom_footerlinks() ?><?cs /def ?>
-<?cs def:custom_buildinfo() ?>Build <?cs var:page.build ?> - <?cs var:page.now ?><?cs /def ?>
-
-<?cs # appears on the side of the page ?>
-<?cs def:custom_left_nav() ?><?cs call:default_left_nav() ?><?cs /def ?>
-
diff --git a/tools/droiddoc/templates/customizations.cs b/tools/droiddoc/templates/customizations.cs
new file mode 100644
index 0000000..59e1205
--- /dev/null
+++ b/tools/droiddoc/templates/customizations.cs
@@ -0,0 +1,5 @@
+<?cs # appear at the bottom of every page ?>
+<?cs def:custom_copyright() ?><?cs /def ?>
+<?cs def:custom_cc_copyright() ?><?cs /def ?>
+<?cs def:custom_footerlinks() ?><?cs /def ?>
+<?cs def:custom_buildinfo() ?>Build <?cs var:page.build ?> - <?cs var:page.now ?><?cs /def ?>
diff --git a/tools/droiddoc/templates/docpage.cs b/tools/droiddoc/templates/docpage.cs
deleted file mode 100644
index 9d85c6f..0000000
--- a/tools/droiddoc/templates/docpage.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-<?cs include:"doctype.cs" ?>
-<?cs include:"macros.cs" ?>
-<html>
-<?cs include:"head_tag.cs" ?>
-<body class="gc-documentation">
-<?cs include:"header.cs" ?>
-
-<div class="g-unit" id="doc-content"><a name="top"></a>
-
-<div id="jd-header" class="guide-header">
-  <span class="crumb">
-    <?cs if:parent.link ?>
-      <a href="<?cs var:parent.link ?>"><?cs var:parent.title ?></a> >
-    <?cs else ?>&nbsp;
-    <?cs /if ?>
-  </span>
-<h1><?cs var:page.title ?></h1>
-</div>
-
-  <div id="jd-content">
-
-    <div class="jd-descr">
-    <?cs call:tag_list(root.descr) ?>
-    </div>
-
-  <a href="#top" style="float:right">&uarr; Go to top</a>
-  <?cs if:parent.link ?>
-    <p><a href="<?cs var:parent.link ?>">&larr; Back to <?cs var:parent.title ?></a></p>
-  <?cs /if ?>
-  </div>
-
-<?cs include:"footer.cs" ?>
-</div><!-- end doc-content -->
-
-<?cs include:"trailer.cs" ?>
-
-</body>
-</html>
-
-
-
diff --git a/tools/droiddoc/templates/doctype.cs b/tools/droiddoc/templates/doctype.cs
deleted file mode 100644
index 763b073..0000000
--- a/tools/droiddoc/templates/doctype.cs
+++ /dev/null
@@ -1 +0,0 @@
-<!DOCTYPE html>
\ No newline at end of file
diff --git a/tools/droiddoc/templates/header.cs b/tools/droiddoc/templates/header.cs
deleted file mode 100644
index e8301be..0000000
--- a/tools/droiddoc/templates/header.cs
+++ /dev/null
@@ -1,3 +0,0 @@
-<?cs call:custom_masthead() ?>
-<?cs call:custom_left_nav() ?>
-
diff --git a/tools/droiddoc/templates/hierarchy.cs b/tools/droiddoc/templates/hierarchy.cs
deleted file mode 100644
index a607ffd..0000000
--- a/tools/droiddoc/templates/hierarchy.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-<?cs include:"macros.cs" ?>
-<html>
-<style>
-    .jd-hierarchy-spacer {
-        width: 15px;
-    }
-    .jd-hierarchy-data {
-        text-align: left;
-        vertical-align: top;
-    }
-</style>
-<?cs include:"head_tag.cs" ?>
-<?cs include:"header.cs" ?>
-
-<div class="g-unit" id="doc-content">
-
-<div id="jd-header">
-<h1><?cs var:page.title ?></h1>
-</div>
-
-<div id="jd-content">
-
-<div style="margin-left: 20px; margin-right: 20px;">
-
-<?cs def:hierarchy_list(classes) ?>
-<?cs each:cl = classes ?>
-<tr>
-    <?cs loop:x=#0,cl.indent,#1 ?><td class="jd-hierarchy-spacer"></td><?cs /loop ?>
-    <td class="jd-hierarchy-data" colspan="<?cs var:cl.colspan ?>">
-    <?cs if:cl.exists ?>
-        <?cs call:type_link(cl.class) ?>
-    <?cs else ?>
-        <?cs var:cl.value ?>
-    <?cs /if ?>
-    </td>
-    <td class="jd-hierarchy-data">
-    <?cs each:iface = cl.interfaces ?>
-        <?cs if:iface.exists ?>
-            <?cs call:type_link(iface.class) ?>
-        <?cs else ?>
-            <?cs var:iface.value ?>
-        <?cs /if ?> &nbsp;&nbsp;
-    <?cs /each ?>
-    &nbsp;
-    </td>
-</tr>
-<?cs call:hierarchy_list(cl.derived) ?>
-<?cs /each ?>
-<?cs /def ?>
-
-
-<table border="0" cellpadding="0" cellspacing="1">
-<th class="jd-hierarchy-data" colspan="<?cs var:colspan ?>">Class</th>
-<th class="jd-hierarchy-data">Interfaces</th>
-<?cs call:hierarchy_list(classes) ?>
-</table>
-
-</div>
-
-<?cs include:"footer.cs" ?>
-</div><!-- end jd-content -->
-</div><!-- end doc-content -->
-
-<?cs include:"trailer.cs" ?>
-
-</body>
-</html>
-
diff --git a/tools/droiddoc/templates/index.cs b/tools/droiddoc/templates/index.cs
deleted file mode 100644
index 15a6a59..0000000
--- a/tools/droiddoc/templates/index.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-<head>
-<meta http-equiv="refresh" content="0;url=packages.html">
-</head>
-<body>
-<?cs include:"analytics.cs" ?>
-</body>
-</html>
\ No newline at end of file
diff --git a/tools/droiddoc/templates/keywords.cs b/tools/droiddoc/templates/keywords.cs
deleted file mode 100644
index 0c8d4e3..0000000
--- a/tools/droiddoc/templates/keywords.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-<?cs include:"macros.cs" ?>
-<html>
-<?cs include:"head_tag.cs" ?>
-<?cs include:"header.cs" ?>
-
-<div class="g-unit" id="doc-content">
-
-<div id="jd-header">
-<h1><?cs var:page.title ?></h1>
-</div>
-
-<div id="jd-content">
-
-<div class="jd-letterlist"><?cs each:letter=keywords ?>
-    <a href="#letter_<?cs name:letter ?>"><?cs name:letter ?></a><?cs /each?>
-</div>
-
-<?cs each:letter=keywords ?>
-<a name="letter_<?cs name:letter ?>"></a>
-<h2><?cs name:letter ?></h2>
-<ul class="jd-letterentries">
-<?cs each:entry=letter
-?>  <li><a href="<?cs var:toroot ?><?cs var:entry.href ?>"><?cs var:entry.label
-        ?></a>&nbsp;<font class="jd-letterentrycomments">(<?cs var:entry.comment ?>)</font></li>
-<?cs /each
-?></ul>
-
-<?cs /each ?>
-
-<?cs include:"footer.cs" ?>
-</div><!-- end jd-content -->
-</div><!-- end doc-content -->
-
-<?cs include:"trailer.cs" ?>
-
-</body>
-</html>
diff --git a/tools/droiddoc/templates/lists.cs b/tools/droiddoc/templates/lists.cs
deleted file mode 100644
index 0af32b2..0000000
--- a/tools/droiddoc/templates/lists.cs
+++ /dev/null
@@ -1,5 +0,0 @@
-var DATA = [
-<?cs each:page = docs.pages
-?>      { id:<?cs var: page.id ?>, label:"<?cs var:page.label ?>", link:"<?cs var:page.link ?>", type:"<?cs var:page.type ?>" }<?cs if:!last(page) ?>,<?cs /if ?>
-<?cs /each ?>
-    ];
diff --git a/tools/droiddoc/templates/macros.cs b/tools/droiddoc/templates/macros.cs
deleted file mode 100644
index 97f5c66..0000000
--- a/tools/droiddoc/templates/macros.cs
+++ /dev/null
@@ -1,266 +0,0 @@
-<?cs # A link to a package ?><?cs 
-def:package_link(pkg) ?>
-  <a href="<?cs var:toroot ?><?cs var:pkg.link ?>"><?cs var:pkg.name ?></a><?cs 
-/def ?>
-
-<?cs # A link to a type, or not if it's a primitive type
-        link: whether to create a link at the top level, always creates links in
-              recursive invocations.
-        Expects the following fields:
-            .name
-            .link
-            .isPrimitive
-            .superBounds.N.(more links)   (... super ... & ...)
-            .extendsBounds.N.(more links) (... extends ... & ...)
-            .typeArguments.N.(more links) (< ... >)
-?><?cs 
-def:type_link_impl(type, link) ?><?cs
-  if:type.link && link=="true" ?><a href="<?cs var:toroot ?><?cs var:type.link ?>"><?cs /if
-      ?><?cs var:type.label ?><?cs if:type.link && link=="true" ?></a><?cs /if ?><?cs
-  if:subcount(type.extendsBounds) ?><?cs
-      each:t=type.extendsBounds ?><?cs
-          if:first(t) ?>&nbsp;extends&nbsp;<?cs else ?>&nbsp;&amp;&nbsp;<?cs /if ?><?cs
-          call:type_link_impl(t, "true") ?><?cs
-      /each ?><?cs
-  /if ?><?cs
-  if:subcount(type.superBounds) ?><?cs
-      each:t=type.superBounds ?><?cs
-          if:first(t) ?>&nbsp;super&nbsp;<?cs else ?>&nbsp;&amp;&nbsp;<?cs /if ?><?cs
-          call:type_link_impl(t, "true") ?><?cs
-      /each ?><?cs
-  /if ?><?cs
-  if:subcount(type.typeArguments)
-      ?>&lt;<?cs each:t=type.typeArguments ?><?cs call:type_link_impl(t, "true") ?><?cs
-          if:!last(t) ?>,&nbsp;<?cs /if ?><?cs
-      /each ?>&gt;<?cs
-  /if ?><?cs
-/def ?>
-
-<?cs def:class_name(type) ?><?cs call:type_link_impl(type, "false") ?><?cs /def ?>
-<?cs def:type_link(type) ?><?cs call:type_link_impl(type, "true") ?><?cs /def ?>
-
-<?cs # a conditional link.
-      if the "condition" parameter evals to true then the link is displayed
-      otherwise only the text is displayed
-?><?cs
-def:cond_link(text, root, path, condition) ?><?cs
-  if:condition ?><a href="<?cs var:root ?><?cs var:path ?>"><?cs /if ?><?cs var:text ?><?cs if:condition ?></a><?cs /if ?><?cs
-/def ?>
-
-
-<?cs # A comma separated parameter list ?><?cs 
-def:parameter_list(params) ?><?cs
-  each:param = params ?><?cs
-      call:type_link(param.type)?> <?cs
-      var:param.name ?><?cs
-      if: name(param)!=subcount(params)-1?>, <?cs /if ?><?cs
-  /each ?><?cs
-/def ?>
-
-<?cs # Print a list of tags (e.g. description text ?><?cs 
-def:tag_list(tags) ?><?cs
-  each:tag = tags ?><?cs
-      if:tag.name == "Text" ?><?cs var:tag.text?><?cs
-      elif:tag.kind == "@more" ?><p><?cs
-      elif:tag.kind == "@see" ?><code><a href="<?cs var:toroot ?><?cs var:tag.href ?>"><?cs var:tag.label ?></a></code><?cs
-      elif:tag.kind == "@seeHref" ?><a href="<?cs var:tag.href ?>"><?cs var:tag.label ?></a><?cs
-      elif:tag.kind == "@seeJustLabel" ?><?cs var:tag.label ?><?cs
-      elif:tag.kind == "@code" ?><code><?cs var:tag.text ?></code><?cs
-      elif:tag.kind == "@samplecode" ?><pre><?cs var:tag.text ?></pre><?cs
-      elif:tag.name == "@sample" ?><pre><?cs var:tag.text ?></pre><?cs
-      elif:tag.name == "@include" ?><?cs var:tag.text ?><?cs
-      elif:tag.kind == "@docRoot" ?><?cs var:toroot ?><?cs
-      elif:tag.kind == "@sdkCurrent" ?><?cs var:sdk.current ?><?cs
-      elif:tag.kind == "@sdkCurrentVersion" ?><?cs var:sdk.version ?><?cs
-      elif:tag.kind == "@sdkCurrentRelId" ?><?cs var:sdk.rel.id ?><?cs
-      elif:tag.kind == "@sdkPlatformVersion" ?><?cs var:sdk.platform.version ?><?cs
-      elif:tag.kind == "@sdkPlatformApiLevel" ?><?cs var:sdk.platform.apiLevel ?><?cs
-      elif:tag.kind == "@sdkPlatformMajorMinor" ?><?cs var:sdk.platform.majorMinor ?><?cs
-      elif:tag.kind == "@sdkPlatformReleaseDate" ?><?cs var:sdk.platform.releaseDate ?><?cs
-      elif:tag.kind == "@sdkPlatformDeployableDate" ?><?cs var:sdk.platform.deployableDate ?><?cs
-      elif:tag.kind == "@adtZipVersion" ?><?cs var:adt.zip.version ?><?cs
-      elif:tag.kind == "@adtZipDownload" ?><?cs var:adt.zip.download ?><?cs
-      elif:tag.kind == "@adtZipBytes" ?><?cs var:adt.zip.bytes ?><?cs
-      elif:tag.kind == "@adtZipChecksum" ?><?cs var:adt.zip.checksum ?><?cs
-      elif:tag.kind == "@inheritDoc" ?><?cs # This is the case when @inheritDoc is in something
-                                              that doesn't inherit from anything?><?cs
-      elif:tag.kind == "@attr" ?><?cs
-      else ?>{<?cs var:tag.name?> <?cs var:tag.text ?>}<?cs
-      /if ?><?cs
-  /each ?><?cs
-/def ?>
-
-<?cs # The message about This xxx is deprecated. ?><?cs 
-def:deprecated_text(kind) ?>
-  This <?cs var:kind ?> is deprecated.<?cs 
-/def ?>
-
-<?cs # Show the short-form description of something.  These come from shortDescr and deprecated ?><?cs 
-def:short_descr(obj) ?><?cs
-  if:subcount(obj.deprecated) ?>
-      <em><?cs call:deprecated_text(obj.kind) ?>
-      <?cs call:tag_list(obj.deprecated) ?></em><?cs
-  else ?><?cs call:tag_list(obj.shortDescr) ?><?cs
-  /if ?><?cs
-/def ?>
-
-<?cs # Show the red box with the deprecated warning ?><?cs 
-def:deprecated_warning(obj) ?><?cs 
-  if:subcount(obj.deprecated) ?><p>
-  <p class="caution">
-      <strong><?cs call:deprecated_text(obj.kind) ?></strong><br/> <?cs 
-      call:tag_list(obj.deprecated) ?>
-  </p><?cs 
-  /if ?><?cs 
-/def ?>
-
-<?cs # print the See Also: section ?><?cs 
-def:see_also_tags(also) ?><?cs 
-  if:subcount(also) ?>
-  <div class="jd-tagdata">
-      <h5 class="jd-tagtitle">See Also</h5>
-      <ul class="nolist"><?cs 
-        each:tag=also ?><li><?cs
-            if:tag.kind == "@see" ?><code><a href="<?cs var:toroot ?><?cs var:tag.href ?>"><?cs
-                    var:tag.label ?></a></code><?cs
-            elif:tag.kind == "@seeHref" ?><a href="<?cs var:tag.href ?>"><?cs var:tag.label ?></a><?cs
-            elif:tag.kind == "@seeJustLabel" ?><?cs var:tag.label ?><?cs
-            else ?>[ERROR: Unknown @see kind]<?cs
-            /if ?></li><?cs 
-        /each ?>
-      </ul>
-  </div><?cs 
-  /if ?>
-<?cs /def ?>
-
-<?cs # print the API Level ?><?cs
-def:since_tags(obj) ?>
-  Since: <a href="<?cs var:toroot ?>guide/appendix/api-levels.html#level<?cs var:obj.since ?>">API Level <?cs var:obj.since ?></a>
-<?cs /def ?>
-
-<?cs # Print the long-form description for something.
-       Uses the following fields: deprecated descr seeAlso since ?><?cs
-def:description(obj) ?><?cs 
-  call:deprecated_warning(obj) ?>
-  <div class="jd-tagdata jd-tagdescr"><p><?cs call:tag_list(obj.descr) ?></p></div><?cs 
-  if:subcount(obj.attrRefs) ?>
-  <div class="jd-tagdata">
-      <h5 class="jd-tagtitle">Related XML Attributes</h5>
-      <ul class="nolist"><?cs 
-        each:attr=obj.attrRefs ?>
-            <li><a href="<?cs var:toroot ?><?cs var:attr.href ?>"><?cs var:attr.name ?></a></li><?cs 
-        /each ?>
-      </ul>
-  </div><?cs 
-  /if ?><?cs 
-  if:subcount(obj.paramTags) ?>
-  <div class="jd-tagdata">
-      <h5 class="jd-tagtitle">Parameters</h5>
-      <table class="jd-tagtable"><?cs 
-      each:tag=obj.paramTags ?>
-        <tr>
-          <th><?cs if:tag.isTypeParameter ?>&lt;<?cs /if ?><?cs var:tag.name
-                  ?><?cs if:tag.isTypeParameter ?>&gt;<?cs /if ?></td>
-          <td><?cs call:tag_list(tag.comment) ?></td>
-        </tr><?cs 
-      /each ?>
-      </table>
-  </div><?cs 
-  /if ?><?cs 
-  if:subcount(obj.returns) ?>
-  <div class="jd-tagdata">
-      <h5 class="jd-tagtitle">Returns</h5>
-      <ul class="nolist"><li><?cs call:tag_list(obj.returns) ?></li></ul>
-  </div><?cs 
-  /if ?><?cs 
-  if:subcount(obj.throws) ?>
-  <div class="jd-tagdata">
-      <h5 class="jd-tagtitle">Throws</h5>
-      <table class="jd-tagtable"><?cs 
-      each:tag=obj.throws ?>  
-        <tr>
-            <th><?cs call:type_link(tag.type) ?></td>
-            <td><?cs call:tag_list(tag.comment) ?></td>
-        </tr><?cs 
-      /each ?>
-      </table>
-  </div><?cs 
-  /if ?><?cs 
-  call:see_also_tags(obj.seeAlso) ?><?cs
-/def ?>
-
-<?cs # A table of links to classes with descriptions, as in a package file or the nested classes ?><?cs
-def:class_link_table(classes) ?><?cs 
-  set:count = #1 ?>
-  <table class="jd-sumtable-expando"><?cs
-      each:cl=classes ?>
-        <tr class="<?cs if:count % #2 ?>alt-color<?cs /if ?> api apilevel-<?cs var:cl.type.since ?>" >
-              <td class="jd-linkcol"><?cs call:type_link(cl.type) ?></td>
-              <td class="jd-descrcol" width="100%"><?cs call:short_descr(cl) ?>&nbsp;</td>
-          </tr><?cs set:count = count + #1 ?><?cs
-      /each ?>
-  </table><?cs 
-/def ?>
-
-<?cs # A list of links to classes, for use in the side navigation of classes when viewing a package (panel nav) ?><?cs 
-def:class_link_list(label, classes) ?><?cs 
-  if:subcount(classes) ?>
-    <li><h2><?cs var:label ?></h2>
-      <ul><?cs 
-      each:cl=classes ?>
-        <li class="api apilevel-<?cs var:cl.type.since ?>"><?cs call:type_link(cl.type) ?></li><?cs 
-      /each ?>
-      </ul>
-    </li><?cs 
-  /if ?><?cs 
-/def ?>
-
-<?cs # A list of links to classes, for use in the side navigation of classes when viewing a class (panel nav) ?><?cs 
-def:list(label, classes) ?><?cs 
-  if:subcount(classes) ?>
-    <li><h2><?cs var:label ?></h2>
-      <ul><?cs 
-      each:cl=classes ?>
-          <li class="<?cs if:class.name == cl.label?>selected <?cs /if ?>api apilevel-<?cs var:cl.since ?>"><?cs call:type_link(cl) ?></li><?cs 
-      /each ?>
-      </ul>
-    </li><?cs 
-  /if ?><?cs 
-/def ?>
-
-<?cs # A list of links to packages, for use in the side navigation of packages (panel nav) ?><?cs 
-def:package_link_list(packages) ?><?cs 
-  each:pkg=packages ?>
-    <li class="<?cs if:(class.package.name == pkg.name) || (package.name == pkg.name)?>selected <?cs /if ?>api apilevel-<?cs var:pkg.since ?>"><?cs call:package_link(pkg) ?></li><?cs 
-  /each ?><?cs
-/def ?>
-
-<?cs # An expando trigger ?><?cs 
-def:expando_trigger(id, default) ?>
-  <a href="#" onclick="return toggleInherited(this, null)" id="<?cs var:id ?>" class="jd-expando-trigger closed"
-          ><img id="<?cs var:id ?>-trigger"
-          src="<?cs var:toroot ?>assets/images/triangle-<?cs var:default ?>.png"
-          class="jd-expando-trigger-img" /></a><?cs 
-/def ?>
-
-<?cs # An expandable list of classes ?><?cs 
-def:expandable_class_list(id, classes, default) ?>
-  <div id="<?cs var:id ?>">
-      <div id="<?cs var:id ?>-list"
-              class="jd-inheritedlinks"
-              <?cs if:default != "list" ?>style="display: none;"<?cs /if ?>
-              ><?cs 
-          each:cl=classes ?>
-              <?cs call:type_link(cl.type) ?><?cs if:!last(cl) ?>,<?cs /if ?><?cs 
-          /each ?>
-      </div>
-      <div id="<?cs var:id ?>-summary"
-              <?cs if:default != "summary" ?>style="display: none;"<?cs /if ?>
-              ><?cs 
-          call:class_link_table(classes) ?>
-      </div>
-  </div><?cs 
-/def ?>
-
-
-<?cs include:"customization.cs" ?>
diff --git a/tools/droiddoc/templates/navtree_data.cs b/tools/droiddoc/templates/navtree_data.cs
deleted file mode 100644
index c707232..0000000
--- a/tools/droiddoc/templates/navtree_data.cs
+++ /dev/null
@@ -1,4 +0,0 @@
-var NAVTREE_DATA =
-<?cs var:reference_tree ?>
-;
-
diff --git a/tools/droiddoc/templates/nosidenavpage.cs b/tools/droiddoc/templates/nosidenavpage.cs
deleted file mode 100644
index 1dec41e..0000000
--- a/tools/droiddoc/templates/nosidenavpage.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-<?cs include:"doctype.cs" ?>
-<?cs include:"macros.cs" ?>
-<html>
-<?cs include:"head_tag.cs" ?>
-<body class="gc-documentation">
-<a name="top"></a>
-<?cs call:custom_masthead() ?>
-
-<div id="body-content">
-<div id="doc-content" style="position:relative;">
-
-<?cs call:tag_list(root.descr) ?>
-
-<?cs include:"footer.cs" ?>
-</div><!-- end doc-content -->
-
-<?cs include:"trailer.cs" ?>
-
-</body>
-</html>
-
-
-
diff --git a/tools/droiddoc/templates/package-descr.cs b/tools/droiddoc/templates/package-descr.cs
deleted file mode 100644
index 08fee18..0000000
--- a/tools/droiddoc/templates/package-descr.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-<?cs include:"doctype.cs" ?>
-<?cs include:"macros.cs" ?>
-<html>
-<?cs include:"head_tag.cs" ?>
-<body class="<?cs var:package.since ?>">
-<?cs include:"header.cs" ?>
-
-<div class="g-unit" id="doc-content">
-
-<div id="api-info-block">
-<div class="api-level">
-  <?cs call:since_tags(package) ?>
-</div>
-</div>
-
-<div id="jd-header">
-  package
-  <h1><?cs var:package.name ?></b></h1>
-  <div class="jd-nav">
-      <a class="jd-navlink" href="package-summary.html">Classes</a> | Description
-  </div>
-</div><!-- end header -->
-
-<div id="naMessage"></div>
-
-<div id="jd-content" class="api apilevel-<?cs var:package.since ?>">
-<div class="jd-descr">
-<p><?cs call:tag_list(package.descr) ?></p>
-</div>
-
-<?cs include:"footer.cs" ?>
-</div><!-- end jd-content -->
-</div> <!-- end doc-content -->
-
-<?cs include:"trailer.cs" ?>
-
-</body>
-</html>
diff --git a/tools/droiddoc/templates/package-list.cs b/tools/droiddoc/templates/package-list.cs
deleted file mode 100644
index 7f0f889..0000000
--- a/tools/droiddoc/templates/package-list.cs
+++ /dev/null
@@ -1,2 +0,0 @@
-<?cs each:pkg=docs.packages ?><?cs var: pkg.name ?>
-<?cs /each ?>
diff --git a/tools/droiddoc/templates/package.cs b/tools/droiddoc/templates/package.cs
deleted file mode 100644
index b29bc77..0000000
--- a/tools/droiddoc/templates/package.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-<?cs include:"doctype.cs" ?>
-<?cs include:"macros.cs" ?>
-<html>
-<?cs include:"head_tag.cs" ?>
-<body class="<?cs var:package.since ?>">
-<?cs include:"header.cs" ?>
-
-<div class="g-unit" id="doc-content">
-
-<div id="api-info-block">
-<div class="api-level">
-  <?cs call:since_tags(package) ?>
-</div>
-</div>
-
-<div id="jd-header">
-  package
-  <h1><?cs var:package.name ?></h1>
-  <div class="jd-nav">
-      <?cs if:subcount(package.shortDescr) ?>
-        Classes | <a class="jd-navlink" href="package-descr.html">Description</a>
-      <?cs /if ?>
-  </div>
-</div><!-- end header -->
-
-<div id="naMessage"></div>
-
-<div id="jd-content" class="api apilevel-<?cs var:package.since ?>">
-
-<?cs if:subcount(package.shortDescr) ?>
-  <div class="jd-descr">
-  <p><?cs call:tag_list(package.shortDescr) ?></p>
-  <p><span class="jd-more"><a href="package-descr.html">more...</a></span></p>
-  </div>
-<?cs /if ?>
-
-<?cs def:class_table(label, classes) ?>
-  <?cs if:subcount(classes) ?>
-    <h3><?cs var:label ?></h3>
-    <div class="jd-sumtable">
-    <?cs call:class_link_table(classes) ?>
-    </div>
-  <?cs /if ?>
-<?cs /def ?>
-
-<?cs call:class_table("Interfaces", package.interfaces) ?>
-<?cs call:class_table("Classes", package.classes) ?>
-<?cs call:class_table("Enums", package.enums) ?>
-<?cs call:class_table("Exceptions", package.exceptions) ?>
-<?cs call:class_table("Errors", package.errors) ?>
-
-<?cs include:"footer.cs" ?>
-</div><!-- end jd-content -->
-</div><!-- doc-content -->
-
-<?cs include:"trailer.cs" ?>
-
-</body>
-</html>
diff --git a/tools/droiddoc/templates/packages.cs b/tools/droiddoc/templates/packages.cs
deleted file mode 100644
index c2d8c75..0000000
--- a/tools/droiddoc/templates/packages.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-<?cs include:"doctype.cs" ?>
-<?cs include:"macros.cs" ?>
-<html>
-<?cs include:"head_tag.cs" ?>
-<body class="gc-documentation">
-<?cs include:"header.cs" ?>
-
-<div class="g-unit" id="doc-content">
-
-<div id="jd-header">
-<h1><?cs var:page.title ?></h1>
-</div>
-
-<div id="jd-content">
-
-<div class="jd-descr">
-<p><?cs call:tag_list(root.descr) ?></p>
-</div>
-
-<?cs set:count = #1 ?>
-<table class="jd-sumtable">
-<?cs each:pkg = docs.packages ?>
-    <tr class="<?cs if:count % #2 ?>alt-color<?cs /if ?> api apilevel-<?cs var:pkg.since ?>" >
-        <td class="jd-linkcol"><?cs call:package_link(pkg) ?></td>
-        <td class="jd-descrcol" width="100%"><?cs call:tag_list(pkg.shortDescr) ?>&nbsp;</td>
-    </tr>
-<?cs set:count = count + #1 ?>
-<?cs /each ?>
-</table>
-
-<?cs include:"footer.cs" ?>
-</div><!-- end jd-content -->
-</div> <!-- end doc-content -->
-
-<?cs include:"trailer.cs" ?>
-
-</body>
-</html>
diff --git a/tools/droiddoc/templates/sample.cs b/tools/droiddoc/templates/sample.cs
deleted file mode 100644
index 7979b2a..0000000
--- a/tools/droiddoc/templates/sample.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-<?cs include:"doctype.cs" ?>
-<?cs include:"macros.cs" ?>
-<?cs set:resources="true" ?>
-<html>
-<?cs include:"head_tag.cs" ?>
-<?cs include:"header.cs" ?>
-<body class="gc-documentation">
-
-
-<a name="top"></a>
-<div class="g-unit" id="doc-content">
- <div id="jd-header" class="guide-header">
-  <span class="crumb">&nbsp;</span>
-  <h1><?cs var:page.title ?></h1>
- </div>
-
-<div id="jd-content">
-
-<p>The file containing the source code shown below is located in the corresponding directory in <code>&lt;sdk&gt;/platforms/android-&lt;version&gt;/samples/...</code></p>
-
-<!-- begin file contents -->
-<pre><?cs var:fileContents ?></pre>
-<!-- end file contents -->
-
-<?cs include:"footer.cs" ?>
-</div><!-- end jd-content -->
-</div> <!-- end doc-content -->
-
-<?cs include:"trailer.cs" ?>
-
-</body>
-</html>
diff --git a/tools/droiddoc/templates/sampleindex.cs b/tools/droiddoc/templates/sampleindex.cs
deleted file mode 100644
index 8a75298..0000000
--- a/tools/droiddoc/templates/sampleindex.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-<?cs include:"doctype.cs" ?>
-<?cs include:"macros.cs" ?>
-<?cs set:resources="true" ?>
-<html>
-<?cs include:"head_tag.cs" ?>
-<?cs include:"header.cs" ?>
-<body class="gc-documentation">
-
-
-<a name="top"></a>
-<div class="g-unit" id="doc-content">
- <div id="jd-header" class="guide-header">
-  <span class="crumb">&nbsp;</span>
-  <h1><?cs var:page.title ?></h1>
- </div>
-
-<div id="jd-content">
-
-<?cs var:summary ?>
-
-<?cs if:android.whichdoc == "online" ?><?cs
-  # If this is the online docs, build the src code navigation links ?>
-
-  <?cs if:subcount(subdirs) ?>
-      <h2>Subdirectories</h2>
-      <ul class="nolist">
-      <?cs each:dir=subdirs ?>
-        <li><a href="<?cs var:dir.name ?>/index.html"><?cs
-          var:dir.name ?>/</a></li>
-      <?cs /each ?>
-      </ul>
-  <?cs /if ?>
-
-  <?cs if:subcount(files) ?>
-      <h2>Files</h2>
-      <ul class="nolist">
-      <?cs each:file=files ?>
-        <li><a href="<?cs var:file.href ?>"><?cs
-          var:file.name ?></a></li>
-      <?cs /each ?>
-      </ul>
-  <?cs /if ?>
-
-<?cs else ?><?cs
-  # else, this means it's offline docs,
-          so don't show src links (we don't have the pages!) ?>
-
-<p>You can find the source code for this sample in your SDK at:</p>
-<p style="margin-left:2em">
-<code><em>&lt;sdk&gt;</em>/platforms/android-<em>&lt;version&gt;</em>/samples/</code>
-</p>
-
-<?cs /if ?><?cs # end if/else online docs ?>
-
-</div><!-- end jd-content -->
-
-<?cs include:"footer.cs" ?>
-
-</div><!-- end doc-content -->
-
-<?cs include:"trailer.cs" ?>
-
-</body>
-</html>
diff --git a/tools/droiddoc/templates/todo.cs b/tools/droiddoc/templates/todo.cs
deleted file mode 100644
index e9f7237..0000000
--- a/tools/droiddoc/templates/todo.cs
+++ /dev/null
@@ -1,99 +0,0 @@
-<html>
-<head>
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-    <title><?cs var:page.title ?></title>
-    <style type="text/css">
-    table {
-        border-width: 1px 1px 1px 1px;
-        border-spacing: 0px;
-        border-style: solid solid solid solid;
-        border-color: black black black black;
-        border-collapse: collapse;
-        background-color: white;
-    }
-    table th {
-        border-width: 1px 1px 1px 1px;
-        padding: 1px 4px 1px 3px;
-        border-style: inset inset inset inset;
-        border-color: gray gray gray gray;
-        background-color: white;
-    }
-    table td {
-        border-width: 1px 1px 1px 1px;
-        padding: 1px 4px 1px 3px;
-        border-style: inset inset inset inset;
-        border-color: gray gray gray gray;
-        background-color: white;
-    }
-    </style>
-</head>
-<body>
-<h1><?cs var:page.title ?></h1>
-
-<h2>Overall</h2>
-<table>
-<tr><th>Errors</th><td><?cs var:all.errorCount ?></td></tr>
-<tr><th>Percent Good</th><td><?cs var:all.percentGood ?></td></tr>
-<tr><th>Total Comments</th><td><?cs var:all.totalCount ?></td></tr>
-</table>
-
-<h2>Package Summary</h2>
-
-<table>
-<tr>
-    <th>Package</th>
-    <th>Errors</th>
-    <th>Percent Good</th>
-    <th>Total</th>
-</tr>
-<?cs each:pkg=packages ?>
-<tr>
-    <td><?cs var:pkg.name ?></td>
-    <td><?cs var:pkg.errorCount ?></td>
-    <td><?cs var:pkg.percentGood ?></td>
-    <td><?cs var:pkg.totalCount ?></td>
-</tr>
-<?cs /each ?>
-</table>
-
-
-<h2>Class Summary</h3>
-
-<table>
-<tr>
-    <th>Class</th>
-    <th>Errors</th>
-    <th>Percent Good</th>
-    <th>Total</th>
-</tr>
-<?cs each:cl=classes ?>
-<tr>
-    <td><a href="#class_<?cs var:cl.qualified ?>"><?cs var:cl.qualified ?></a></td>
-    <td><?cs var:cl.errorCount ?></td>
-    <td><?cs var:cl.percentGood ?></td>
-    <td><?cs var:cl.totalCount ?></td>
-</tr>
-<?cs /each ?>
-</table>
-
-<h2>Detail</h2>
-
-<?cs each:cl=classes ?>
-<h3><a name="class_<?cs var:cl.qualified ?>"><?cs var:cl.qualified ?></a></h3>
-<p>Errors: <?cs var:cl.errorCount ?><br/>
-Total: <?cs var:cl.totalCount ?><br/>
-Percent Good: <?cs var:cl.percentGood ?></p>
-<table>
-<?cs each:err=cl.errors ?>
-<tr>
-    <td><?cs var:err.pos ?></td>
-    <td><?cs var:err.name ?></td>
-    <td><?cs var:err.descr ?></td>
-</tr>
-<?cs /each ?>
-</table>
-
-<?cs /each ?>
-
-</body>
-</html>
diff --git a/tools/soslim/main.c b/tools/soslim/main.c
index e23fbce..affc2bc 100644
--- a/tools/soslim/main.c
+++ b/tools/soslim/main.c
@@ -191,7 +191,7 @@
         int prelinked = 0, retouched = 0;
         int elf_little; /* valid if prelinked != 0 */
         long prelink_addr; /* valid if prelinked != 0 */
-#define RETOUCH_MAX_SIZE 500000
+#define RETOUCH_MAX_SIZE 550000
         /* _cnt valid if retouched != 0 */
         unsigned int retouch_byte_cnt = RETOUCH_MAX_SIZE;
         char retouch_buf[RETOUCH_MAX_SIZE]; /* valid if retouched != 0 */
