Merge changes Ib927629c,Iac268723

* changes:
  Update copyright dates on generated CTS files.
  Fix inconsistency between API generator and CTS files
diff --git a/hostsidetests/security/src/android/cts/security/SELinuxHostTest.java b/hostsidetests/security/src/android/cts/security/SELinuxHostTest.java
index c80d676..2048185 100644
--- a/hostsidetests/security/src/android/cts/security/SELinuxHostTest.java
+++ b/hostsidetests/security/src/android/cts/security/SELinuxHostTest.java
@@ -34,7 +34,6 @@
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.lang.String;
-import java.net.URL;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -724,10 +723,11 @@
 
             /* take the output of a ps -Z to do our analysis */
             CollectingOutputReceiver psOut = new CollectingOutputReceiver();
-            tDevice.executeShellCommand("ps -Z", psOut);
+            // TODO: remove "toybox" below and just run "ps"
+            tDevice.executeShellCommand("toybox ps -A -o label,user,pid,ppid,cmdline", psOut);
             String psOutString = psOut.getOutput();
             Pattern p = Pattern.compile(
-                    "^([\\w_:]+)\\s+([\\w_]+)\\s+(\\d+)\\s+(\\d+)\\s+(\\p{Graph}+)\\s*$",
+                    "^([\\w_:]+)\\s+([\\w_]+)\\s+(\\d+)\\s+(\\d+)\\s+(\\p{Graph}+)(\\s\\p{Graph}+)*\\s*$",
                     Pattern.MULTILINE);
             Matcher m = p.matcher(psOutString);
             procMap = new HashMap<String, ArrayList<ProcessDetails>>();
@@ -743,7 +743,7 @@
                     procMap.put(domainLabel, new ArrayList<ProcessDetails>());
                 }
                 procMap.get(domainLabel).add(proc);
