diff --git a/build/Android.common_test.mk b/build/Android.common_test.mk
index b536fe4..c750399 100644
--- a/build/Android.common_test.mk
+++ b/build/Android.common_test.mk
@@ -160,6 +160,10 @@
 # $(4): additional dependencies
 # $(5): a make variable used to collate target dependencies, e.g ART_TEST_TARGET_OAT_HelloWorld_DEX
 # $(6): a make variable used to collate host dependencies, e.g ART_TEST_HOST_OAT_HelloWorld_DEX
+#
+# If the input test directory contains a file called main.list, then a
+# multi-dex file is created passing main.list as the --main-dex-list argument
+# to dx.
 define build-art-test-dex
   ifeq ($(ART_BUILD_TARGET),true)
     include $(CLEAR_VARS)
@@ -172,6 +176,9 @@
     LOCAL_JAVA_LIBRARIES := $(TARGET_CORE_JARS)
     LOCAL_MODULE_PATH := $(3)
     LOCAL_DEX_PREOPT_IMAGE_LOCATION := $(TARGET_CORE_IMG_OUT)
+    ifneq ($(wildcard $(LOCAL_PATH)/$(2)/main.list),)
+      LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(LOCAL_PATH)/$(2)/main.list --minimal-main-dex
+    endif
     include $(BUILD_JAVA_LIBRARY)
     $(5) := $$(LOCAL_INSTALLED_MODULE)
   endif
@@ -184,6 +191,9 @@
     LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common_test.mk $(4)
     LOCAL_JAVA_LIBRARIES := $(HOST_CORE_JARS)
     LOCAL_DEX_PREOPT_IMAGE := $(HOST_CORE_IMG_LOCATION)
+    ifneq ($(wildcard $(LOCAL_PATH)/$(2)/main.list),)
+      LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(LOCAL_PATH)/$(2)/main.list --minimal-main-dex
+    endif
     include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
     $(6) := $$(LOCAL_INSTALLED_MODULE)
   endif
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index 7ab4d64..6967808 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -28,6 +28,7 @@
   GetMethodSignature \
   Interfaces \
   Main \
+  MultiDex \
   MyClass \
   MyClassNatives \
   Nested \
@@ -45,6 +46,19 @@
   $(ART_TARGET_NATIVETEST_OUT),art/build/Android.gtest.mk,ART_TEST_TARGET_GTEST_$(dir)_DEX, \
   ART_TEST_HOST_GTEST_$(dir)_DEX)))
 
+# Create rules for MainStripped, a copy of Main with the classes.dex stripped
+# for the oat file assistant tests.
+ART_TEST_HOST_GTEST_MainStripped_DEX := $(basename $(ART_TEST_HOST_GTEST_Main_DEX))Stripped$(suffix $(ART_TEST_HOST_GTEST_Main_DEX))
+ART_TEST_TARGET_GTEST_MainStripped_DEX := $(basename $(ART_TEST_TARGET_GTEST_Main_DEX))Stripped$(suffix $(ART_TEST_TARGET_GTEST_Main_DEX))
+
+$(ART_TEST_HOST_GTEST_MainStripped_DEX): $(ART_TEST_HOST_GTEST_Main_DEX)
+	cp $< $@
+	$(call dexpreopt-remove-classes.dex,$@)
+
+$(ART_TEST_TARGET_GTEST_MainStripped_DEX): $(ART_TEST_TARGET_GTEST_Main_DEX)
+	cp $< $@
+	$(call dexpreopt-remove-classes.dex,$@)
+
 # Dex file dependencies for each gtest.
 ART_GTEST_class_linker_test_DEX_DEPS := Interfaces MyClass Nested Statics StaticsFromCode
 ART_GTEST_compiler_driver_test_DEX_DEPS := AbstractMethod
@@ -52,6 +66,7 @@
 ART_GTEST_exception_test_DEX_DEPS := ExceptionHandle
 ART_GTEST_jni_compiler_test_DEX_DEPS := MyClassNatives
 ART_GTEST_jni_internal_test_DEX_DEPS := AllFields StaticLeafMethods
+ART_GTEST_oat_file_assistant_test_DEX_DEPS := Main MainStripped MultiDex Nested
 ART_GTEST_object_test_DEX_DEPS := ProtoCompare ProtoCompare2 StaticsFromCode XandY
 ART_GTEST_proxy_test_DEX_DEPS := Interfaces
 ART_GTEST_reflection_test_DEX_DEPS := Main NonStaticLeafMethods StaticLeafMethods
@@ -62,6 +77,9 @@
 ART_GTEST_elf_writer_test_HOST_DEPS := $(HOST_CORE_IMAGE_default_no-pic_64) $(HOST_CORE_IMAGE_default_no-pic_32)
 ART_GTEST_elf_writer_test_TARGET_DEPS := $(TARGET_CORE_IMAGE_default_no-pic_64) $(TARGET_CORE_IMAGE_default_no-pic_32)
 
+ART_GTEST_oat_file_assistant_test_HOST_DEPS := $(HOST_CORE_IMAGE_default_no-pic_64) $(HOST_CORE_IMAGE_default_no-pic_32)
+ART_GTEST_oat_file_assistant_test_TARGET_DEPS := $(TARGET_CORE_IMAGE_default_no-pic_64) $(TARGET_CORE_IMAGE_default_no-pic_32)
+
 # TODO: document why this is needed.
 ART_GTEST_proxy_test_HOST_DEPS := $(HOST_CORE_IMAGE_default_no-pic_64) $(HOST_CORE_IMAGE_default_no-pic_32)
 
@@ -141,6 +159,7 @@
   runtime/mirror/object_test.cc \
   runtime/monitor_pool_test.cc \
   runtime/monitor_test.cc \
+  runtime/oat_file_assistant_test.cc \
   runtime/parsed_options_test.cc \
   runtime/reference_table_test.cc \
   runtime/thread_pool_test.cc \
@@ -462,12 +481,12 @@
 endef  # define-art-gtest
 
 ifeq ($(ART_BUILD_TARGET),true)
-  $(foreach file,$(RUNTIME_GTEST_TARGET_SRC_FILES), $(eval $(call define-art-gtest,target,$(file),,)))
-  $(foreach file,$(COMPILER_GTEST_TARGET_SRC_FILES), $(eval $(call define-art-gtest,target,$(file),art/compiler,libartd-compiler)))
+  $(foreach file,$(RUNTIME_GTEST_TARGET_SRC_FILES), $(eval $(call define-art-gtest,target,$(file),,libbacktrace)))
+  $(foreach file,$(COMPILER_GTEST_TARGET_SRC_FILES), $(eval $(call define-art-gtest,target,$(file),art/compiler,libartd-compiler libbacktrace)))
 endif
 ifeq ($(ART_BUILD_HOST),true)
-  $(foreach file,$(RUNTIME_GTEST_HOST_SRC_FILES), $(eval $(call define-art-gtest,host,$(file),,)))
-  $(foreach file,$(COMPILER_GTEST_HOST_SRC_FILES), $(eval $(call define-art-gtest,host,$(file),art/compiler,libartd-compiler)))
+  $(foreach file,$(RUNTIME_GTEST_HOST_SRC_FILES), $(eval $(call define-art-gtest,host,$(file),,libbacktrace)))
+  $(foreach file,$(COMPILER_GTEST_HOST_SRC_FILES), $(eval $(call define-art-gtest,host,$(file),art/compiler,libartd-compiler libbacktrace)))
 endif
 
 # Used outside the art project to get a list of the current tests
@@ -559,6 +578,9 @@
 ART_GTEST_elf_writer_test_TARGET_DEPS :=
 ART_GTEST_jni_compiler_test_DEX_DEPS :=
 ART_GTEST_jni_internal_test_DEX_DEPS :=
+ART_GTEST_oat_file_assistant_test_DEX_DEPS :=
+ART_GTEST_oat_file_assistant_test_HOST_DEPS :=
+ART_GTEST_oat_file_assistant_test_TARGET_DEPS :=
 ART_GTEST_object_test_DEX_DEPS :=
 ART_GTEST_proxy_test_DEX_DEPS :=
 ART_GTEST_reflection_test_DEX_DEPS :=
@@ -567,5 +589,7 @@
 ART_VALGRIND_DEPENDENCIES :=
 $(foreach dir,$(GTEST_DEX_DIRECTORIES), $(eval ART_TEST_TARGET_GTEST_$(dir)_DEX :=))
 $(foreach dir,$(GTEST_DEX_DIRECTORIES), $(eval ART_TEST_HOST_GTEST_$(dir)_DEX :=))
+ART_TEST_HOST_GTEST_MainStripped_DEX :=
+ART_TEST_TARGET_GTEST_MainStripped_DEX :=
 GTEST_DEX_DIRECTORIES :=
 LOCAL_PATH :=
diff --git a/cmdline/cmdline_parser_test.cc b/cmdline/cmdline_parser_test.cc
index 130eed2..9f873b3 100644
--- a/cmdline/cmdline_parser_test.cc
+++ b/cmdline/cmdline_parser_test.cc
@@ -260,6 +260,13 @@
   }
 
   EXPECT_SINGLE_PARSE_FAIL("-verbose:blablabla", CmdlineResult::kUsage);  // invalid verbose opt
+
+  {
+    const char* log_args = "-verbose:oat";
+    LogVerbosity log_verbosity = LogVerbosity();
+    log_verbosity.oat = true;
+    EXPECT_SINGLE_PARSE_VALUE(log_verbosity, log_args, M::Verbose);
+  }
 }  // TEST_F
 
 // TODO: Enable this b/19274810
diff --git a/cmdline/cmdline_types.h b/cmdline/cmdline_types.h
index de99278..03165ed 100644
--- a/cmdline/cmdline_types.h
+++ b/cmdline/cmdline_types.h
@@ -591,6 +591,8 @@
         log_verbosity.jni = true;
       } else if (verbose_options[j] == "monitor") {
         log_verbosity.monitor = true;
+      } else if (verbose_options[j] == "oat") {
+        log_verbosity.oat = true;
       } else if (verbose_options[j] == "profiler") {
         log_verbosity.profiler = true;
       } else if (verbose_options[j] == "signals") {
diff --git a/runtime/Android.mk b/runtime/Android.mk
index c5cf890..6490434 100644
--- a/runtime/Android.mk
+++ b/runtime/Android.mk
@@ -135,6 +135,7 @@
   native/sun_misc_Unsafe.cc \
   oat.cc \
   oat_file.cc \
+  oat_file_assistant.cc \
   object_lock.cc \
   offsets.cc \
   os_linux.cc \
diff --git a/runtime/base/logging.h b/runtime/base/logging.h
index 3d007ba..014f4ab 100644
--- a/runtime/base/logging.h
+++ b/runtime/base/logging.h
@@ -45,6 +45,7 @@
   bool jit;
   bool jni;
   bool monitor;
+  bool oat;
   bool profiler;
   bool signals;
   bool startup;
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index f0c8819..785adf5 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -48,6 +48,7 @@
 #include "leb128.h"
 #include "oat.h"
 #include "oat_file.h"
+#include "oat_file_assistant.h"
 #include "object_lock.h"
 #include "mirror/art_field-inl.h"
 #include "mirror/art_method-inl.h"
@@ -662,77 +663,6 @@
   }
 }
 
