Adds Java scanner and placeholders for Native Scanner and Xml Generators.

This patch also includes the bare minimum of tradefed wrappers required
in order to run the tests.

Change-Id: I87b9b1af4e91115180365385e4ee48f91dd100a2
diff --git a/common/host-side/java-scanner/Android.mk b/common/host-side/java-scanner/Android.mk
new file mode 100644
index 0000000..3acf988
--- /dev/null
+++ b/common/host-side/java-scanner/Android.mk
@@ -0,0 +1,47 @@
+# Copyright (C) 2014 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 := $(call all-java-files-under, src)
+
+LOCAL_JAR_MANIFEST := MANIFEST.mf
+
+LOCAL_CLASSPATH := $(HOST_JDK_TOOLS_JAR)
+
+LOCAL_JAVA_LIBRARIES := junit
+
+LOCAL_MODULE := compatibility-java-scanner_v2
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+################################################################################
+# Build the tests
+###############################################################################
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, tests/src)
+
+LOCAL_JAVA_LIBRARIES := compatibility-tradefed_v2 compatibility-java-scanner_v2 junit
+
+LOCAL_MODULE := compatibility-java-scanner-tests_v2
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/common/host-side/java-scanner/MANIFEST.mf b/common/host-side/java-scanner/MANIFEST.mf
new file mode 100644
index 0000000..a04249a
--- /dev/null
+++ b/common/host-side/java-scanner/MANIFEST.mf
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+Main-Class: com.android.compatibility.common.scanner.JavaScanner
diff --git a/common/host-side/java-scanner/src/com/android/compatibility/common/scanner/JavaScanner.java b/common/host-side/java-scanner/src/com/android/compatibility/common/scanner/JavaScanner.java
new file mode 100644
index 0000000..c423290
--- /dev/null
+++ b/common/host-side/java-scanner/src/com/android/compatibility/common/scanner/JavaScanner.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2014 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.compatibility.common.scanner;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Scans a source directory for java tests and outputs a list of test classes and methods.
+ */
+public class JavaScanner {
+
+    static final String[] SOURCE_PATHS = {
+        "./frameworks/base/core/java",
+        "./frameworks/base/test-runner/src",
+        "./external/junit/src",
+        "./development/tools/hosttestlib/src",
+        "./libcore/dalvik/src/main/java",
+        "./common/device-side/util/src",
+        "./common/host-side/tradefed/src",
+        "./common/util/src"
+    };
+    static final String[] CLASS_PATHS = {
+        "./prebuilts/misc/common/tradefed/tradefed-prebuilt.java",
+        "./prebuilts/misc/common/ub-uiautomator/ub-uiautomator.java"
+    };
+    private final File mSourceDir;
+    private final File mDocletDir;
+
+    /**
+     * @param sourceDir The directory holding the source to scan.
+     * @param docletDir The directory holding the doclet (or its jar).
+     */
+    JavaScanner(File sourceDir, File docletDir) {
+        this.mSourceDir = sourceDir;
+        this.mDocletDir = docletDir;
+    }
+
+    int scan() throws Exception {
+        final List<String> args = new ArrayList<String>();
+        args.add("javadoc");
+        args.add("-doclet");
+        args.add("com.android.compatibility.common.scanner.JavaScannerDoclet");
+        args.add("-sourcepath");
+        args.add(getSourcePath(mSourceDir));
+        args.add("-classpath");
+        args.add(getClassPath());
+        args.add("-docletpath");
+        args.add(mDocletDir.toString());
+        args.addAll(getSourceFiles(mSourceDir));
+
+        // Dont want p to get blocked due to a full pipe.
+        final Process p = new ProcessBuilder(args).redirectErrorStream(true).start();
+        final BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
+        try {
+            String line = null;
+            while ((line = in.readLine()) != null) {
+                if (line.startsWith("suite:") ||
+                    line.startsWith("case:") ||
+                    line.startsWith("test:")) {
+                    System.out.println(line);
+                }
+            }
+        } finally {
+          if (in != null) {
+              in.close();
+          }
+        }
+
+        return p.waitFor();
+    }
+
+    private static String getSourcePath(File sourceDir) {
+        List<String> sourcePath = new ArrayList<String>(Arrays.asList(SOURCE_PATHS));
+        sourcePath.add(sourceDir.toString());
+        return join(sourcePath, ":");
+    }
+
+    private static String getClassPath() {
+        return join(Arrays.asList(CLASS_PATHS), ":");
+    }
+
+    private static List<String> getSourceFiles(File sourceDir) {
+        List<String> sourceFiles = new ArrayList<String>();
+        final File[] files = sourceDir.listFiles(new FileFilter() {
+            public boolean accept(File pathname) {
+                return pathname.isDirectory() || pathname.toString().endsWith(".java");
+            }
+        });
+        for (File f : files) {
+            if (f.isDirectory()) {
+                sourceFiles.addAll(getSourceFiles(f));
+            } else {
+                sourceFiles.add(f.toString());
+            }
+        }
+        return sourceFiles;
+    }
+
+    private static String join(List<String> list, String delimiter) {
+        StringBuilder builder = new StringBuilder();
+        for (String s : list) {
+            builder.append(s);
+            builder.append(delimiter);
+        }
+        // Adding the delimiter each time and then removing the last one at the end is more
+        // efficient than doing a check in each iteration of the loop.
+        return builder.substring(0, builder.length() - delimiter.length());
+    }
+
+    public static void main(String[] args) throws Exception {
+        String sourcePath = null;
+        String docletPath = null;
+        for (int i = 0; i < args.length; i++) {
+            if (args[i].equals("-s") && ++i < args.length) {
+                sourcePath = args[i];
+            } else if (args[i].equals("-d") && ++i < args.length) {
+                docletPath = args[i];
+            }
+        }
+        if (sourcePath == null || docletPath == null) {
+            System.err.println("Usage: javascanner -s SOURCE_DIR -d DOCLET_PATH");
+            System.exit(1);
+        }
+        System.exit(new JavaScanner(new File(sourcePath), new File(docletPath)).scan());
+    }
+}
diff --git a/common/host-side/java-scanner/src/com/android/compatibility/common/scanner/JavaScannerDoclet.java b/common/host-side/java-scanner/src/com/android/compatibility/common/scanner/JavaScannerDoclet.java
new file mode 100644
index 0000000..94eccd0
--- /dev/null
+++ b/common/host-side/java-scanner/src/com/android/compatibility/common/scanner/JavaScannerDoclet.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2014 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.compatibility.common.scanner;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.Doclet;
+import com.sun.javadoc.MethodDoc;
+import com.sun.javadoc.RootDoc;
+
+import java.io.PrintWriter;
+
+/**
+ * Doclet that scans java files looking for tests.
+ *
+ * Sample Ouput;
+ * suite:com.android.sample.cts
+ * case:SampleDeviceTest
+ * test:testSharedPreferences
+ */
+public class JavaScannerDoclet extends Doclet {
+
+    private static final String JUNIT_TEST_CASE_CLASS_NAME = "junit.framework.testcase";
+
+    public static boolean start(RootDoc root) {
+        ClassDoc[] classes = root.classes();
+        if (classes == null) {
+            return false;
+        }
+
+        PrintWriter writer = new PrintWriter(System.out);
+
+        for (ClassDoc clazz : classes) {
+            if (clazz.isAbstract() || !isValidJUnitTestCase(clazz)) {
+                continue;
+            }
+            writer.append("suite:").println(clazz.containingPackage().name());
+            writer.append("case:").println(clazz.name());
+            for (; clazz != null; clazz = clazz.superclass()) {
+                for (MethodDoc method : clazz.methods()) {
+                    if (method.name().startsWith("test")) {
+                        writer.append("test:").println(method.name());
+                    }
+                }
+            }
+        }
+
+        writer.close();
+        return true;
+    }
+
+    private static boolean isValidJUnitTestCase(ClassDoc clazz) {
+        while ((clazz = clazz.superclass()) != null) {
+            if (JUNIT_TEST_CASE_CLASS_NAME.equals(clazz.qualifiedName().toLowerCase())) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/common/host-side/java-scanner/tests/src/com/android/compatibility/common/scanner/JavaScannerTest.java b/common/host-side/java-scanner/tests/src/com/android/compatibility/common/scanner/JavaScannerTest.java
new file mode 100644
index 0000000..e18cf16
--- /dev/null
+++ b/common/host-side/java-scanner/tests/src/com/android/compatibility/common/scanner/JavaScannerTest.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2014 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.compatibility.common.scanner;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+public class JavaScannerTest extends TestCase {
+
+    private static final String JAR = "out/host/linux-x86/framework/compatibility-java-scanner_v2.jar";
+    private static final String VALID_RESULT =
+        "suite:com.android.test" +
+        "case:ValidTest" +
+        "test:testA";
+
+    private static final String VALID_FILENAME = "ValidTest";
+    private static final String VALID =
+        "package com.android.test;" +
+        "import junit.framework.TestCase;" +
+        "public class ValidTest extends TestCase {" +
+        "  public void testA() throws Exception {" +
+        "    helper();" +
+        "  }" +
+        "  public void helper() {" +
+        "    fail();" +
+        "  }" +
+        "}";
+
+    // TestCases must have TestCase in their hierarchy
+    private static final String INVALID_A_FILENAME = "NotTestCase";
+    private static final String INVALID_A =
+        "package com.android.test;" +
+        "public class NotTestCase {" +
+        "  public void testA() throws Exception {" +
+        "    helper();" +
+        "  }" +
+        "  public void helper() {" +
+        "    fail();" +
+        "  }" +
+        "}";
+
+    // TestCases cant be abstract classes
+    private static final String INVALID_B_FILENAME = "AbstractClass";
+    private static final String INVALID_B =
+        "package com.android.test;" +
+        "import junit.framework.TestCase;" +
+        "public abstract class AbstractClass extends TestCase {" +
+        "  public void testA() throws Exception {" +
+        "    helper();" +
+        "  }" +
+        "  public void helper() {" +
+        "    fail();" +
+        "  }" +
+        "}";
+
+    public void testValidFile() throws Exception {
+        String result = runScanner(VALID_FILENAME, VALID);
+        assertEquals(VALID_RESULT, result);
+    }
+
+    public void testInvalidFileA() throws Exception {
+        assertEquals("", runScanner(INVALID_A_FILENAME, INVALID_A));
+    }
+
+    public void testInvalidFileB() throws Exception {
+        assertEquals("", runScanner(INVALID_B_FILENAME, INVALID_B));
+    }
+
+    private static String runScanner(String filename, String content) throws Exception {
+        final File parent0 = new File(System.getProperty("java.io.tmpdir"));
+        final File parent1 = new File(parent0, "tmp" + System.currentTimeMillis());
+        final File parent2 = new File(parent1, "com");
+        final File parent3 = new File(parent2, "android");
+        final File parent4 = new File(parent3, "test");
+        File f = null;
+        try {
+            parent4.mkdirs();
+            f = new File(parent4, filename + ".java");
+            final PrintWriter out = new PrintWriter(f);
+            out.print(content);
+            out.flush();
+            out.close();
+            List<String> args = new ArrayList<String>();
+            args.add("java");
+            args.add("-jar");
+            args.add(JAR);
+            args.add("-s");
+            args.add(parent1.toString());
+            args.add("-d");
+            args.add(JAR);
+
+            final Process p = new ProcessBuilder(args).start();
+            final StringBuilder output = new StringBuilder();
+            final BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
+            String line = null;
+            while ((line = in.readLine()) != null) {
+                output.append(line);
+            }
+            int ret = p.waitFor();
+            if (ret == 0) {
+                return output.toString();
+            }
+        } finally {
+            if (f != null) {
+                f.delete();
+            }
+            parent4.delete();
+            parent3.delete();
+            parent2.delete();
+            parent1.delete();
+        }
+        return null;
+    }
+}
diff --git a/common/host-side/native-scanner/Android.mk b/common/host-side/native-scanner/Android.mk
new file mode 100644
index 0000000..8d3242f
--- /dev/null
+++ b/common/host-side/native-scanner/Android.mk
@@ -0,0 +1,47 @@
+# Copyright (C) 2014 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 := $(call all-java-files-under, src)
+
+LOCAL_JAR_MANIFEST := MANIFEST.mf
+
+LOCAL_CLASSPATH := $(HOST_JDK_TOOLS_JAR)
+
+LOCAL_JAVA_LIBRARIES := junit
+
+LOCAL_MODULE := compatibility-native-scanner_v2
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+################################################################################
+# Build the tests
+###############################################################################
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, tests/src)
+
+LOCAL_JAVA_LIBRARIES := compatibility-tradefed_v2 compatibility-native-scanner_v2 junit
+
+LOCAL_MODULE := compatibility-native-scanner-tests_v2
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/common/host-side/native-scanner/MANIFEST.mf b/common/host-side/native-scanner/MANIFEST.mf
new file mode 100644
index 0000000..86a7212
--- /dev/null
+++ b/common/host-side/native-scanner/MANIFEST.mf
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+Main-Class: com.android.compatibility.common.scanner.NativeScanner
diff --git a/common/host-side/native-scanner/src/com/android/compatibility/common/scanner/NativeScanner.java b/common/host-side/native-scanner/src/com/android/compatibility/common/scanner/NativeScanner.java
new file mode 100644
index 0000000..581ee0b
--- /dev/null
+++ b/common/host-side/native-scanner/src/com/android/compatibility/common/scanner/NativeScanner.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2014 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.compatibility.common.scanner;
+
+/**
+ * Passes the gtest output and outputs a list of test classes and methods.
+ */
+public class NativeScanner {
+
+    public static void main(String[] args) throws Exception {
+        // TODO(stuartscott): Parse the gtest output comming from System.in and output in the format
+        // suite:com.android.sample.cts
+        // case:SampleDeviceTest
+        // test:testSharedPreferences
+    }
+}
diff --git a/common/host-side/native-scanner/tests/src/com/android/compatibility/common/scanner/NativeScannerTest.java b/common/host-side/native-scanner/tests/src/com/android/compatibility/common/scanner/NativeScannerTest.java
new file mode 100644
index 0000000..3e9ba17
--- /dev/null
+++ b/common/host-side/native-scanner/tests/src/com/android/compatibility/common/scanner/NativeScannerTest.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2014 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.compatibility.common.scanner;
+
+import junit.framework.TestCase;
+
+public class NativeScannerTest extends TestCase {
+
+    // TODO(stuartscott): Add tests when there is something to test.
+
+}
diff --git a/common/host-side/scripts/compatibility-tests_v2 b/common/host-side/scripts/compatibility-tests_v2
new file mode 100755
index 0000000..b9e479a
--- /dev/null
+++ b/common/host-side/scripts/compatibility-tests_v2
@@ -0,0 +1,61 @@
+#!/bin/bash
+#
+# Copyright (C) 2014 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.
+
+checkFile() {
+    if [ ! -f "$1" ]; then
+        echo "Unable to locate $1"
+        exit
+    fi;
+}
+
+HOST_JAR_DIR=${ANDROID_HOST_OUT}/framework
+HOST_JARS="ddmlib-prebuilt.jar tradefed-prebuilt.jar hosttestlib.jar\
+    compatibility-tradefed_v2.jar compatibility-tradefed-tests_v2.jar\
+    compatibility-java-scanner_v2.jar compatibility-java-scanner-tests_v2.jar\
+    compatibility-native-scanner_v2.jar compatibility-native-scanner-tests_v2.jar\
+    compatibility-xml-plan-generator_v2.jar compatibility-xml-plan-generator-tests_v2.jar\
+    compatibility-device-util-tests_v2.jar compatibility-device-setup-tests_v2.jar\
+    compatibility-common-util-hostsidelib_v2.jar compatibility-common-util-tests_v2.jar"
+
+for JAR in ${HOST_JARS}; do
+    checkFile ${HOST_JAR_DIR}/${JAR}
+    JAR_PATH=${JAR_PATH}:${HOST_JAR_DIR}/${JAR}
+done
+
+DEVICE_LIBS_DIR=${ANDROID_PRODUCT_OUT}/obj/JAVA_LIBRARIES
+DEVICE_LIBS="compatibility-common-util-devicesidelib_v2 compatibility-device-util_v2\
+    compatibility-device-setup_v2"
+
+for LIB in ${DEVICE_LIBS}; do
+    checkFile ${DEVICE_LIBS_DIR}/${LIB}_intermediates/javalib.jar
+    JAR_PATH=${JAR_PATH}:${DEVICE_LIBS_DIR}/${LIB}_intermediates/javalib.jar
+done
+
+# TODO(stuartscott): Currently the test classes are explicitly set here, but
+# once our wrappers for tradefed are in place we can make it scan and generate
+# the list of test at runtime.
+TEST_CLASSES="com.android.compatibility.common.devicesetup.DeviceSetupTest\
+    com.android.compatibility.common.scanner.JavaScannerTest\
+    com.android.compatibility.common.scanner.NativeScannerTest\
+    com.android.compatibility.common.tradefed.TradefedTest\
+    com.android.compatibility.common.util.DeviceUtilTest\
+    com.android.compatibility.common.util.CommonUtilTest\
+    com.android.compatibility.common.xmlgenerator.XmlPlanGeneratorTest"
+
+for CLASS in ${TEST_CLASSES}; do
+    java $RDBG_FLAG -cp ${JAR_PATH} com.android.compatibility.common.tradefed.command.CompatibilityConsole run\
+            singleCommand host -n --class ${CLASS} "$@"
+done
diff --git a/common/host-side/tradefed/cts-tradefed_v2 b/common/host-side/scripts/compatibility-tradefed_v2
old mode 100644
new mode 100755
similarity index 100%
rename from common/host-side/tradefed/cts-tradefed_v2
rename to common/host-side/scripts/compatibility-tradefed_v2
diff --git a/common/host-side/tradefed/Android.mk b/common/host-side/tradefed/Android.mk
index 5b5f15c..2cb559a 100644
--- a/common/host-side/tradefed/Android.mk
+++ b/common/host-side/tradefed/Android.mk
@@ -12,7 +12,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# Builds the cts tradefed host library
+###############################################################################
+# Builds the compatibility tradefed host library
+###############################################################################
 
 LOCAL_PATH := $(call my-dir)
 
@@ -22,37 +24,27 @@
 
 #LOCAL_JAVA_RESOURCE_DIRS := res
 
-LOCAL_MODULE := cts-tradefed_v2
+LOCAL_MODULE := compatibility-tradefed_v2
 
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_JAVA_LIBRARIES := ddmlib-prebuilt tradefed-prebuilt hosttestlib cts-common-util-host_v2
+LOCAL_JAVA_LIBRARIES := ddmlib-prebuilt tradefed-prebuilt hosttestlib compatibility-common-util-hostsidelib_v2
 
 include $(BUILD_HOST_JAVA_LIBRARY)
 
 ###############################################################################
-# Builds the cts tradefed executable
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_PREBUILT_EXECUTABLES := cts-tradefed_v2
-
-include $(BUILD_HOST_PREBUILT)
-
+# Build the compatibility tradefed tests
 ###############################################################################
-# Builds the cts tradefed tests
 
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES := $(call all-java-files-under, tests)
+LOCAL_SRC_FILES := $(call all-java-files-under, tests/src)
 
-LOCAL_MODULE := cts-tradefed-tests_v2
+LOCAL_MODULE := compatibility-tradefed-tests_v2
 
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_JAVA_LIBRARIES := ddmlib-prebuilt tradefed-prebuilt cts-tradefed_v2
+LOCAL_JAVA_LIBRARIES := ddmlib-prebuilt tradefed-prebuilt compatibility-tradefed_v2 junit
 
 LOCAL_STATIC_JAVA_LIBRARIES := easymock
 
diff --git a/common/host-side/tradefed/src/android/cts/tradefed/util/HostReportLog.java b/common/host-side/tradefed/src/android/cts/tradefed/util/HostReportLog.java
deleted file mode 100644
index 8857b5e..0000000
--- a/common/host-side/tradefed/src/android/cts/tradefed/util/HostReportLog.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2014 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 android.cts.tradefed.util;
-
-import android.cts.util.ReportLog;
-
-/**
- * ReportLog for host tests
- * Note that setTestInfo should be set before throwing report
- */
-public class HostReportLog extends ReportLog {
-
-    private String mKey;
-
-    /**
-     * @param deviceSerial serial number of the device
-     */
-    public HostReportLog(String deviceSerial) {
-        final StackTraceElement e = Thread.currentThread().getStackTrace()[1];
-        mKey = String.format("%s#%s#%s", deviceSerial, e.getClassName(), e.getMethodName());
-    }
-
-    public void submit() {
-        ResultStore.addResult(mKey, this);
-    }
-}
diff --git a/common/host-side/tradefed/src/android/cts/tradefed/util/ResultStore.java b/common/host-side/tradefed/src/android/cts/tradefed/util/ResultStore.java
deleted file mode 100644
index 0e2be7c..0000000
--- a/common/host-side/tradefed/src/android/cts/tradefed/util/ResultStore.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2014 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 android.cts.tradefed.util;
-
-import android.cts.util.ReportLog;
-
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Utility class for storing Cts Results.
- * This is necessary for host tests where test metrics cannot be passed.
- */
-public class ResultStore {
-
-    // needs concurrent verion as there can be multiple client accessing this.
-    // But there is no additional protection for the same key as that should not happen.
-    private static final ConcurrentHashMap<String, ReportLog> mMap =
-            new ConcurrentHashMap<String, ReportLog>();
-
-    /**
-     * Stores CTS result. Existing result with the same key will be replaced.
-     * Note that key is generated in the form of device_serial#class#method_name.
-     * So there should be no concurrent test for the same (serial, class, method).
-     * @param key
-     * @param result CTS result
-     */
-    public static void addResult(String key, ReportLog result) {
-        mMap.put(key, result);
-    }
-
-    /**
-     * retrieves a CTS result for the given condition and remove it from the internal
-     * storage. If there is no result for the given condition, it will return null.
-     */
-    public static ReportLog removeResult(String key) {
-        return mMap.remove(key);
-    }
-
-}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/command/CompatibilityConsole.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/command/CompatibilityConsole.java
new file mode 100644
index 0000000..56f7db8
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/command/CompatibilityConsole.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2014 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.compatibility.common.tradefed.command;
+
+import com.android.tradefed.command.Console;
+
+/**
+ * An extension of Tradefed's console which adds features specific to compatibility testing.
+ */
+public class CompatibilityConsole extends Console {
+
+    public static void main(String[] args) throws InterruptedException {
+        CompatibilityConsole console = new CompatibilityConsole();
+        Console.startConsole(console, args);
+    }
+}
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/TradefedTest.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/TradefedTest.java
new file mode 100644
index 0000000..ab19369
--- /dev/null
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/TradefedTest.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2014 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.compatibility.common.tradefed;
+
+import junit.framework.TestCase;
+
+public class TradefedTest extends TestCase {
+
+    // TODO(stuartscott): Add tests when there is something to test.
+
+}
diff --git a/common/host-side/xml-plan-generator/Android.mk b/common/host-side/xml-plan-generator/Android.mk
new file mode 100644
index 0000000..36491bd
--- /dev/null
+++ b/common/host-side/xml-plan-generator/Android.mk
@@ -0,0 +1,45 @@
+# Copyright (C) 2014 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 := $(call all-java-files-under, src)
+
+LOCAL_JAR_MANIFEST := MANIFEST.mf
+
+LOCAL_CLASSPATH := $(HOST_JDK_TOOLS_JAR)
+
+LOCAL_MODULE := compatibility-xml-plan-generator_v2
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+###############################################################################
+# Build the tests
+###############################################################################
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, tests/src)
+
+LOCAL_JAVA_LIBRARIES := compatibility-tradefed_v2 compatibility-xml-plan-generator_v2 junit
+
+LOCAL_MODULE := compatibility-xml-plan-generator-tests_v2
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/common/host-side/xml-plan-generator/MANIFEST.mf b/common/host-side/xml-plan-generator/MANIFEST.mf
new file mode 100644
index 0000000..c021388
--- /dev/null
+++ b/common/host-side/xml-plan-generator/MANIFEST.mf
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+Main-Class: com.android.compatibility.common.xmlgenerator.XmlPlanGenerator
diff --git a/common/host-side/xml-plan-generator/src/com/android/compatibility/common/xmlgenerator/XmlPlanGenerator.java b/common/host-side/xml-plan-generator/src/com/android/compatibility/common/xmlgenerator/XmlPlanGenerator.java
new file mode 100644
index 0000000..510c935
--- /dev/null
+++ b/common/host-side/xml-plan-generator/src/com/android/compatibility/common/xmlgenerator/XmlPlanGenerator.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2014 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.compatibility.common.xmlgenerator;
+
+/**
+ * Passes the scanner output and outputs an xml description of the tests.
+ */
+public class XmlPlanGenerator {
+
+    public static void main(String[] args) throws Exception {
+        // TODO(stuartscott)
+    }
+}
diff --git a/common/host-side/xml-plan-generator/tests/src/com/android/compatibility/common/xmlgenerator/XmlPlanGeneratorTest.java b/common/host-side/xml-plan-generator/tests/src/com/android/compatibility/common/xmlgenerator/XmlPlanGeneratorTest.java
new file mode 100644
index 0000000..35bcb02
--- /dev/null
+++ b/common/host-side/xml-plan-generator/tests/src/com/android/compatibility/common/xmlgenerator/XmlPlanGeneratorTest.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2014 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.compatibility.common.xmlgenerator;
+
+import junit.framework.TestCase;
+
+public class XmlPlanGeneratorTest extends TestCase {
+
+    // TODO(stuartscott): Add tests when there is something to test.
+}