-                if (procTitle.equals("kthreadd") && ppid == 0) {
+                if (procTitle.equals("[kthreadd]") && ppid == 0) {
                     kernelParentThreadpid = pid;
                 }
                 if (exeMap.get(procTitle) == null) {
diff --git a/tests/core/libcore/libcore/Android.mk b/tests/core/libcore/libcore/Android.mk
index d8e3fcb..a547166 100644
--- a/tests/core/libcore/libcore/Android.mk
+++ b/tests/core/libcore/libcore/Android.mk
@@ -16,5 +16,5 @@
 
 include $(CLEAR_VARS)
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.libcore
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests mockito-target
+LOCAL_STATIC_JAVA_LIBRARIES := core-tests mockito-api
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/tests/jni/libjnitest/Android.mk b/tests/tests/jni/libjnitest/Android.mk
index 7a2d577..7140de4 100644
--- a/tests/tests/jni/libjnitest/Android.mk
+++ b/tests/tests/jni/libjnitest/Android.mk
@@ -30,13 +30,14 @@
 	android_jni_cts_JniCTest.c \
 	android_jni_cts_JniCppTest.cpp \
 	android_jni_cts_JniStaticTest.cpp \
+	android_jni_cts_LinkerNamespacesTest.cpp \
 	android_jni_cts_StaticNonce.c \
 	helper.c \
 	register.c
 
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
 
-LOCAL_SHARED_LIBRARIES := liblog libnativehelper_compat_libc++
+LOCAL_SHARED_LIBRARIES := libdl liblog libnativehelper_compat_libc++
 
 LOCAL_SDK_VERSION := 23
 LOCAL_NDK_STL_VARIANT := c++_static
diff --git a/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp b/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
new file mode 100644
index 0000000..5876532
--- /dev/null
+++ b/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+/*
+ * Tests accessibility of platform native libraries
+ */
+
+#include <dirent.h>
+#include <dlfcn.h>
+#include <jni.h>
+#include <JNIHelp.h>
+#include <libgen.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <list>
+#include <string>
+#include <unordered_set>
+#include <vector>
+
+static std::vector<std::string> kDefaultLibraryPaths = {
+#if defined(__LP64__)
+    "/system/lib64",
+    "/vendor/lib64",
+#else
+    "/system/lib",
+    "/vendor/lib",
+#endif
+  };
+
+static std::unordered_set<std::string> kPublicLibraries = {
+    "libandroid.so",
+    "libc.so",
+    "libdl.so",
+    "libEGL.so",
+    "libGLESv1_CM.so",
+    "libGLESv2.so",
+    "libGLESv3.so",
+    "libicui18n.so",
+    "libicuuc.so",
+    "libjnigraphics.so",
+    "liblog.so",
+    "libmediandk.so",
+    "libm.so",
+    "libOpenMAXAL.so",
+    "libOpenSLES.so",
+    "libRS.so",
+    "libstdc++.so",
+    "libwebviewchromium_plat_support.so",
+    "libz.so"
+  };
+
+template <typename F>
+static bool for_each_file(const std::string& dir, F functor, std::string* error_msg) {
+  auto dir_deleter = [](DIR* handle) { closedir(handle); };
+  std::unique_ptr<DIR, decltype(dir_deleter)> dirp(opendir(dir.c_str()), dir_deleter);
+  if (dirp == nullptr) {
+    *error_msg = strerror(errno);
+    return false;
+  }
+
+  dirent* dp;
+  while ((dp = readdir(dirp.get())) != nullptr) {
+    // skip "." and ".."
+    if (strcmp(".", dp->d_name) == 0 ||
+        strcmp("..", dp->d_name) == 0) {
+      continue;
+    }
+
+    if (!functor(dp->d_name, error_msg)) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+static bool should_be_accessible(const std::string& path) {
+  std::string name = basename(path.c_str());
+  return (kPublicLibraries.find(name) != kPublicLibraries.end()) &&
+         (kDefaultLibraryPaths.front() + "/" + name == path);
+}
+
+static bool is_directory(const std::string path) {
+  struct stat sb;
+  if (stat(path.c_str(), &sb) != -1) {
+    return S_ISDIR(sb.st_mode);
+  }
+
+  return false;
+}
+
+static bool is_libdl(const std::string path) {
+  return kDefaultLibraryPaths.front() + "/libdl.so" == path;
+}
+
+extern "C" JNIEXPORT jstring JNICALL Java_android_jni_cts_LinkerNamespacesHelper_runAccessibilityTest(
+        JNIEnv* env, jclass clazz __attribute__((unused))) {
+  std::list<std::string> dirs(kDefaultLibraryPaths.begin(), kDefaultLibraryPaths.end());
+  while (!dirs.empty()) {
+    const auto dir = dirs.front();
+    dirs.pop_front();
+    std::string error;
+    bool success = for_each_file(dir, [&dirs,&dir](const char* name, std::string* error_msg) {
+      std::string path = dir + "/" + name;
+      if (is_directory(path)) {
+        dirs.push_back(path);
+        return true;
+      }
+
+      if (is_libdl(path)) {
+        // TODO (dimitry): we skip check for libdl.so because
+        // 1. Linker will fail to check accessibility because it imposes as libdl.so (see http://b/27106625)
+        // 2. It is impractical to dlopen libdl.so because this library already depends
+        //    on it in order to have dlopen()
+        return true;
+      }
+
+      auto dlcloser = [](void* handle) { dlclose(handle); };
+      std::unique_ptr<void, decltype(dlcloser)> handle(dlopen(path.c_str(), RTLD_NOW), dlcloser);
+      if (should_be_accessible(path)) {
+        if (handle.get() == nullptr) {
+          *error_msg = "The library \"" + path + "\" should be accessible but isn't: " + dlerror();
+          return false;
+        }
+      } else if (handle != nullptr) {
+        *error_msg = "The library \"" + path + "\" should not be accessible";
+        return false;
+      } else { // (handle == nullptr && !shouldBeAccessible(path))
+        // Check the error message
+        std::string err = dlerror();
+
+        if (err != "dlopen failed: library \"" + path + "\" is not accessible for the namespace \"classloader-namespace\"") {
+          *error_msg = "unexpected dlerror: " + err;
+          return false;
+        }
+      }
+      return true;
+    }, &error);
+
+    if (!success) {
+      return env->NewStringUTF(error.c_str());
+    }
+  }
+
+  return nullptr;
+}
+
diff --git a/tests/tests/jni/src/android/jni/cts/JniStaticTest.java b/tests/tests/jni/src/android/jni/cts/JniStaticTest.java
index d4b51b9..8a91c44 100644
--- a/tests/tests/jni/src/android/jni/cts/JniStaticTest.java
+++ b/tests/tests/jni/src/android/jni/cts/JniStaticTest.java
@@ -31,6 +31,17 @@
     }
 
     /**
+     * Test library accessibility. Internal platform libraries should not
+     * be accessible from the jni code.
+     */
+    public void test_linker_namespaces() {
+        String error = LinkerNamespacesHelper.runAccessibilityTest();
+        if (error != null) {
+            fail(error);
+        }
+    }
+
+    /**
      * Test that accessing classes true JNI works as expected. b/19382130
      */
     public void test_classload() {
diff --git a/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java b/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java
new file mode 100644
index 0000000..2dff019
--- /dev/null
+++ b/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 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.jni.cts;
+
+class LinkerNamespacesHelper {
+    public static native String runAccessibilityTest();
+}
diff --git a/tests/tests/os/src/android/os/cts/AbiTest.java b/tests/tests/os/src/android/os/cts/AbiTest.java
index ee2c168..1d343e6 100644
--- a/tests/tests/os/src/android/os/cts/AbiTest.java
+++ b/tests/tests/os/src/android/os/cts/AbiTest.java
@@ -17,16 +17,35 @@
 package android.os.cts;
 
 import android.cts.util.ReadElf;
+import android.util.ArraySet;
 
 import java.io.File;
+import java.util.Arrays;
 
 import junit.framework.TestCase;
 
 public class AbiTest extends TestCase {
     public void testNo64() throws Exception {
-        for (String dir : new File("/").list()) {
-            if (!dir.equals("data") && !dir.equals("dev") && !dir.equals("proc") && !dir.equals("sys")) {
-                checkElfFilesInDirectory(new File("/" + dir));
+        ArraySet<String> abiDirs = new ArraySet(Arrays.asList(
+            "/sbin",
+            "/system",
+            "/vendor"));
+        String pathVar = System.getenv("PATH");
+        if (pathVar != null) {
+            abiDirs.addAll(Arrays.asList(pathVar.split(":")));
+        }
+        for (String dir : abiDirs) {
+            boolean skip_dir = false;
+            for (String dirOther : abiDirs) {
+                if (dir.equals(dirOther)) {
+                    continue;
+                } else if (dir.startsWith(dirOther + "/")) {
+                    skip_dir = true;
+                    break;
+                }
+            }
+            if (!skip_dir) {
+                checkElfFilesInDirectory(new File(dir));
             }
         }
     }
diff --git a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
index 05079d7..de5a828 100644
--- a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
@@ -284,6 +284,40 @@
         assertFileOwnedByGroup(dir, "root");
     }
 
+
+    @MediumTest
+    public void testProcfsMmapRndBitsExistsAndSane() throws Exception {
+        String arch = System.getProperty("os.arch");
+        boolean supported = false;
+        boolean supported_64 = false;
+
+        if (arch.equals("aarch64") || arch.equals("x86_64"))
+            supported_64 = true;
+        else if (arch.startsWith("arm") || arch.endsWith("86"))
+            supported = true;
+
+        /* 64-bit OS should support running 32-bit applications */
+        if (supported_64) {
+            File f = new File("/proc/sys/vm/mmap_rnd_compat_bits");
+            assertTrue(f.exists());
+            assertFalse(f.canRead());
+            assertFalse(f.canWrite());
+            assertFalse(f.canExecute());
+            assertFileOwnedBy(f, "root");
+            assertFileOwnedByGroup(f, "root");
+        }
+
+        if (supported_64 || supported) {
+            File f = new File("/proc/sys/vm/mmap_rnd_bits");
+            assertTrue(f.exists());
+            assertFalse(f.canRead());
+            assertFalse(f.canWrite());
+            assertFalse(f.canExecute());
+            assertFileOwnedBy(f, "root");
+            assertFileOwnedByGroup(f, "root");
+        }
+    }
+
     /**
      * Assert that a file is owned by a specific owner. This is a noop if the
      * file does not exist.
diff --git a/tests/tests/renderscript/AndroidManifest.xml b/tests/tests/renderscript/AndroidManifest.xml
index 6e67f9e..b7e1e1a 100644
--- a/tests/tests/renderscript/AndroidManifest.xml
+++ b/tests/tests/renderscript/AndroidManifest.xml
@@ -24,7 +24,7 @@
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
-    <application>
+    <application android:largeHeap="true">
         <uses-library android:name="android.test.runner" />
     </application>
 
diff --git a/tests/tests/rsblas/libbnnmdata/Android.mk b/tests/tests/rsblas/libbnnmdata/Android.mk
index 471d74a..bbfd289 100644
--- a/tests/tests/rsblas/libbnnmdata/Android.mk
+++ b/tests/tests/rsblas/libbnnmdata/Android.mk
@@ -19,6 +19,8 @@
 LOCAL_MODULE := libbnnmdata_jni
 LOCAL_MODULE_TAGS := optional
 LOCAL_SRC_FILES := test_data.cpp
+LOCAL_SDK_VERSION := 23
+LOCAL_NDK_STL_VARIANT := c++_static
 
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
 
diff --git a/tools/vm-tests-tf/Android.mk b/tools/vm-tests-tf/Android.mk
index 7578fa9..4958d4e 100644
--- a/tools/vm-tests-tf/Android.mk
+++ b/tools/vm-tests-tf/Android.mk
@@ -30,12 +30,6 @@
 
 cts-tf-dalvik-lib.jack := $(full_classes_jack)
 
-private_jill_jarjar_asm := $(addprefix $(HOST_OUT_JAVA_LIBRARIES)/,jill-jarjar-asm.jar)
-$(private_jill_jarjar_asm) : PRIVATE_JARJAR_RULES := $(LOCAL_PATH)/jill-jarjar-rules.txt
-$(private_jill_jarjar_asm) : $(addprefix $(HOST_OUT_JAVA_LIBRARIES)/,jill.jar) | $(JARJAR)
-	@echo JarJar: $@
-	$(hide) java -jar $(JARJAR) process $(PRIVATE_JARJAR_RULES) $< $@
-
 # buildutil java library
 # ============================================================
 include $(CLEAR_VARS)
@@ -53,7 +47,7 @@
 LOCAL_JAVA_LIBRARIES := dx dasm cfassembler junit
 LOCAL_JAVA_LIBRARIES += jack
 
-LOCAL_CLASSPATH := $(HOST_JDK_TOOLS_JAR) $(private_jill_jarjar_asm)
+LOCAL_CLASSPATH := $(HOST_JDK_TOOLS_JAR)
 
 include $(BUILD_HOST_JAVA_LIBRARY)
 
@@ -66,8 +60,6 @@
 intermediates := $(call intermediates-dir-for,JAVA_LIBRARIES,vm-tests-tf,HOST)
 vmteststf_jar := $(intermediates)/android.core.vm-tests-tf.jar
 vmteststf_dep_jars := $(addprefix $(HOST_OUT_JAVA_LIBRARIES)/, cts-tf-dalvik-buildutil.jar dasm.jar dx.jar cfassembler.jar junit.jar)
-vmteststf_dep_jars += $(addprefix $(HOST_OUT_JAVA_LIBRARIES)/, jack.jar)
-vmteststf_dep_jars += $(private_jill_jarjar_asm)
 
 $(vmteststf_jar): PRIVATE_JACK_EXTRA_ARGS := $(LOCAL_JACK_EXTRA_ARGS)
 
@@ -83,7 +75,7 @@
 $(vmteststf_jar): PRIVATE_INTERMEDIATES_HOSTJUNIT_FILES := $(intermediates)/hostjunit_files
 $(vmteststf_jar): PRIVATE_CLASS_PATH := $(subst $(space),:,$(vmteststf_dep_jars)):$(HOST_JDK_TOOLS_JAR)
 ifndef LOCAL_JACK_ENABLED
-$(vmteststf_jar) : $(vmteststf_dep_jars) $(JACK_JAR) $(JILL_JAR) $(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar
+$(vmteststf_jar) : $(vmteststf_dep_jars) $(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar
 	$(hide) rm -rf $(dir $@) && mkdir -p $(dir $@)
 	$(hide) mkdir -p $(PRIVATE_INTERMEDIATES_HOSTJUNIT_FILES)/dot/junit $(dir $(PRIVATE_INTERMEDIATES_DEXCORE_JAR))
 	# generated and compile the host side junit tests
@@ -102,18 +94,18 @@
 oj_jack := $(call intermediates-dir-for,JAVA_LIBRARIES,core-oj,,COMMON)/classes.jack
 libart_jack := $(call intermediates-dir-for,JAVA_LIBRARIES,core-libart,,COMMON)/classes.jack
 $(vmteststf_jar): PRIVATE_DALVIK_SUITE_CLASSPATH := $(oj_jack):$(libart_jack):$(cts-tf-dalvik-lib.jack):$(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar
-$(vmteststf_jar) : $(vmteststf_dep_jars) $(JACK_JAR) $(JILL_JAR) $(oj_jack) $(libart_jack) $(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar
+$(vmteststf_jar) : $(vmteststf_dep_jars) $(JACK) $(oj_jack) $(libart_jack) $(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar | setup-jack-server
 	$(hide) rm -rf $(dir $@) && mkdir -p $(dir $@)
 	$(hide) mkdir -p $(PRIVATE_INTERMEDIATES_HOSTJUNIT_FILES)/dot/junit $(dir $(PRIVATE_INTERMEDIATES_DEXCORE_JAR))
 	# generated and compile the host side junit tests
 	@echo "Write generated Main_*.java files to $(PRIVATE_INTERMEDIATES_MAIN_FILES)"
-	$(hide) java -cp $(PRIVATE_CLASS_PATH) util.build.JackBuildDalvikSuite $(PRIVATE_SRC_FOLDER) $(PRIVATE_INTERMEDIATES) \
+	$(hide) JACK_VERSION=$(JACK_DEFAULT_VERSION) java -cp $(PRIVATE_CLASS_PATH) util.build.JackBuildDalvikSuite $(JACK) $(PRIVATE_SRC_FOLDER) $(PRIVATE_INTERMEDIATES) \
 		$(PRIVATE_DALVIK_SUITE_CLASSPATH) \
 		$(PRIVATE_INTERMEDIATES_MAIN_FILES) $(PRIVATE_INTERMEDIATES_CLASSES) $(PRIVATE_INTERMEDIATES_HOSTJUNIT_FILES) $$RUN_VM_TESTS_RTO
 	@echo "Generate $(PRIVATE_INTERMEDIATES_DEXCORE_JAR)"
 	$(hide) jar -cf $(PRIVATE_INTERMEDIATES_DEXCORE_JAR)-class.jar \
 		$(addprefix -C $(PRIVATE_INTERMEDIATES_CLASSES) , dot/junit/DxUtil.class dot/junit/DxAbstractMain.class)
-	$(hide) $(JILL) --output $(PRIVATE_INTERMEDIATES_DEXCORE_JAR).jack $(PRIVATE_INTERMEDIATES_DEXCORE_JAR)-class.jar
+	$(hide) $(JACK) --import $(PRIVATE_INTERMEDIATES_DEXCORE_JAR)-class.jar --output-jack $(PRIVATE_INTERMEDIATES_DEXCORE_JAR).jack
 	$(hide) mkdir -p $(PRIVATE_INTERMEDIATES_DEXCORE_JAR).tmp
 	$(hide) $(call call-jack,$(PRIVATE_JACK_EXTRA_ARGS)) --output-dex $(PRIVATE_INTERMEDIATES_DEXCORE_JAR).tmp \
 		$(if $(NO_OPTIMIZE_DX), -D jack.dex.optimize "false") --import $(PRIVATE_INTERMEDIATES_DEXCORE_JAR).jack && rm -f $(PRIVATE_INTERMEDIATES_DEXCORE_JAR).jack
diff --git a/tools/vm-tests-tf/src/util/build/BuildDalvikSuite.java b/tools/vm-tests-tf/src/util/build/BuildDalvikSuite.java
index a25fce2..08b1e5f 100644
--- a/tools/vm-tests-tf/src/util/build/BuildDalvikSuite.java
+++ b/tools/vm-tests-tf/src/util/build/BuildDalvikSuite.java
@@ -105,7 +105,10 @@
      */
     public static void main(String[] args) throws IOException {
 
-        parseArgs(args);
+        if (!parseArgs(args)) {
+          printUsage();
+          System.exit(-1);
+        }
 
         long start = System.currentTimeMillis();
         BuildDalvikSuite cat = new BuildDalvikSuite(false);
@@ -115,7 +118,7 @@
         System.out.println("elapsed seconds: " + (end - start) / 1000);
     }
 
-    public static void parseArgs(String[] args) {
+    public static boolean parseArgs(String[] args) {
       if (args.length > 5) {
           JAVASRC_FOLDER = args[0];
           OUTPUT_FOLDER = args[1];
@@ -133,15 +136,18 @@
               restrictTo = args[6];
               System.out.println("restricting build to: " + restrictTo);
           }
-
+          return true;
       } else {
-          System.out.println("usage: java-src-folder output-folder classpath " +
-                  "generated-main-files compiled_output generated-main-files " +
-          "[restrict-to-opcode]");
-          System.exit(-1);
+          return false;
       }
     }
 
+    private static void printUsage() {
+        System.out.println("usage: java-src-folder output-folder classpath " +
+                           "generated-main-files compiled_output generated-main-files " +
+                           "[restrict-to-opcode]");
+    }
+
     public BuildDalvikSuite(boolean useJack) {
       this.useJack = useJack;
     }
diff --git a/tools/vm-tests-tf/src/util/build/BytesStreamSucker.java b/tools/vm-tests-tf/src/util/build/BytesStreamSucker.java
new file mode 100644
index 0000000..f243c17
--- /dev/null
+++ b/tools/vm-tests-tf/src/util/build/BytesStreamSucker.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2012 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 util.build;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.annotation.Nonnull;
+
+/**
+ * Class that continuously read an {@link InputStream} and optionally could write the input in a
+ * {@link OutputStream}.
+ */
+public class BytesStreamSucker {
+
+  private static final int BUFFER_SIZE = 4096;
+
+  @Nonnull
+  private final byte[] buffer = new byte[BUFFER_SIZE];
+
+  @Nonnull
+  private final InputStream is;
+
+  @Nonnull
+  private final OutputStream os;
+
+  private final boolean toBeClose;
+
+  public BytesStreamSucker(
+      @Nonnull InputStream is, @Nonnull OutputStream os, boolean toBeClose) {
+    this.is = is;
+    this.os = os;
+    this.toBeClose = toBeClose;
+  }
+
+  public BytesStreamSucker(@Nonnull InputStream is, @Nonnull OutputStream os) {
+    this(is, os, false);
+  }
+
+  public void suck() throws IOException {
+    try {
+      int bytesRead;
+      while ((bytesRead = is.read(buffer)) >= 0) {
+        os.write(buffer, 0, bytesRead);
+        os.flush();
+      }
+    } finally {
+      if (toBeClose) {
+        os.close();
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/tools/vm-tests-tf/src/util/build/CharactersStreamSucker.java b/tools/vm-tests-tf/src/util/build/CharactersStreamSucker.java
new file mode 100644
index 0000000..ce4dfb1
--- /dev/null
+++ b/tools/vm-tests-tf/src/util/build/CharactersStreamSucker.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2012 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 util.build;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+
+import javax.annotation.Nonnull;
+
+/**
+ * Class that continuously read an {@link InputStream} and optionally could print the input in a
+ * {@link PrintStream}.
+ */
+public class CharactersStreamSucker {
+
+  @Nonnull
+  private final BufferedReader ir;
+
+  @Nonnull
+  private final PrintStream os;
+
+  private final boolean toBeClose;
+
+  public CharactersStreamSucker(
+      @Nonnull InputStream is, @Nonnull PrintStream os, boolean toBeClose) {
+    this.ir = new BufferedReader(new InputStreamReader(is));
+    this.os = os;
+    this.toBeClose = toBeClose;
+  }
+
+  public CharactersStreamSucker(@Nonnull InputStream is, @Nonnull PrintStream os) {
+    this(is, os, false);
+  }
+
+  public void suck() throws IOException {
+    String line;
+
+    try {
+      while ((line = ir.readLine()) != null) {
+        os.println(line);
+      }
+    } finally {
+      if (toBeClose) {
+        os.close();
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/tools/vm-tests-tf/src/util/build/ExecuteFile.java b/tools/vm-tests-tf/src/util/build/ExecuteFile.java
new file mode 100644
index 0000000..128e477
--- /dev/null
+++ b/tools/vm-tests-tf/src/util/build/ExecuteFile.java
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2012 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 util.build;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.StreamTokenizer;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+
+/**
+ * Class to handle the execution of an external process
+ */
+public class ExecuteFile {
+  @Nonnull
+  private final String[] cmdLine;
+
+  @CheckForNull
+  private File workDir;
+
+  @CheckForNull
+  private InputStream inStream;
+  private boolean inToBeClose;
+
+  @CheckForNull
+  private OutputStream outStream;
+  private boolean outToBeClose;
+
+  @CheckForNull
+  private OutputStream errStream;
+  private boolean errToBeClose;
+  private boolean verbose;
+
+  @Nonnull
+  private final Logger logger = Logger.getLogger(this.getClass().getName());
+
+  public void setErr(@Nonnull File file) throws FileNotFoundException {
+    errStream = new FileOutputStream(file);
+    errToBeClose = true;
+  }
+
+  public void setOut(@Nonnull File file) throws FileNotFoundException {
+    outStream = new FileOutputStream(file);
+    outToBeClose = true;
+  }
+
+  public void setIn(@Nonnull File file) throws FileNotFoundException {
+    inStream = new FileInputStream(file);
+    inToBeClose = true;
+  }
+
+  public void setErr(@Nonnull OutputStream stream) {
+    errStream = stream;
+  }
+
+  public void setOut(@Nonnull OutputStream stream) {
+    outStream = stream;
+  }
+
+  public void setIn(@Nonnull InputStream stream) {
+    inStream = stream;
+  }
+
+  public void setWorkingDir(@Nonnull File dir, boolean create) throws IOException {
+    if (!dir.isDirectory()) {
+      if (create && !dir.exists()) {
+        if (!dir.mkdirs()) {
+          throw new IOException("Directory creation failed");
+        }
+      } else {
+        throw new FileNotFoundException(dir.getPath() + " is not a directory");
+      }
+    }
+
+    workDir = dir;
+  }
+
+  public void setVerbose(boolean verbose) {
+    this.verbose = verbose;
+  }
+
+  public ExecuteFile(@Nonnull File exec, @Nonnull String[] args) {
+    cmdLine = new String[args.length + 1];
+    System.arraycopy(args, 0, cmdLine, 1, args.length);
+
+    cmdLine[0] = exec.getAbsolutePath();
+  }
+
+  public ExecuteFile(@Nonnull String exec, @Nonnull String[] args) {
+    cmdLine = new String[args.length + 1];
+    System.arraycopy(args, 0, cmdLine, 1, args.length);
+
+    cmdLine[0] = exec;
+  }
+
+  public ExecuteFile(@Nonnull File exec) {
+    cmdLine = new String[1];
+    cmdLine[0] = exec.getAbsolutePath();
+  }
+
+  public ExecuteFile(@Nonnull String[] cmdLine) {
+    this.cmdLine = cmdLine.clone();
+  }
+
+  public ExecuteFile(@Nonnull String cmdLine) throws IOException {
+    StringReader reader = new StringReader(cmdLine);
+    StreamTokenizer tokenizer = new StreamTokenizer(reader);
+    tokenizer.resetSyntax();
+    // Only standard spaces are recognized as whitespace chars
+    tokenizer.whitespaceChars(' ', ' ');
+    // Matches alphanumerical and common special symbols like '(' and ')'
+    tokenizer.wordChars('!', 'z');
+    // Quote chars will be ignored when parsing strings
+    tokenizer.quoteChar('\'');
+    tokenizer.quoteChar('\"');
+    ArrayList<String> tokens = new ArrayList<String>();
+    while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) {
+      String token = tokenizer.sval;
+      if (token != null) {
+        tokens.add(token);
+      }
+    }
+    this.cmdLine = tokens.toArray(new String[0]);
+  }
+
+  public boolean run() {
+    int ret;
+    Process proc = null;
+    Thread suckOut = null;
+    Thread suckErr = null;
+    Thread suckIn = null;
+
+    try {
+      StringBuilder cmdLineBuilder = new StringBuilder();
+      for (String arg : cmdLine) {
+        cmdLineBuilder.append(arg).append(' ');
+      }
+      if (verbose) {
+        PrintStream printStream;
+        if (outStream instanceof PrintStream) {
+          printStream = (PrintStream) outStream;
+        } else {
+          printStream = System.out;
+        }
+
+        if (printStream != null) {
+          printStream.println(cmdLineBuilder);
+        }
+      } else {
+        logger.log(Level.FINE, "Execute: {0}", cmdLineBuilder);
+      }
+
+      proc = Runtime.getRuntime().exec(cmdLine, null, workDir);
+
+      InputStream localInStream = inStream;
+      if (localInStream != null) {
+        suckIn = new Thread(
+            new ThreadBytesStreamSucker(localInStream, proc.getOutputStream(), inToBeClose));
+      } else {
+        proc.getOutputStream().close();
+      }
+
+      OutputStream localOutStream = outStream;
+      if (localOutStream != null) {
+        if (localOutStream instanceof PrintStream) {
+          suckOut = new Thread(new ThreadCharactersStreamSucker(proc.getInputStream(),
+              (PrintStream) localOutStream, outToBeClose));
+        } else {
+          suckOut = new Thread(
+              new ThreadBytesStreamSucker(proc.getInputStream(), localOutStream, outToBeClose));
+        }
+      }
+
+      OutputStream localErrStream = errStream;
+      if (localErrStream != null) {
+        if (localErrStream instanceof PrintStream) {
+          suckErr = new Thread(new ThreadCharactersStreamSucker(proc.getErrorStream(),
+              (PrintStream) localErrStream, errToBeClose));
+        } else {
+          suckErr = new Thread(
+              new ThreadBytesStreamSucker(proc.getErrorStream(), localErrStream, errToBeClose));
+        }
+      }
+
+      if (suckIn != null) {
+        suckIn.start();
+      }
+      if (suckOut != null) {
+        suckOut.start();
+      }
+      if (suckErr != null) {
+        suckErr.start();
+      }
+
+      proc.waitFor();
+      if (suckIn != null) {
+        suckIn.join();
+      }
+      if (suckOut != null) {
+        suckOut.join();
+      }
+      if (suckErr != null) {
+        suckErr.join();
+      }
+
+      ret = proc.exitValue();
+      proc.destroy();
+
+      return ret == 0;
+    } catch (Throwable e) {
+      e.printStackTrace();
+      return false;
+    }
+  }
+
+  private static class ThreadBytesStreamSucker extends BytesStreamSucker implements Runnable {
+
+    public ThreadBytesStreamSucker(@Nonnull InputStream is, @Nonnull OutputStream os,
+        boolean toBeClose) {
+      super(is, os, toBeClose);
+    }
+
+    @Override
+    public void run() {
+      try {
+        suck();
+      } catch (IOException e) {
+        // Best effort
+      }
+    }
+  }
+
+  private static class ThreadCharactersStreamSucker extends CharactersStreamSucker implements
+      Runnable {
+
+    public ThreadCharactersStreamSucker(@Nonnull InputStream is, @Nonnull PrintStream ps,
+        boolean toBeClose) {
+      super(is, ps, toBeClose);
+    }
+
+    @Override
+    public void run() {
+      try {
+        suck();
+      } catch (IOException e) {
+        // Best effort
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/tools/vm-tests-tf/src/util/build/JackBuildDalvikSuite.java b/tools/vm-tests-tf/src/util/build/JackBuildDalvikSuite.java
index a508e5b..2b45f9c 100644
--- a/tools/vm-tests-tf/src/util/build/JackBuildDalvikSuite.java
+++ b/tools/vm-tests-tf/src/util/build/JackBuildDalvikSuite.java
@@ -20,9 +20,23 @@
 
 public class JackBuildDalvikSuite {
 
+    public static String JACK;
+
     public static void main(String[] args) throws IOException {
 
-        BuildDalvikSuite.parseArgs(args);
+        String[] remainingArgs;
+        if (args.length > 0) {
+            JACK = args[0];
+            remainingArgs = new String[args.length - 1];
+            System.arraycopy(args, 1, remainingArgs, 0, remainingArgs.length);
+        } else {
+            remainingArgs = args;
+        }
+
+        if (!BuildDalvikSuite.parseArgs(remainingArgs)) {
+            printUsage();
+            System.exit(-1);
+        }
 
         long start = System.currentTimeMillis();
         BuildDalvikSuite cat = new BuildDalvikSuite(true);
@@ -31,4 +45,11 @@
 
         System.out.println("elapsed seconds: " + (end - start) / 1000);
     }
+
+
+    private static void printUsage() {
+        System.out.println("usage: java-src-folder output-folder classpath " +
+                           "generated-main-files compiled_output generated-main-files " +
+                           "[restrict-to-opcode]");
+    }
 }
diff --git a/tools/vm-tests-tf/src/util/build/JackBuildStep.java b/tools/vm-tests-tf/src/util/build/JackBuildStep.java
index 061ff07..ed46582 100644
--- a/tools/vm-tests-tf/src/util/build/JackBuildStep.java
+++ b/tools/vm-tests-tf/src/util/build/JackBuildStep.java
@@ -16,16 +16,10 @@
 
 package util.build;
 
-import com.android.jack.CLILogConfiguration;
-import com.android.jack.CLILogConfiguration.LogConfigurationException;
-
-import util.build.BuildStep.BuildFile;
-
-import com.android.jack.Jack;
-import com.android.jack.Main;
-import com.android.jack.Options;
 import java.io.File;
+import java.io.FileWriter;
 import java.io.IOException;
+import java.io.Writer;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -33,14 +27,6 @@
 
 public class JackBuildStep extends SourceBuildStep {
 
-    static {
-        try {
-              CLILogConfiguration.setupLogs();
-            } catch (LogConfigurationException e) {
-              throw new Error("Failed to setup logs", e);
-            }
-    }
-
     private final String destPath;
     private final String classPath;
     private final Set<String> sourceFiles = new HashSet<String>();
@@ -78,7 +64,18 @@
             }
             File tmpDex = new File(tmpOutDir, "classes.dex");
 
+            File tmpArgs = new File(outDir, outputFile.fileName.getName() + ".args");
+
+            Writer argsOut = null;
             try {
+                argsOut = new FileWriter(tmpArgs);
+                for (String source : sourceFiles) {
+                    argsOut.append(source);
+                    argsOut.append('\n');
+                }
+                argsOut.close();
+                argsOut = null;
+
                 List<String> commandLine = new ArrayList<String>(6 + sourceFiles.size());
                 commandLine.add("--verbose");
                 commandLine.add("error");
@@ -86,10 +83,15 @@
                 commandLine.add(classPath);
                 commandLine.add("--output-dex");
                 commandLine.add(tmpOutDir.getAbsolutePath());
-                commandLine.addAll(sourceFiles);
+                commandLine.add("@" + tmpArgs.getPath());
 
-                Options options = Main.parseCommandLine(commandLine);
-                Jack.checkAndRun(options);
+                ExecuteFile exec = new ExecuteFile(JackBuildDalvikSuite.JACK,
+                    commandLine.toArray(new String[commandLine.size()]));
+                exec.setErr(System.err);
+                exec.setOut(System.out);
+                if (!exec.run()) {
+                    return false;
+                }
 
                 JarBuildStep jarStep = new JarBuildStep(
                     new BuildFile(tmpDex),
@@ -104,8 +106,16 @@
                 ex.printStackTrace();
                 return false;
             } finally {
-              tmpDex.delete();
-              tmpOutDir.delete();
+                tmpDex.delete();
+                tmpArgs.delete();
+                tmpOutDir.delete();
+                if (argsOut != null) {
+                    try {
+                        argsOut.close();
+                    } catch (IOException io) {
+                        // Ignore, don't override already thrown exception
+                    }
+                }
             }
         }
         return false;
diff --git a/tools/vm-tests-tf/src/util/build/JackDexBuildStep.java b/tools/vm-tests-tf/src/util/build/JackDexBuildStep.java
index 8734cf0..cbd5a3b 100644
--- a/tools/vm-tests-tf/src/util/build/JackDexBuildStep.java
+++ b/tools/vm-tests-tf/src/util/build/JackDexBuildStep.java
@@ -16,10 +16,6 @@
 
 package util.build;
 
-import com.android.jack.Jack;
-import com.android.jack.Main;
-import com.android.jack.Options;
-
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
@@ -69,8 +65,13 @@
                 commandLine.add("--import");
                 commandLine.add(inputFile.fileName.getAbsolutePath());
 
-                Options options = Main.parseCommandLine(commandLine);
-                Jack.checkAndRun(options);
+                ExecuteFile exec = new ExecuteFile(JackBuildDalvikSuite.JACK,
+                    commandLine.toArray(new String[commandLine.size()]));
+                exec.setErr(System.err);
+                exec.setOut(System.out);
+                if (!exec.run()) {
+                  return false;
+                }
 
                 JarBuildStep jarStep = new JarBuildStep(
                     new BuildFile(tmpDex),
diff --git a/tools/vm-tests-tf/src/util/build/JillBuildStep.java b/tools/vm-tests-tf/src/util/build/JillBuildStep.java
index d2e435e..80cd49c 100644
--- a/tools/vm-tests-tf/src/util/build/JillBuildStep.java
+++ b/tools/vm-tests-tf/src/util/build/JillBuildStep.java
@@ -16,11 +16,8 @@
 
 package util.build;
 
-import com.android.jill.Jill;
-import com.android.jill.Main;
-import com.android.jill.Options;
-
 import java.io.File;
+import java.io.IOException;
 
 public class JillBuildStep extends BuildStep {
 
@@ -31,29 +28,52 @@
     @Override
     boolean build() {
         if (super.build()) {
-
-            File outDir = outputFile.fileName.getParentFile();
-            if (!outDir.exists() && !outDir.mkdirs()) {
-                System.err.println("failed to create output dir: "
-                        + outDir.getAbsolutePath());
-                return false;
-            }
-
-            int args = 3;
-            String[] commandLine = new String[args];
-            commandLine[0] = "--output";
-            commandLine[1] = outputFile.fileName.getAbsolutePath();
-            commandLine[2] = inputFile.fileName.getAbsolutePath();
-
+            File tmpInputJar = new File(inputFile.fileName.getPath() + ".jar");
             try {
-                Options options = Main.getOptions(commandLine);
-                Jill.process(options);
-            } catch (Throwable ex) {
-                ex.printStackTrace();
-                return false;
-            }
 
-            return true;
+                File outDir = outputFile.fileName.getParentFile();
+                if (!outDir.exists() && !outDir.mkdirs()) {
+                    System.err.println("failed to create output dir: "
+                            + outDir.getAbsolutePath());
+                    return false;
+                }
+
+                // input file is a class file but jack supports only jar
+                JarBuildStep jarStep = new JarBuildStep(
+                    inputFile,
+                    inputFile.fileName.getName(),
+                    new BuildFile(tmpInputJar),
+                    /* deleteInputFileAfterBuild = */ false);
+                if (!jarStep.build()) {
+                  throw new IOException("Failed to make jar: " + outputFile.getPath());
+                }
+
+
+                String[] commandLine = new String[] {
+                    "--verbose",
+                    "error",
+                    "--import",
+                    tmpInputJar.getAbsolutePath(),
+                    "--output-jack",
+                    outputFile.fileName.getAbsolutePath(),
+                  };
+
+                ExecuteFile exec = new ExecuteFile(JackBuildDalvikSuite.JACK, commandLine);
+                exec.setErr(System.err);
+                exec.setOut(System.out);
+                if (!exec.run()) {
+                    return false;
+                }
+
+                return true;
+            } catch (Throwable ex) {
+                System.err.println("exception while transforming jack file from jar "
+                        + inputFile.fileName.getAbsolutePath() + " to "
+                        + outputFile.fileName.getAbsolutePath());
+                ex.printStackTrace();
+            } finally {
+                tmpInputJar.delete();
+            }
         }
         return false;
     }