diff --git a/development/ide/eclipse/.classpath b/development/ide/eclipse/.classpath
index edb6b1b..40ec20e 100644
--- a/development/ide/eclipse/.classpath
+++ b/development/ide/eclipse/.classpath
@@ -57,7 +57,6 @@
     <classpathentry kind="src" path="cts/tools/host/test"/>
     <classpathentry kind="src" path="cts/tools/signature-tools/src"/>
     <classpathentry kind="src" path="cts/tools/signature-tools/test"/>
-    <classpathentry kind="src" path="cts/tools/spec-progress/src"/>
     <classpathentry kind="src" path="cts/tools/utils"/>
     <classpathentry kind="src" path="cts/tools/vm-tests/src"/>
     <classpathentry kind="src" path="out/target/common/obj/APPS/CtsAccessibilityServiceTestCases_intermediates/src/src"/>
diff --git a/tools/spec-progress/Android.mk b/tools/spec-progress/Android.mk
deleted file mode 100644
index e4026e9..0000000
--- a/tools/spec-progress/Android.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE := spec-progress
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/etc/spec-progress | $(ACP)
-	@echo "Copy: $(PRIVATE_MODULE) ($@)"
-	$(copy-file-to-new-target)
-	$(hide) chmod 755 $@
-
-include $(LOCAL_PATH)/src/Android.mk
diff --git a/tools/spec-progress/etc/spec-progress b/tools/spec-progress/etc/spec-progress
deleted file mode 100644
index a8f14d7..0000000
--- a/tools/spec-progress/etc/spec-progress
+++ /dev/null
@@ -1,154 +0,0 @@
-#!/bin/bash
-#
-# 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.
-
-# 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.
-prog="$0"
-while [ -h "${prog}" ]; do
-    newProg=`/bin/ls -ld "${prog}"`
-    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
-    if expr "x${newProg}" : 'x/' >/dev/null; then
-        prog="${newProg}"
-    else
-        progdir=`dirname "${prog}"`
-        prog="${progdir}/${newProg}"
-    fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-cd "${oldwd}"
-
-libdir=`dirname $progdir`/framework
-
-javaOpts=""
-while expr "x$1" : 'x-J' >/dev/null; do
-    opt=`expr "$1" : '-J\(.*\)'`
-    javaOpts="${javaOpts} -${opt}"
-    shift
-done
-
-#exec java $javaOpts -jar $libdir/hat.jar "$@"
-
-#######################################################################
-# Original content of invocation script follows. Uses values cleverly
-# deduced by the above code. If you want to use this for a different
-# set of packages, adjust both the list of source directories and the
-# list of packages.
-#######################################################################
-export CLASSES=$progdir/../framework/spec-progress.jar
-export INPUT=$ANDROID_BUILD_TOP
-export OUTPUT=$ANDROID_BUILD_TOP/out/target/common/cts/spec-progress
-
-if [ "$1" != "" ]; then
-   export OUTPUT=$1
-fi
-
-javadoc -J-Xmx512m -docletpath $CLASSES -doclet SpecProgressDoclet -d $OUTPUT -sourcepath \
-$INPUT/dalvik/libcore/dalvik/src/main/java:\
-$INPUT/dalvik/libcore/annotation/src/main/java:\
-$INPUT/dalvik/libcore/archive/src/main/java:\
-$INPUT/dalvik/libcore/auth/src/main/java:\
-$INPUT/dalvik/libcore/awt-kernel/src/main/java:\
-$INPUT/dalvik/libcore/beans/src/main/java:\
-$INPUT/dalvik/libcore/crypto/src/main/java:\
-$INPUT/dalvik/libcore/logging/src/main/java:\
-$INPUT/dalvik/libcore/luni/src/main/java:\
-$INPUT/dalvik/libcore/luni-kernel/src/main/java:\
-$INPUT/dalvik/libcore/math/src/main/java:\
-$INPUT/dalvik/libcore/nio/src/main/java:\
-$INPUT/dalvik/libcore/nio_char/src/main/java:\
-$INPUT/dalvik/libcore/prefs/src/main/java:\
-$INPUT/dalvik/libcore/regex/src/main/java:\
-$INPUT/dalvik/libcore/security/src/main/java:\
-$INPUT/dalvik/libcore/security-kernel/src/main/java:\
-$INPUT/dalvik/libcore/sql/src/main/java:\
-$INPUT/dalvik/libcore/text/src/main/java:\
-$INPUT/dalvik/libcore/xml/src/main/java:\
-$INPUT/dalvik/libcore/x-net/src/main/java:\
- \
-dalvik.annotation \
-dalvik.bytecode \
-dalvik.system \
-java.io \
-java.lang \
-java.lang.annotation \
-java.lang.ref \
-java.lang.reflect \
-java.math \
-java.net \
-java.nio \
-java.nio.channels \
-java.nio.channels.spi \
-java.nio.charset \
-java.nio.charset.spi \
-java.security \
-java.security.acl \
-java.security.cert \
-java.security.interfaces \
-java.security.spec \
-java.sql \
-java.text \
-java.util \
-java.util.jar \
-java.util.logging \
-java.util.prefs \
-java.util.regex \
-java.util.zip \
-javax.crypto \
-javax.crypto.interfaces \
-javax.crypto.spec \
-javax.net \
-javax.net.ssl \
-javax.security.auth \
-javax.security.auth.callback \
-javax.security.auth.login \
-javax.security.auth.x500 \
-javax.security.cert \
-javax.sql \
-javax.xml.parsers \
-org.w3c.dom \
-org.xml.sax \
-org.xml.sax.ext \
-org.xml.sax.helpers \
-
-# Not part of core libs any more:
-# java.lang.instrument \
-# javax.sound.midi \
-# javax.sound.midi.spi \
-# javax.sound.sampled \
-# javax.sound.sampled.spi \
-# java.awt \
-# java.awt.color \
-# java.awt.event \
-# java.awt.font \
-# java.awt.geom \
-# java.awt.im \
-# java.awt.im.spi \
-# java.awt.image \
-# java.awt.image.renderable \
-# javax.imageio \
-# javax.imageio.event \
-# javax.imageio.metadata \
-# javax.imageio.plugins.bmp \
-# javax.imageio.plugins.jpeg \
-# javax.imageio.spi \
-# javax.imageio.stream \
-# java.util.concurrent \
-# java.util.concurrent.atomic \
-# java.util.concurrent.locks \
diff --git a/tools/spec-progress/src/Android.mk b/tools/spec-progress/src/Android.mk
deleted file mode 100644
index 8ab5a7b..0000000
--- a/tools/spec-progress/src/Android.mk
+++ /dev/null
@@ -1,14 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-#LOCAL_MODULE_TAGS := cts
-
-LOCAL_SRC_FILES := \
-	SpecProgressDoclet.java
-
-LOCAL_CLASSPATH := \
-	$(HOST_JDK_TOOLS_JAR)
-
-LOCAL_MODULE:= spec-progress
-
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/spec-progress/src/SpecProgressDoclet.java b/tools/spec-progress/src/SpecProgressDoclet.java
deleted file mode 100644
index 4c5b6cc..0000000
--- a/tools/spec-progress/src/SpecProgressDoclet.java
+++ /dev/null
@@ -1,1074 +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.BufferedOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import com.sun.javadoc.ClassDoc;
-import com.sun.javadoc.ConstructorDoc;
-import com.sun.javadoc.Doc;
-import com.sun.javadoc.ExecutableMemberDoc;
-import com.sun.javadoc.FieldDoc;
-import com.sun.javadoc.LanguageVersion;
-import com.sun.javadoc.MemberDoc;
-import com.sun.javadoc.MethodDoc;
-import com.sun.javadoc.PackageDoc;
-import com.sun.javadoc.ParamTag;
-import com.sun.javadoc.Parameter;
-import com.sun.javadoc.RootDoc;
-import com.sun.javadoc.Tag;
-import com.sun.javadoc.ThrowsTag;
-import com.sun.javadoc.TypeVariable;
-
-/**
- * Provides a Doclet for checking the correctness and completeness of the
- * Android core library JavaDoc (aka "the spec"). It generates an HTML-based
- * report vaguely similar to the standard JavaDoc output. The following rules
- * are currently implemented:
- * 
- * Each package must have a package.html doc, and all classes must be documented
- * as described below.
- * 
- * Each class must have an individual doc and all members (fields, constructors,
- * methods) must be documented as described below. All type parameters on class 
- * level need to be documented.
- * 
- * Each member must have an individual doc.
- * 
- * Each executable member (constructor or method) must have a "@param" tag
- * describing each declared parameter. "@param" tags for non-existing parameters
- * are not allowed.
- * 
- * Each method that has a non-void return type must have at least one "@return"
- * tag. A method that has a void return type must not have a "@return" tag.
- * 
- * Each executable member must have a "@throws" tag for each declared exception
- * that does not extend java.lang.RuntimeException or java.lang.Error. This
- * tag may refer to a superclass of the exception actually being thrown. Each
- * exception specified by a "@throws" tag must actually be declared by the
- * member, unless it extends java.lang.RuntimeException or java.lang.Error.
- * Again, the exception being thrown might be more specific than the one
- * documented.
- * 
- * Methods that override or implement another method are allowed to be
- * undocumented, resulting in the inherited documentation being used. If such a
- * method is documented anyway, it must have the complete documentation as
- * described above.
- * 
- * Elements that have a "@hide" JavaDoc tag are not considered part of the
- * official API and hence are not required to be documented.
- * 
- * Based on checking the above rules, the Doclet assigns statuses to individual
- * documentation elements as follows:
- * 
- * Red: the element violates at least one of the above rules.
- * 
- * Yellow: the element fulfills all the above rules, but neither it nor one of
- * its parent elements (class, package) has been marked with the
- * "@since Android-1.0" tag.
- * 
- * Green: the element fulfills all the above rules, it does not have any "@cts"
- * tags, and either it or one if its parent elements (class, package) has been
- * marked with the "@since Android-1.0" tag.
- * 
- * These colors propagate upwards in the hierarchy. Parent elements are assigned
- * colors as follows:
- * 
- * Red: At least on the children is red.
- * 
- * Yellow: None of the children are red and at least one of the children is
- * yellow.
- * 
- * Green: All of the children are green.
- * 
- * The ultimate goal, of course, is to get the summary for the complete API
- * green.
- */
-public class SpecProgressDoclet {
-
-    public static final int TYPE_FIELD = 0;
-
-    public static final int TYPE_METHOD = 1;
-
-    public static final int TYPE_CLASS = 2;
-
-    public static final int TYPE_PACKAGE = 3;
-
-    public static final int TYPE_ROOT = 4;
-
-    public static final int VALUE_RED = 0;
-
-    public static final int VALUE_YELLOW = 1;
-
-    public static final int VALUE_GREEN = 2;
-
-    public static final String[] COLORS = { "#ffa0a0", "#ffffa0", "#a0ffa0" };
-
-    public static final String[] TYPES = { "Field", "Method", "Class",
-                                           "Package", "All packages" };
-
-    /**
-     * Holds our basic output directory.
-     */
-    private File directory;
-
-    /**
-     * Holds a reference to the doc for java.lang.RuntimeException, so we can
-     * compare against it later.
-     */
-    private ClassDoc runtimeException;
-
-    /**
-     * Holds a reference to the doc for java.lang.Error, so we can
-     * compare against it later.
-     */
-    private ClassDoc error;
-
-    /**
-     * States whether to check type parameters on class level. 
-     * To enable these checks use the option: '-Xgeneric' 
-     */
-    private static boolean checkTypeParameters;
-
-    /**
-     * Helper class for comparing element with each other, in oder to determine
-     * an order. Uses lexicographic order of names.
-     */
-    private class DocComparator implements Comparator<Doc> {
-        public int compare(Doc elem1, Doc elem2) {
-            return elem1.name().compareTo(elem2.name());
-        }
-
-        public boolean equals(Doc elem) {
-            return this == elem;
-        }
-    }
-
-    /**
-     * Class for collecting stats and propagating them upwards in the element
-     * hierarchy.
-     */
-    class Stats {
-
-        /**
-         * Holds the element type.
-         */
-        int type;
-
-        /**
-         * Holds the name of the element.
-         */
-        String name;
-
-        /**
-         * Holds information that is sufficient for building a hyperlink.
-         */
-        String link;
-
-        /**
-         * Holds the total number of elements per type (package, class, etc.).
-         */
-        private int[] numbersPerType = new int[4];
-
-        /**
-         * Holds the total number of elements per status value (red, yellow,
-         * green).
-         */
-        private int[] numbersPerValue = new int[3];
-
-        /**
-         * Holds the total number of "@cts" comments.
-         */
-        private int numberOfComments;
-
-        /**
-         * Creates a new Stats instance.
-         */
-        public Stats(int type, String name, String link) {
-            this.type = type;
-            this.name = name;
-            this.link = link;
-        }
-
-        /**
-         * Adds the contents of a single child element to this instance,
-         * propagating values up in the hierachy
-         */
-        public void add(int type, int status, int comments) {
-            numbersPerType[type]++;
-            numbersPerValue[status]++;
-            numberOfComments += comments;
-        }
-
-        /**
-         * Adds the contents of a child Stats instance to this instance,
-         * propagating values up in the hierachy
-         */
-        public void add(Stats stats) {
-            for (int i = 0; i < numbersPerType.length; i++) {
-                numbersPerType[i] += stats.numbersPerType[i];
-            }
-
-            for (int i = 0; i < numbersPerValue.length; i++) {
-                numbersPerValue[i] += stats.numbersPerValue[i];
-            }
-
-            numberOfComments += stats.numberOfComments;
-        }
-
-        /**
-         * Returns the link.
-         */
-        public String getLink() {
-            return link;
-        }
-
-        /**
-         * Returns the name.
-         */
-        public String getName() {
-            return name;
-        }
-
-        /**
-         * Returns the number of elements per element type.
-         */
-        public int getNumbersPerType(int type) {
-            return numbersPerType[type];
-        }
-
-        /**
-         * Returns the number of elements per status value.
-         */
-        public int getNumbersPerValue(int type) {
-            return numbersPerValue[type];
-        }
-
-        /**
-         * Returns the number of comments.
-         */
-        public int getNumberOfComments() {
-            return numberOfComments;
-        }
-
-        /**
-         * Returns the type of the element to which this Stats instance belongs.
-         */
-        public int getType() {
-            return type;
-        }
-
-        /**
-         * Returns the accumulated status value.
-         */
-        public int getValue() {
-            if (numbersPerValue[VALUE_RED] != 0) {
-                return VALUE_RED;
-            } else if (numbersPerValue[VALUE_YELLOW] != 0) {
-                return VALUE_YELLOW;
-            } else {
-                return VALUE_GREEN;
-            }
-        }
-
-    }
-
-    /**
-     * Holds our comparator instance for everything.
-     */
-    private DocComparator comparator = new DocComparator();
-
-    /**
-     * Creates a new instance of the SpecProgressDoclet for a given target
-     * directory.
-     */
-    public SpecProgressDoclet(String directory) {
-        this.directory = new File(directory);
-    }
-
-    /**
-     * Opens a new output file and writes the usual HTML header. Directories
-     * are created on demand.
-     */
-    private PrintWriter openFile(String name, String title) throws IOException {
-        System.out.println("Writing file \"" + name + "\"...");
-        
-        File file = new File(directory, name);
-        File parent = file.getParentFile();
-        parent.mkdirs();
-
-        OutputStream stream = new BufferedOutputStream(new FileOutputStream(file));
-        PrintWriter printer = new PrintWriter(stream);
-
-        printer.println("<html>");
-        printer.println("  <head>");
-        printer.println("    <title>" + title + "</title>");
-        printer.println("  <head>");
-        printer.println("  <body>");
-        printer.println("    <h1>" + title + "</h1>");
-
-        return printer;
-    }
-
-    /**
-     * Closes the given output file, writing the usual HTML footer before.
-     */
-    private void closeFile(PrintWriter printer) {
-        printer.println("  </body>");
-        printer.println("</html>");
-
-        printer.flush();
-        printer.close();
-    }
-
-    /**
-     * Processes the whole list of classes that JavaDoc knows about.
-     */
-    private void process(RootDoc root) throws IOException {
-        runtimeException = root.classNamed("java.lang.RuntimeException");
-        error = root.classNamed("java.lang.Error");
-
-        PrintWriter printer = openFile("index.html", "All packages");
-
-        printer.println("Generated " + new Date().toString());
-        
-        Stats derived = new Stats(TYPE_ROOT, "All packages", null);
-
-        printer.println("      <h2>Children</h2>");
-        printer.println("      <table width=\"100%\">");
-        printStatsHeader(printer);
-
-        PackageDoc[] packages = root.specifiedPackages();
-        Arrays.sort(packages, comparator);
-        for (PackageDoc pack : packages) {
-            if (pack.allClasses().length != 0 && !isHidden(pack)) {
-                Stats subStats = processPackage(pack);
-                printStats(printer, subStats, true);
-                derived.add(subStats);
-            }
-        }
-
-        printer.println("      </table>");
-
-        printer.println("      <p>");
-
-        printer.println("      <h2>Summary</h2>");
-        printer.println("      <table width=\"100%\">");
-        printStatsHeader(printer);
-        printStats(printer, derived, false);
-        printer.println("      </table>");
-
-        closeFile(printer);
-    }
-
-    /**
-     * Processes the details of a single package.
-     */
-    private Stats processPackage(PackageDoc pack) throws IOException {
-        String file = getPackageDir(pack) + "/package.html";
-        PrintWriter printer = openFile(file, "Package " + pack.name());
-
-        Stats derived = new Stats(TYPE_PACKAGE, pack.name(), file);
-
-        printer.println("      <h2>Elements</h2>");
-        printer.println("      <table width=\"100%\">");
-
-        printElementHeader(printer);
-        processElement(printer, pack, TYPE_PACKAGE, derived);
-
-        printer.println("      </table>");
-
-        printer.println("      <p>");
-
-        printer.println("      <h2>Children</h2>");
-        printer.println("      <table width=\"100%\">");
-
-        printStatsHeader(printer);
-
-        ClassDoc[] classes = pack.allClasses();
-        Arrays.sort(classes, comparator);
-        for (ClassDoc clazz : classes) {
-            if (!isHidden(clazz)) {
-                Stats subStats = processClass(clazz);
-                printStats(printer, subStats, true);
-                derived.add(subStats);
-            }
-        }
-
-        printer.println("      </table>");
-
-        printer.println("      <h2>Summary</h2>");
-        printer.println("      <table width=\"100%\">");
-        printStatsHeader(printer);
-        printStats(printer, derived, false);
-        printer.println("      </table>");
-
-        closeFile(printer);
-
-        return derived;
-    }
-
-    /**
-     * Processes the details of a single class.
-     */
-    private Stats processClass(ClassDoc clazz) throws IOException {
-        String file = getPackageDir(clazz.containingPackage()) + "/" + clazz.name() + ".html";
-        PrintWriter printer = openFile(file, "Class " + clazz.name());
-
-        Stats derived = new Stats(TYPE_CLASS, clazz.name(), clazz.name() + ".html");
-
-        printer.println("      <h2>Elements</h2>");
-        printer.println("      <table width=\"100%\">");
-
-        printElementHeader(printer);
-
-        processElement(printer, clazz, TYPE_CLASS, derived);
-
-        if(clazz.isEnum()){
-            FieldDoc[] enums = clazz.enumConstants();
-            Arrays.sort(enums, comparator);
-            for(FieldDoc e : enums) {
-                processElement(printer, e, TYPE_FIELD, derived);
-            }
-        }
-
-        FieldDoc[] fields = clazz.fields();
-        Arrays.sort(fields, comparator);
-        for (FieldDoc field : fields) {
-            processElement(printer, field, TYPE_FIELD, derived);
-        }
-
-        ConstructorDoc[] constructors = clazz.constructors();
-        Arrays.sort(constructors, comparator);
-        for (ConstructorDoc constructor : constructors) {
-            if (constructor.position() != null) {
-                String constPos = constructor.position().toString();
-                String classPos = constructor.containingClass().position()
-                        .toString();
-
-                if (!constPos.equals(classPos)) {
-                    processElement(printer, constructor, TYPE_METHOD, derived);
-                }
-            }
-        }
-
-        HashSet<MethodDoc> methodSet = new HashSet<MethodDoc>();
-        
-        
-        ClassDoc superClass = clazz.superclass();
-        MethodDoc[] methods = null;
-        if (superClass != null && superClass.isPackagePrivate())
-        {
-            MethodDoc[] classMethods = clazz.methods();
-            for (int i = 0; i < classMethods.length; i++) {
-                methodSet.add(classMethods[i]);
-            }
-
-
-            while (superClass != null && superClass.isPackagePrivate()) {
-                classMethods = superClass.methods();
-                for (int i = 0; i < classMethods.length; i++) {
-                    methodSet.add(classMethods[i]);
-                }
-                superClass = superClass.superclass();
-            }
-
-            methods = new MethodDoc[methodSet.size()];
-            methodSet.toArray(methods);
-        }
-        else
-        {
-            methods = clazz.methods();
-        }
-
-        Arrays.sort(methods, comparator);
-        for (MethodDoc method : methods) {
-            if (!(clazz.isEnum() && ("values".equals(method.name()) ||
-                                     "valueOf".equals(method.name())))) {
-                processElement(printer, method, TYPE_METHOD, derived);
-            }
-        }
-
-        printer.println("      </table>");
-
-        printer.println("      <p>");
-
-        printer.println("      <h2>Summary</h2>");
-        printer.println("      <table width=\"100%\">");
-        printStatsHeader(printer);
-        printStats(printer, derived, false);
-        printer.println("      </table>");
-
-        closeFile(printer);
-
-        return derived;
-    }
-
-    /**
-     * Processes a single element.
-     */
-    private void processElement(PrintWriter printer, Doc doc, int type, Stats derived) {
-        if (isHidden(doc)) {
-            return;
-        }
-
-        List<String> errors = new ArrayList<String>();
-        
-        boolean documented = isValidComment(doc.commentText());
-        boolean inherited = false;
-
-        if(checkTypeParameters && (doc.isClass() || doc.isInterface())){
-            boolean typeParamsOk = hasAllTypeParameterDocs((ClassDoc)doc, errors);
-            documented = documented && typeParamsOk;
-        }
-
-        if (doc.isMethod()) {
-            MethodDoc method = (MethodDoc) doc;
-            
-            if ("".equals(method.commentText().trim())) {
-                inherited = method.overriddenMethod() != null || 
-                            implementedMethod(method) != null;
-                documented = inherited;
-            }
-        }
-
-        if (!documented) {
-            errors.add("Missing or insufficient doc.");
-        }
-        
-        if (!inherited) {
-            if (doc.isMethod() || doc.isConstructor()) {
-                ExecutableMemberDoc executable = (ExecutableMemberDoc) doc;
-                boolean paramsOk = hasAllParameterDocs(executable, errors);
-                boolean exceptionsOk = hasAllExceptionDocs(executable, errors);
-
-                documented = documented && paramsOk && exceptionsOk;
-            }
-
-            if (doc.isMethod()) {
-                MethodDoc method = (MethodDoc) doc;
-                boolean resultOk = hasReturnDoc(method, errors);
-                documented = documented && resultOk;
-            }
-        }
-        
-        boolean reviewed = hasSinceTag(doc);
-        Tag[] comments = doc.tags("cts");
-
-        int status = getStatus(documented, reviewed || inherited, comments);
-
-        printer.println("        <tr bgcolor=\"" + COLORS[status] + "\">");
-        printer.println("          <td>" + TYPES[type] + "</td>");
-        
-        if (doc instanceof PackageDoc) {
-            printer.println("          <td>" + doc.toString() + "</td>");
-        } else {
-            String s = doc.name();
-            String t = doc.toString();
-            
-            int i = t.indexOf(s);
-            
-            if (i != -1) {
-                t = t.substring(i);
-            }
-            
-            printer.println("          <td>" + t + "</td>");
-        }
-        
-        printer.println("          <td>" + getFirstSentence(doc) + "</td>");
-        printer.println("          <td>" + (documented ? "Yes" : "No") + "</td>");
-        printer.println("          <td>" + (reviewed ? "Yes" : "No") + "</td>");
-        printer.println("          <td>");
-
-        if (comments.length != 0 || errors.size() != 0) {
-            printer.println("            </ul>");
-
-            for (int i = 0; i < comments.length; i++) {
-                printer.print("              <li>");
-                printer.print(comments[i].text());
-                printer.println("</li>");
-            }
-            
-            for (int i = 0; i < errors.size(); i++) {
-                printer.print("              <li>");
-                printer.print(errors.get(i));
-                printer.println("</li>");
-            }
-
-            printer.println("            </ul>");
-        } else {
-            printer.println("&nbsp;");
-        }
-
-        printer.println("          </td>");
-        printer.println("        </tr>");
-
-        derived.add(type, status, comments.length);
-    }
-
-    /**
-     * Print the table header for an element table.
-     */
-    private void printElementHeader(PrintWriter printer) {
-        printer.println("        <tr>");
-        printer.println("          <td>Type</td>");
-        printer.println("          <td>Name</td>");
-        printer.println("          <td>First sentence</td>");
-        printer.println("          <td>Doc'd</td>");
-        printer.println("          <td>Rev'd</td>");
-        printer.println("          <td>Comments</td>");
-        printer.println("        </tr>");
-    }
-
-    /**
-     * Print the table header for stats table table.
-     */
-    private void printStatsHeader(PrintWriter printer) {
-        printer.println("        <tr>");
-        printer.println("          <td>Type</td>");
-        printer.println("          <td>Name</td>");
-        printer.println("          <td>#Classes</td>");
-        printer.println("          <td>#Fields</td>");
-        printer.println("          <td>#Methods</td>");
-        printer.println("          <td>#Red</td>");
-        printer.println("          <td>#Yellow</td>");
-        printer.println("          <td>#Green</td>");
-        printer.println("          <td>#Comments</td>");
-        printer.println("        </tr>");
-    }
-
-    /**
-     * Prints a single row to a stats table.
-     */
-    private void printStats(PrintWriter printer, Stats info, boolean wantLink) {
-        printer.println("        <tr bgcolor=\"" + COLORS[info.getValue()] + "\">");
-        printer.println("          <td>" + TYPES[info.getType()] + "</td>");
-
-        printer.print("          <td>");
-        String link = info.getLink();
-        if (wantLink && link != null) {
-            printer.print("<a href=\"" + link + "\">" + info.getName() + "</a>");
-        } else {
-            printer.print(info.getName());
-        }
-        printer.println("</td>");
-
-        printer.println("          <td>" + info.getNumbersPerType(TYPE_CLASS) + "</td>");
-        printer.println("          <td>" + info.getNumbersPerType(TYPE_FIELD) + "</td>");
-        printer.println("          <td>" + info.getNumbersPerType(TYPE_METHOD) + "</td>");
-        printer.println("          <td>" + info.getNumbersPerValue(VALUE_RED) + "</td>");
-        printer.println("          <td>" + info.getNumbersPerValue(VALUE_YELLOW) + "</td>");
-        printer.println("          <td>" + info.getNumbersPerValue(VALUE_GREEN) + "</td>");
-        printer.println("          <td>" + info.getNumberOfComments() + "</td>");
-        printer.println("        </tr>");
-    }
-
-    /**
-     * Returns the directory for a given package. Basically converts embedded
-     * dots in the name into slashes. 
-     */
-    private File getPackageDir(PackageDoc pack) {
-        if (pack == null || pack.name() == null || "".equals(pack.name())) {
-            return new File(".");
-        } else {
-            return new File(pack.name().replace('.', '/'));
-        }
-    }
-
-    /**
-     * Checks whether the given comment is not null and not of length 0.
-     */
-    private boolean isValidComment(String comment) {
-        return comment != null && comment.length() > 0;
-    }
-
-    /**
-     * Checks whether the given interface or class has documentation for
-     * all declared type parameters (no less, no more). 
-     */
-    private boolean hasAllTypeParameterDocs(ClassDoc doc, List<String> errors) {
-        boolean result = true;
-        
-        TypeVariable[] params = doc.typeParameters();
-        Set<String> paramsSet = new HashSet<String>();
-        for (TypeVariable param : params) {
-            paramsSet.add(param.typeName()); 
-        }  
-
-        ParamTag[] paramTags = doc.typeParamTags();
-        Map<String, String> paramTagsMap = new HashMap<String, String>();
-        for (ParamTag paramTag : paramTags) {
-            if (!paramsSet.contains(paramTag.parameterName())) {
-                errors.add("Unknown type parameter \"" + paramTag.parameterName() + "\"");
-                result = false;
-            }
-            paramTagsMap.put(paramTag.parameterName(), paramTag.parameterComment());
-        }
-
-        for (TypeVariable param : params) {
-            if (!isValidComment(paramTagsMap.get(param.typeName()))) {
-                errors.add("Undocumented type parameter \"" + param.typeName() + "\"");
-                result = false;
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Checks whether the given executable member has documentation for
-     * all declared parameters (no less, no more).  
-     */
-    private boolean hasAllParameterDocs(ExecutableMemberDoc doc, List<String> errors) {
-        boolean result = true;
-        
-        Parameter params[] = doc.parameters();
-        Set<String> paramsSet = new HashSet<String>();
-        for (int i = 0; i < params.length; i++) {
-            Parameter param = params[i];
-            paramsSet.add(param.name());
-        }
-
-        ParamTag[] paramTags = doc.paramTags();
-        Map<String, String> paramTagsMap = new HashMap<String, String>();
-        for (int i = 0; i < paramTags.length; i++) {
-            ParamTag paramTag = paramTags[i];
-
-            if (!paramsSet.contains(paramTag.parameterName())) {
-                errors.add("Unknown parameter \"" + paramTag.parameterName() + "\"");
-                result = false;
-            }
-
-            paramTagsMap.put(paramTag.parameterName(), paramTag.parameterComment());
-        }
-
-        for (int i = 0; i < params.length; i++) {
-            Parameter param = params[i];
-
-            if (!isValidComment(paramTagsMap.get(param.name()))) {
-                errors.add("Undocumented parameter \"" + param.name() + "\"");
-                result = false;
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Checks whether the given executable member has documentation for
-     * all non-runtime exceptions. Runtime exceptions may or may not be
-     * documented.   
-     */
-    private boolean hasAllExceptionDocs(ExecutableMemberDoc doc, List<String> errors) {
-        boolean result = true;
-        
-        ClassDoc exceptions[] = doc.thrownExceptions();
-        Set<ClassDoc> exceptionSet = new HashSet<ClassDoc>();
-        for (int i = 0; i < exceptions.length; i++) {
-            ClassDoc exception = exceptions[i];
-            if (isRelevantException(exception)) {
-                exceptionSet.add(exception);
-            }
-        }
-
-        ThrowsTag[] throwsTags = doc.throwsTags();
-        Map<ClassDoc, String> throwsTagsMap = new HashMap<ClassDoc, String>();
-        for (int i = 0; i < throwsTags.length; i++) {
-            ThrowsTag throwsTag = throwsTags[i];
-
-            if (throwsTag.exception() == null) {
-                errors.add("Unknown exception \"" + throwsTag.exceptionName() + "\"");
-                result = false;
-            } else if (isRelevantException(throwsTag.exception())) {
-
-                ClassDoc exception = throwsTag.exception();
-                while (exception != null && !exceptionSet.contains(exception)) {
-                    exception = exception.superclass();
-                }
-                if (exception == null) {
-                    errors.add("Unknown exception \"" + throwsTag.exceptionName() + "\"");
-                    result = false;
-                }
-            }
-            
-            throwsTagsMap.put(throwsTag.exception(), throwsTag.exceptionComment());
-        }
-
-        for (int i = 0; i < exceptions.length; i++) {
-            ClassDoc exception = exceptions[i];
-            boolean found = false;
-            
-            for (int j = 0; j < throwsTags.length && !found; j++) {
-                ThrowsTag throwsTag = throwsTags[j];
-                
-                ClassDoc candidate = throwsTag.exception();
-                if (candidate != null) {
-                    if (candidate.equals(exception) || candidate.subclassOf(exception)) {
-                        if (isValidComment(throwsTag.exceptionComment())) {
-                            found = true;
-                        }
-                    }
-                }
-            }
-            
-            if (!found) {
-                errors.add("Undocumented exception \"" + exception.name() + "\"");
-                result = false;
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Checks whether an exception needs to be documented. Runtime exceptions
-     * and errors don't necessarily need documentation (although it doesn't
-     * hurt to have it).
-     */
-    private boolean isRelevantException(ClassDoc clazz) {
-        return !(clazz.subclassOf(runtimeException) || clazz.subclassOf(error));
-    }
-    
-    /**
-     * Checks whether the given method has documentation for the return value.
-     */
-    private boolean hasReturnDoc(MethodDoc method, List<String> errors) {
-        boolean result = true;
-        
-        if (!"void".equals(method.returnType().typeName())) {
-            Tag[] returnTags = method.tags("return");
-
-            if (returnTags.length == 0) {
-                errors.add("Missing result.");
-                result = false;
-            }
-
-            for (int i = 0; i < returnTags.length; i++) {
-                Tag tag = returnTags[i];
-                if (!isValidComment(tag.text())) {
-                    errors.add("Insufficient result.");
-                    result = false;
-                }
-            }
-        } else {
-            Tag[] returnTags = method.tags("return");
-            if (returnTags.length != 0) {
-                errors.add("Unknown result.");
-                result = false;
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Returns the first sentence for the given documentation element.
-     */
-    private String getFirstSentence(Doc doc) {
-        StringBuilder builder = new StringBuilder();
-
-        Tag[] tags = doc.firstSentenceTags();
-        for (int i = 0; i < tags.length; i++) {
-            Tag tag = tags[i];
-
-            if ("Text".equals(tag.kind())) {
-                builder.append(tag.text());
-            } else {
-                builder.append("{" + tag.toString() + "}");
-            }
-        }
-
-        return builder.toString();
-    }
-
-    /**
-     * Returns the interface method that a given method implements, or null if
-     * the method does not implement any interface method.
-     */
-    private MethodDoc implementedMethod(MethodDoc doc) {
-        ClassDoc clazz = doc.containingClass();
-        MethodDoc myDoc = null;
-        while(clazz != null && myDoc == null){
-        ClassDoc[] interfaces = clazz.interfaces();
-            myDoc = implementedMethod0(doc, interfaces);
-            clazz = clazz.superclass();
-        }
-        return myDoc;
-    }
-
-    /**
-     * Recursive helper method for finding out which interface method a given
-     * method implements.
-     */
-    private MethodDoc implementedMethod0(MethodDoc doc, ClassDoc[] interfaces) {
-        for (int i = 0; i < interfaces.length; i++) {
-            ClassDoc classDoc = interfaces[i];
-
-            MethodDoc[] methods = classDoc.methods();
-            for (int j = 0; j < methods.length; j++) {
-                MethodDoc methodDoc = methods[j];
-                if (doc.overrides(methodDoc)) {
-                    return methodDoc;
-                }
-            }
-        }
-
-        for (int i = 0; i < interfaces.length; i++) {
-            MethodDoc myDoc = implementedMethod0(doc, interfaces[i].interfaces());
-            if (myDoc != null) {
-                return myDoc;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Checks whether the given documentation element has a "@since" tag for
-     * Android.
-     */
-    private boolean hasSinceTag(Doc doc) {
-        Tag[] tags = doc.tags("since");
-
-        for (int i = 0; i < tags.length; i++) {
-            if ("Android 1.0".equals(tags[i].text())) {
-                return true;
-            }
-        }
-
-        if (doc instanceof MemberDoc) {
-            return hasSinceTag(((MemberDoc)doc).containingClass());
-        }
-        
-        if (doc instanceof ClassDoc) {
-            return hasSinceTag(((ClassDoc)doc).containingPackage());
-        }
-        
-        return false;
-    }
-
-    /**
-     * Checks whether the given documentation element has a "@hide" tag that
-     * excludes it from the official API.
-     */
-    private boolean isHidden(Doc doc) {
-        Tag[] tags = doc.tags("hide");
-
-        return tags != null && tags.length != 0;
-    }
-    
-    /**
-     * Determines the status of an element based on the existence of
-     * documentation, the review status, and any comments it might have.
-     */
-    private int getStatus(boolean documented, boolean reviewed, Tag[] comments) {
-        if (!documented) {
-            return VALUE_RED;
-        } else if (reviewed && comments.length == 0) {
-            return VALUE_GREEN;
-        } else {
-            return VALUE_YELLOW;
-        }
-    }
-
-    /**
-     * Called by JavaDoc to find our which command line arguments are supported
-     * and how many parameters they take. Part of the JavaDoc API.
-     */
-    public static int optionLength(String option) {
-        if ("-d".equals(option)) {
-            return 2;
-        } else if("-Xgeneric".equals(option)){
-            return 1;
-        } else {
-            return 0;
-        }
-    }
-
-    /**
-     * Returns a particular command line argument for a given option.
-     */
-    private static String getOption(RootDoc root, String option, int index, String defValue) {
-        String[][] allOptions = root.options();
-        for (int i = 0; i < allOptions.length; i++) {
-            if (allOptions[i][0].equals(option)) {
-                return allOptions[i][index];
-            }
-        }
-
-        return defValue;
-    }
-    
-    /**
-     * Returns whether the specified option is present.
-     */
-    private static boolean isOptionSet(RootDoc root, String option){
-        String[][] allOptions = root.options();
-        for (int i = 0; i < allOptions.length; i++) {
-            if (allOptions[i][0].equals(option)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Called by JavaDoc to find out which Java version we claim to support.
-     * Part of the JavaDoc API.
-     */
-    public static LanguageVersion languageVersion() {
-        return LanguageVersion.JAVA_1_5;
-    }
-
-    /**
-     * The main entry point called by JavaDoc after all required information has
-     * been collected. Part of the JavaDoc API.
-     */
-    public static boolean start(RootDoc root) {
-        try {
-            String target = getOption(root, "-d", 1, ".");
-            checkTypeParameters = isOptionSet(root, "-Xgeneric");
-
-            SpecProgressDoclet doclet = new SpecProgressDoclet(target);
-            doclet.process(root);
-
-            File file = new File(target, "index.html");
-            System.out.println("Please see complete report in " + 
-                    file.getAbsolutePath());
-            
-        } catch (Exception ex) {
-            ex.printStackTrace();
-            return false;
-        }
-
-        return true;
-    }
-
-}