-bool ClassLinker::GenerateOatFile(const char* dex_filename,
-                                  int oat_fd,
-                                  const char* oat_cache_filename,
-                                  std::string* error_msg) {
-  Locks::mutator_lock_->AssertNotHeld(Thread::Current());  // Avoid starving GC.
-  std::string dex2oat(Runtime::Current()->GetCompilerExecutable());
-
-  gc::Heap* heap = Runtime::Current()->GetHeap();
-  std::string boot_image_option("--boot-image=");
-  if (heap->GetImageSpace() == nullptr) {
-    // TODO If we get a dex2dex compiler working we could maybe use that, OTOH since we are likely
-    // out of space anyway it might not matter.
-    *error_msg = StringPrintf("Cannot create oat file for '%s' because we are running "
-                              "without an image.", dex_filename);
-    return false;
-  }
-  boot_image_option += heap->GetImageSpace()->GetImageLocation();
-
-  std::string dex_file_option("--dex-file=");
-  dex_file_option += dex_filename;
-
-  std::string oat_fd_option("--oat-fd=");
-  StringAppendF(&oat_fd_option, "%d", oat_fd);
-
-  std::string oat_location_option("--oat-location=");
-  oat_location_option += oat_cache_filename;
-
-  std::vector<std::string> argv;
-  argv.push_back(dex2oat);
-  argv.push_back("--runtime-arg");
-  argv.push_back("-classpath");
-  argv.push_back("--runtime-arg");
-  argv.push_back(Runtime::Current()->GetClassPathString());
-
-  Runtime::Current()->AddCurrentRuntimeFeaturesAsDex2OatArguments(&argv);
-
-  if (!Runtime::Current()->IsVerificationEnabled()) {
-    argv.push_back("--compiler-filter=verify-none");
-  }
-
-  if (Runtime::Current()->MustRelocateIfPossible()) {
-    argv.push_back("--runtime-arg");
-    argv.push_back("-Xrelocate");
-  } else {
-    argv.push_back("--runtime-arg");
-    argv.push_back("-Xnorelocate");
-  }
-
-  if (!kIsTargetBuild) {
-    argv.push_back("--host");
-  }
-
-  argv.push_back(boot_image_option);
-  argv.push_back(dex_file_option);
-  argv.push_back(oat_fd_option);
-  argv.push_back(oat_location_option);
-  const std::vector<std::string>& compiler_options = Runtime::Current()->GetCompilerOptions();
-  for (size_t i = 0; i < compiler_options.size(); ++i) {
-    argv.push_back(compiler_options[i].c_str());
-  }
-
-  if (!Exec(argv, error_msg)) {
-    // Manually delete the file. Ensures there is no garbage left over if the process unexpectedly
-    // died. Ignore unlink failure, propagate the original error.
-    TEMP_FAILURE_RETRY(unlink(oat_cache_filename));
-    return false;
-  }
-
-  return true;
-}
-
 const OatFile* ClassLinker::RegisterOatFile(const OatFile* oat_file) {
   WriterMutexLock mu(Thread::Current(), dex_lock_);
   if (kIsDebugBuild) {
@@ -782,504 +712,81 @@
   return nullptr;
 }
 
+std::vector<std::unique_ptr<const DexFile>> ClassLinker::OpenDexFilesFromOat(
+    const char* dex_location, const char* oat_location,
+    std::vector<std::string>* error_msgs) {
+  CHECK(error_msgs != nullptr);
 
-// Loads all multi dex files from the given oat file returning true on success.
-//
-// Parameters:
-//   oat_file - the oat file to load from
-//   dex_location - the dex location used to generate the oat file
-//   dex_location_checksum - the checksum of the dex_location (may be null for pre-opted files)
-//   generated - whether or not the oat_file existed before or was just (re)generated
-//   error_msgs - any error messages will be appended here
-//   dex_files - the loaded dex_files will be appended here (only if the loading succeeds)
-static bool LoadMultiDexFilesFromOatFile(const OatFile* oat_file,
-                                         const char* dex_location,
-                                         const uint32_t* dex_location_checksum,
-                                         bool generated,
-                                         std::vector<std::string>* error_msgs,
-                                         std::vector<std::unique_ptr<const DexFile>>* dex_files) {
-  if (oat_file == nullptr) {
-    return false;
+  // Verify we aren't holding the mutator lock, which could starve GC if we
+  // have to generate or relocate an oat file.
+  Locks::mutator_lock_->AssertNotHeld(Thread::Current());
+
+  OatFileAssistant oat_file_assistant(dex_location, oat_location, kRuntimeISA,
+     !Runtime::Current()->IsAotCompiler());
+
+  // Lock the target oat location to avoid races generating and loading the
+  // oat file.
+  std::string error_msg;
+  if (!oat_file_assistant.Lock(&error_msg)) {
+    // Don't worry too much if this fails. If it does fail, it's unlikely we
+    // can generate an oat file anyway.
+    VLOG(class_linker) << "OatFileAssistant::Lock: " << error_msg;
   }
 
-  size_t old_size = dex_files->size();  // To rollback on error.
-
-  bool success = true;
-  for (size_t i = 0; success; ++i) {
-    std::string next_name_str = DexFile::GetMultiDexClassesDexName(i, dex_location);
-    const char* next_name = next_name_str.c_str();
-
-    uint32_t next_location_checksum;
-    uint32_t* next_location_checksum_pointer = &next_location_checksum;
-    std::string error_msg;
-    if ((i == 0) && (strcmp(next_name, dex_location) == 0)) {
-      // When i=0 the multidex name should be the same as the location name. We already have the
-      // checksum it so we don't need to recompute it.
-      if (dex_location_checksum == nullptr) {
-        next_location_checksum_pointer = nullptr;
-      } else {
-        next_location_checksum = *dex_location_checksum;
-      }
-    } else if (!DexFile::GetChecksum(next_name, next_location_checksum_pointer, &error_msg)) {
-      DCHECK_EQ(false, i == 0 && generated);
-      next_location_checksum_pointer = nullptr;
-    }
-
-    const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(next_name, nullptr, false);
-
-    if (oat_dex_file == nullptr) {
-      if (i == 0 && generated) {
-        error_msg = StringPrintf("\nFailed to find dex file '%s' (checksum 0x%x) in generated out "
-                                 " file'%s'", dex_location, next_location_checksum,
-                                 oat_file->GetLocation().c_str());
-        error_msgs->push_back(error_msg);
-      }
-      break;  // Not found, done.
-    }
-
-    // Checksum test. Test must succeed when generated.
-    success = !generated;
-    if (next_location_checksum_pointer != nullptr) {
-      success = next_location_checksum == oat_dex_file->GetDexFileLocationChecksum();
-    }
-
-    if (success) {
-      std::unique_ptr<const DexFile> dex_file = oat_dex_file->OpenDexFile(&error_msg);
-      if (dex_file.get() == nullptr) {
-        success = false;
-        error_msgs->push_back(error_msg);
-      } else {
-        dex_files->push_back(std::move(dex_file));
+  // Check if we already have an up-to-date oat file open.
+  const OatFile* source_oat_file = nullptr;
+  {
+    ReaderMutexLock mu(Thread::Current(), dex_lock_);
+    for (const OatFile* oat_file : oat_files_) {
+      CHECK(oat_file != nullptr);
+      if (oat_file_assistant.GivenOatFileIsUpToDate(*oat_file)) {
+        source_oat_file = oat_file;
+        break;
       }
     }
-
-    // When we generated the file, we expect success, or something is terribly wrong.
-    CHECK_EQ(false, generated && !success)
-        << "dex_location=" << next_name << " oat_location=" << oat_file->GetLocation().c_str()
-        << std::hex << " dex_location_checksum=" << next_location_checksum
-        << " OatDexFile::GetLocationChecksum()=" << oat_dex_file->GetDexFileLocationChecksum();
   }
 
-  if (dex_files->size() == old_size) {
-    success = false;  // We did not even find classes.dex
-  }
-
-  if (success) {
-    return true;
-  } else {
-    dex_files->erase(dex_files->begin() + old_size, dex_files->end());
-    return false;
-  }
-}
-
-// Multidex files make it possible that some, but not all, dex files can be broken/outdated. This
-// complicates the loading process, as we should not use an iterative loading process, because that
-// would register the oat file and dex files that come before the broken one. Instead, check all
-// multidex ahead of time.
-bool ClassLinker::OpenDexFilesFromOat(const char* dex_location, const char* oat_location,
-                                      std::vector<std::string>* error_msgs,
-                                      std::vector<std::unique_ptr<const DexFile>>* dex_files) {
-  // 1) Check whether we have an open oat file.
-  // This requires a dex checksum, use the "primary" one.
-  uint32_t dex_location_checksum;
-  uint32_t* dex_location_checksum_pointer = &dex_location_checksum;
-  bool have_checksum = true;
-  std::string checksum_error_msg;
-  if (!DexFile::GetChecksum(dex_location, dex_location_checksum_pointer, &checksum_error_msg)) {
-    // This happens for pre-opted files since the corresponding dex files are no longer on disk.
-    dex_location_checksum_pointer = nullptr;
-    have_checksum = false;
-  }
-
-  bool needs_registering = false;
-
-  const OatFile::OatDexFile* oat_dex_file = FindOpenedOatDexFile(oat_location, dex_location,
-                                                                 dex_location_checksum_pointer);
-  std::unique_ptr<const OatFile> open_oat_file(
-      oat_dex_file != nullptr ? oat_dex_file->GetOatFile() : nullptr);
-
-  // 2) If we do not have an open one, maybe there's one on disk already.
-
-  // In case the oat file is not open, we play a locking game here so
-  // that if two different processes race to load and register or generate
-  // (or worse, one tries to open a partial generated file) we will be okay.
-  // This is actually common with apps that use DexClassLoader to work
-  // around the dex method reference limit and that have a background
-  // service running in a separate process.
-  ScopedFlock scoped_flock;
-
-  if (open_oat_file.get() == nullptr) {
-    if (oat_location != nullptr) {
-      // Can only do this if we have a checksum, else error.
-      if (!have_checksum) {
-        error_msgs->push_back(checksum_error_msg);
-        return false;
-      }
-
-      std::string error_msg;
-
-      // We are loading or creating one in the future. Time to set up the file lock.
-      if (!scoped_flock.Init(oat_location, &error_msg)) {
-        error_msgs->push_back(error_msg);
-        return false;
-      }
-
-      // TODO Caller specifically asks for this oat_location. We should honor it. Probably?
-      open_oat_file.reset(FindOatFileInOatLocationForDexFile(dex_location, dex_location_checksum,
-                                                             oat_location, &error_msg));
-
-      if (open_oat_file.get() == nullptr) {
-        std::string compound_msg = StringPrintf("Failed to find dex file '%s' in oat location '%s': %s",
-                                                dex_location, oat_location, error_msg.c_str());
-        VLOG(class_linker) << compound_msg;
-        error_msgs->push_back(compound_msg);
-      }
-    } else {
-      // TODO: What to lock here?
-      bool obsolete_file_cleanup_failed;
-      open_oat_file.reset(FindOatFileContainingDexFileFromDexLocation(dex_location,
-                                                                      dex_location_checksum_pointer,
-                                                                      kRuntimeISA, error_msgs,
-                                                                      &obsolete_file_cleanup_failed));
-      // There's no point in going forward and eventually try to regenerate the
-      // file if we couldn't remove the obsolete one. Mostly likely we will fail
-      // with the same error when trying to write the new file.
-      // TODO: should we maybe do this only when we get permission issues? (i.e. EACCESS).
-      if (obsolete_file_cleanup_failed) {
-        return false;
-      }
+  // If we didn't have an up-to-date oat file open, try to load one from disk.
+  if (source_oat_file == nullptr) {
+    // Update the oat file on disk if we can. This may fail, but that's okay.
+    // Best effort is all that matters here.
+    if (!oat_file_assistant.MakeUpToDate(&error_msg)) {
+      LOG(WARNING) << error_msg;
     }
-    needs_registering = true;
-  }
 
-  // 3) If we have an oat file, check all contained multidex files for our dex_location.
-  // Note: LoadMultiDexFilesFromOatFile will check for nullptr in the first argument.
-  bool success = LoadMultiDexFilesFromOatFile(open_oat_file.get(), dex_location,
-                                              dex_location_checksum_pointer,
-                                              false, error_msgs, dex_files);
-  if (success) {
-    const OatFile* oat_file = open_oat_file.release();  // Avoid deleting it.
-    if (needs_registering) {
-      // We opened the oat file, so we must register it.
-      RegisterOatFile(oat_file);
-    }
-    // If the file isn't executable we failed patchoat but did manage to get the dex files.
-    return oat_file->IsExecutable();
-  } else {
-    if (needs_registering) {
-      // We opened it, delete it.
-      open_oat_file.reset();
-    } else {
-      open_oat_file.release();  // Do not delete open oat files.
+    // Get the oat file on disk.
+    std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
+    if (oat_file.get() != nullptr) {
+      source_oat_file = oat_file.release();
+      RegisterOatFile(source_oat_file);
     }
   }
 
-  // 4) If it's not the case (either no oat file or mismatches), regenerate and load.
+  std::vector<std::unique_ptr<const DexFile>> dex_files;
 
-  // Need a checksum, fail else.
-  if (!have_checksum) {
-    error_msgs->push_back(checksum_error_msg);
-    return false;
-  }
-
-  // Look in cache location if no oat_location is given.
-  std::string cache_location;
-  if (oat_location == nullptr) {
-    // Use the dalvik cache.
-    const std::string dalvik_cache(GetDalvikCacheOrDie(GetInstructionSetString(kRuntimeISA)));
-    cache_location = GetDalvikCacheFilenameOrDie(dex_location, dalvik_cache.c_str());
-    oat_location = cache_location.c_str();
-  }
-
-  bool has_flock = true;
-  // Definitely need to lock now.
-  if (!scoped_flock.HasFile()) {
-    std::string error_msg;
-    if (!scoped_flock.Init(oat_location, &error_msg)) {
-      error_msgs->push_back(error_msg);
-      has_flock = false;
+  // Load the dex files from the oat file.
+  if (source_oat_file != nullptr) {
+    dex_files = oat_file_assistant.LoadDexFiles(*source_oat_file, dex_location);
+    if (dex_files.empty()) {
+      error_msgs->push_back("Failed to open dex files from "
+          + source_oat_file->GetLocation());
     }
   }
 
-  if (Runtime::Current()->IsDex2OatEnabled() && has_flock && scoped_flock.HasFile()) {
-    // Create the oat file.
-    open_oat_file.reset(CreateOatFileForDexLocation(dex_location, scoped_flock.GetFile()->Fd(),
-                                                    oat_location, error_msgs));
-  }
-
-  // Failed, bail.
-  if (open_oat_file.get() == nullptr) {
-    // dex2oat was disabled or crashed. Add the dex file in the list of dex_files to make progress.
+  // Fall back to running out of the original dex file if we couldn't load any
+  // dex_files from the oat file.
+  if (dex_files.empty()) {
     if (Runtime::Current()->IsDexFileFallbackEnabled()) {
-      std::string error_msg;
-      if (!DexFile::Open(dex_location, dex_location, &error_msg, dex_files)) {
-        error_msgs->push_back(error_msg);
+      if (!DexFile::Open(dex_location, dex_location, &error_msg, &dex_files)) {
+        LOG(WARNING) << error_msg;
+        error_msgs->push_back("Failed to open dex files from "
+            + std::string(dex_location));
       }
     } else {
       error_msgs->push_back("Fallback mode disabled, skipping dex files.");
     }
-    return false;
   }
-
-  // Try to load again, but stronger checks.
-  success = LoadMultiDexFilesFromOatFile(open_oat_file.get(), dex_location,
-                                         dex_location_checksum_pointer,
-                                         true, error_msgs, dex_files);
-  if (success) {
-    RegisterOatFile(open_oat_file.release());
-    return true;
-  } else {
-    return false;
-  }
-}
-
-const OatFile* ClassLinker::FindOatFileInOatLocationForDexFile(const char* dex_location,
-                                                               uint32_t dex_location_checksum,
-                                                               const char* oat_location,
-                                                               std::string* error_msg) {
-  std::unique_ptr<OatFile> oat_file(OatFile::Open(oat_location, oat_location, nullptr, nullptr,
-                                                  !Runtime::Current()->IsAotCompiler(), error_msg));
-  if (oat_file.get() == nullptr) {
-    *error_msg = StringPrintf("Failed to find existing oat file at %s: %s", oat_location,
-                              error_msg->c_str());
-    return nullptr;
-  }
-  Runtime* runtime = Runtime::Current();
-  const gc::space::ImageSpace* image_space = runtime->GetHeap()->GetImageSpace();
-  if (image_space != nullptr) {
-    const ImageHeader& image_header = image_space->GetImageHeader();
-    uint32_t expected_image_oat_checksum = image_header.GetOatChecksum();
-    uint32_t actual_image_oat_checksum = oat_file->GetOatHeader().GetImageFileLocationOatChecksum();
-    if (expected_image_oat_checksum != actual_image_oat_checksum) {
-      *error_msg = StringPrintf("Failed to find oat file at '%s' with expected image oat checksum of "
-                                "0x%x, found 0x%x", oat_location, expected_image_oat_checksum,
-                                actual_image_oat_checksum);
-      return nullptr;
-    }
-
-    uintptr_t expected_image_oat_offset = reinterpret_cast<uintptr_t>(image_header.GetOatDataBegin());
-    uint32_t actual_image_oat_offset = oat_file->GetOatHeader().GetImageFileLocationOatDataBegin();
-    if (expected_image_oat_offset != actual_image_oat_offset) {
-      *error_msg = StringPrintf("Failed to find oat file at '%s' with expected image oat offset %"
-                                PRIuPTR ", found %ud", oat_location, expected_image_oat_offset,
-                                actual_image_oat_offset);
-      return nullptr;
-    }
-    int32_t expected_patch_delta = image_header.GetPatchDelta();
-    int32_t actual_patch_delta = oat_file->GetOatHeader().GetImagePatchDelta();
-    if (expected_patch_delta != actual_patch_delta) {
-      *error_msg = StringPrintf("Failed to find oat file at '%s' with expected patch delta %d, "
-                                " found %d", oat_location, expected_patch_delta, actual_patch_delta);
-      return nullptr;
-    }
-  }
-
-  const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_location,
-                                                                    &dex_location_checksum);
-  if (oat_dex_file == nullptr) {
-    *error_msg = StringPrintf("Failed to find oat file at '%s' containing '%s'", oat_location,
-                              dex_location);
-    return nullptr;
-  }
-  uint32_t expected_dex_checksum = dex_location_checksum;
-  uint32_t actual_dex_checksum = oat_dex_file->GetDexFileLocationChecksum();
-  if (expected_dex_checksum != actual_dex_checksum) {
-    *error_msg = StringPrintf("Failed to find oat file at '%s' with expected dex checksum of 0x%x, "
-                              "found 0x%x", oat_location, expected_dex_checksum,
-                              actual_dex_checksum);
-    return nullptr;
-  }
-  std::unique_ptr<const DexFile> dex_file(oat_dex_file->OpenDexFile(error_msg));
-  if (dex_file.get() != nullptr) {
-    return oat_file.release();
-  } else {
-    return nullptr;
-  }
-}
-
-const OatFile* ClassLinker::CreateOatFileForDexLocation(const char* dex_location,
-                                                        int fd, const char* oat_location,
-                                                        std::vector<std::string>* error_msgs) {
-  // Generate the output oat file for the dex file
-  VLOG(class_linker) << "Generating oat file " << oat_location << " for " << dex_location;
-  std::string error_msg;
-  if (!GenerateOatFile(dex_location, fd, oat_location, &error_msg)) {
-    CHECK(!error_msg.empty());
-    error_msgs->push_back(error_msg);
-    return nullptr;
-  }
-  std::unique_ptr<OatFile> oat_file(OatFile::Open(oat_location, oat_location, nullptr, nullptr,
-                                                  !Runtime::Current()->IsAotCompiler(),
-                                                  &error_msg));
-  if (oat_file.get() == nullptr) {
-    std::string compound_msg = StringPrintf("\nFailed to open generated oat file '%s': %s",
-                                            oat_location, error_msg.c_str());
-    error_msgs->push_back(compound_msg);
-    return nullptr;
-  }
-
-  return oat_file.release();
-}
-
-bool ClassLinker::VerifyOatImageChecksum(const OatFile* oat_file,
-                                         const InstructionSet instruction_set) {
-  Runtime* runtime = Runtime::Current();
-  const gc::space::ImageSpace* image_space = runtime->GetHeap()->GetImageSpace();
-  if (image_space == nullptr) {
-    return false;
-  }
-  uint32_t image_oat_checksum = 0;
-  if (instruction_set == kRuntimeISA) {
-    const ImageHeader& image_header = image_space->GetImageHeader();
-    image_oat_checksum = image_header.GetOatChecksum();
-  } else {
-    std::unique_ptr<ImageHeader> image_header(gc::space::ImageSpace::ReadImageHeaderOrDie(
-        image_space->GetImageLocation().c_str(), instruction_set));
-    image_oat_checksum = image_header->GetOatChecksum();
-  }
-  return oat_file->GetOatHeader().GetImageFileLocationOatChecksum() == image_oat_checksum;
-}
-
-bool ClassLinker::VerifyOatChecksums(const OatFile* oat_file,
-                                     const InstructionSet instruction_set,
-                                     std::string* error_msg) {
-  Runtime* runtime = Runtime::Current();
-  const gc::space::ImageSpace* image_space = runtime->GetHeap()->GetImageSpace();
-  if (image_space == nullptr) {
-    *error_msg = "No image space for verification against";
-    return false;
-  }
-
-  // If the requested instruction set is the same as the current runtime,
-  // we can use the checksums directly. If it isn't, we'll have to read the
-  // image header from the image for the right instruction set.
-  uint32_t image_oat_checksum = 0;
-  uintptr_t image_oat_data_begin = 0;
-  int32_t image_patch_delta = 0;
-  if (instruction_set == runtime->GetInstructionSet()) {
-    const ImageHeader& image_header = image_space->GetImageHeader();
-    image_oat_checksum = image_header.GetOatChecksum();
-    image_oat_data_begin = reinterpret_cast<uintptr_t>(image_header.GetOatDataBegin());
-    image_patch_delta = image_header.GetPatchDelta();
-  } else {
-    std::unique_ptr<ImageHeader> image_header(gc::space::ImageSpace::ReadImageHeaderOrDie(
-        image_space->GetImageLocation().c_str(), instruction_set));
-    image_oat_checksum = image_header->GetOatChecksum();
-    image_oat_data_begin = reinterpret_cast<uintptr_t>(image_header->GetOatDataBegin());
-    image_patch_delta = image_header->GetPatchDelta();
-  }
-  const OatHeader& oat_header = oat_file->GetOatHeader();
-  bool ret = (oat_header.GetImageFileLocationOatChecksum() == image_oat_checksum);
-
-  // If the oat file is PIC, it doesn't care if/how image was relocated. Ignore these checks.
-  if (!oat_file->IsPic()) {
-    ret = ret && (oat_header.GetImagePatchDelta() == image_patch_delta)
-              && (oat_header.GetImageFileLocationOatDataBegin() == image_oat_data_begin);
-  }
-  if (!ret) {
-    *error_msg = StringPrintf("oat file '%s' mismatch (0x%x, %d, %d) with (0x%x, %" PRIdPTR ", %d)",
-                              oat_file->GetLocation().c_str(),
-                              oat_file->GetOatHeader().GetImageFileLocationOatChecksum(),
-                              oat_file->GetOatHeader().GetImageFileLocationOatDataBegin(),
-                              oat_file->GetOatHeader().GetImagePatchDelta(),
-                              image_oat_checksum, image_oat_data_begin, image_patch_delta);
-  }
-  return ret;
-}
-
-bool ClassLinker::VerifyOatAndDexFileChecksums(const OatFile* oat_file,
-                                               const char* dex_location,
-                                               uint32_t dex_location_checksum,
-                                               const InstructionSet instruction_set,
-                                               std::string* error_msg) {
-  if (!VerifyOatChecksums(oat_file, instruction_set, error_msg)) {
-    return false;
-  }
-
-  const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_location,
-                                                                    &dex_location_checksum);
-  if (oat_dex_file == nullptr) {
-    *error_msg = StringPrintf("oat file '%s' does not contain contents for '%s' with checksum 0x%x",
-                              oat_file->GetLocation().c_str(), dex_location, dex_location_checksum);
-    for (const OatFile::OatDexFile* oat_dex_file_in : oat_file->GetOatDexFiles()) {
-      *error_msg  += StringPrintf("\noat file '%s' contains contents for '%s' with checksum 0x%x",
-                                  oat_file->GetLocation().c_str(),
-                                  oat_dex_file_in->GetDexFileLocation().c_str(),
-                                  oat_dex_file_in->GetDexFileLocationChecksum());
-    }
-    return false;
-  }
-
-  DCHECK_EQ(dex_location_checksum, oat_dex_file->GetDexFileLocationChecksum());
-  return true;
-}
-
-bool ClassLinker::VerifyOatWithDexFile(const OatFile* oat_file,
-                                       const char* dex_location,
-                                       const uint32_t* dex_location_checksum,
-                                       std::string* error_msg) {
-  CHECK(oat_file != nullptr);
-  CHECK(dex_location != nullptr);
-  std::unique_ptr<const DexFile> dex_file;
-  if (dex_location_checksum == nullptr) {
-    // If no classes.dex found in dex_location, it has been stripped or is corrupt, assume oat is
-    // up-to-date. This is the common case in user builds for jar's and apk's in the /system
-    // directory.
-    const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_location, nullptr);
-    if (oat_dex_file == nullptr) {
-      *error_msg = StringPrintf("Dex checksum mismatch for location '%s' and failed to find oat "
-                                "dex file '%s': %s", oat_file->GetLocation().c_str(), dex_location,
-                                error_msg->c_str());
-      return false;
-    }
-    dex_file = oat_dex_file->OpenDexFile(error_msg);
-  } else {
-    bool verified = VerifyOatAndDexFileChecksums(oat_file, dex_location, *dex_location_checksum,
-                                                 kRuntimeISA, error_msg);
-    if (!verified) {
-      return false;
-    }
-    dex_file = oat_file->GetOatDexFile(dex_location,
-                                       dex_location_checksum)->OpenDexFile(error_msg);
-  }
-  return dex_file.get() != nullptr;
-}
-
-const OatFile* ClassLinker::FindOatFileContainingDexFileFromDexLocation(
-    const char* dex_location,
-    const uint32_t* dex_location_checksum,
-    InstructionSet isa,
-    std::vector<std::string>* error_msgs,
-    bool* obsolete_file_cleanup_failed) {
-  *obsolete_file_cleanup_failed = false;
-  bool already_opened = false;
-  std::string dex_location_str(dex_location);
-  std::unique_ptr<const OatFile> oat_file(OpenOatFileFromDexLocation(dex_location_str, isa,
-                                                                     &already_opened,
-                                                                     obsolete_file_cleanup_failed,
-                                                                     error_msgs));
-  std::string error_msg;
-  if (oat_file.get() == nullptr) {
-    error_msgs->push_back(StringPrintf("Failed to open oat file from dex location '%s'",
-                                       dex_location));
-    return nullptr;
-  } else if (oat_file->IsExecutable() &&
-             !VerifyOatWithDexFile(oat_file.get(), dex_location,
-                                   dex_location_checksum, &error_msg)) {
-    error_msgs->push_back(StringPrintf("Failed to verify oat file '%s' found for dex location "
-                                       "'%s': %s", oat_file->GetLocation().c_str(), dex_location,
-                                       error_msg.c_str()));
-    return nullptr;
-  } else if (!oat_file->IsExecutable() &&
-             Runtime::Current()->GetHeap()->HasImageSpace() &&
-             !VerifyOatImageChecksum(oat_file.get(), isa)) {
-    error_msgs->push_back(StringPrintf("Failed to verify non-executable oat file '%s' found for "
-                                       "dex location '%s'. Image checksum incorrect.",
-                                       oat_file->GetLocation().c_str(), dex_location));
-    return nullptr;
-  } else {
-    return oat_file.release();
-  }
+  return dex_files;
 }
 
 const OatFile* ClassLinker::FindOpenedOatFileFromOatLocation(const std::string& oat_location) {
@@ -1294,335 +801,6 @@
   return nullptr;
 }
 
-const OatFile* ClassLinker::OpenOatFileFromDexLocation(const std::string& dex_location,
-                                                       InstructionSet isa,
-                                                       bool *already_opened,
-                                                       bool *obsolete_file_cleanup_failed,
-                                                       std::vector<std::string>* error_msgs) {
-  // Find out if we've already opened the file
-  const OatFile* ret = nullptr;
-  std::string odex_filename(DexFilenameToOdexFilename(dex_location, isa));
-  ret = FindOpenedOatFileFromOatLocation(odex_filename);
-  if (ret != nullptr) {
-    *already_opened = true;
-    return ret;
-  }
-
-  std::string dalvik_cache;
-  bool have_android_data = false;
-  bool have_dalvik_cache = false;
-  bool is_global_cache = false;
-  GetDalvikCache(GetInstructionSetString(kRuntimeISA), false, &dalvik_cache,
-                 &have_android_data, &have_dalvik_cache, &is_global_cache);
-  std::string cache_filename;
-  if (have_dalvik_cache) {
-    cache_filename = GetDalvikCacheFilenameOrDie(dex_location.c_str(), dalvik_cache.c_str());
-    ret = FindOpenedOatFileFromOatLocation(cache_filename);
-    if (ret != nullptr) {
-      *already_opened = true;
-      return ret;
-    }
-  } else {
-    // If we need to relocate we should just place odex back where it started.
-    cache_filename = odex_filename;
-  }
-
-  ret = nullptr;
-
-  // We know that neither the odex nor the cache'd version is already in use, if it even exists.
-  //
-  // Now we do the following:
-  // 1) Try and open the odex version
-  // 2) If present, checksum-verified & relocated correctly return it
-  // 3) Close the odex version to free up its address space.
-  // 4) Try and open the cache version
-  // 5) If present, checksum-verified & relocated correctly return it
-  // 6) Close the cache version to free up its address space.
-  // 7) If we should relocate:
-  //   a) If we have opened and checksum-verified the odex version relocate it to
-  //      'cache_filename' and return it
-  //   b) If we have opened and checksum-verified the cache version relocate it in place and return
-  //      it. This should not happen often (I think only the run-test's will hit this case).
-  // 8) If the cache-version was present we should delete it since it must be obsolete if we get to
-  //    this point.
-  // 9) Return nullptr
-
-  *already_opened = false;
-  const Runtime* runtime = Runtime::Current();
-  CHECK(runtime != nullptr);
-  bool executable = !runtime->IsAotCompiler();
-
-  std::string odex_error_msg;
-  bool should_patch_system = false;
-  bool odex_checksum_verified = false;
-  bool have_system_odex = false;
-  {
-    // There is a high probability that both these oat files map similar/the same address
-    // spaces so we must scope them like this so they each gets its turn.
-    std::unique_ptr<OatFile> odex_oat_file(OatFile::Open(odex_filename, odex_filename, nullptr,
-                                                         nullptr,
-                                                         executable, &odex_error_msg));
-    if (odex_oat_file.get() != nullptr && CheckOatFile(runtime, odex_oat_file.get(), isa,
-                                                       &odex_checksum_verified,
-                                                       &odex_error_msg)) {
-      return odex_oat_file.release();
-    } else {
-      if (odex_checksum_verified) {
-        // We can just relocate
-        should_patch_system = true;
-        odex_error_msg = "Image Patches are incorrect";
-      }
-      if (odex_oat_file.get() != nullptr) {
-        have_system_odex = true;
-      }
-    }
-  }
-
-  std::string cache_error_msg;
-  bool should_patch_cache = false;
-  bool cache_checksum_verified = false;
-  if (have_dalvik_cache) {
-    std::unique_ptr<OatFile> cache_oat_file(OatFile::Open(cache_filename, cache_filename, nullptr,
-                                                          nullptr,
-                                                          executable, &cache_error_msg));
-    if (cache_oat_file.get() != nullptr && CheckOatFile(runtime, cache_oat_file.get(), isa,
-                                                        &cache_checksum_verified,
-                                                        &cache_error_msg)) {
-      return cache_oat_file.release();
-    } else if (cache_checksum_verified) {
-      // We can just relocate
-      should_patch_cache = true;
-      cache_error_msg = "Image Patches are incorrect";
-    }
-  } else if (have_android_data) {
-    // dalvik_cache does not exist but android data does. This means we should be able to create
-    // it, so we should try.
-    GetDalvikCacheOrDie(GetInstructionSetString(kRuntimeISA), true);
-  }
-
-  ret = nullptr;
-  std::string error_msg;
-  if (runtime->CanRelocate()) {
-    // Run relocation
-    gc::space::ImageSpace* space = Runtime::Current()->GetHeap()->GetImageSpace();
-    if (space != nullptr) {
-      const std::string& image_location = space->GetImageLocation();
-      if (odex_checksum_verified && should_patch_system) {
-        ret = PatchAndRetrieveOat(odex_filename, cache_filename, image_location, isa, &error_msg);
-      } else if (cache_checksum_verified && should_patch_cache) {
-        CHECK(have_dalvik_cache);
-        ret = PatchAndRetrieveOat(cache_filename, cache_filename, image_location, isa, &error_msg);
-      }
-    } else if (have_system_odex) {
-      ret = GetInterpretedOnlyOat(odex_filename, isa, &error_msg);
-    }
-  }
-  if (ret == nullptr && have_dalvik_cache && OS::FileExists(cache_filename.c_str())) {
-    // implicitly: were able to fine where the cached version is but we were unable to use it,
-    // either as a destination for relocation or to open a file. We should delete it if it is
-    // there.
-    if (TEMP_FAILURE_RETRY(unlink(cache_filename.c_str())) != 0) {
-      std::string rm_error_msg = StringPrintf("Failed to remove obsolete file from %s when "
-                                              "searching for dex file %s: %s",
-                                              cache_filename.c_str(), dex_location.c_str(),
-                                              strerror(errno));
-      error_msgs->push_back(rm_error_msg);
-      VLOG(class_linker) << rm_error_msg;
-      // Let the caller know that we couldn't remove the obsolete file.
-      // This is a good indication that further writes may fail as well.
-      *obsolete_file_cleanup_failed = true;
-    }
-  }
-  if (ret == nullptr) {
-    VLOG(class_linker) << error_msg;
-    error_msgs->push_back(error_msg);
-    std::string relocation_msg;
-    if (runtime->CanRelocate()) {
-      relocation_msg = StringPrintf(" and relocation failed");
-    }
-    if (have_dalvik_cache && cache_checksum_verified) {
-      error_msg = StringPrintf("Failed to open oat file from %s (error %s) or %s "
-                                "(error %s)%s.", odex_filename.c_str(), odex_error_msg.c_str(),
-                                cache_filename.c_str(), cache_error_msg.c_str(),
-                                relocation_msg.c_str());
-    } else {
-      error_msg = StringPrintf("Failed to open oat file from %s (error %s) (no "
-                               "dalvik_cache availible)%s.", odex_filename.c_str(),
-                               odex_error_msg.c_str(), relocation_msg.c_str());
-    }
-    VLOG(class_linker) << error_msg;
-    error_msgs->push_back(error_msg);
-  }
-  return ret;
-}
-
-const OatFile* ClassLinker::GetInterpretedOnlyOat(const std::string& oat_path,
-                                                  InstructionSet isa,
-                                                  std::string* error_msg) {
-  // We open it non-executable
-  std::unique_ptr<OatFile> output(OatFile::Open(oat_path, oat_path, nullptr, nullptr, false, error_msg));
-  if (output.get() == nullptr) {
-    return nullptr;
-  }
-  if (!Runtime::Current()->GetHeap()->HasImageSpace() ||
-      VerifyOatImageChecksum(output.get(), isa)) {
-    return output.release();
-  } else {
-    *error_msg = StringPrintf("Could not use oat file '%s', image checksum failed to verify.",
-                              oat_path.c_str());
-    return nullptr;
-  }
-}
-
-const OatFile* ClassLinker::PatchAndRetrieveOat(const std::string& input_oat,
-                                                const std::string& output_oat,
-                                                const std::string& image_location,
-                                                InstructionSet isa,
-                                                std::string* error_msg) {
-  Runtime* runtime = Runtime::Current();
-  DCHECK(runtime != nullptr);
-  if (!runtime->GetHeap()->HasImageSpace()) {
-    // We don't have an image space so there is no point in trying to patchoat.
-    LOG(WARNING) << "Patching of oat file '" << input_oat << "' not attempted because we are "
-                 << "running without an image. Attempting to use oat file for interpretation.";
-    return GetInterpretedOnlyOat(input_oat, isa, error_msg);
-  }
-  if (!runtime->IsDex2OatEnabled()) {
-    // We don't have dex2oat so we can assume we don't have patchoat either. We should just use the
-    // input_oat but make sure we only do interpretation on it's dex files.
-    LOG(WARNING) << "Patching of oat file '" << input_oat << "' not attempted due to dex2oat being "
-                 << "disabled. Attempting to use oat file for interpretation";
-    return GetInterpretedOnlyOat(input_oat, isa, error_msg);
-  }
-  Locks::mutator_lock_->AssertNotHeld(Thread::Current());  // Avoid starving GC.
-  std::string patchoat(runtime->GetPatchoatExecutable());
-
-  std::string isa_arg("--instruction-set=");
-  isa_arg += GetInstructionSetString(isa);
-  std::string input_oat_filename_arg("--input-oat-file=");
-  input_oat_filename_arg += input_oat;
-  std::string output_oat_filename_arg("--output-oat-file=");
-  output_oat_filename_arg += output_oat;
-  std::string patched_image_arg("--patched-image-location=");
-  patched_image_arg += image_location;
-
-  std::vector<std::string> argv;
-  argv.push_back(patchoat);
-  argv.push_back(isa_arg);
-  argv.push_back(input_oat_filename_arg);
-  argv.push_back(output_oat_filename_arg);
-  argv.push_back(patched_image_arg);
-
-  std::string command_line(Join(argv, ' '));
-  LOG(INFO) << "Relocate Oat File: " << command_line;
-  bool success = Exec(argv, error_msg);
-  if (success) {
-    std::unique_ptr<OatFile> output(OatFile::Open(output_oat, output_oat, nullptr, nullptr,
-                                                  !runtime->IsAotCompiler(), error_msg));
-    bool checksum_verified = false;
-    if (output.get() != nullptr && CheckOatFile(runtime, output.get(), isa, &checksum_verified,
-                                                error_msg)) {
-      return output.release();
-    } else if (output.get() != nullptr) {
-      *error_msg = StringPrintf("Patching of oat file '%s' succeeded "
-                                "but output file '%s' failed verifcation: %s",
-                                input_oat.c_str(), output_oat.c_str(), error_msg->c_str());
-    } else {
-      *error_msg = StringPrintf("Patching of oat file '%s' succeeded "
-                                "but was unable to open output file '%s': %s",
-                                input_oat.c_str(), output_oat.c_str(), error_msg->c_str());
-    }
-  } else if (!runtime->IsAotCompiler()) {
-    // patchoat failed which means we probably don't have enough room to place the output oat file,
-    // instead of failing we should just run the interpreter from the dex files in the input oat.
-    LOG(WARNING) << "Patching of oat file '" << input_oat << "' failed. Attempting to use oat file "
-                 << "for interpretation. patchoat failure was: " << *error_msg;
-    return GetInterpretedOnlyOat(input_oat, isa, error_msg);
-  } else {
-    *error_msg = StringPrintf("Patching of oat file '%s to '%s' "
-                              "failed: %s", input_oat.c_str(), output_oat.c_str(),
-                              error_msg->c_str());
-  }
-  return nullptr;
-}
-
-bool ClassLinker::CheckOatFile(const Runtime* runtime, const OatFile* oat_file, InstructionSet isa,
-                               bool* checksum_verified,
-                               std::string* error_msg) {
-  const gc::space::ImageSpace* image_space = runtime->GetHeap()->GetImageSpace();
-  if (image_space == nullptr) {
-    *error_msg = "No image space present";
-    return false;
-  }
-  uint32_t real_image_checksum;
-  void* real_image_oat_offset;
-  int32_t real_patch_delta;
-  if (isa == runtime->GetInstructionSet()) {
-    const ImageHeader& image_header = image_space->GetImageHeader();
-    real_image_checksum = image_header.GetOatChecksum();
-    real_image_oat_offset = image_header.GetOatDataBegin();
-    real_patch_delta = image_header.GetPatchDelta();
-  } else {
-    std::unique_ptr<ImageHeader> image_header(gc::space::ImageSpace::ReadImageHeaderOrDie(
-        image_space->GetImageLocation().c_str(), isa));
-    real_image_checksum = image_header->GetOatChecksum();
-    real_image_oat_offset = image_header->GetOatDataBegin();
-    real_patch_delta = image_header->GetPatchDelta();
-  }
-
-  const OatHeader& oat_header = oat_file->GetOatHeader();
-  std::string compound_msg;
-
-  uint32_t oat_image_checksum = oat_header.GetImageFileLocationOatChecksum();
-  *checksum_verified = oat_image_checksum == real_image_checksum;
-  if (!*checksum_verified) {
-    StringAppendF(&compound_msg, " Oat Image Checksum Incorrect (expected 0x%x, received 0x%x)",
-                  real_image_checksum, oat_image_checksum);
-  }
-
-  bool offset_verified;
-  bool patch_delta_verified;
-
-  if (!oat_file->IsPic()) {
-    // If an oat file is not PIC, we need to check that the image is at the expected location and
-    // patched in the same way.
-    void* oat_image_oat_offset =
-        reinterpret_cast<void*>(oat_header.GetImageFileLocationOatDataBegin());
-    offset_verified = oat_image_oat_offset == real_image_oat_offset;
-    if (!offset_verified) {
-      StringAppendF(&compound_msg, " Oat Image oat offset incorrect (expected 0x%p, received 0x%p)",
-                    real_image_oat_offset, oat_image_oat_offset);
-    }
-
-    int32_t oat_patch_delta = oat_header.GetImagePatchDelta();
-    patch_delta_verified = oat_patch_delta == real_patch_delta;
-    if (!patch_delta_verified) {
-      StringAppendF(&compound_msg, " Oat image patch delta incorrect (expected 0x%x, "
-                    "received 0x%x)", real_patch_delta, oat_patch_delta);
-    }
-  } else {
-    // If an oat file is PIC, we ignore offset and patching delta.
-    offset_verified = true;
-    patch_delta_verified = true;
-  }
-
-  bool ret = (*checksum_verified && offset_verified && patch_delta_verified);
-  if (!ret) {
-    *error_msg = "Oat file failed to verify:" + compound_msg;
-  }
-  return ret;
-}
-
-const OatFile* ClassLinker::FindOatFileFromOatLocation(const std::string& oat_location,
-                                                       std::string* error_msg) {
-  const OatFile* oat_file = FindOpenedOatFileFromOatLocation(oat_location);
-  if (oat_file != nullptr) {
-    return oat_file;
-  }
-  return OatFile::Open(oat_location, oat_location, nullptr, nullptr,
-                       !Runtime::Current()->IsAotCompiler(), error_msg);
-}
-
 void ClassLinker::InitFromImageInterpretOnlyCallback(mirror::Object* obj, void* arg) {
   ClassLinker* class_linker = reinterpret_cast<ClassLinker*>(arg);
   DCHECK(obj != nullptr);
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 6570c5f..75fbdf3 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -313,33 +313,25 @@
       LOCKS_EXCLUDED(dex_lock_)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  // Generate an oat file from a dex file
-  bool GenerateOatFile(const char* dex_filename,
-                       int oat_fd,
-                       const char* oat_cache_filename,
-                       std::string* error_msg)
-      LOCKS_EXCLUDED(Locks::mutator_lock_);
-
-  // Find or create the oat file holding dex_location. Then load all corresponding dex files
-  // (if multidex) into the given vector.
-  bool OpenDexFilesFromOat(const char* dex_location, const char* oat_location,
-                           std::vector<std::string>* error_msgs,
-                           std::vector<std::unique_ptr<const DexFile>>* dex_files)
+  // Finds or creates the oat file holding dex_location. Then loads and returns
+  // all corresponding dex files (there may be more than one dex file loaded
+  // in the case of multidex).
+  // This may return the original, unquickened dex files if the oat file could
+  // not be generated.
+  //
+  // Returns an empty vector if the dex files could not be loaded. In this
+  // case, there will be at least one error message returned describing why no
+  // dex files could not be loaded. The 'error_msgs' argument must not be
+  // null, regardless of whether there is an error or not.
+  //
+  // This method should not be called with the mutator_lock_ held, because it
+  // could end up starving GC if we need to generate or relocate any oat
+  // files.
+  std::vector<std::unique_ptr<const DexFile>>  OpenDexFilesFromOat(
+      const char* dex_location, const char* oat_location,
+      std::vector<std::string>* error_msgs)
       LOCKS_EXCLUDED(dex_lock_, Locks::mutator_lock_);
 
-  // Returns true if the given oat file has the same image checksum as the image it is paired with.
-  static bool VerifyOatImageChecksum(const OatFile* oat_file, const InstructionSet instruction_set);
-  // Returns true if the oat file checksums match with the image and the offsets are such that it
-  // could be loaded with it.
-  static bool VerifyOatChecksums(const OatFile* oat_file, const InstructionSet instruction_set,
-                                 std::string* error_msg);
-  // Returns true if oat file contains the dex file with the given location and checksum.
-  static bool VerifyOatAndDexFileChecksums(const OatFile* oat_file,
-                                           const char* dex_location,
-                                           uint32_t dex_location_checksum,
-                                           InstructionSet instruction_set,
-                                           std::string* error_msg);
-
   // Allocate an instance of a java.lang.Object.
   mirror::Object* AllocObject(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
@@ -612,73 +604,9 @@
                                                   const uint32_t* dex_location_checksum)
       LOCKS_EXCLUDED(dex_lock_);
 
-  // Will open the oat file directly without relocating, even if we could/should do relocation.
-  const OatFile* FindOatFileFromOatLocation(const std::string& oat_location,
-                                            std::string* error_msg)
-      LOCKS_EXCLUDED(dex_lock_);
-
   const OatFile* FindOpenedOatFileFromOatLocation(const std::string& oat_location)
       LOCKS_EXCLUDED(dex_lock_);
 
-  const OatFile* OpenOatFileFromDexLocation(const std::string& dex_location,
-                                            InstructionSet isa,
-                                            bool* already_opened,
-                                            bool* obsolete_file_cleanup_failed,
-                                            std::vector<std::string>* error_msg)
-      LOCKS_EXCLUDED(dex_lock_, Locks::mutator_lock_);
-
-  const OatFile* GetInterpretedOnlyOat(const std::string& oat_path,
-                                       InstructionSet isa,
-                                       std::string* error_msg);
-
-  const OatFile* PatchAndRetrieveOat(const std::string& input, const std::string& output,
-                                     const std::string& image_location, InstructionSet isa,
-                                     std::string* error_msg)
-      LOCKS_EXCLUDED(Locks::mutator_lock_);
-
-  bool CheckOatFile(const Runtime* runtime, const OatFile* oat_file, InstructionSet isa,
-                    bool* checksum_verified, std::string* error_msg);
-
-  // Note: will not register the oat file.
-  const OatFile* FindOatFileInOatLocationForDexFile(const char* dex_location,
-                                                    uint32_t dex_location_checksum,
-                                                    const char* oat_location,
-                                                    std::string* error_msg)
-      LOCKS_EXCLUDED(dex_lock_);
-
-  // Creates the oat file from the dex_location to the oat_location. Needs a file descriptor for
-  // the file to be written, which is assumed to be under a lock.
-  const OatFile* CreateOatFileForDexLocation(const char* dex_location,
-                                             int fd, const char* oat_location,
-                                             std::vector<std::string>* error_msgs)
-      LOCKS_EXCLUDED(dex_lock_, Locks::mutator_lock_);
-
-  // Finds an OatFile that contains a DexFile for the given a DexFile location.
-  //
-  // Note 1: this will not check open oat files, which are assumed to be stale when this is run.
-  // Note 2: Does not register the oat file. It is the caller's job to register if the file is to
-  //         be kept.
-  const OatFile* FindOatFileContainingDexFileFromDexLocation(const char* dex_location,
-                                                             const uint32_t* dex_location_checksum,
-                                                             InstructionSet isa,
-                                                             std::vector<std::string>* error_msgs,
-                                                             bool* obsolete_file_cleanup_failed)
-      LOCKS_EXCLUDED(dex_lock_, Locks::mutator_lock_);
-
-  // Verifies:
-  //  - that the oat file contains the dex file (with a matching checksum, which may be null if the
-  // file was pre-opted)
-  //  - the checksums of the oat file (against the image space)
-  //  - the checksum of the dex file against dex_location_checksum
-  //  - that the dex file can be opened
-  // Returns true iff all verification succeed.
-  //
-  // The dex_location is the dex location as stored in the oat file header.
-  // (see DexFile::GetDexCanonicalLocation for a description of location conventions)
-  bool VerifyOatWithDexFile(const OatFile* oat_file, const char* dex_location,
-                            const uint32_t* dex_location_checksum,
-                            std::string* error_msg);
-
   mirror::ArtMethod* CreateProxyConstructor(Thread* self, Handle<mirror::Class> klass,
                                             mirror::Class* proxy_class)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -803,7 +731,6 @@
 
   friend class ImageWriter;  // for GetClassRoots
   friend class ImageDumper;  // for FindOpenedOatFileFromOatLocation
-  friend class ElfPatcher;  // for FindOpenedOatFileForDexFile & FindOpenedOatFileFromOatLocation
   friend class JniCompilerTest;  // for GetRuntimeQuickGenericJniStub
   friend class NoDex2OatTest;  // for FindOpenedOatFileForDexFile
   friend class NoPatchoatTest;  // for FindOpenedOatFileForDexFile
diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc
index b7ffd60..1c8a892 100644
--- a/runtime/common_runtime_test.cc
+++ b/runtime/common_runtime_test.cc
@@ -36,6 +36,7 @@
 #include "gtest/gtest.h"
 #include "jni_internal.h"
 #include "mirror/class_loader.h"
+#include "mem_map.h"
 #include "noop_compiler_callbacks.h"
 #include "os.h"
 #include "runtime-inl.h"
@@ -194,6 +195,7 @@
 std::unique_ptr<const DexFile> CommonRuntimeTest::LoadExpectSingleDexFile(const char* location) {
   std::vector<std::unique_ptr<const DexFile>> dex_files;
   std::string error_msg;
+  MemMap::Init();
   if (!DexFile::Open(location, location, &error_msg, &dex_files)) {
     LOG(FATAL) << "Could not open .dex file '" << location << "': " << error_msg << "\n";
     UNREACHABLE();
@@ -225,10 +227,12 @@
   options.push_back(std::make_pair("compilercallbacks", callbacks_.get()));
   SetUpRuntimeOptions(&options);
 
+  PreRuntimeCreate();
   if (!Runtime::Create(options, false)) {
     LOG(FATAL) << "Failed to create runtime";
     return;
   }
+  PostRuntimeCreate();
   runtime_.reset(Runtime::Current());
   class_linker_ = runtime_->GetClassLinker();
   class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
@@ -335,7 +339,7 @@
 #define ART_TARGET_NATIVETEST_DIR_STRING ""
 #endif
 
-std::vector<std::unique_ptr<const DexFile>> CommonRuntimeTest::OpenTestDexFiles(const char* name) {
+std::string CommonRuntimeTest::GetTestDexFileName(const char* name) {
   CHECK(name != nullptr);
   std::string filename;
   if (IsHost()) {
@@ -347,6 +351,11 @@
   filename += "art-gtest-";
   filename += name;
   filename += ".jar";
+  return filename;
+}
+
+std::vector<std::unique_ptr<const DexFile>> CommonRuntimeTest::OpenTestDexFiles(const char* name) {
+  std::string filename = GetTestDexFileName(name);
   std::string error_msg;
   std::vector<std::unique_ptr<const DexFile>> dex_files;
   bool success = DexFile::Open(filename.c_str(), filename.c_str(), &error_msg, &dex_files);
diff --git a/runtime/common_runtime_test.h b/runtime/common_runtime_test.h
index 9efea84..cce8485 100644
--- a/runtime/common_runtime_test.h
+++ b/runtime/common_runtime_test.h
@@ -101,11 +101,19 @@
 
   virtual void TearDown();
 
+  // Called before the runtime is created.
+  virtual void PreRuntimeCreate() {}
+
+  // Called after the runtime is created.
+  virtual void PostRuntimeCreate() {}
+
   // Gets the path of the specified dex file for host or target.
   static std::string GetDexFileName(const std::string& jar_prefix);
 
   std::string GetTestAndroidRoot();
 
+  std::string GetTestDexFileName(const char* name);
+
   std::vector<std::unique_ptr<const DexFile>> OpenTestDexFiles(const char* name)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc
index e1fe3eb..c182a4d 100644
--- a/runtime/native/dalvik_system_DexFile.cc
+++ b/runtime/native/dalvik_system_DexFile.cc
@@ -16,31 +16,17 @@
 
 #include "dalvik_system_DexFile.h"
 
-#include <algorithm>
-#include <set>
-#include <fcntl.h>
-#ifdef __linux__
-#include <sys/sendfile.h>
-#else
-#include <sys/socket.h>
-#endif
-#include <sys/stat.h>
-#include <unistd.h>
-
 #include "base/logging.h"
 #include "base/stl_util.h"
 #include "base/stringprintf.h"
 #include "class_linker.h"
 #include "common_throws.h"
 #include "dex_file-inl.h"
-#include "gc/space/image_space.h"
-#include "gc/space/space-inl.h"
-#include "image.h"
 #include "jni_internal.h"
 #include "mirror/class_loader.h"
 #include "mirror/object-inl.h"
 #include "mirror/string.h"
-#include "oat.h"
+#include "oat_file_assistant.h"
 #include "os.h"
 #include "profiler.h"
 #include "runtime.h"
@@ -51,11 +37,6 @@
 #include "well_known_classes.h"
 #include "zip_archive.h"
 
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wshadow"
-#include "ScopedFd.h"
-#pragma GCC diagnostic pop
-
 namespace art {
 
 static std::unique_ptr<std::vector<const DexFile*>>
@@ -182,10 +163,9 @@
   std::vector<std::unique_ptr<const DexFile>> dex_files;
   std::vector<std::string> error_msgs;
 
-  bool success = linker->OpenDexFilesFromOat(sourceName.c_str(), outputName.c_str(), &error_msgs,
-                                             &dex_files);
+  dex_files = linker->OpenDexFilesFromOat(sourceName.c_str(), outputName.c_str(), &error_msgs);
 
-  if (success || !dex_files.empty()) {
+  if (!dex_files.empty()) {
     jlongArray array = ConvertNativeToJavaArray(env, dex_files);
     if (array == nullptr) {
       ScopedObjectAccess soa(env);
@@ -197,9 +177,6 @@
     }
     return array;
   } else {
-    // The vector should be empty after a failed loading attempt.
-    DCHECK_EQ(0U, dex_files.size());
-
     ScopedObjectAccess soa(env);
     CHECK(!error_msgs.empty());
     // The most important message is at the end. So set up nesting by going forward, which will
@@ -320,40 +297,6 @@
   return result;
 }
 
-static void CopyProfileFile(const char* oldfile, const char* newfile) {
-  ScopedFd src(open(oldfile, O_RDONLY));
-  if (src.get() == -1) {
-    PLOG(ERROR) << "Failed to open profile file " << oldfile
-      << ". My uid:gid is " << getuid() << ":" << getgid();
-    return;
-  }
-
-  struct stat stat_src;
-  if (fstat(src.get(), &stat_src) == -1) {
-    PLOG(ERROR) << "Failed to get stats for profile file  " << oldfile
-      << ". My uid:gid is " << getuid() << ":" << getgid();
-    return;
-  }
-
-  // Create the copy with rw------- (only accessible by system)
-  ScopedFd dst(open(newfile, O_WRONLY|O_CREAT|O_TRUNC, 0600));
-  if (dst.get()  == -1) {
-    PLOG(ERROR) << "Failed to create/write prev profile file " << newfile
-      << ".  My uid:gid is " << getuid() << ":" << getgid();
-    return;
-  }
-
-#ifdef __linux__
-  if (sendfile(dst.get(), src.get(), nullptr, stat_src.st_size) == -1) {
-#else
-  off_t len;
-  if (sendfile(dst.get(), src.get(), 0, &len, nullptr, 0) == -1) {
-#endif
-    PLOG(ERROR) << "Failed to copy profile file " << oldfile << " to " << newfile
-      << ". My uid:gid is " << getuid() << ":" << getgid();
-  }
-}
-
 // Java: dalvik.system.DexFile.UP_TO_DATE
 static const jbyte kUpToDate = 0;
 // Java: dalvik.system.DexFile.DEXOPT_NEEDED
@@ -361,102 +304,8 @@
 // Java: dalvik.system.DexFile.PATCHOAT_NEEDED
 static const jbyte kDexoptNeeded = 2;
 
-template <const bool kVerboseLogging, const bool kReasonLogging>
-static jbyte IsDexOptNeededForFile(const std::string& oat_filename, const char* filename,
-                                   InstructionSet target_instruction_set,
-                                   bool* oat_is_pic) {
-  std::string error_msg;
-  std::unique_ptr<const OatFile> oat_file(OatFile::Open(oat_filename, oat_filename, nullptr,
-                                                        nullptr,
-                                                        false, &error_msg));
-  if (oat_file.get() == nullptr) {
-    // Note that even though this is kDexoptNeeded, we use
-    // kVerboseLogging instead of the usual kReasonLogging since it is
-    // the common case on first boot and very spammy.
-    if (kVerboseLogging) {
-      LOG(INFO) << "DexFile_isDexOptNeeded failed to open oat file '" << oat_filename
-          << "' for file location '" << filename << "': " << error_msg;
-    }
-    error_msg.clear();
-    return kDexoptNeeded;
-  }
-
-  // Pass-up the information about if this is PIC.
-  // TODO: Refactor this function to be less complicated.
-  *oat_is_pic = oat_file->IsPic();
-
-  bool should_relocate_if_possible = Runtime::Current()->ShouldRelocate();
-  uint32_t location_checksum = 0;
-  const art::OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(filename, nullptr,
-                                                                          kReasonLogging);
-  if (oat_dex_file != nullptr) {
-    // If its not possible to read the classes.dex assume up-to-date as we won't be able to
-    // compile it anyway.
-    if (!DexFile::GetChecksum(filename, &location_checksum, &error_msg)) {
-      if (kVerboseLogging) {
-        LOG(INFO) << "DexFile_isDexOptNeeded found precompiled stripped file: "
-            << filename << " for " << oat_filename << ": " << error_msg;
-      }
-      if (ClassLinker::VerifyOatChecksums(oat_file.get(), target_instruction_set, &error_msg)) {
-        if (kVerboseLogging) {
-          LOG(INFO) << "DexFile_isDexOptNeeded file " << oat_filename
-                    << " is up-to-date for " << filename;
-        }
-        return kUpToDate;
-      } else if (should_relocate_if_possible &&
-                  ClassLinker::VerifyOatImageChecksum(oat_file.get(), target_instruction_set)) {
-        if (kReasonLogging) {
-          LOG(INFO) << "DexFile_isDexOptNeeded file " << oat_filename
-                    << " needs to be relocated for " << filename;
-        }
-        return kPatchoatNeeded;
-      } else {
-        if (kReasonLogging) {
-          LOG(INFO) << "DexFile_isDexOptNeeded file " << oat_filename
-                    << " is out of date for " << filename;
-        }
-        return kDexoptNeeded;
-      }
-      // If we get here the file is out of date and we should use the system one to relocate.
-    } else {
-      if (ClassLinker::VerifyOatAndDexFileChecksums(oat_file.get(), filename, location_checksum,
-                                                    target_instruction_set, &error_msg)) {
-        if (kVerboseLogging) {
-          LOG(INFO) << "DexFile_isDexOptNeeded file " << oat_filename
-                    << " is up-to-date for " << filename;
-        }
-        return kUpToDate;
-      } else if (location_checksum == oat_dex_file->GetDexFileLocationChecksum()
-                  && should_relocate_if_possible
-                  && ClassLinker::VerifyOatImageChecksum(oat_file.get(), target_instruction_set)) {
-        if (kReasonLogging) {
-          LOG(INFO) << "DexFile_isDexOptNeeded file " << oat_filename
-                    << " needs to be relocated for " << filename;
-        }
-        return kPatchoatNeeded;
-      } else {
-        if (kReasonLogging) {
-          LOG(INFO) << "DexFile_isDexOptNeeded file " << oat_filename
-                    << " is out of date for " << filename;
-        }
-        return kDexoptNeeded;
-      }
-    }
-  } else {
-    if (kReasonLogging) {
-      LOG(INFO) << "DexFile_isDexOptNeeded file " << oat_filename
-                << " does not contain " << filename;
-    }
-    return kDexoptNeeded;
-  }
-}
-
 static jbyte IsDexOptNeededInternal(JNIEnv* env, const char* filename,
     const char* pkgname, const char* instruction_set, const jboolean defer) {
-  // Spammy logging for kUpToDate
-  const bool kVerboseLogging = false;
-  // Logging of reason for returning kDexoptNeeded or kPatchoatNeeded.
-  const bool kReasonLogging = true;
 
   if ((filename == nullptr) || !OS::FileExists(filename)) {
     LOG(ERROR) << "DexFile_isDexOptNeeded file '" << filename << "' does not exist";
@@ -466,117 +315,6 @@
     return kUpToDate;
   }
 
-  // Always treat elements of the bootclasspath as up-to-date.  The
-  // fact that code is running at all means that this should be true.
-  Runtime* runtime = Runtime::Current();
-  ClassLinker* class_linker = runtime->GetClassLinker();
-  // TODO: We're assuming that the 64 and 32 bit runtimes have identical
-  // class paths. isDexOptNeeded will not necessarily be called on a runtime
-  // that has the same instruction set as the file being dexopted.
-  const std::vector<const DexFile*>& boot_class_path = class_linker->GetBootClassPath();
-  for (size_t i = 0; i < boot_class_path.size(); i++) {
-    if (boot_class_path[i]->GetLocation() == filename) {
-      if (kVerboseLogging) {
-        LOG(INFO) << "DexFile_isDexOptNeeded ignoring boot class path file: " << filename;
-      }
-      return kUpToDate;
-    }
-  }
-
-  bool force_system_only = false;
-  bool require_system_version = false;
-
-  // Check the profile file.  We need to rerun dex2oat if the profile has changed significantly
-  // since the last time, or it's new.
-  // If the 'defer' argument is true then this will be retried later.  In this case we
-  // need to make sure that the profile file copy is not made so that we will get the
-  // same result second time.
-  std::string profile_file;
-  std::string prev_profile_file;
-  bool should_copy_profile = false;
-  if (Runtime::Current()->GetProfilerOptions().IsEnabled() && (pkgname != nullptr)) {
-    profile_file = GetDalvikCacheOrDie("profiles", false /* create_if_absent */)
-        + std::string("/") + pkgname;
-    prev_profile_file = profile_file + std::string("@old");
-
-    struct stat profstat, prevstat;
-    int e1 = stat(profile_file.c_str(), &profstat);
-    int e1_errno = errno;
-    int e2 = stat(prev_profile_file.c_str(), &prevstat);
-    int e2_errno = errno;
-    if (e1 < 0) {
-      if (e1_errno != EACCES) {
-        // No profile file, need to run dex2oat, unless we find a file in system
-        if (kReasonLogging) {
-          LOG(INFO) << "DexFile_isDexOptNeededInternal profile file " << profile_file << " doesn't exist. "
-                    << "Will check odex to see if we can find a working version.";
-        }
-        // Force it to only accept system files/files with versions in system.
-        require_system_version = true;
-      } else {
-        LOG(INFO) << "DexFile_isDexOptNeededInternal recieved EACCES trying to stat profile file "
-                  << profile_file;
-      }
-    } else if (e2 == 0) {
-      // There is a previous profile file.  Check if the profile has changed significantly.
-      // A change in profile is considered significant if X% (change_thr property) of the top K%
-      // (compile_thr property) samples has changed.
-      double top_k_threshold = Runtime::Current()->GetProfilerOptions().GetTopKThreshold();
-      double change_threshold = Runtime::Current()->GetProfilerOptions().GetTopKChangeThreshold();
-      double change_percent = 0.0;
-      ProfileFile new_profile, old_profile;
-      bool new_ok = new_profile.LoadFile(profile_file);
-      bool old_ok = old_profile.LoadFile(prev_profile_file);
-      if (!new_ok || !old_ok) {
-        if (kVerboseLogging) {
-          LOG(INFO) << "DexFile_isDexOptNeededInternal Ignoring invalid profiles: "
-                    << (new_ok ?  "" : profile_file) << " " << (old_ok ? "" : prev_profile_file);
-        }
-      } else {
-        std::set<std::string> new_top_k, old_top_k;
-        new_profile.GetTopKSamples(new_top_k, top_k_threshold);
-        old_profile.GetTopKSamples(old_top_k, top_k_threshold);
-        if (new_top_k.empty()) {
-          if (kVerboseLogging) {
-            LOG(INFO) << "DexFile_isDexOptNeededInternal empty profile: " << profile_file;
-          }
-          // If the new topK is empty we shouldn't optimize so we leave the change_percent at 0.0.
-        } else {
-          std::set<std::string> diff;
-          std::set_difference(new_top_k.begin(), new_top_k.end(), old_top_k.begin(), old_top_k.end(),
-            std::inserter(diff, diff.end()));
-          // TODO: consider using the usedPercentage instead of the plain diff count.
-          change_percent = 100.0 * static_cast<double>(diff.size()) / static_cast<double>(new_top_k.size());
-          if (kVerboseLogging) {
-            std::set<std::string>::iterator end = diff.end();
-            for (std::set<std::string>::iterator it = diff.begin(); it != end; it++) {
-              LOG(INFO) << "DexFile_isDexOptNeededInternal new in topK: " << *it;
-            }
-          }
-        }
-      }
-
-      if (change_percent > change_threshold) {
-        if (kReasonLogging) {
-          LOG(INFO) << "DexFile_isDexOptNeededInternal size of new profile file " << profile_file <<
-          " is significantly different from old profile file " << prev_profile_file << " (top "
-          << top_k_threshold << "% samples changed in proportion of " << change_percent << "%)";
-        }
-        should_copy_profile = !defer;
-        // Force us to only accept system files.
-        force_system_only = true;
-      }
-    } else if (e2_errno == ENOENT) {
-      // Previous profile does not exist.  Make a copy of the current one.
-      if (kVerboseLogging) {
-        LOG(INFO) << "DexFile_isDexOptNeededInternal previous profile doesn't exist: " << prev_profile_file;
-      }
-      should_copy_profile = !defer;
-    } else {
-      PLOG(INFO) << "Unable to stat previous profile file " << prev_profile_file;
-    }
-  }
-
   const InstructionSet target_instruction_set = GetInstructionSetFromString(instruction_set);
   if (target_instruction_set == kNone) {
     ScopedLocalRef<jclass> iae(env, env->FindClass("java/lang/IllegalArgumentException"));
@@ -585,75 +323,43 @@
     return 0;
   }
 
-  // Get the filename for odex file next to the dex file.
-  std::string odex_filename(DexFilenameToOdexFilename(filename, target_instruction_set));
-  // Get the filename for the dalvik-cache file
-  std::string cache_dir;
-  bool have_android_data = false;
-  bool dalvik_cache_exists = false;
-  bool is_global_cache = false;
-  GetDalvikCache(instruction_set, false, &cache_dir, &have_android_data, &dalvik_cache_exists,
-                 &is_global_cache);
-  std::string cache_filename;  // was cache_location
-  bool have_cache_filename = false;
-  if (dalvik_cache_exists) {
-    std::string error_msg;
-    have_cache_filename = GetDalvikCacheFilename(filename, cache_dir.c_str(), &cache_filename,
-                                                 &error_msg);
-    if (!have_cache_filename && kVerboseLogging) {
-      LOG(INFO) << "DexFile_isDexOptNeededInternal failed to find cache file for dex file " << filename
-                << ": " << error_msg;
+  // TODO: Verify the dex location is well formed, and throw an IOException if
+  // not?
+
+  OatFileAssistant oat_file_assistant(filename, target_instruction_set, false, pkgname);
+
+  // Always treat elements of the bootclasspath as up-to-date.
+  if (oat_file_assistant.IsInBootClassPath()) {
+    return kUpToDate;
+  }
+
+  // TODO: Checking the profile should probably be done in the GetStatus()
+  // function. We have it here because GetStatus() should not be copying
+  // profile files. But who should be copying profile files?
+  if (oat_file_assistant.OdexFileIsOutOfDate()) {
+    // Needs recompile if profile has changed significantly.
+    if (Runtime::Current()->GetProfilerOptions().IsEnabled()) {
+      if (oat_file_assistant.IsProfileChangeSignificant()) {
+        if (!defer) {
+          oat_file_assistant.CopyProfileFile();
+        }
+        return kDexoptNeeded;
+      } else if (oat_file_assistant.ProfileExists()
+          && !oat_file_assistant.OldProfileExists()) {
+        if (!defer) {
+          oat_file_assistant.CopyProfileFile();
+        }
+      }
     }
   }
 
-  bool should_relocate_if_possible = Runtime::Current()->ShouldRelocate();
-
-  jbyte dalvik_cache_decision = -1;
-  // Lets try the cache first (since we want to load from there since thats where the relocated
-  // versions will be).
-  if (have_cache_filename && !force_system_only) {
-    bool oat_is_pic;
-    // We can use the dalvik-cache if we find a good file.
-    dalvik_cache_decision =
-        IsDexOptNeededForFile<kVerboseLogging, kReasonLogging>(cache_filename, filename,
-                                                               target_instruction_set, &oat_is_pic);
-
-    // Apps that are compiled with --compile-pic never need to be patchoat-d
-    if (oat_is_pic && dalvik_cache_decision == kPatchoatNeeded) {
-      dalvik_cache_decision = kUpToDate;
-    }
-    // We will only return DexOptNeeded if both the cache and system return it.
-    if (dalvik_cache_decision != kDexoptNeeded && !require_system_version) {
-      CHECK(!(dalvik_cache_decision == kPatchoatNeeded && !should_relocate_if_possible))
-          << "May not return PatchoatNeeded when patching is disabled.";
-      return dalvik_cache_decision;
-    }
-    // We couldn't find one thats easy. We should now try the system.
+  OatFileAssistant::Status status = oat_file_assistant.GetStatus();
+  switch (status) {
+    case OatFileAssistant::kUpToDate: return kUpToDate;
+    case OatFileAssistant::kNeedsRelocation: return kPatchoatNeeded;
+    case OatFileAssistant::kOutOfDate: return kDexoptNeeded;
   }
-
-  bool oat_is_pic;
-  jbyte system_decision =
-      IsDexOptNeededForFile<kVerboseLogging, kReasonLogging>(odex_filename, filename,
-                                                             target_instruction_set, &oat_is_pic);
-  CHECK(!(system_decision == kPatchoatNeeded && !should_relocate_if_possible))
-      << "May not return PatchoatNeeded when patching is disabled.";
-
-  // Apps that are compiled with --compile-pic never need to be patchoat-d
-  if (oat_is_pic && system_decision == kPatchoatNeeded) {
-    system_decision = kUpToDate;
-  }
-
-  if (require_system_version && system_decision == kPatchoatNeeded
-                             && dalvik_cache_decision == kUpToDate) {
-    // We have a version from system relocated to the cache. Return it.
-    return dalvik_cache_decision;
-  }
-
-  if (should_copy_profile && system_decision == kDexoptNeeded) {
-    CopyProfileFile(profile_file.c_str(), prev_profile_file.c_str());
-  }
-
-  return system_decision;
+  UNREACHABLE();
 }
 
 static jbyte DexFile_isDexOptNeededInternal(JNIEnv* env, jclass, jstring javaFilename,
diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc
new file mode 100644
index 0000000..f87fa4f
--- /dev/null
+++ b/runtime/oat_file_assistant.cc
@@ -0,0 +1,952 @@
+/*
+ * 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.
+ */
+
+#include "oat_file_assistant.h"
+
+#include <fcntl.h>
+#ifdef __linux__
+#include <sys/sendfile.h>
+#else
+#include <sys/socket.h>
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <set>
+
+#include "base/logging.h"
+#include "base/stringprintf.h"
+#include "class_linker.h"
+#include "gc/heap.h"
+#include "gc/space/image_space.h"
+#include "image.h"
+#include "oat.h"
+#include "os.h"
+#include "profiler.h"
+#include "runtime.h"
+#include "ScopedFd.h"
+#include "utils.h"
+
+namespace art {
+
+OatFileAssistant::OatFileAssistant(const char* dex_location,
+                                   const InstructionSet isa,
+                                   bool load_executable)
+    : OatFileAssistant(dex_location, nullptr, isa, load_executable, nullptr) { }
+
+OatFileAssistant::OatFileAssistant(const char* dex_location,
+                                   const char* oat_location,
+                                   const InstructionSet isa,
+                                   bool load_executable)
+    : OatFileAssistant(dex_location, oat_location, isa, load_executable, nullptr) { }
+
+OatFileAssistant::OatFileAssistant(const char* dex_location,
+                                   const InstructionSet isa,
+                                   bool load_executable,
+                                   const char* package_name)
+    : OatFileAssistant(dex_location, nullptr, isa, load_executable, package_name) { }
+
+OatFileAssistant::OatFileAssistant(const char* dex_location,
+                                   const char* oat_location,
+                                   const InstructionSet isa,
+                                   bool load_executable,
+                                   const char* package_name)
+    : dex_location_(dex_location), isa_(isa),
+      package_name_(package_name), load_executable_(load_executable) {
+  if (load_executable_ && isa != kRuntimeISA) {
+    LOG(WARNING) << "OatFileAssistant: Load executable specified, "
+      << "but isa is not kRuntimeISA. Will not attempt to load executable.";
+    load_executable_ = false;
+  }
+
+  // If the user gave a target oat location, save that as the cached oat
+  // location now so we won't try to construct the default location later.
+  if (oat_location != nullptr) {
+    cached_oat_file_name_ = std::string(oat_location);
+    cached_oat_file_name_attempted_ = true;
+    cached_oat_file_name_found_ = true;
+  }
+
+  // If there is no package name given, we will not be able to find any
+  // profiles associated with this dex location. Preemptively mark that to
+  // be the case, rather than trying to find and load the profiles later.
+  // Similarly, if profiling is disabled.
+  if (package_name == nullptr
+      || !Runtime::Current()->GetProfilerOptions().IsEnabled()) {
+    profile_load_attempted_ = true;
+    profile_load_succeeded_ = false;
+    old_profile_load_attempted_ = true;
+    old_profile_load_succeeded_ = false;
+  }
+}
+
+OatFileAssistant::~OatFileAssistant() {
+  // Clean up the lock file.
+  if (lock_file_.get() != nullptr) {
+    lock_file_->Erase();
+    TEMP_FAILURE_RETRY(unlink(lock_file_->GetPath().c_str()));
+  }
+}
+
+bool OatFileAssistant::IsInBootClassPath() {
+  // Note: We check the current boot class path, regardless of the ISA
+  // specified by the user. This is okay, because the boot class path should
+  // be the same for all ISAs.
+  // TODO: Can we verify the boot class path is the same for all ISAs?
+  Runtime* runtime = Runtime::Current();
+  ClassLinker* class_linker = runtime->GetClassLinker();
+  const auto& boot_class_path = class_linker->GetBootClassPath();
+  for (size_t i = 0; i < boot_class_path.size(); i++) {
+    if (boot_class_path[i]->GetLocation() == std::string(dex_location_)) {
+      VLOG(oat) << "Dex location " << dex_location_ << " is in boot class path";
+      return true;
+    }
+  }
+  return false;
+}
+
+bool OatFileAssistant::Lock(std::string* error_msg) {
+  CHECK(error_msg != nullptr);
+  CHECK(lock_file_.get() == nullptr) << "OatFileAssistant::Lock already acquired";
+
+  if (OatFileName() == nullptr) {
+    *error_msg = "Failed to determine lock file";
+    return false;
+  }
+  std::string lock_file_name = *OatFileName() + ".flock";
+
+  lock_file_.reset(OS::CreateEmptyFile(lock_file_name.c_str()));
+  if (lock_file_.get() == nullptr) {
+    *error_msg = "Failed to create lock file " + lock_file_name;
+    return false;
+  }
+
+  if (!flock_.Init(lock_file_.get(), error_msg)) {
+    TEMP_FAILURE_RETRY(unlink(lock_file_name.c_str()));
+    return false;
+  }
+  return true;
+}
+
+OatFileAssistant::Status OatFileAssistant::GetStatus() {
+  // TODO: If the profiling code is ever restored, it's worth considering
+  // whether we should check to see if the profile is out of date here.
+
+  if (OdexFileIsOutOfDate()) {
+    // The DEX file is not pre-compiled.
+    // TODO: What if the oat file is not out of date? Could we relocate it
+    // from itself?
+    return OatFileIsUpToDate() ? kUpToDate : kOutOfDate;
+  } else {
+    // The DEX file is pre-compiled. If the oat file isn't up to date, we can
+    // patch the pre-compiled version rather than recompiling.
+    if (OatFileIsUpToDate() || OdexFileIsUpToDate()) {
+      return kUpToDate;
+    } else {
+      return kNeedsRelocation;
+    }
+  }
+}
+
+bool OatFileAssistant::MakeUpToDate(std::string* error_msg) {
+  switch (GetStatus()) {
+    case kUpToDate: return true;
+    case kNeedsRelocation: return RelocateOatFile(error_msg);
+    case kOutOfDate: return GenerateOatFile(error_msg);
+  }
+  UNREACHABLE();
+}
+
+std::unique_ptr<OatFile> OatFileAssistant::GetBestOatFile() {
+  if (OatFileIsUpToDate()) {
+    oat_file_released_ = true;
+    return std::move(cached_oat_file_);
+  }
+
+  if (OdexFileIsUpToDate()) {
+    oat_file_released_ = true;
+    return std::move(cached_odex_file_);
+  }
+
+  if (load_executable_) {
+    VLOG(oat) << "Oat File Assistant: No relocated oat file found,"
+      << " attempting to fall back to interpreting oat file instead.";
+
+    if (!OatFileIsOutOfDate()) {
+      load_executable_ = false;
+      ClearOatFileCache();
+      if (!OatFileIsOutOfDate()) {
+        oat_file_released_ = true;
+        return std::move(cached_oat_file_);
+      }
+    }
+
+    if (!OdexFileIsOutOfDate()) {
+      load_executable_ = false;
+      ClearOdexFileCache();
+      if (!OdexFileIsOutOfDate()) {
+        oat_file_released_ = true;
+        return std::move(cached_odex_file_);
+      }
+    }
+  }
+
+  return std::unique_ptr<OatFile>();
+}
+
+std::vector<std::unique_ptr<const DexFile>> OatFileAssistant::LoadDexFiles(
+    const OatFile& oat_file, const char* dex_location) {
+  std::vector<std::unique_ptr<const DexFile>> dex_files;
+
+  // Load the primary dex file.
+  std::string error_msg;
+  const OatFile::OatDexFile* oat_dex_file = oat_file.GetOatDexFile(
+      dex_location, nullptr, false);
+  if (oat_dex_file == nullptr) {
+    LOG(WARNING) << "Attempt to load out-of-date oat file "
+      << oat_file.GetLocation() << " for dex location " << dex_location;
+    return std::vector<std::unique_ptr<const DexFile>>();
+  }
+
+  std::unique_ptr<const DexFile> dex_file = oat_dex_file->OpenDexFile(&error_msg);
+  if (dex_file.get() == nullptr) {
+    LOG(WARNING) << "Failed to open dex file from oat dex file: " << error_msg;
+    return std::vector<std::unique_ptr<const DexFile>>();
+  }
+  dex_files.push_back(std::move(dex_file));
+
+  // Load secondary multidex files
+  for (int i = 1; ; i++) {
+    std::string secondary_dex_location = DexFile::GetMultiDexClassesDexName(i, dex_location);
+    oat_dex_file = oat_file.GetOatDexFile(secondary_dex_location.c_str(), nullptr, false);
+    if (oat_dex_file == NULL) {
+      // There are no more secondary dex files to load.
+      break;
+    }
+
+    dex_file = oat_dex_file->OpenDexFile(&error_msg);
+    if (dex_file.get() == nullptr) {
+      LOG(WARNING) << "Failed to open dex file from oat dex file: " << error_msg;
+      return std::vector<std::unique_ptr<const DexFile>>();
+    }
+    dex_files.push_back(std::move(dex_file));
+  }
+  return dex_files;
+}
+
+const std::string* OatFileAssistant::OdexFileName() {
+  if (!cached_odex_file_name_attempted_) {
+    CHECK(dex_location_ != nullptr) << "OatFileAssistant: null dex location";
+    cached_odex_file_name_attempted_ = true;
+
+    std::string error_msg;
+    cached_odex_file_name_found_ = DexFilenameToOdexFilename(
+        dex_location_, isa_, &cached_odex_file_name_, &error_msg);
+    if (!cached_odex_file_name_found_) {
+      // If we can't figure out the odex file, we treat it as if the odex
+      // file was inaccessible.
+      LOG(WARNING) << "Failed to determine odex file name: " << error_msg;
+    }
+  }
+  return cached_odex_file_name_found_ ? &cached_odex_file_name_ : nullptr;
+}
+
+bool OatFileAssistant::OdexFileExists() {
+  return GetOdexFile() != nullptr;
+}
+
+OatFileAssistant::Status OatFileAssistant::OdexFileStatus() {
+  if (OdexFileIsOutOfDate()) {
+    return kOutOfDate;
+  }
+  if (OdexFileIsUpToDate()) {
+    return kUpToDate;
+  }
+  return kNeedsRelocation;
+}
+
+bool OatFileAssistant::OdexFileIsOutOfDate() {
+  if (!odex_file_is_out_of_date_attempted_) {
+    odex_file_is_out_of_date_attempted_ = true;
+    const OatFile* odex_file = GetOdexFile();
+    if (odex_file == nullptr) {
+      cached_odex_file_is_out_of_date_ = true;
+    } else {
+      cached_odex_file_is_out_of_date_ = GivenOatFileIsOutOfDate(*odex_file);
+    }
+  }
+  return cached_odex_file_is_out_of_date_;
+}
+
+bool OatFileAssistant::OdexFileNeedsRelocation() {
+  return OdexFileStatus() == kNeedsRelocation;
+}
+
+bool OatFileAssistant::OdexFileIsUpToDate() {
+  if (!odex_file_is_up_to_date_attempted_) {
+    odex_file_is_up_to_date_attempted_ = true;
+    const OatFile* odex_file = GetOdexFile();
+    if (odex_file == nullptr) {
+      cached_odex_file_is_up_to_date_ = false;
+    } else {
+      cached_odex_file_is_up_to_date_ = GivenOatFileIsUpToDate(*odex_file);
+    }
+  }
+  return cached_odex_file_is_up_to_date_;
+}
+
+const std::string* OatFileAssistant::OatFileName() {
+  if (!cached_oat_file_name_attempted_) {
+    cached_oat_file_name_attempted_ = true;
+
+    // Compute the oat file name from the dex location.
+    CHECK(dex_location_ != nullptr) << "OatFileAssistant: null dex location";
+
+    // TODO: The oat file assistant should be the definitive place for
+    // determining the oat file name from the dex location, not
+    // GetDalvikCacheFilename.
+    std::string cache_dir = StringPrintf("%s%s",
+        DalvikCacheDirectory().c_str(), GetInstructionSetString(isa_));
+    std::string error_msg;
+    cached_oat_file_name_found_ = GetDalvikCacheFilename(dex_location_,
+        cache_dir.c_str(), &cached_oat_file_name_, &error_msg);
+    if (!cached_oat_file_name_found_) {
+      // If we can't determine the oat file name, we treat the oat file as
+      // inaccessible.
+      LOG(WARNING) << "Failed to determine oat file name for dex location "
+        << dex_location_ << ": " << error_msg;
+    }
+  }
+  return cached_oat_file_name_found_ ? &cached_oat_file_name_ : nullptr;
+}
+
+bool OatFileAssistant::OatFileExists() {
+  return GetOatFile() != nullptr;
+}
+
+OatFileAssistant::Status OatFileAssistant::OatFileStatus() {
+  if (OatFileIsOutOfDate()) {
+    return kOutOfDate;
+  }
+  if (OatFileIsUpToDate()) {
+    return kUpToDate;
+  }
+  return kNeedsRelocation;
+}
+
+bool OatFileAssistant::OatFileIsOutOfDate() {
+  if (!oat_file_is_out_of_date_attempted_) {
+    oat_file_is_out_of_date_attempted_ = true;
+    const OatFile* oat_file = GetOatFile();
+    if (oat_file == nullptr) {
+      cached_oat_file_is_out_of_date_ = true;
+    } else {
+      cached_oat_file_is_out_of_date_ = GivenOatFileIsOutOfDate(*oat_file);
+    }
+  }
+  return cached_oat_file_is_out_of_date_;
+}
+
+bool OatFileAssistant::OatFileNeedsRelocation() {
+  return OatFileStatus() == kNeedsRelocation;
+}
+
+bool OatFileAssistant::OatFileIsUpToDate() {
+  if (!oat_file_is_up_to_date_attempted_) {
+    oat_file_is_up_to_date_attempted_ = true;
+    const OatFile* oat_file = GetOatFile();
+    if (oat_file == nullptr) {
+      cached_oat_file_is_up_to_date_ = false;
+    } else {
+      cached_oat_file_is_up_to_date_ = GivenOatFileIsUpToDate(*oat_file);
+    }
+  }
+  return cached_oat_file_is_up_to_date_;
+}
+
+OatFileAssistant::Status OatFileAssistant::GivenOatFileStatus(const OatFile& file) {
+  // TODO: This could cause GivenOatFileIsOutOfDate to be called twice, which
+  // is more work than we need to do. If performance becomes a concern, and
+  // this method is actually called, this should be fixed.
+  if (GivenOatFileIsOutOfDate(file)) {
+    return kOutOfDate;
+  }
+  if (GivenOatFileIsUpToDate(file)) {
+    return kUpToDate;
+  }
+  return kNeedsRelocation;
+}
+
+bool OatFileAssistant::GivenOatFileIsOutOfDate(const OatFile& file) {
+  // Verify the dex checksum.
+  // Note: GetOatDexFile will return NULL if the dex checksum doesn't match
+  // what we provide, which verifies the primary dex checksum for us.
+  const uint32_t* dex_checksum_pointer = GetRequiredDexChecksum();
+  const OatFile::OatDexFile* oat_dex_file = file.GetOatDexFile(
+      dex_location_, dex_checksum_pointer, false);
+  if (oat_dex_file == NULL) {
+    return true;
+  }
+
+  // Verify the dex checksums for any secondary multidex files
+  for (int i = 1; ; i++) {
+    std::string secondary_dex_location
+      = DexFile::GetMultiDexClassesDexName(i, dex_location_);
+    const OatFile::OatDexFile* secondary_oat_dex_file
+      = file.GetOatDexFile(secondary_dex_location.c_str(), nullptr, false);
+    if (secondary_oat_dex_file == NULL) {
+      // There are no more secondary dex files to check.
+      break;
+    }
+
+    std::string error_msg;
+    uint32_t expected_secondary_checksum = 0;
+    if (DexFile::GetChecksum(secondary_dex_location.c_str(),
+          &expected_secondary_checksum, &error_msg)) {
+      uint32_t actual_secondary_checksum
+        = secondary_oat_dex_file->GetDexFileLocationChecksum();
+      if (expected_secondary_checksum != actual_secondary_checksum) {
+        VLOG(oat) << "Dex checksum does not match for secondary dex: "
+          << secondary_dex_location
+          << ". Expected: " << expected_secondary_checksum
+          << ", Actual: " << actual_secondary_checksum;
+        return false;
+      }
+    } else {
+      // If we can't get the checksum for the secondary location, we assume
+      // the dex checksum is up to date for this and all other secondary dex
+      // files.
+      break;
+    }
+  }
+
+  // Verify the image checksum
+  const ImageInfo* image_info = GetImageInfo();
+  if (image_info == nullptr) {
+    VLOG(oat) << "No image for oat image checksum to match against.";
+    return true;
+  }
+
+  if (file.GetOatHeader().GetImageFileLocationOatChecksum() != image_info->oat_checksum) {
+    VLOG(oat) << "Oat image checksum does not match image checksum.";
+    return true;
+  }
+
+  // The checksums are all good; the dex file is not out of date.
+  return false;
+}
+
+bool OatFileAssistant::GivenOatFileNeedsRelocation(const OatFile& file) {
+  return GivenOatFileStatus(file) == kNeedsRelocation;
+}
+
+bool OatFileAssistant::GivenOatFileIsUpToDate(const OatFile& file) {
+  if (GivenOatFileIsOutOfDate(file)) {
+    return false;
+  }
+
+  if (file.IsPic()) {
+    return true;
+  }
+
+  const ImageInfo* image_info = GetImageInfo();
+  if (image_info == nullptr) {
+    VLOG(oat) << "No image for to check oat relocation against.";
+    return false;
+  }
+
+  // Verify the oat_data_begin recorded for the image in the oat file matches
+  // the actual oat_data_begin for boot.oat in the image.
+  const OatHeader& oat_header = file.GetOatHeader();
+  uintptr_t oat_data_begin = oat_header.GetImageFileLocationOatDataBegin();
+  if (oat_data_begin != image_info->oat_data_begin) {
+    VLOG(oat) << file.GetLocation() <<
+      ": Oat file image oat_data_begin (" << oat_data_begin << ")"
+      << " does not match actual image oat_data_begin ("
+      << image_info->oat_data_begin << ")";
+    return false;
+  }
+
+  // Verify the oat_patch_delta recorded for the image in the oat file matches
+  // the actual oat_patch_delta for the image.
+  int32_t oat_patch_delta = oat_header.GetImagePatchDelta();
+  if (oat_patch_delta != image_info->patch_delta) {
+    VLOG(oat) << file.GetLocation() <<
+      ": Oat file image patch delta (" << oat_patch_delta << ")"
+      << " does not match actual image patch delta ("
+      << image_info->patch_delta << ")";
+    return false;
+  }
+  return true;
+}
+
+bool OatFileAssistant::ProfileExists() {
+  return GetProfile() != nullptr;
+}
+
+bool OatFileAssistant::OldProfileExists() {
+  return GetOldProfile() != nullptr;
+}
+
+// TODO: The IsProfileChangeSignificant implementation was copied from likely
+// bit-rotted code.
+bool OatFileAssistant::IsProfileChangeSignificant() {
+  ProfileFile* profile = GetProfile();
+  if (profile == nullptr) {
+    return false;
+  }
+
+  ProfileFile* old_profile = GetOldProfile();
+  if (old_profile == nullptr) {
+    return false;
+  }
+
+  // TODO: The following code to compare two profile files should live with
+  // the rest of the profiler code, not the oat file assistant code.
+
+  // A change in profile is considered significant if X% (change_thr property)
+  // of the top K% (compile_thr property) samples has changed.
+  const ProfilerOptions& options = Runtime::Current()->GetProfilerOptions();
+  const double top_k_threshold = options.GetTopKThreshold();
+  const double change_threshold = options.GetTopKChangeThreshold();
+  std::set<std::string> top_k, old_top_k;
+  profile->GetTopKSamples(top_k, top_k_threshold);
+  old_profile->GetTopKSamples(old_top_k, top_k_threshold);
+  std::set<std::string> diff;
+  std::set_difference(top_k.begin(), top_k.end(), old_top_k.begin(),
+      old_top_k.end(), std::inserter(diff, diff.end()));
+
+  // TODO: consider using the usedPercentage instead of the plain diff count.
+  double change_percent = 100.0 * static_cast<double>(diff.size())
+                                / static_cast<double>(top_k.size());
+  std::set<std::string>::iterator end = diff.end();
+  for (std::set<std::string>::iterator it = diff.begin(); it != end; it++) {
+    VLOG(oat) << "Profile new in topK: " << *it;
+  }
+
+  if (change_percent > change_threshold) {
+      VLOG(oat) << "Oat File Assistant: Profile for " << dex_location_
+        << "has changed significantly: (top "
+        << top_k_threshold << "% samples changed in proportion of "
+        << change_percent << "%)";
+      return true;
+  }
+  return false;
+}
+
+// TODO: The CopyProfileFile implementation was copied from likely bit-rotted
+// code.
+void OatFileAssistant::CopyProfileFile() {
+  if (!ProfileExists()) {
+    return;
+  }
+
+  std::string profile_name = ProfileFileName();
+  std::string old_profile_name = OldProfileFileName();
+
+  ScopedFd src(open(old_profile_name.c_str(), O_RDONLY));
+  if (src.get() == -1) {
+    PLOG(WARNING) << "Failed to open profile file " << old_profile_name
+      << ". My uid:gid is " << getuid() << ":" << getgid();
+    return;
+  }
+
+  struct stat stat_src;
+  if (fstat(src.get(), &stat_src) == -1) {
+    PLOG(WARNING) << "Failed to get stats for profile file  " << old_profile_name
+      << ". My uid:gid is " << getuid() << ":" << getgid();
+    return;
+  }
+
+  // Create the copy with rw------- (only accessible by system)
+  ScopedFd dst(open(profile_name.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0600));
+  if (dst.get()  == -1) {
+    PLOG(WARNING) << "Failed to create/write prev profile file " << profile_name
+      << ".  My uid:gid is " << getuid() << ":" << getgid();
+    return;
+  }
+
+#ifdef __linux__
+  if (sendfile(dst.get(), src.get(), nullptr, stat_src.st_size) == -1) {
+#else
+  off_t len;
+  if (sendfile(dst.get(), src.get(), 0, &len, nullptr, 0) == -1) {
+#endif
+    PLOG(WARNING) << "Failed to copy profile file " << old_profile_name
+      << " to " << profile_name << ". My uid:gid is " << getuid()
+      << ":" << getgid();
+  }
+}
+
+bool OatFileAssistant::RelocateOatFile(std::string* error_msg) {
+  CHECK(error_msg != nullptr);
+
+  if (OdexFileName() == nullptr) {
+    *error_msg = "Patching of oat file for dex location "
+      + std::string(dex_location_)
+      + " not attempted because the odex file name could not be determined.";
+    return false;
+  }
+  const std::string& odex_file_name = *OdexFileName();
+
+  if (OatFileName() == nullptr) {
+    *error_msg = "Patching of oat file for dex location "
+      + std::string(dex_location_)
+      + " not attempted because the oat file name could not be determined.";
+    return false;
+  }
+  const std::string& oat_file_name = *OatFileName();
+
+  const ImageInfo* image_info = GetImageInfo();
+  Runtime* runtime = Runtime::Current();
+  if (image_info == nullptr) {
+    *error_msg = "Patching of oat file " + oat_file_name
+      + " not attempted because no image location was found.";
+    return false;
+  }
+
+  if (!runtime->IsDex2OatEnabled()) {
+    *error_msg = "Patching of oat file " + oat_file_name
+      + " not attempted because dex2oat is disabled";
+    return false;
+  }
+
+  std::vector<std::string> argv;
+  argv.push_back(runtime->GetPatchoatExecutable());
+  argv.push_back("--instruction-set=" + std::string(GetInstructionSetString(isa_)));
+  argv.push_back("--input-oat-file=" + odex_file_name);
+  argv.push_back("--output-oat-file=" + oat_file_name);
+  argv.push_back("--patched-image-location=" + image_info->location);
+
+  std::string command_line(Join(argv, ' '));
+  if (!Exec(argv, error_msg)) {
+    // Manually delete the file. This ensures there is no garbage left over if
+    // the process unexpectedly died.
+    TEMP_FAILURE_RETRY(unlink(oat_file_name.c_str()));
+    return false;
+  }
+
+  // Mark that the oat file has changed and we should try to reload.
+  ClearOatFileCache();
+  return true;
+}
+
+bool OatFileAssistant::GenerateOatFile(std::string* error_msg) {
+  CHECK(error_msg != nullptr);
+
+  if (OatFileName() == nullptr) {
+    *error_msg = "Generation of oat file for dex location "
+      + std::string(dex_location_)
+      + " not attempted because the oat file name could not be determined.";
+    return false;
+  }
+  const std::string& oat_file_name = *OatFileName();
+
+  Runtime* runtime = Runtime::Current();
+  if (!runtime->IsDex2OatEnabled()) {
+    *error_msg = "Generation of oat file " + oat_file_name
+      + " not attempted because dex2oat is disabled";
+    return false;
+  }
+
+  std::vector<std::string> args;
+  args.push_back("--dex-file=" + std::string(dex_location_));
+  args.push_back("--oat-file=" + oat_file_name);
+
+  // dex2oat ignores missing dex files and doesn't report an error.
+  // Check explicitly here so we can detect the error properly.
+  // TODO: Why does dex2oat behave that way?
+  if (!OS::FileExists(dex_location_)) {
+    *error_msg = "Dex location " + std::string(dex_location_) + " does not exists.";
+    return false;
+  }
+
+  if (!Dex2Oat(args, error_msg)) {
+    // Manually delete the file. This ensures there is no garbage left over if
+    // the process unexpectedly died.
+    TEMP_FAILURE_RETRY(unlink(oat_file_name.c_str()));
+    return false;
+  }
+
+  // Mark that the oat file has changed and we should try to reload.
+  ClearOatFileCache();
+  return true;
+}
+
+bool OatFileAssistant::Dex2Oat(const std::vector<std::string>& args,
+                               std::string* error_msg) {
+  Runtime* runtime = Runtime::Current();
+  std::string image_location = ImageLocation();
+  if (image_location.empty()) {
+    *error_msg = "No image location found for Dex2Oat.";
+    return false;
+  }
+
+  std::vector<std::string> argv;
+  argv.push_back(runtime->GetCompilerExecutable());
+  argv.push_back("--runtime-arg");
+  argv.push_back("-classpath");
+  argv.push_back("--runtime-arg");
+  argv.push_back(runtime->GetClassPathString());
+  runtime->AddCurrentRuntimeFeaturesAsDex2OatArguments(&argv);
+
+  if (!runtime->IsVerificationEnabled()) {
+    argv.push_back("--compiler-filter=verify-none");
+  }
+
+  if (runtime->MustRelocateIfPossible()) {
+    argv.push_back("--runtime-arg");
+    argv.push_back("-Xrelocate");
+  } else {
+    argv.push_back("--runtime-arg");
+    argv.push_back("-Xnorelocate");
+  }
+
+  if (!kIsTargetBuild) {
+    argv.push_back("--host");
+  }
+
+  argv.push_back("--boot-image=" + image_location);
+
+  std::vector<std::string> compiler_options = runtime->GetCompilerOptions();
+  argv.insert(argv.end(), compiler_options.begin(), compiler_options.end());
+
+  argv.insert(argv.end(), args.begin(), args.end());
+
+  std::string command_line(Join(argv, ' '));
+  return Exec(argv, error_msg);
+}
+
+bool OatFileAssistant::DexFilenameToOdexFilename(const std::string& location,
+    InstructionSet isa, std::string* odex_filename, std::string* error_msg) {
+  CHECK(odex_filename != nullptr);
+  CHECK(error_msg != nullptr);
+
+  // The odex file name is formed by replacing the dex_location extension with
+  // .odex and inserting an isa directory. For example:
+  //   location = /foo/bar/baz.jar
+  //   odex_location = /foo/bar/<isa>/baz.odex
+
+  // Find the directory portion of the dex location and add the isa directory.
+  size_t pos = location.rfind('/');
+  if (pos == std::string::npos) {
+    *error_msg = "Dex location " + location + " has no directory.";
+    return false;
+  }
+  std::string dir = location.substr(0, pos+1);
+  dir += std::string(GetInstructionSetString(isa));
+
+  // Find the file portion of the dex location.
+  std::string file;
+  if (pos == std::string::npos) {
+    file = location;
+  } else {
+    file = location.substr(pos+1);
+  }
+
+  // Get the base part of the file without the extension.
+  pos = file.rfind('.');
+  if (pos == std::string::npos) {
+    *error_msg = "Dex location " + location + " has no extension.";
+    return false;
+  }
+  std::string base = file.substr(0, pos);
+
+  *odex_filename = dir + "/" + base + ".odex";
+  return true;
+}
+
+std::string OatFileAssistant::DalvikCacheDirectory() {
+  // Note: We don't cache this, because it will only be called once by
+  // OatFileName, and we don't care about the performance of the profiling
+  // code, which isn't used in practice.
+
+  // TODO: The work done in GetDalvikCache is overkill for what we need.
+  // Ideally a new API for getting the DalvikCacheDirectory the way we want
+  // (without existence testing, creation, or death) is provided with the rest
+  // of the GetDalvikCache family of functions. Until such an API is in place,
+  // we use GetDalvikCache to avoid duplicating the logic for determining the
+  // dalvik cache directory.
+  std::string result;
+  bool have_android_data;
+  bool dalvik_cache_exists;
+  bool is_global_cache;
+  GetDalvikCache("", false, &result, &have_android_data, &dalvik_cache_exists, &is_global_cache);
+  return result;
+}
+
+std::string OatFileAssistant::ProfileFileName() {
+  if (package_name_ != nullptr) {
+    return DalvikCacheDirectory() + std::string("profiles/") + package_name_;
+  }
+  return "";
+}
+
+std::string OatFileAssistant::OldProfileFileName() {
+  std::string profile_name = ProfileFileName();
+  if (profile_name.empty()) {
+    return "";
+  }
+  return profile_name + "@old";
+}
+
+std::string OatFileAssistant::ImageLocation() {
+  Runtime* runtime = Runtime::Current();
+  const gc::space::ImageSpace* image_space = runtime->GetHeap()->GetImageSpace();
+  if (image_space == nullptr) {
+    return "";
+  }
+  return image_space->GetImageLocation();
+}
+
+const uint32_t* OatFileAssistant::GetRequiredDexChecksum() {
+  if (!required_dex_checksum_attempted) {
+    required_dex_checksum_attempted = true;
+    required_dex_checksum_found = false;
+    std::string error_msg;
+    CHECK(dex_location_ != nullptr) << "OatFileAssistant provided no dex location";
+    if (DexFile::GetChecksum(dex_location_, &cached_required_dex_checksum, &error_msg)) {
+      required_dex_checksum_found = true;
+    } else {
+      // This can happen if the original dex file has been stripped from the
+      // apk.
+      VLOG(oat) << "OatFileAssistant: " << error_msg;
+
+      // Get the checksum from the odex if we can.
+      const OatFile* odex_file = GetOdexFile();
+      if (odex_file != nullptr) {
+        const OatFile::OatDexFile* odex_dex_file = odex_file->GetOatDexFile(
+            dex_location_, nullptr, false);
+        if (odex_dex_file != nullptr) {
+          cached_required_dex_checksum = odex_dex_file->GetDexFileLocationChecksum();
+          required_dex_checksum_found = true;
+        }
+      }
+    }
+  }
+  return required_dex_checksum_found ? &cached_required_dex_checksum : nullptr;
+}
+
+const OatFile* OatFileAssistant::GetOdexFile() {
+  CHECK(!oat_file_released_) << "OdexFile called after oat file released.";
+  if (!odex_file_load_attempted_) {
+    odex_file_load_attempted_ = true;
+    if (OdexFileName() != nullptr) {
+      const std::string& odex_file_name = *OdexFileName();
+      std::string error_msg;
+      cached_odex_file_.reset(OatFile::Open(odex_file_name.c_str(),
+            odex_file_name.c_str(), nullptr, nullptr, load_executable_,
+            &error_msg));
+      if (cached_odex_file_.get() == nullptr) {
+        VLOG(oat) << "OatFileAssistant test for existing pre-compiled oat file "
+          << odex_file_name << ": " << error_msg;
+      }
+    }
+  }
+  return cached_odex_file_.get();
+}
+
+void OatFileAssistant::ClearOdexFileCache() {
+  odex_file_load_attempted_ = false;
+  cached_odex_file_.reset();
+  odex_file_is_out_of_date_attempted_ = false;
+  odex_file_is_up_to_date_attempted_ = false;
+}
+
+const OatFile* OatFileAssistant::GetOatFile() {
+  CHECK(!oat_file_released_) << "OatFile called after oat file released.";
+  if (!oat_file_load_attempted_) {
+    oat_file_load_attempted_ = true;
+    if (OatFileName() != nullptr) {
+      const std::string& oat_file_name = *OatFileName();
+      std::string error_msg;
+      cached_oat_file_.reset(OatFile::Open(oat_file_name.c_str(),
+            oat_file_name.c_str(), nullptr, nullptr, load_executable_, &error_msg));
+      if (cached_oat_file_.get() == nullptr) {
+        VLOG(oat) << "OatFileAssistant test for existing oat file "
+          << oat_file_name << ": " << error_msg;
+      }
+    }
+  }
+  return cached_oat_file_.get();
+}
+
+void OatFileAssistant::ClearOatFileCache() {
+  oat_file_load_attempted_ = false;
+  cached_oat_file_.reset();
+  oat_file_is_out_of_date_attempted_ = false;
+  oat_file_is_up_to_date_attempted_ = false;
+}
+
+const OatFileAssistant::ImageInfo* OatFileAssistant::GetImageInfo() {
+  if (!image_info_load_attempted_) {
+    image_info_load_attempted_ = true;
+
+    Runtime* runtime = Runtime::Current();
+    const gc::space::ImageSpace* image_space = runtime->GetHeap()->GetImageSpace();
+    if (image_space != nullptr) {
+      cached_image_info_.location = image_space->GetImageLocation();
+
+      if (isa_ == kRuntimeISA) {
+        const ImageHeader& image_header = image_space->GetImageHeader();
+        cached_image_info_.oat_checksum = image_header.GetOatChecksum();
+        cached_image_info_.oat_data_begin = reinterpret_cast<uintptr_t>(image_header.GetOatDataBegin());
+        cached_image_info_.patch_delta = image_header.GetPatchDelta();
+      } else {
+        std::unique_ptr<ImageHeader> image_header(
+            gc::space::ImageSpace::ReadImageHeaderOrDie(
+                cached_image_info_.location.c_str(), isa_));
+        cached_image_info_.oat_checksum = image_header->GetOatChecksum();
+        cached_image_info_.oat_data_begin = reinterpret_cast<uintptr_t>(image_header->GetOatDataBegin());
+        cached_image_info_.patch_delta = image_header->GetPatchDelta();
+      }
+    }
+    image_info_load_succeeded_ = (image_space != nullptr);
+  }
+  return image_info_load_succeeded_ ? &cached_image_info_ : nullptr;
+}
+
+ProfileFile* OatFileAssistant::GetProfile() {
+  if (!profile_load_attempted_) {
+    CHECK(package_name_ != nullptr)
+      << "pakage_name_ is nullptr: "
+      << "profile_load_attempted_ should have been true";
+    profile_load_attempted_ = true;
+    std::string profile_name = ProfileFileName();
+    if (!profile_name.empty()) {
+      profile_load_succeeded_ = cached_profile_.LoadFile(profile_name);
+    }
+  }
+  return profile_load_succeeded_ ? &cached_profile_ : nullptr;
+}
+
+ProfileFile* OatFileAssistant::GetOldProfile() {
+  if (!old_profile_load_attempted_) {
+    CHECK(package_name_ != nullptr)
+      << "pakage_name_ is nullptr: "
+      << "old_profile_load_attempted_ should have been true";
+    old_profile_load_attempted_ = true;
+    std::string old_profile_name = OldProfileFileName();
+    if (!old_profile_name.empty()) {
+      old_profile_load_succeeded_ = cached_old_profile_.LoadFile(old_profile_name);
+    }
+  }
+  return old_profile_load_succeeded_ ? &cached_old_profile_ : nullptr;
+}
+
+}  // namespace art
+
diff --git a/runtime/oat_file_assistant.h b/runtime/oat_file_assistant.h
new file mode 100644
index 0000000..958b440
--- /dev/null
+++ b/runtime/oat_file_assistant.h
@@ -0,0 +1,431 @@
+/*
+ * 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.
+ */
+
+#ifndef ART_RUNTIME_OAT_FILE_ASSISTANT_H_
+#define ART_RUNTIME_OAT_FILE_ASSISTANT_H_
+
+#include <cstdint>
+#include <memory>
+#include <string>
+
+#include "arch/instruction_set.h"
+#include "base/scoped_flock.h"
+#include "base/unix_file/fd_file.h"
+#include "oat_file.h"
+#include "os.h"
+#include "profiler.h"
+
+namespace art {
+
+// Class for assisting with oat file management.
+//
+// This class collects common utilities for determining the status of an oat
+// file on the device, updating the oat file, and loading the oat file.
+//
+// The oat file assistant is intended to be used with dex locations not on the
+// boot class path. See the IsInBootClassPath method for a way to check if the
+// dex location is in the boot class path.
+//
+// TODO: All the profiling related code is old and untested. It should either
+// be restored and tested, or removed.
+class OatFileAssistant {
+ public:
+  enum Status {
+    // kOutOfDate - An oat file is said to be out of date if the file does not
+    // exist, or is out of date with respect to the dex file or boot image.
+    kOutOfDate,
+
+    // kNeedsRelocation - An oat file is said to need relocation if the code
+    // is up to date, but not yet properly relocated for address space layout
+    // randomization (ASLR). In this case, the oat file is neither "out of
+    // date" nor "up to date".
+    kNeedsRelocation,
+
+    // kUpToDate - An oat file is said to be up to date if it is not out of
+    // date and has been properly relocated for the purposes of ASLR.
+    kUpToDate,
+  };
+
+  // Constructs an OatFileAssistant object to assist the oat file
+  // corresponding to the given dex location with the target instruction set.
+  //
+  // The dex_location must not be NULL and should remain available and
+  // unchanged for the duration of the lifetime of the OatFileAssistant object.
+  // Typically the dex_location is the absolute path to the original,
+  // un-optimized dex file.
+  //
+  //
+  // Note: Currently the dex_location must have an extension.
+  // TODO: Relax this restriction?
+  //
+  // The isa should be either the 32 bit or 64 bit variant for the current
+  // device. For example, on an arm device, use arm or arm64. An oat file can
+  // be loaded executable only if the ISA matches the current runtime.
+  OatFileAssistant(const char* dex_location, const InstructionSet isa,
+                   bool load_executable);
+
+  // Constructs an OatFileAssistant, providing an explicit target oat_location
+  // to use instead of the standard oat location.
+  OatFileAssistant(const char* dex_location, const char* oat_location,
+                   const InstructionSet isa, bool load_executable);
+
+  // Constructs an OatFileAssistant, providing an additional package_name used
+  // solely for the purpose of locating profile files.
+  //
+  // TODO: Why is the name of the profile file based on the package name and
+  // not the dex location? If there is no technical reason the dex_location
+  // can't be used, we should prefer that instead.
+  OatFileAssistant(const char* dex_location, const InstructionSet isa,
+                   bool load_executable, const char* package_name);
+
+  // Constructs an OatFileAssistant with user specified oat location and a
+  // package name.
+  OatFileAssistant(const char* dex_location, const char* oat_location,
+                   const InstructionSet isa, bool load_executable,
+                   const char* package_name);
+
+  ~OatFileAssistant();
+
+  // Returns true if the dex location refers to an element of the boot class
+  // path.
+  bool IsInBootClassPath();
+
+  // Obtains a lock on the target oat file.
+  // Only one OatFileAssistant object can hold the lock for a target oat file
+  // at a time. The Lock is released automatically when the OatFileAssistant
+  // object goes out of scope. The Lock() method must not be called if the
+  // lock has already been acquired.
+  //
+  // Returns true on success.
+  // Returns false on error, in which case error_msg will contain more
+  // information on the error.
+  //
+  // The 'error_msg' argument must not be null.
+  //
+  // This is intended to be used to avoid race conditions when multiple
+  // processes generate oat files, such as when a foreground Activity and
+  // a background Service both use DexClassLoaders pointing to the same dex
+  // file.
+  bool Lock(std::string* error_msg);
+
+  // Returns the overall compilation status for the given dex location.
+  Status GetStatus();
+
+  // Attempts to generate or relocate the oat file as needed to make it up to
+  // date.
+  // Returns true on success.
+  //
+  // If there is a failure, the value of error_msg will be set to a string
+  // describing why there was failure. error_msg must not be nullptr.
+  bool MakeUpToDate(std::string* error_msg);
+
+  // Returns an oat file that can be used for loading dex files.
+  // Returns nullptr if no suitable oat file was found.
+  //
+  // After this call, no other methods of the OatFileAssistant should be
+  // called, because access to the loaded oat file has been taken away from
+  // the OatFileAssistant object.
+  std::unique_ptr<OatFile> GetBestOatFile();
+
+  // Loads the dex files in the given oat file for the given dex location.
+  // The oat file should be up to date for the given dex location.
+  // This loads multiple dex files in the case of multidex.
+  // Returns an empty vector if no dex files for that location could be loaded
+  // from the oat file.
+  //
+  // The caller is responsible for freeing the dex_files returned, if any. The
+  // dex_files will only remain valid as long as the oat_file is valid.
+  static std::vector<std::unique_ptr<const DexFile>> LoadDexFiles(
+      const OatFile& oat_file, const char* dex_location);
+
+  // If the dex file has been pre-compiled on the host, the compiled oat file
+  // will have the extension .odex, and is referred to as the odex file.
+  // It is called odex for legacy reasons; the file is really an oat file. The
+  // odex file will typically have a patch delta of 0 and need to be relocated
+  // before use for the purposes of ASLR.
+  // These methods return the location and status of the odex file for the dex
+  // location.
+  // Notes:
+  //  * OdexFileName may return null if the odex file name could not be
+  //    determined.
+  const std::string* OdexFileName();
+  bool OdexFileExists();
+  Status OdexFileStatus();
+  bool OdexFileIsOutOfDate();
+  bool OdexFileNeedsRelocation();
+  bool OdexFileIsUpToDate();
+
+  // When the dex files is compiled on the target device, the oat file is the
+  // result. The oat file will have been relocated to some
+  // (possibly-out-of-date) offset for ASLR.
+  // These methods return the location and status of the target oat file for
+  // the dex location.
+  //
+  // Notes:
+  //  * To get the overall status of the compiled code for this dex_location,
+  //    use the GetStatus() method, not the OatFileStatus() method.
+  //  * OatFileName may return null if the oat file name could not be
+  //    determined.
+  const std::string* OatFileName();
+  bool OatFileExists();
+  Status OatFileStatus();
+  bool OatFileIsOutOfDate();
+  bool OatFileNeedsRelocation();
+  bool OatFileIsUpToDate();
+
+  // These methods return the status for a given opened oat file with respect
+  // to the dex location.
+  Status GivenOatFileStatus(const OatFile& file);
+  bool GivenOatFileIsOutOfDate(const OatFile& file);
+  bool GivenOatFileNeedsRelocation(const OatFile& file);
+  bool GivenOatFileIsUpToDate(const OatFile& file);
+
+  // Returns true if there is an accessible profile associated with the dex
+  // location.
+  // This returns false if profiling is disabled.
+  bool ProfileExists();
+
+  // The old profile is a file containing a previous snapshot of profiling
+  // information associated with the dex file code. This is used to track how
+  // the profiling information has changed over time.
+  //
+  // Returns true if there is an accessible old profile associated with the
+  // dex location.
+  // This returns false if profiling is disabled.
+  bool OldProfileExists();
+
+  // Returns true if there has been a significant change between the old
+  // profile and the current profile.
+  // This returns false if profiling is disabled.
+  bool IsProfileChangeSignificant();
+
+  // Copy the current profile to the old profile location.
+  void CopyProfileFile();
+
+  // Generates the oat file by relocation from the odex file.
+  // This does not check the current status before attempting to relocate the
+  // oat file.
+  // Returns true on success.
+  // This will fail if dex2oat is not enabled in the current runtime.
+  //
+  // If there is a failure, the value of error_msg will be set to a string
+  // describing why there was failure. error_msg must not be nullptr.
+  bool RelocateOatFile(std::string* error_msg);
+
+  // Generate the oat file from the dex file.
+  // This does not check the current status before attempting to generate the
+  // oat file.
+  // Returns true on success.
+  // This will fail if dex2oat is not enabled in the current runtime.
+  //
+  // If there is a failure, the value of error_msg will be set to a string
+  // describing why there was failure. error_msg must not be nullptr.
+  bool GenerateOatFile(std::string* error_msg);
+
+  // Executes dex2oat using the current runtime configuration overridden with
+  // the given arguments. This does not check to see if dex2oat is enabled in
+  // the runtime configuration.
+  // Returns true on success.
+  //
+  // If there is a failure, the value of error_msg will be set to a string
+  // describing why there was failure. error_msg must not be nullptr.
+  //
+  // TODO: The OatFileAssistant probably isn't the right place to have this
+  // function.
+  static bool Dex2Oat(const std::vector<std::string>& args, std::string* error_msg);
+
+  // Constructs the odex file name for the given dex location.
+  // Returns true on success, in which case odex_filename is set to the odex
+  // file name.
+  // Returns false on error, in which case error_msg describes the error.
+  // Neither odex_filename nor error_msg may be null.
+  static bool DexFilenameToOdexFilename(const std::string& location,
+      InstructionSet isa, std::string* odex_filename, std::string* error_msg);
+
+ private:
+  struct ImageInfo {
+    uint32_t oat_checksum = 0;
+    uintptr_t oat_data_begin = 0;
+    int32_t patch_delta = 0;
+    std::string location;
+  };
+
+  // Returns the path to the dalvik cache directory.
+  // Does not check existence of the cache or try to create it.
+  // Includes the trailing slash.
+  // Returns an empty string if we can't get the dalvik cache directory path.
+  std::string DalvikCacheDirectory();
+
+  // Constructs the filename for the profile file.
+  // Returns an empty string if we do not have the necessary information to
+  // construct the filename.
+  std::string ProfileFileName();
+
+  // Constructs the filename for the old profile file.
+  // Returns an empty string if we do not have the necessary information to
+  // construct the filename.
+  std::string OldProfileFileName();
+
+  // Returns the current image location.
+  // Returns an empty string if the image location could not be retrieved.
+  //
+  // TODO: This method should belong with an image file manager, not
+  // the oat file assistant.
+  static std::string ImageLocation();
+
+  // Gets the dex checksum required for an up-to-date oat file.
+  // Returns dex_checksum if a required checksum was located. Returns
+  // nullptr if the required checksum was not found.
+  // The caller shouldn't clean up or free the returned pointer.
+  const uint32_t* GetRequiredDexChecksum();
+
+  // Returns the loaded odex file.
+  // Loads the file if needed. Returns nullptr if the file failed to load.
+  // The caller shouldn't clean up or free the returned pointer.
+  const OatFile* GetOdexFile();
+
+  // Clear any cached information about the odex file that depends on the
+  // contents of the file.
+  void ClearOdexFileCache();
+
+  // Returns the loaded oat file.
+  // Loads the file if needed. Returns nullptr if the file failed to load.
+  // The caller shouldn't clean up or free the returned pointer.
+  const OatFile* GetOatFile();
+
+  // Clear any cached information about the oat file that depends on the
+  // contents of the file.
+  void ClearOatFileCache();
+
+  // Returns the loaded image info.
+  // Loads the image info if needed. Returns nullptr if the image info failed
+  // to load.
+  // The caller shouldn't clean up or free the returned pointer.
+  const ImageInfo* GetImageInfo();
+
+  // Returns the loaded profile.
+  // Loads the profile if needed. Returns nullptr if the profile failed
+  // to load.
+  // The caller shouldn't clean up or free the returned pointer.
+  ProfileFile* GetProfile();
+
+  // Returns the loaded old profile.
+  // Loads the old profile if needed. Returns nullptr if the old profile
+  // failed to load.
+  // The caller shouldn't clean up or free the returned pointer.
+  ProfileFile* GetOldProfile();
+
+  // To implement Lock(), we lock a dummy file where the oat file would go
+  // (adding ".flock" to the target file name) and retain the lock for the
+  // remaining lifetime of the OatFileAssistant object.
+  std::unique_ptr<File> lock_file_;
+  ScopedFlock flock_;
+
+  // In a properly constructed OatFileAssistant object, dex_location_ should
+  // never be nullptr.
+  const char* dex_location_ = nullptr;
+
+  // In a properly constructed OatFileAssistant object, isa_ should be either
+  // the 32 or 64 bit variant for the current device.
+  const InstructionSet isa_ = kNone;
+
+  // The package name, used solely to find the profile file.
+  // This may be nullptr in a properly constructed object. In this case,
+  // profile_load_attempted_ and old_profile_load_attempted_ will be true, and
+  // profile_load_succeeded_ and old_profile_load_succeeded_ will be false.
+  const char* package_name_ = nullptr;
+
+  // Whether we will attempt to load oat files executable.
+  bool load_executable_ = false;
+
+  // Cached value of the required dex checksum.
+  // This should be accessed only by the GetRequiredDexChecksum() method.
+  uint32_t cached_required_dex_checksum;
+  bool required_dex_checksum_attempted = false;
+  bool required_dex_checksum_found;
+
+  // Cached value of the odex file name.
+  // This should be accessed only by the OdexFileName() method.
+  bool cached_odex_file_name_attempted_ = false;
+  bool cached_odex_file_name_found_;
+  std::string cached_odex_file_name_;
+
+  // Cached value of the loaded odex file.
+  // Use the GetOdexFile method rather than accessing this directly, unless you
+  // know the odex file isn't out of date.
+  bool odex_file_load_attempted_ = false;
+  std::unique_ptr<OatFile> cached_odex_file_;
+
+  // Cached results for OdexFileIsOutOfDate
+  bool odex_file_is_out_of_date_attempted_ = false;
+  bool cached_odex_file_is_out_of_date_;
+
+  // Cached results for OdexFileIsUpToDate
+  bool odex_file_is_up_to_date_attempted_ = false;
+  bool cached_odex_file_is_up_to_date_;
+
+  // Cached value of the oat file name.
+  // This should be accessed only by the OatFileName() method.
+  bool cached_oat_file_name_attempted_ = false;
+  bool cached_oat_file_name_found_;
+  std::string cached_oat_file_name_;
+
+  // Cached value of the loaded odex file.
+  // Use the GetOatFile method rather than accessing this directly, unless you
+  // know the odex file isn't out of date.
+  bool oat_file_load_attempted_ = false;
+  std::unique_ptr<OatFile> cached_oat_file_;
+
+  // Cached results for OatFileIsOutOfDate
+  bool oat_file_is_out_of_date_attempted_ = false;
+  bool cached_oat_file_is_out_of_date_;
+
+  // Cached results for OatFileIsUpToDate
+  bool oat_file_is_up_to_date_attempted_ = false;
+  bool cached_oat_file_is_up_to_date_;
+
+  // Cached value of the image info.
+  // Use the GetImageInfo method rather than accessing these directly.
+  // TODO: The image info should probably be moved out of the oat file
+  // assistant to an image file manager.
+  bool image_info_load_attempted_ = false;
+  bool image_info_load_succeeded_ = false;
+  ImageInfo cached_image_info_;
+
+  // Cached value of the profile file.
+  // Use the GetProfile method rather than accessing these directly.
+  bool profile_load_attempted_ = false;
+  bool profile_load_succeeded_ = false;
+  ProfileFile cached_profile_;
+
+  // Cached value of the profile file.
+  // Use the GetOldProfile method rather than accessing these directly.
+  bool old_profile_load_attempted_ = false;
+  bool old_profile_load_succeeded_ = false;
+  ProfileFile cached_old_profile_;
+
+  // For debugging only.
+  // If this flag is set, the oat or odex file has been released to the user
+  // of the OatFileAssistant object and the OatFileAssistant object is in a
+  // bad state and should no longer be used.
+  bool oat_file_released_ = false;
+
+  DISALLOW_COPY_AND_ASSIGN(OatFileAssistant);
+};
+
+}  // namespace art
+
+#endif  // ART_RUNTIME_OAT_FILE_ASSISTANT_H_
diff --git a/runtime/oat_file_assistant_test.cc b/runtime/oat_file_assistant_test.cc
new file mode 100644
index 0000000..d683cdc
--- /dev/null
+++ b/runtime/oat_file_assistant_test.cc
@@ -0,0 +1,874 @@
+/*
+ * 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.
+ */
+
+#include "oat_file_assistant.h"
+
+#include <algorithm>
+#include <fstream>
+#include <string>
+#include <vector>
+#include <sys/param.h>
+
+#include <backtrace/BacktraceMap.h>
+#include <gtest/gtest.h>
+
+#include "class_linker.h"
+#include "common_runtime_test.h"
+#include "mem_map.h"
+#include "os.h"
+#include "thread-inl.h"
+#include "utils.h"
+
+namespace art {
+
+class OatFileAssistantTest : public CommonRuntimeTest {
+ public:
+  virtual void SetUp() {
+    ReserveImageSpace();
+    CommonRuntimeTest::SetUp();
+
+    // Create a scratch directory to work from.
+    scratch_dir_ = android_data_ + "/OatFileAssistantTest";
+    ASSERT_EQ(0, mkdir(scratch_dir_.c_str(), 0700));
+
+    // Create a subdirectory in scratch for the current isa.
+    // This is the location that will be used for odex files in the tests.
+    isa_dir_ = scratch_dir_ + "/" + GetInstructionSetString(kRuntimeISA);
+    ASSERT_EQ(0, mkdir(isa_dir_.c_str(), 0700));
+
+    // Verify the environment is as we expect
+    uint32_t checksum;
+    std::string error_msg;
+    ASSERT_TRUE(OS::FileExists(GetImageFile().c_str()))
+      << "Expected pre-compiled boot image to be at: " << GetImageFile();
+    ASSERT_TRUE(OS::FileExists(GetDexSrc1().c_str()))
+      << "Expected dex file to be at: " << GetDexSrc1();
+    ASSERT_TRUE(OS::FileExists(GetStrippedDexSrc1().c_str()))
+      << "Expected stripped dex file to be at: " << GetStrippedDexSrc1();
+    ASSERT_FALSE(DexFile::GetChecksum(GetStrippedDexSrc1().c_str(), &checksum, &error_msg))
+      << "Expected stripped dex file to be stripped: " << GetStrippedDexSrc1();
+    ASSERT_TRUE(OS::FileExists(GetMultiDexSrc1().c_str()))
+      << "Expected multidex file to be at: " << GetMultiDexSrc1();
+    ASSERT_TRUE(OS::FileExists(GetDexSrc2().c_str()))
+      << "Expected dex file to be at: " << GetDexSrc2();
+  }
+
+  virtual void SetUpRuntimeOptions(RuntimeOptions* options) {
+    // options->push_back(std::make_pair("-verbose:oat", nullptr));
+
+    // Set up the image location.
+    options->push_back(std::make_pair("-Ximage:" + GetImageLocation(),
+          nullptr));
+    // Make sure compilercallbacks are not set so that relocation will be
+    // enabled.
+    for (std::pair<std::string, const void*>& pair : *options) {
+      if (pair.first == "compilercallbacks") {
+        pair.second = nullptr;
+      }
+    }
+  }
+
+  virtual void PreRuntimeCreate() {
+    UnreserveImageSpace();
+  }
+
+  virtual void PostRuntimeCreate() {
+    ReserveImageSpace();
+  }
+
+  virtual void TearDown() {
+    ClearDirectory(isa_dir_.c_str());
+    ASSERT_EQ(0, rmdir(isa_dir_.c_str()));
+
+    ClearDirectory(scratch_dir_.c_str());
+    ASSERT_EQ(0, rmdir(scratch_dir_.c_str()));
+
+    CommonRuntimeTest::TearDown();
+  }
+
+  void Copy(std::string src, std::string dst) {
+    std::ifstream  src_stream(src, std::ios::binary);
+    std::ofstream  dst_stream(dst, std::ios::binary);
+
+    dst_stream << src_stream.rdbuf();
+  }
+
+  // Returns the directory where the pre-compiled core.art can be found.
+  // TODO: We should factor out this into common tests somewhere rather than
+  // re-hardcoding it here (This was copied originally from the elf writer
+  // test).
+  std::string GetImageDirectory() {
+    if (IsHost()) {
+      const char* host_dir = getenv("ANDROID_HOST_OUT");
+      CHECK(host_dir != NULL);
+      return std::string(host_dir) + "/framework";
+    } else {
+      return std::string("/data/art-test");
+    }
+  }
+
+  std::string GetImageLocation() {
+    return GetImageDirectory() + "/core.art";
+  }
+
+  std::string GetImageFile() {
+    return GetImageDirectory() + "/" + GetInstructionSetString(kRuntimeISA)
+      + "/core.art";
+  }
+
+  std::string GetDexSrc1() {
+    return GetTestDexFileName("Main");
+  }
+
+  // Returns the path to a dex file equivalent to GetDexSrc1, but with the dex
+  // file stripped.
+  std::string GetStrippedDexSrc1() {
+    return GetTestDexFileName("MainStripped");
+  }
+
+  std::string GetMultiDexSrc1() {
+    return GetTestDexFileName("MultiDex");
+  }
+
+  std::string GetDexSrc2() {
+    return GetTestDexFileName("Nested");
+  }
+
+  // Scratch directory, for dex and odex files (oat files will go in the
+  // dalvik cache).
+  std::string GetScratchDir() {
+    return scratch_dir_;
+  }
+
+  // ISA directory is the subdirectory in the scratch directory where odex
+  // files should be located.
+  std::string GetISADir() {
+    return isa_dir_;
+  }
+
+  // Generate an odex file for the purposes of test.
+  // If pic is true, generates a PIC odex.
+  void GenerateOdexForTest(const std::string& dex_location,
+                           const std::string& odex_location,
+                           bool pic = false) {
+    // For this operation, we temporarily redirect the dalvik cache so dex2oat
+    // doesn't find the relocated image file.
+    std::string android_data_tmp = GetScratchDir() + "AndroidDataTmp";
+    setenv("ANDROID_DATA", android_data_tmp.c_str(), 1);
+    std::vector<std::string> args;
+    args.push_back("--dex-file=" + dex_location);
+    args.push_back("--oat-file=" + odex_location);
+    if (pic) {
+      args.push_back("--compile-pic");
+    } else {
+      args.push_back("--include-patch-information");
+    }
+    args.push_back("--runtime-arg");
+    args.push_back("-Xnorelocate");
+    std::string error_msg;
+    ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
+    setenv("ANDROID_DATA", android_data_.c_str(), 1);
+  }
+
+  void GeneratePicOdexForTest(const std::string& dex_location,
+                              const std::string& odex_location) {
+    GenerateOdexForTest(dex_location, odex_location, true);
+  }
+
+ private:
+  // Reserve memory around where the image will be loaded so other memory
+  // won't conflict when it comes time to load the image.
+  // This can be called with an already loaded image to reserve the space
+  // around it.
+  void ReserveImageSpace() {
+    MemMap::Init();
+
+    // Ensure a chunk of memory is reserved for the image space.
+    uintptr_t reservation_start = ART_BASE_ADDRESS + ART_BASE_ADDRESS_MIN_DELTA;
+    uintptr_t reservation_end = ART_BASE_ADDRESS + ART_BASE_ADDRESS_MAX_DELTA
+      + 100 * 1024 * 1024;
+
+    std::string error_msg;
+    std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(getpid(), true));
+    ASSERT_TRUE(map.get() != nullptr) << "Failed to build process map";
+    for (BacktraceMap::const_iterator it = map->begin();
+        reservation_start < reservation_end && it != map->end(); ++it) {
+      if (it->end <= reservation_start) {
+        continue;
+      }
+
+      if (it->start < reservation_start) {
+        reservation_start = std::min(reservation_end, it->end);
+      }
+
+      image_reservation_.push_back(std::unique_ptr<MemMap>(
+          MemMap::MapAnonymous("image reservation",
+              reinterpret_cast<uint8_t*>(reservation_start),
+              std::min(it->start, reservation_end) - reservation_start,
+              PROT_NONE, false, false, &error_msg)));
+      ASSERT_TRUE(image_reservation_.back().get() != nullptr) << error_msg;
+      LOG(INFO) << "Reserved space for image " <<
+        reinterpret_cast<void*>(image_reservation_.back()->Begin()) << "-" <<
+        reinterpret_cast<void*>(image_reservation_.back()->End());
+      reservation_start = it->end;
+    }
+  }
+
+
+  // Unreserve any memory reserved by ReserveImageSpace. This should be called
+  // before the image is loaded.
+  void UnreserveImageSpace() {
+    image_reservation_.clear();
+  }
+
+  std::string scratch_dir_;
+  std::string isa_dir_;
+  std::vector<std::unique_ptr<MemMap>> image_reservation_;
+};
+
+class OatFileAssistantNoDex2OatTest : public OatFileAssistantTest {
+ public:
+  virtual void SetUpRuntimeOptions(RuntimeOptions* options) {
+    OatFileAssistantTest::SetUpRuntimeOptions(options);
+    options->push_back(std::make_pair("-Xnodex2oat", nullptr));
+  }
+};
+
+// Generate an oat file for the purposes of test, as opposed to testing
+// generation of oat files.
+static void GenerateOatForTest(const char* dex_location) {
+  OatFileAssistant oat_file_assistant(dex_location, kRuntimeISA, false);
+
+  std::string error_msg;
+  ASSERT_TRUE(oat_file_assistant.GenerateOatFile(&error_msg)) << error_msg;
+}
+
+// Case: We have a DEX file, but no OAT file for it.
+// Expect: The oat file status is kOutOfDate.
+TEST_F(OatFileAssistantTest, DexNoOat) {
+  std::string dex_location = GetScratchDir() + "/DexNoOat.jar";
+  Copy(GetDexSrc1(), dex_location);
+
+  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
+
+  EXPECT_EQ(OatFileAssistant::kOutOfDate, oat_file_assistant.GetStatus());
+
+  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
+  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
+  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
+  EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
+  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
+  EXPECT_EQ(OatFileAssistant::kOutOfDate, oat_file_assistant.OdexFileStatus());
+  EXPECT_FALSE(oat_file_assistant.OatFileExists());
+  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
+  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
+  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
+  EXPECT_EQ(OatFileAssistant::kOutOfDate, oat_file_assistant.OatFileStatus());
+}
+
+// Case: We have no DEX file and no OAT file.
+// Expect: Status is out of date. Loading should fail, but not crash.
+TEST_F(OatFileAssistantTest, NoDexNoOat) {
+  std::string dex_location = GetScratchDir() + "/NoDexNoOat.jar";
+
+  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
+
+  EXPECT_EQ(OatFileAssistant::kOutOfDate, oat_file_assistant.GetStatus());
+  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
+  EXPECT_EQ(nullptr, oat_file.get());
+}
+
+// Case: We have a DEX file and up-to-date OAT file for it.
+// Expect: The oat file status is kUpToDate.
+TEST_F(OatFileAssistantTest, OatUpToDate) {
+  std::string dex_location = GetScratchDir() + "/OatUpToDate.jar";
+  Copy(GetDexSrc1(), dex_location);
+  GenerateOatForTest(dex_location.c_str());
+
+  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
+
+  EXPECT_EQ(OatFileAssistant::kUpToDate, oat_file_assistant.GetStatus());
+  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
+  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
+  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
+  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
+  EXPECT_TRUE(oat_file_assistant.OatFileExists());
+  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
+  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
+  EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
+  EXPECT_EQ(OatFileAssistant::kUpToDate, oat_file_assistant.OatFileStatus());
+}
+
+// Case: We have a MultiDEX file and up-to-date OAT file for it.
+// Expect: The oat file status is kUpToDate.
+TEST_F(OatFileAssistantTest, MultiDexOatUpToDate) {
+  std::string dex_location = GetScratchDir() + "/MultiDexOatUpToDate.jar";
+  Copy(GetMultiDexSrc1(), dex_location);
+  GenerateOatForTest(dex_location.c_str());
+
+  // Verify we can load both dex files.
+  OatFileAssistant executable_oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
+  std::unique_ptr<OatFile> oat_file = executable_oat_file_assistant.GetBestOatFile();
+  ASSERT_TRUE(oat_file.get() != nullptr);
+  EXPECT_TRUE(oat_file->IsExecutable());
+  std::vector<std::unique_ptr<const DexFile>> dex_files;
+  dex_files = executable_oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
+  EXPECT_EQ(2u, dex_files.size());
+}
+
+// Case: We have a DEX file and out of date OAT file.
+// Expect: The oat file status is kOutOfDate.
+TEST_F(OatFileAssistantTest, OatOutOfDate) {
+  std::string dex_location = GetScratchDir() + "/OatOutOfDate.jar";
+
+  // We create a dex, generate an oat for it, then overwrite the dex with a
+  // different dex to make the oat out of date.
+  Copy(GetDexSrc1(), dex_location);
+  GenerateOatForTest(dex_location.c_str());
+  Copy(GetDexSrc2(), dex_location);
+
+  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
+  EXPECT_EQ(OatFileAssistant::kOutOfDate, oat_file_assistant.GetStatus());
+
+  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
+  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
+  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
+  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
+  EXPECT_TRUE(oat_file_assistant.OatFileExists());
+  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
+  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
+}
+
+// Case: We have a DEX file and an ODEX file, but no OAT file.
+// Expect: The oat file status is kNeedsRelocation.
+TEST_F(OatFileAssistantTest, DexOdexNoOat) {
+  std::string dex_location = GetScratchDir() + "/DexOdexNoOat.jar";
+  std::string odex_location = GetISADir() + "/DexOdexNoOat.odex";
+
+  // Create the dex and odex files
+  Copy(GetDexSrc1(), dex_location);
+  GenerateOdexForTest(dex_location, odex_location);
+
+  // Verify the status.
+  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
+
+  EXPECT_EQ(OatFileAssistant::kNeedsRelocation, oat_file_assistant.GetStatus());
+
+  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
+  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
+  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
+  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
+  EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation());
+  EXPECT_EQ(OatFileAssistant::kNeedsRelocation, oat_file_assistant.OdexFileNeedsRelocation());
+  EXPECT_FALSE(oat_file_assistant.OatFileExists());
+  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
+  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
+}
+
+// Case: We have a stripped DEX file and an ODEX file, but no OAT file.
+// Expect: The oat file status is kNeedsRelocation.
+TEST_F(OatFileAssistantTest, StrippedDexOdexNoOat) {
+  std::string dex_location = GetScratchDir() + "/StrippedDexOdexNoOat.jar";
+  std::string odex_location = GetISADir() + "/StrippedDexOdexNoOat.odex";
+
+  // Create the dex and odex files
+  Copy(GetDexSrc1(), dex_location);
+  GenerateOdexForTest(dex_location, odex_location);
+
+  // Strip the dex file
+  Copy(GetStrippedDexSrc1(), dex_location);
+
+  // Verify the status.
+  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
+
+  EXPECT_EQ(OatFileAssistant::kNeedsRelocation, oat_file_assistant.GetStatus());
+
+  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
+  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
+  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
+  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
+  EXPECT_FALSE(oat_file_assistant.OatFileExists());
+  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
+  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
+
+  // Make the oat file up to date.
+  std::string error_msg;
+  ASSERT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg;
+
+  EXPECT_EQ(OatFileAssistant::kUpToDate, oat_file_assistant.GetStatus());
+
+  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
+  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
+  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
+  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
+  EXPECT_TRUE(oat_file_assistant.OatFileExists());
+  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
+  EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
+
+  // Verify we can load the dex files from it.
+  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
+  ASSERT_TRUE(oat_file.get() != nullptr);
+  EXPECT_TRUE(oat_file->IsExecutable());
+  std::vector<std::unique_ptr<const DexFile>> dex_files;
+  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
+  EXPECT_EQ(1u, dex_files.size());
+}
+
+// Case: We have a stripped DEX file, an ODEX file, and an out of date OAT file.
+// Expect: The oat file status is kNeedsRelocation.
+TEST_F(OatFileAssistantTest, StrippedDexOdexOat) {
+  std::string dex_location = GetScratchDir() + "/StrippedDexOdexOat.jar";
+  std::string odex_location = GetISADir() + "/StrippedDexOdexOat.odex";
+
+  // Create the oat file from a different dex file so it looks out of date.
+  Copy(GetDexSrc2(), dex_location);
+  GenerateOatForTest(dex_location.c_str());
+
+  // Create the odex file
+  Copy(GetDexSrc1(), dex_location);
+  GenerateOdexForTest(dex_location, odex_location);
+
+  // Strip the dex file.
+  Copy(GetStrippedDexSrc1(), dex_location);
+
+  // Verify the status.
+  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
+
+  EXPECT_EQ(OatFileAssistant::kNeedsRelocation, oat_file_assistant.GetStatus());
+
+  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
+  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
+  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
+  EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation());
+  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
+  EXPECT_TRUE(oat_file_assistant.OatFileExists());
+  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
+  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
+
+  // Make the oat file up to date.
+  std::string error_msg;
+  ASSERT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg;
+
+  EXPECT_EQ(OatFileAssistant::kUpToDate, oat_file_assistant.GetStatus());
+
+  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
+  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
+  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
+  EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation());
+  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
+  EXPECT_TRUE(oat_file_assistant.OatFileExists());
+  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
+  EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
+  EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
+
+  // Verify we can load the dex files from it.
+  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
+  ASSERT_TRUE(oat_file.get() != nullptr);
+  EXPECT_TRUE(oat_file->IsExecutable());
+  std::vector<std::unique_ptr<const DexFile>> dex_files;
+  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
+  EXPECT_EQ(1u, dex_files.size());
+}
+
+// Case: We have a DEX file, an ODEX file and an OAT file, where the ODEX and
+// OAT files both have patch delta of 0.
+// Expect: It shouldn't crash.
+TEST_F(OatFileAssistantTest, OdexOatOverlap) {
+  std::string dex_location = GetScratchDir() + "/OdexOatOverlap.jar";
+  std::string odex_location = GetISADir() + "/OdexOatOverlap.odex";
+  std::string oat_location = GetISADir() + "/OdexOatOverlap.oat";
+
+  // Create the dex and odex files
+  Copy(GetDexSrc1(), dex_location);
+  GenerateOdexForTest(dex_location, odex_location);
+
+  // Create the oat file by copying the odex so they are located in the same
+  // place in memory.
+  Copy(odex_location, oat_location);
+
+  // Verify things don't go bad.
+  OatFileAssistant oat_file_assistant(dex_location.c_str(),
+      oat_location.c_str(), kRuntimeISA, true);
+
+  EXPECT_EQ(OatFileAssistant::kNeedsRelocation, oat_file_assistant.GetStatus());
+
+  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
+  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
+  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
+  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
+  EXPECT_TRUE(oat_file_assistant.OatFileExists());
+  EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
+  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
+
+  // Things aren't relocated, so it should fall back to interpreted.
+  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
+  ASSERT_TRUE(oat_file.get() != nullptr);
+  EXPECT_FALSE(oat_file->IsExecutable());
+  std::vector<std::unique_ptr<const DexFile>> dex_files;
+  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
+  EXPECT_EQ(1u, dex_files.size());
+}
+
+// Case: We have a DEX file and a PIC ODEX file, but no OAT file.
+// Expect: The oat file status is kUpToDate, because PIC needs no relocation.
+TEST_F(OatFileAssistantTest, DexPicOdexNoOat) {
+  std::string dex_location = GetScratchDir() + "/DexPicOdexNoOat.jar";
+  std::string odex_location = GetISADir() + "/DexPicOdexNoOat.odex";
+
+  // Create the dex and odex files
+  Copy(GetDexSrc1(), dex_location);
+  GeneratePicOdexForTest(dex_location, odex_location);
+
+  // Verify the status.
+  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
+
+  EXPECT_EQ(OatFileAssistant::kUpToDate, oat_file_assistant.GetStatus());
+
+  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
+  EXPECT_TRUE(oat_file_assistant.OdexFileExists());
+  EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
+  EXPECT_TRUE(oat_file_assistant.OdexFileIsUpToDate());
+  EXPECT_FALSE(oat_file_assistant.OatFileExists());
+  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
+  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
+}
+
+// Case: We have a DEX file and up-to-date OAT file for it.
+// Expect: We should load an executable dex file.
+TEST_F(OatFileAssistantTest, LoadOatUpToDate) {
+  std::string dex_location = GetScratchDir() + "/LoadOatUpToDate.jar";
+
+  Copy(GetDexSrc1(), dex_location);
+  GenerateOatForTest(dex_location.c_str());
+
+  // Load the oat using an oat file assistant.
+  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
+
+  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
+  ASSERT_TRUE(oat_file.get() != nullptr);
+  EXPECT_TRUE(oat_file->IsExecutable());
+  std::vector<std::unique_ptr<const DexFile>> dex_files;
+  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
+  EXPECT_EQ(1u, dex_files.size());
+}
+
+// Case: We have a DEX file and up-to-date OAT file for it.
+// Expect: Loading non-executable should load the oat non-executable.
+TEST_F(OatFileAssistantTest, LoadNoExecOatUpToDate) {
+  std::string dex_location = GetScratchDir() + "/LoadNoExecOatUpToDate.jar";
+
+  Copy(GetDexSrc1(), dex_location);
+  GenerateOatForTest(dex_location.c_str());
+
+  // Load the oat using an oat file assistant.
+  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
+
+  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
+  ASSERT_TRUE(oat_file.get() != nullptr);
+  EXPECT_FALSE(oat_file->IsExecutable());
+  std::vector<std::unique_ptr<const DexFile>> dex_files;
+  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
+  EXPECT_EQ(1u, dex_files.size());
+}
+
+// Case: We have a DEX file.
+// Expect: We should load an executable dex file from an alternative oat
+// location.
+TEST_F(OatFileAssistantTest, LoadDexNoAlternateOat) {
+  std::string dex_location = GetScratchDir() + "/LoadDexNoAlternateOat.jar";
+  std::string oat_location = GetScratchDir() + "/LoadDexNoAlternateOat.oat";
+
+  Copy(GetDexSrc1(), dex_location);
+
+  OatFileAssistant oat_file_assistant(
+      dex_location.c_str(), oat_location.c_str(), kRuntimeISA, true);
+  std::string error_msg;
+  ASSERT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg;
+
+  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
+  ASSERT_TRUE(oat_file.get() != nullptr);
+  EXPECT_TRUE(oat_file->IsExecutable());
+  std::vector<std::unique_ptr<const DexFile>> dex_files;
+  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
+  EXPECT_EQ(1u, dex_files.size());
+
+  EXPECT_TRUE(OS::FileExists(oat_location.c_str()));
+
+  // Verify it didn't create an oat in the default location.
+  OatFileAssistant ofm(dex_location.c_str(), kRuntimeISA, false);
+  EXPECT_FALSE(ofm.OatFileExists());
+}
+
+// Case: Non-existent Dex location.
+// Expect: The dex code is out of date, and trying to update it fails.
+TEST_F(OatFileAssistantTest, NonExsistentDexLocation) {
+  std::string dex_location = GetScratchDir() + "/BadDexLocation.jar";
+
+  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
+
+  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
+  EXPECT_EQ(OatFileAssistant::kOutOfDate, oat_file_assistant.GetStatus());
+  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
+  EXPECT_FALSE(oat_file_assistant.OatFileExists());
+  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
+  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
+  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
+  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
+
+  std::string error_msg;
+  EXPECT_FALSE(oat_file_assistant.MakeUpToDate(&error_msg));
+  EXPECT_FALSE(error_msg.empty());
+}
+
+// Turn an absolute path into a path relative to the current working
+// directory.
+static std::string MakePathRelative(std::string target) {
+  char buf[MAXPATHLEN];
+  std::string cwd = getcwd(buf, MAXPATHLEN);
+
+  // Split the target and cwd paths into components.
+  std::vector<std::string> target_path;
+  std::vector<std::string> cwd_path;
+  Split(target, '/', &target_path);
+  Split(cwd, '/', &cwd_path);
+
+  // Reverse the path components, so we can use pop_back().
+  std::reverse(target_path.begin(), target_path.end());
+  std::reverse(cwd_path.begin(), cwd_path.end());
+
+  // Drop the common prefix of the paths. Because we reversed the path
+  // components, this becomes the common suffix of target_path and cwd_path.
+  while (!target_path.empty() && !cwd_path.empty()
+      && target_path.back() == cwd_path.back()) {
+    target_path.pop_back();
+    cwd_path.pop_back();
+  }
+
+  // For each element of the remaining cwd_path, add '..' to the beginning
+  // of the target path. Because we reversed the path components, we add to
+  // the end of target_path.
+  for (unsigned int i = 0; i < cwd_path.size(); i++) {
+    target_path.push_back("..");
+  }
+
+  // Reverse again to get the right path order, and join to get the result.
+  std::reverse(target_path.begin(), target_path.end());
+  return Join(target_path, '/');
+}
+
+// Case: Non-absolute path to Dex location.
+// Expect: Not sure, but it shouldn't crash.
+TEST_F(OatFileAssistantTest, NonAbsoluteDexLocation) {
+  std::string abs_dex_location = GetScratchDir() + "/NonAbsoluteDexLocation.jar";
+  Copy(GetDexSrc1(), abs_dex_location);
+
+  std::string dex_location = MakePathRelative(abs_dex_location);
+  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
+
+  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
+  EXPECT_EQ(OatFileAssistant::kOutOfDate, oat_file_assistant.GetStatus());
+  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
+  EXPECT_FALSE(oat_file_assistant.OatFileExists());
+  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
+  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
+  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
+  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
+}
+
+// Case: Very short, non-existent Dex location.
+// Expect: Dex code is out of date, and trying to update it fails.
+TEST_F(OatFileAssistantTest, ShortDexLocation) {
+  std::string dex_location = "/xx";
+
+  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
+
+  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
+  EXPECT_EQ(OatFileAssistant::kOutOfDate, oat_file_assistant.GetStatus());
+  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
+  EXPECT_FALSE(oat_file_assistant.OatFileExists());
+  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
+  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
+  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
+  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
+
+  std::string error_msg;
+  EXPECT_FALSE(oat_file_assistant.MakeUpToDate(&error_msg));
+  EXPECT_FALSE(error_msg.empty());
+}
+
+// Case: Non-standard extension for dex file.
+// Expect: The oat file status is kOutOfDate.
+TEST_F(OatFileAssistantTest, LongDexExtension) {
+  std::string dex_location = GetScratchDir() + "/LongDexExtension.jarx";
+  Copy(GetDexSrc1(), dex_location);
+
+  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
+
+  EXPECT_EQ(OatFileAssistant::kOutOfDate, oat_file_assistant.GetStatus());
+
+  EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
+  EXPECT_FALSE(oat_file_assistant.OdexFileExists());
+  EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
+  EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
+  EXPECT_FALSE(oat_file_assistant.OatFileExists());
+  EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
+  EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
+}
+
+// A task to generate a dex location. Used by the RaceToGenerate test.
+class RaceGenerateTask : public Task {
+ public:
+  explicit RaceGenerateTask(const std::string& dex_location, const std::string& oat_location)
+    : dex_location_(dex_location), oat_location_(oat_location),
+      loaded_oat_file_(nullptr)
+  {}
+
+  void Run(Thread* self) {
+    UNUSED(self);
+
+    // Load the dex files, and save a pointer to the loaded oat file, so that
+    // we can verify only one oat file was loaded for the dex location.
+    ClassLinker* linker = Runtime::Current()->GetClassLinker();
+    std::vector<std::unique_ptr<const DexFile>> dex_files;
+    std::vector<std::string> error_msgs;
+    dex_files = linker->OpenDexFilesFromOat(dex_location_.c_str(), oat_location_.c_str(), &error_msgs);
+    CHECK(!dex_files.empty()) << Join(error_msgs, '\n');
+    loaded_oat_file_ = dex_files[0]->GetOatFile();
+  }
+
+  const OatFile* GetLoadedOatFile() const {
+    return loaded_oat_file_;
+  }
+
+ private:
+  std::string dex_location_;
+  std::string oat_location_;
+  const OatFile* loaded_oat_file_;
+};
+
+// Test the case where multiple processes race to generate an oat file.
+// This simulates multiple processes using multiple threads.
+//
+// We want only one Oat file to be loaded when there is a race to load, to
+// avoid using up the virtual memory address space.
+TEST_F(OatFileAssistantTest, RaceToGenerate) {
+  std::string dex_location = GetScratchDir() + "/RaceToGenerate.jar";
+  std::string oat_location = GetISADir() + "/RaceToGenerate.oat";
+
+  // We use the lib core dex file, because it's large, and hopefully should
+  // take a while to generate.
+  Copy(GetLibCoreDexFileName(), dex_location);
+
+  const int kNumThreads = 32;
+  Thread* self = Thread::Current();
+  ThreadPool thread_pool("Oat file assistant test thread pool", kNumThreads);
+  std::vector<std::unique_ptr<RaceGenerateTask>> tasks;
+  for (int i = 0; i < kNumThreads; i++) {
+    std::unique_ptr<RaceGenerateTask> task(new RaceGenerateTask(dex_location, oat_location));
+    thread_pool.AddTask(self, task.get());
+    tasks.push_back(std::move(task));
+  }
+  thread_pool.StartWorkers(self);
+  thread_pool.Wait(self, true, false);
+
+  // Verify every task got the same pointer.
+  const OatFile* expected = tasks[0]->GetLoadedOatFile();
+  for (auto& task : tasks) {
+    EXPECT_EQ(expected, task->GetLoadedOatFile());
+  }
+}
+
+// Case: We have a DEX file and an ODEX file, no OAT file, and dex2oat is
+// disabled.
+// Expect: We should load the odex file non-executable.
+TEST_F(OatFileAssistantNoDex2OatTest, LoadDexOdexNoOat) {
+  std::string dex_location = GetScratchDir() + "/LoadDexOdexNoOat.jar";
+  std::string odex_location = GetISADir() + "/LoadDexOdexNoOat.odex";
+
+  // Create the dex and odex files
+  Copy(GetDexSrc1(), dex_location);
+  GenerateOdexForTest(dex_location, odex_location);
+
+  // Load the oat using an executable oat file assistant.
+  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
+
+  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
+  ASSERT_TRUE(oat_file.get() != nullptr);
+  EXPECT_FALSE(oat_file->IsExecutable());
+  std::vector<std::unique_ptr<const DexFile>> dex_files;
+  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
+  EXPECT_EQ(1u, dex_files.size());
+}
+
+// Case: We have a MultiDEX file and an ODEX file, no OAT file, and dex2oat is
+// disabled.
+// Expect: We should load the odex file non-executable.
+TEST_F(OatFileAssistantNoDex2OatTest, LoadMultiDexOdexNoOat) {
+  std::string dex_location = GetScratchDir() + "/LoadMultiDexOdexNoOat.jar";
+  std::string odex_location = GetISADir() + "/LoadMultiDexOdexNoOat.odex";
+
+  // Create the dex and odex files
+  Copy(GetMultiDexSrc1(), dex_location);
+  GenerateOdexForTest(dex_location, odex_location);
+
+  // Load the oat using an executable oat file assistant.
+  OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
+
+  std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
+  ASSERT_TRUE(oat_file.get() != nullptr);
+  EXPECT_FALSE(oat_file->IsExecutable());
+  std::vector<std::unique_ptr<const DexFile>> dex_files;
+  dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
+  EXPECT_EQ(2u, dex_files.size());
+}
+
+TEST(OatFileAssistantUtilsTest, DexFilenameToOdexFilename) {
+  std::string error_msg;
+  std::string odex_file;
+
+  EXPECT_TRUE(OatFileAssistant::DexFilenameToOdexFilename(
+        "/foo/bar/baz.jar", kArm, &odex_file, &error_msg)) << error_msg;
+  EXPECT_EQ("/foo/bar/arm/baz.odex", odex_file);
+
+  EXPECT_TRUE(OatFileAssistant::DexFilenameToOdexFilename(
+        "/foo/bar/baz.funnyext", kArm, &odex_file, &error_msg)) << error_msg;
+  EXPECT_EQ("/foo/bar/arm/baz.odex", odex_file);
+
+  EXPECT_FALSE(OatFileAssistant::DexFilenameToOdexFilename(
+        "nopath.jar", kArm, &odex_file, &error_msg));
+  EXPECT_FALSE(OatFileAssistant::DexFilenameToOdexFilename(
+        "/foo/bar/baz_noext", kArm, &odex_file, &error_msg));
+}
+
+
+// TODO: More Tests:
+//  * Test class linker falls back to unquickened dex for DexNoOat
+//  * Test class linker falls back to unquickened dex for MultiDexNoOat
+//  * Test multidex files:
+//     - Multidex with only classes2.dex out of date should have status
+//       kOutOfDate
+//  * Test using secondary isa
+//  * Test with profiling info?
+//  * Test for status of oat while oat is being generated (how?)
+//  * Test case where 32 and 64 bit boot class paths differ,
+//      and we ask IsInBootClassPath for a class in exactly one of the 32 or
+//      64 bit boot class paths.
+//  * Test unexpected scenarios (?):
+//    - Dex is stripped, don't have odex.
+//    - Oat file corrupted after status check, before reload unexecutable
+//    because it's unrelocated and no dex2oat
+
+}  // namespace art
diff --git a/runtime/utils.cc b/runtime/utils.cc
index 851eceb..8a23ff7 100644
--- a/runtime/utils.cc
+++ b/runtime/utils.cc
@@ -1508,23 +1508,6 @@
   return filename;
 }
 
-std::string DexFilenameToOdexFilename(const std::string& location, const InstructionSet isa) {
-  // location = /foo/bar/baz.jar
-  // odex_location = /foo/bar/<isa>/baz.odex
-  std::string odex_location(location);
-  InsertIsaDirectory(isa, &odex_location);
-  size_t dot_index = odex_location.rfind('.');
-
-  // The location must have an extension, otherwise it's not clear what we
-  // should return.
-  CHECK_NE(dot_index, std::string::npos) << odex_location;
-  CHECK_EQ(std::string::npos, odex_location.find('/', dot_index)) << odex_location;
-
-  odex_location.resize(dot_index + 1);
-  odex_location += "odex";
-  return odex_location;
-}
-
 bool IsZipMagic(uint32_t magic) {
   return (('P' == ((magic >> 0) & 0xff)) &&
           ('K' == ((magic >> 8) & 0xff)));
diff --git a/runtime/utils.h b/runtime/utils.h
index 9d04d35..d294f4b 100644
--- a/runtime/utils.h
+++ b/runtime/utils.h
@@ -516,12 +516,6 @@
 // Returns the system location for an image
 std::string GetSystemImageFilename(const char* location, InstructionSet isa);
 
-// Returns an .odex file name adjacent to the dex location.
-// For example, for "/foo/bar/baz.jar", return "/foo/bar/<isa>/baz.odex".
-// The dex location must include a directory component and have an extension.
-// Note: does not support multidex location strings.
-std::string DexFilenameToOdexFilename(const std::string& location, InstructionSet isa);
-
 // Check whether the given magic matches a known file type.
 bool IsZipMagic(uint32_t magic);
 bool IsDexMagic(uint32_t magic);
diff --git a/runtime/utils_test.cc b/runtime/utils_test.cc
index 5465762..6b36c19 100644
--- a/runtime/utils_test.cc
+++ b/runtime/utils_test.cc
@@ -371,13 +371,6 @@
                GetSystemImageFilename("/system/framework/boot.art", kArm).c_str());
 }
 
-TEST_F(UtilsTest, DexFilenameToOdexFilename) {
-  EXPECT_STREQ("/foo/bar/arm/baz.odex",
-               DexFilenameToOdexFilename("/foo/bar/baz.jar", kArm).c_str());
-  EXPECT_STREQ("/foo/bar/arm/baz.odex",
-               DexFilenameToOdexFilename("/foo/bar/baz.funnyext", kArm).c_str());
-}
-
 TEST_F(UtilsTest, ExecSuccess) {
   std::vector<std::string> command;
   if (kIsTargetBuild) {
diff --git a/test/MultiDex/Main.java b/test/MultiDex/Main.java
new file mode 100644
index 0000000..659dba9
--- /dev/null
+++ b/test/MultiDex/Main.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+class Main {
+    public static void main(String args[]) {
+      Second second = new Second();
+      System.out.println(second.getSecond());
+    }
+}
diff --git a/test/MultiDex/Second.java b/test/MultiDex/Second.java
new file mode 100644
index 0000000..540aedb
--- /dev/null
+++ b/test/MultiDex/Second.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+class Second {
+  public String getSecond() {
+    return "I Second That.";
+  }
+}
diff --git a/test/MultiDex/main.list b/test/MultiDex/main.list
new file mode 100644
index 0000000..44ba78e
--- /dev/null
+++ b/test/MultiDex/main.list
@@ -0,0 +1 @@
+Main.class
