diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h
index 2dfdc16..1acb625 100644
--- a/runtime/art_method-inl.h
+++ b/runtime/art_method-inl.h
@@ -399,7 +399,11 @@
 
 inline mirror::DexCache* ArtMethod::GetDexCache() {
   DCHECK(!IsProxyMethod());
-  return GetDeclaringClass()->GetDexCache();
+  if (UNLIKELY(IsObsolete())) {
+    return GetObsoleteDexCache();
+  } else {
+    return GetDeclaringClass()->GetDexCache();
+  }
 }
 
 template<ReadBarrierOption kReadBarrierOption>
diff --git a/runtime/art_method.cc b/runtime/art_method.cc
index d1454b6..eeece90 100644
--- a/runtime/art_method.cc
+++ b/runtime/art_method.cc
@@ -35,6 +35,7 @@
 #include "jit/profiling_info.h"
 #include "jni_internal.h"
 #include "mirror/class-inl.h"
+#include "mirror/class_ext.h"
 #include "mirror/executable.h"
 #include "mirror/object_array-inl.h"
 #include "mirror/object-inl.h"
@@ -57,6 +58,28 @@
   return executable->GetArtMethod();
 }
 
+mirror::DexCache* ArtMethod::GetObsoleteDexCache() {
+  DCHECK(!Runtime::Current()->IsAotCompiler()) << PrettyMethod();
+  DCHECK(IsObsolete());
+  ObjPtr<mirror::ClassExt> ext(GetDeclaringClass()->GetExtData());
+  CHECK(!ext.IsNull());
+  ObjPtr<mirror::PointerArray> obsolete_methods(ext->GetObsoleteMethods());
+  CHECK(!obsolete_methods.IsNull());
+  DCHECK(ext->GetObsoleteDexCaches() != nullptr);
+  int32_t len = obsolete_methods->GetLength();
+  DCHECK_EQ(len, ext->GetObsoleteDexCaches()->GetLength());
+  // TODO I think this is fine since images should never have obsolete methods in them.
+  PointerSize pointer_size = kRuntimePointerSize;
+  DCHECK_EQ(kRuntimePointerSize, Runtime::Current()->GetClassLinker()->GetImagePointerSize());
+  for (int32_t i = 0; i < len; i++) {
+    if (this == obsolete_methods->GetElementPtrSize<ArtMethod*>(i, pointer_size)) {
+      return ext->GetObsoleteDexCaches()->Get(i);
+    }
+  }
+  LOG(FATAL) << "This method does not appear in the obsolete map of its class!";
+  UNREACHABLE();
+}
+
 mirror::String* ArtMethod::GetNameAsString(Thread* self) {
   CHECK(!IsProxyMethod());
   StackHandleScope<1> hs(self);
diff --git a/runtime/art_method.h b/runtime/art_method.h
index 0e1d7e7..00fab65 100644
--- a/runtime/art_method.h
+++ b/runtime/art_method.h
@@ -227,6 +227,11 @@
     return (GetAccessFlags() & kAccDefault) != 0;
   }
 
+  bool IsObsolete() {
+    // TODO Should maybe make this IsIntrinsic check not needed
+    return !IsIntrinsic() && (GetAccessFlags() & kAccObsoleteMethod) != 0;
+  }
+
   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
   bool IsNative() {
     return (GetAccessFlags<kReadBarrierOption>() & kAccNative) != 0;
@@ -557,6 +562,7 @@
   mirror::ClassLoader* GetClassLoader() REQUIRES_SHARED(Locks::mutator_lock_);
 
   mirror::DexCache* GetDexCache() REQUIRES_SHARED(Locks::mutator_lock_);
+  mirror::DexCache* GetObsoleteDexCache() REQUIRES_SHARED(Locks::mutator_lock_);
 
   ALWAYS_INLINE ArtMethod* GetInterfaceMethodIfProxy(PointerSize pointer_size)
       REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 9e17be2..7c06ffe 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -614,6 +614,9 @@
 
 struct ClassExtOffsets : public CheckOffsets<mirror::ClassExt> {
   ClassExtOffsets() : CheckOffsets<mirror::ClassExt>(false, "Ldalvik/system/ClassExt;") {
+    addOffset(OFFSETOF_MEMBER(mirror::ClassExt, obsolete_dex_caches_), "obsoleteDexCaches");
+    addOffset(OFFSETOF_MEMBER(mirror::ClassExt, obsolete_methods_), "obsoleteMethods");
+    addOffset(OFFSETOF_MEMBER(mirror::ClassExt, original_dex_cache_), "originalDexCache");
     addOffset(OFFSETOF_MEMBER(mirror::ClassExt, verify_error_), "verifyError");
   }
 };
diff --git a/runtime/handle.h b/runtime/handle.h
index 3db3be2..e4b6d29 100644
--- a/runtime/handle.h
+++ b/runtime/handle.h
@@ -61,6 +61,10 @@
     return down_cast<T*>(reference_->AsMirrorPtr());
   }
 
+  ALWAYS_INLINE bool IsNull() const REQUIRES_SHARED(Locks::mutator_lock_) {
+    return Get() == nullptr;
+  }
+
   ALWAYS_INLINE jobject ToJObject() const REQUIRES_SHARED(Locks::mutator_lock_) {
     if (UNLIKELY(reference_->AsMirrorPtr() == nullptr)) {
       // Special case so that we work with null handles.
diff --git a/runtime/mirror/array-inl.h b/runtime/mirror/array-inl.h
index b11dad8..7d7c1d7 100644
--- a/runtime/mirror/array-inl.h
+++ b/runtime/mirror/array-inl.h
@@ -424,6 +424,29 @@
   }
 }
 
+template<bool kUnchecked>
+void PointerArray::Memcpy(int32_t dst_pos,
+                          ObjPtr<PointerArray> src,
+                          int32_t src_pos,
+                          int32_t count,
+                          PointerSize ptr_size) {
+  DCHECK(!Runtime::Current()->IsActiveTransaction());
+  DCHECK(!src.IsNull());
+  if (ptr_size == PointerSize::k64) {
+    LongArray* l_this = (kUnchecked ? down_cast<LongArray*>(static_cast<Object*>(this))
+                                    : AsLongArray());
+    LongArray* l_src = (kUnchecked ? down_cast<LongArray*>(static_cast<Object*>(src.Ptr()))
+                                   : src->AsLongArray());
+    l_this->Memcpy(dst_pos, l_src, src_pos, count);
+  } else {
+    IntArray* i_this = (kUnchecked ? down_cast<IntArray*>(static_cast<Object*>(this))
+                                   : AsIntArray());
+    IntArray* i_src = (kUnchecked ? down_cast<IntArray*>(static_cast<Object*>(src.Ptr()))
+                                  : src->AsIntArray());
+    i_this->Memcpy(dst_pos, i_src, src_pos, count);
+  }
+}
+
 template<typename T>
 inline void PrimitiveArray<T>::SetArrayClass(ObjPtr<Class> array_class) {
   CHECK(array_class_.IsNull());
diff --git a/runtime/mirror/array.h b/runtime/mirror/array.h
index 994e9b2..19d300e 100644
--- a/runtime/mirror/array.h
+++ b/runtime/mirror/array.h
@@ -208,6 +208,17 @@
             typename Visitor>
   void Fixup(mirror::PointerArray* dest, PointerSize pointer_size, const Visitor& visitor)
       REQUIRES_SHARED(Locks::mutator_lock_);
+
+  // Works like memcpy(), except we guarantee not to allow tearing of array values (ie using smaller
+  // than element size copies). Arguments are assumed to be within the bounds of the array and the
+  // arrays non-null. Cannot be called in an active transaction.
+  template<bool kUnchecked = false>
+  void Memcpy(int32_t dst_pos,
+              ObjPtr<PointerArray> src,
+              int32_t src_pos,
+              int32_t count,
+              PointerSize pointer_size)
+      REQUIRES_SHARED(Locks::mutator_lock_);
 };
 
 }  // namespace mirror
diff --git a/runtime/mirror/class_ext.cc b/runtime/mirror/class_ext.cc
index cc208e4..259bbbe 100644
--- a/runtime/mirror/class_ext.cc
+++ b/runtime/mirror/class_ext.cc
@@ -34,6 +34,71 @@
 
 GcRoot<Class> ClassExt::dalvik_system_ClassExt_;
 
+void ClassExt::SetObsoleteArrays(ObjPtr<PointerArray> methods,
+                                 ObjPtr<ObjectArray<DexCache>> dex_caches) {
+  DCHECK_EQ(GetLockOwnerThreadId(), Thread::Current()->GetThreadId())
+      << "Obsolete arrays are set without synchronization!";
+  CHECK_EQ(methods.IsNull(), dex_caches.IsNull());
+  auto obsolete_dex_cache_off = OFFSET_OF_OBJECT_MEMBER(ClassExt, obsolete_dex_caches_);
+  auto obsolete_methods_off = OFFSET_OF_OBJECT_MEMBER(ClassExt, obsolete_methods_);
+  DCHECK(!Runtime::Current()->IsActiveTransaction());
+  SetFieldObject<false>(obsolete_dex_cache_off, dex_caches.Ptr());
+  SetFieldObject<false>(obsolete_methods_off, methods.Ptr());
+}
+
+// TODO We really need to be careful how we update this. If we ever in the future make it so that
+// these arrays are written into without all threads being suspended we have a race condition!
+bool ClassExt::ExtendObsoleteArrays(Thread* self, uint32_t increase) {
+  DCHECK_EQ(GetLockOwnerThreadId(), Thread::Current()->GetThreadId())
+      << "Obsolete arrays are set without synchronization!";
+  StackHandleScope<5> hs(self);
+  Handle<ClassExt> h_this(hs.NewHandle(this));
+  Handle<PointerArray> old_methods(hs.NewHandle(h_this->GetObsoleteMethods()));
+  Handle<ObjectArray<DexCache>> old_dex_caches(hs.NewHandle(h_this->GetObsoleteDexCaches()));
+  ClassLinker* cl = Runtime::Current()->GetClassLinker();
+  size_t new_len;
+  if (old_methods.Get() == nullptr) {
+    CHECK(old_dex_caches.Get() == nullptr);
+    new_len = increase;
+  } else {
+    CHECK_EQ(old_methods->GetLength(), old_dex_caches->GetLength());
+    new_len = increase + old_methods->GetLength();
+  }
+  Handle<PointerArray> new_methods(hs.NewHandle<PointerArray>(
+      cl->AllocPointerArray(self, new_len)));
+  if (new_methods.IsNull()) {
+    // Fail.
+    self->AssertPendingOOMException();
+    return false;
+  }
+  Handle<ObjectArray<DexCache>> new_dex_caches(hs.NewHandle<ObjectArray<DexCache>>(
+      ObjectArray<DexCache>::Alloc(self,
+                                   cl->FindClass(self,
+                                                 "[Ljava/lang/DexCache;",
+                                                 ScopedNullHandle<ClassLoader>()),
+                                   new_len)));
+  if (new_dex_caches.IsNull()) {
+    // Fail.
+    self->AssertPendingOOMException();
+    return false;
+  }
+
+  if (!old_methods.IsNull()) {
+    // Copy the old contents.
+    new_methods->Memcpy(0,
+                        old_methods.Get(),
+                        0,
+                        old_methods->GetLength(),
+                        cl->GetImagePointerSize());
+    new_dex_caches->AsObjectArray<Object>()->AssignableCheckingMemcpy<false>(
+        0, old_dex_caches->AsObjectArray<Object>(), 0, old_dex_caches->GetLength(), false);
+  }
+  // Set the fields.
+  h_this->SetObsoleteArrays(new_methods.Get(), new_dex_caches.Get());
+
+  return true;
+}
+
 ClassExt* ClassExt::Alloc(Thread* self) {
   DCHECK(dalvik_system_ClassExt_.Read() != nullptr);
   return down_cast<ClassExt*>(dalvik_system_ClassExt_.Read()->AllocObject(self).Ptr());
diff --git a/runtime/mirror/class_ext.h b/runtime/mirror/class_ext.h
index 35eaae1..9104631 100644
--- a/runtime/mirror/class_ext.h
+++ b/runtime/mirror/class_ext.h
@@ -19,8 +19,11 @@
 
 #include "class-inl.h"
 
+#include "array.h"
+#include "dex_cache.h"
 #include "gc_root.h"
 #include "object.h"
+#include "object_array.h"
 #include "object_callbacks.h"
 #include "string.h"
 
@@ -49,6 +52,22 @@
     return GetFieldObject<ClassExt>(OFFSET_OF_OBJECT_MEMBER(ClassExt, verify_error_));
   }
 
+  ObjectArray<DexCache>* GetObsoleteDexCaches() REQUIRES_SHARED(Locks::mutator_lock_) {
+    return GetFieldObject<ObjectArray<DexCache>>(
+        OFFSET_OF_OBJECT_MEMBER(ClassExt, obsolete_dex_caches_));
+  }
+
+  PointerArray* GetObsoleteMethods() REQUIRES_SHARED(Locks::mutator_lock_) {
+    return GetFieldObject<PointerArray>(OFFSET_OF_OBJECT_MEMBER(ClassExt, obsolete_methods_));
+  }
+
+  void SetObsoleteArrays(ObjPtr<PointerArray> methods, ObjPtr<ObjectArray<DexCache>> dex_caches)
+      REQUIRES_SHARED(Locks::mutator_lock_);
+
+  // Extend the obsolete arrays by the given amount.
+  bool ExtendObsoleteArrays(Thread* self, uint32_t increase)
+      REQUIRES_SHARED(Locks::mutator_lock_);
+
   static void SetClass(ObjPtr<Class> dalvik_system_ClassExt);
   static void ResetClass();
   static void VisitRoots(RootVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_);
@@ -57,6 +76,13 @@
 
  private:
   // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
+  HeapReference<ObjectArray<DexCache>> obsolete_dex_caches_;
+
+  HeapReference<PointerArray> obsolete_methods_;
+
+  HeapReference<DexCache> original_dex_cache_;
+
+  // The saved verification error of this class.
   HeapReference<Object> verify_error_;
 
   static GcRoot<Class> dalvik_system_ClassExt_;
diff --git a/runtime/modifiers.h b/runtime/modifiers.h
index dd32df6..a1110d9 100644
--- a/runtime/modifiers.h
+++ b/runtime/modifiers.h
@@ -67,6 +67,10 @@
 
 // Set by the verifier for a method that could not be verified to follow structured locking.
 static constexpr uint32_t kAccMustCountLocks =        0x02000000;  // method (runtime)
+// Set to indicate that the ArtMethod is obsolete and has a different DexCache from it's declaring
+// class.
+// TODO Might want to re-arrange some of these so that we can have obsolete + intrinsic methods.
+static constexpr uint32_t kAccObsoleteMethod =        0x04000000;  // method (runtime)
 static constexpr uint32_t kAccIntrinsic  =            0x80000000;  // method (runtime)
 
 // Special runtime-only flags.
diff --git a/runtime/object_lock.cc b/runtime/object_lock.cc
index b8754a4..39ab52f 100644
--- a/runtime/object_lock.cc
+++ b/runtime/object_lock.cc
@@ -17,6 +17,7 @@
 #include "object_lock.h"
 
 #include "mirror/object-inl.h"
+#include "mirror/class_ext.h"
 #include "monitor.h"
 
 namespace art {
@@ -61,6 +62,7 @@
 }
 
 template class ObjectLock<mirror::Class>;
+template class ObjectLock<mirror::ClassExt>;
 template class ObjectLock<mirror::Object>;
 template class ObjectTryLock<mirror::Class>;
 template class ObjectTryLock<mirror::Object>;
diff --git a/runtime/openjdkjvmti/Android.bp b/runtime/openjdkjvmti/Android.bp
index b323aef..0f9fbb2 100644
--- a/runtime/openjdkjvmti/Android.bp
+++ b/runtime/openjdkjvmti/Android.bp
@@ -24,6 +24,7 @@
            "ti_heap.cc",
            "ti_method.cc",
            "ti_stack.cc",
+           "ti_redefine.cc",
            "transform.cc"],
     include_dirs: ["art/runtime"],
     shared_libs: [
diff --git a/runtime/openjdkjvmti/OpenjdkJvmTi.cc b/runtime/openjdkjvmti/OpenjdkJvmTi.cc
index 6480843..d1c2293 100644
--- a/runtime/openjdkjvmti/OpenjdkJvmTi.cc
+++ b/runtime/openjdkjvmti/OpenjdkJvmTi.cc
@@ -40,15 +40,16 @@
 #include "base/mutex.h"
 #include "events-inl.h"
 #include "jni_env_ext-inl.h"
-#include "object_tagging.h"
 #include "obj_ptr-inl.h"
+#include "object_tagging.h"
 #include "runtime.h"
 #include "scoped_thread_state_change-inl.h"
-#include "thread_list.h"
 #include "thread-inl.h"
+#include "thread_list.h"
 #include "ti_class.h"
 #include "ti_heap.h"
 #include "ti_method.h"
+#include "ti_redefine.h"
 #include "ti_stack.h"
 #include "transform.h"
 
@@ -1148,6 +1149,8 @@
     if (!IsValidEnv(env)) {
       return ERR(INVALID_ENVIRONMENT);
     }
+    jvmtiError res = OK;
+    std::string error;
     for (jclass klass : classes) {
       JNIEnv* jni_env = nullptr;
       jobject loader = nullptr;
@@ -1183,11 +1186,22 @@
            /*out*/&new_dex_data);
       // Check if anything actually changed.
       if ((new_data_len != 0 || new_dex_data != nullptr) && new_dex_data != dex_data) {
-        MoveTransformedFileIntoRuntime(klass, std::move(location), new_data_len, new_dex_data);
+        res = Redefiner::RedefineClass(env,
+                                       art::Runtime::Current(),
+                                       art::Thread::Current(),
+                                       klass,
+                                       location,
+                                       new_data_len,
+                                       new_dex_data,
+                                       &error);
         env->Deallocate(new_dex_data);
       }
       // Deallocate the old dex data.
       env->Deallocate(dex_data);
+      if (res != OK) {
+        LOG(ERROR) << "FAILURE TO REDEFINE " << error;
+        return res;
+      }
     }
     return OK;
   }
diff --git a/runtime/openjdkjvmti/ti_redefine.cc b/runtime/openjdkjvmti/ti_redefine.cc
new file mode 100644
index 0000000..69bd887
--- /dev/null
+++ b/runtime/openjdkjvmti/ti_redefine.cc
@@ -0,0 +1,507 @@
+/* Copyright (C) 2016 The Android Open Source Project
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This file implements interfaces from the file jvmti.h. This implementation
+ * is licensed under the same terms as the file jvmti.h.  The
+ * copyright and license information for the file jvmti.h follows.
+ *
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "ti_redefine.h"
+
+#include <limits>
+
+#include "art_jvmti.h"
+#include "base/logging.h"
+#include "events-inl.h"
+#include "gc/allocation_listener.h"
+#include "instrumentation.h"
+#include "jni_env_ext-inl.h"
+#include "jvmti_allocator.h"
+#include "mirror/class.h"
+#include "mirror/class_ext.h"
+#include "mirror/object.h"
+#include "object_lock.h"
+#include "runtime.h"
+#include "ScopedLocalRef.h"
+
+namespace openjdkjvmti {
+
+// Moves dex data to an anonymous, read-only mmap'd region.
+std::unique_ptr<art::MemMap> Redefiner::MoveDataToMemMap(const std::string& original_location,
+                                                         jint data_len,
+                                                         unsigned char* dex_data,
+                                                         std::string* error_msg) {
+  std::unique_ptr<art::MemMap> map(art::MemMap::MapAnonymous(
+      art::StringPrintf("%s-transformed", original_location.c_str()).c_str(),
+      nullptr,
+      data_len,
+      PROT_READ|PROT_WRITE,
+      /*low_4gb*/false,
+      /*reuse*/false,
+      error_msg));
+  if (map == nullptr) {
+    return map;
+  }
+  memcpy(map->Begin(), dex_data, data_len);
+  // Make the dex files mmap read only.
+  map->Protect(PROT_READ);
+  return map;
+}
+
+jvmtiError Redefiner::RedefineClass(ArtJvmTiEnv* env,
+                                    art::Runtime* runtime,
+                                    art::Thread* self,
+                                    jclass klass,
+                                    const std::string& original_dex_location,
+                                    jint data_len,
+                                    unsigned char* dex_data,
+                                    std::string* error_msg) {
+  std::unique_ptr<art::MemMap> map(MoveDataToMemMap(original_dex_location,
+                                                    data_len,
+                                                    dex_data,
+                                                    error_msg));
+  std::ostringstream os;
+  char* generic_ptr_unused = nullptr;
+  char* signature_ptr = nullptr;
+  if (env->GetClassSignature(klass, &signature_ptr, &generic_ptr_unused) != OK) {
+    signature_ptr = const_cast<char*>("<UNKNOWN CLASS>");
+  }
+  if (map.get() == nullptr) {
+    os << "Failed to create anonymous mmap for modified dex file of class " << signature_ptr
+       << "in dex file " << original_dex_location << " because: " << *error_msg;
+    *error_msg = os.str();
+    return ERR(OUT_OF_MEMORY);
+  }
+  if (map->Size() < sizeof(art::DexFile::Header)) {
+    *error_msg = "Could not read dex file header because dex_data was too short";
+    return ERR(INVALID_CLASS_FORMAT);
+  }
+  uint32_t checksum = reinterpret_cast<const art::DexFile::Header*>(map->Begin())->checksum_;
+  std::unique_ptr<const art::DexFile> dex_file(art::DexFile::Open(map->GetName(),
+                                                                  checksum,
+                                                                  std::move(map),
+                                                                  /*verify*/true,
+                                                                  /*verify_checksum*/true,
+                                                                  error_msg));
+  if (dex_file.get() == nullptr) {
+    os << "Unable to load modified dex file for " << signature_ptr << ": " << *error_msg;
+    *error_msg = os.str();
+    return ERR(INVALID_CLASS_FORMAT);
+  }
+  // Get shared mutator lock.
+  art::ScopedObjectAccess soa(self);
+  art::StackHandleScope<1> hs(self);
+  Redefiner r(runtime, self, klass, signature_ptr, dex_file, error_msg);
+  // Lock around this class to avoid races.
+  art::ObjectLock<art::mirror::Class> lock(self, hs.NewHandle(r.GetMirrorClass()));
+  return r.Run();
+}
+
+// TODO *MAJOR* This should return the actual source java.lang.DexFile object for the klass.
+// TODO Make mirror of DexFile and associated types to make this less hellish.
+// TODO Make mirror of BaseDexClassLoader and associated types to make this less hellish.
+art::mirror::Object* Redefiner::FindSourceDexFileObject(
+    art::Handle<art::mirror::ClassLoader> loader) {
+  const char* dex_path_list_element_array_name = "[Ldalvik/system/DexPathList$Element;";
+  const char* dex_path_list_element_name = "Ldalvik/system/DexPathList$Element;";
+  const char* dex_file_name = "Ldalvik/system/DexFile;";
+  const char* dex_path_list_name = "Ldalvik/system/DexPathList;";
+  const char* dex_class_loader_name = "Ldalvik/system/BaseDexClassLoader;";
+
+  CHECK(!self_->IsExceptionPending());
+  art::StackHandleScope<11> hs(self_);
+  art::ClassLinker* class_linker = runtime_->GetClassLinker();
+
+  art::Handle<art::mirror::ClassLoader> null_loader(hs.NewHandle<art::mirror::ClassLoader>(
+      nullptr));
+  art::Handle<art::mirror::Class> base_dex_loader_class(hs.NewHandle(class_linker->FindClass(
+      self_, dex_class_loader_name, null_loader)));
+
+  // Get all the ArtFields so we can look in the BaseDexClassLoader
+  art::ArtField* path_list_field = base_dex_loader_class->FindDeclaredInstanceField(
+      "pathList", dex_path_list_name);
+  CHECK(path_list_field != nullptr);
+
+  art::ArtField* dex_path_list_element_field =
+      class_linker->FindClass(self_, dex_path_list_name, null_loader)
+        ->FindDeclaredInstanceField("dexElements", dex_path_list_element_array_name);
+  CHECK(dex_path_list_element_field != nullptr);
+
+  art::ArtField* element_dex_file_field =
+      class_linker->FindClass(self_, dex_path_list_element_name, null_loader)
+        ->FindDeclaredInstanceField("dexFile", dex_file_name);
+  CHECK(element_dex_file_field != nullptr);
+
+  // Check if loader is a BaseDexClassLoader
+  art::Handle<art::mirror::Class> loader_class(hs.NewHandle(loader->GetClass()));
+  if (!loader_class->IsSubClass(base_dex_loader_class.Get())) {
+    LOG(ERROR) << "The classloader is not a BaseDexClassLoader which is currently the only "
+               << "supported class loader type!";
+    return nullptr;
+  }
+  // Start navigating the fields of the loader (now known to be a BaseDexClassLoader derivative)
+  art::Handle<art::mirror::Object> path_list(
+      hs.NewHandle(path_list_field->GetObject(loader.Get())));
+  CHECK(path_list.Get() != nullptr);
+  CHECK(!self_->IsExceptionPending());
+  art::Handle<art::mirror::ObjectArray<art::mirror::Object>> dex_elements_list(hs.NewHandle(
+      dex_path_list_element_field->GetObject(path_list.Get())->
+      AsObjectArray<art::mirror::Object>()));
+  CHECK(!self_->IsExceptionPending());
+  CHECK(dex_elements_list.Get() != nullptr);
+  size_t num_elements = dex_elements_list->GetLength();
+  art::MutableHandle<art::mirror::Object> current_element(
+      hs.NewHandle<art::mirror::Object>(nullptr));
+  art::MutableHandle<art::mirror::Object> first_dex_file(
+      hs.NewHandle<art::mirror::Object>(nullptr));
+  // Iterate over the DexPathList$Element to find the right one
+  // TODO Or not ATM just return the first one.
+  for (size_t i = 0; i < num_elements; i++) {
+    current_element.Assign(dex_elements_list->Get(i));
+    CHECK(current_element.Get() != nullptr);
+    CHECK(!self_->IsExceptionPending());
+    CHECK(dex_elements_list.Get() != nullptr);
+    CHECK_EQ(current_element->GetClass(), class_linker->FindClass(self_,
+                                                                  dex_path_list_element_name,
+                                                                  null_loader));
+    // TODO It would be cleaner to put the art::DexFile into the dalvik.system.DexFile the class
+    // comes from but it is more annoying because we would need to find this class. It is not
+    // necessary for proper function since we just need to be in front of the classes old dex file
+    // in the path.
+    first_dex_file.Assign(element_dex_file_field->GetObject(current_element.Get()));
+    if (first_dex_file.Get() != nullptr) {
+      return first_dex_file.Get();
+    }
+  }
+  return nullptr;
+}
+
+art::mirror::Class* Redefiner::GetMirrorClass() {
+  return self_->DecodeJObject(klass_)->AsClass();
+}
+
+art::mirror::ClassLoader* Redefiner::GetClassLoader() {
+  return GetMirrorClass()->GetClassLoader();
+}
+
+art::mirror::DexCache* Redefiner::CreateNewDexCache(art::Handle<art::mirror::ClassLoader> loader) {
+  return runtime_->GetClassLinker()->RegisterDexFile(*dex_file_, loader.Get());
+}
+
+// TODO Really wishing I had that mirror of java.lang.DexFile now.
+art::mirror::LongArray* Redefiner::AllocateDexFileCookie(
+    art::Handle<art::mirror::Object> java_dex_file_obj) {
+  art::StackHandleScope<2> hs(self_);
+  // mCookie is nulled out if the DexFile has been closed but mInternalCookie sticks around until
+  // the object is finalized. Since they always point to the same array if mCookie is not null we
+  // just use the mInternalCookie field. We will update one or both of these fields later.
+  // TODO Should I get the class from the classloader or directly?
+  art::ArtField* internal_cookie_field = java_dex_file_obj->GetClass()->FindDeclaredInstanceField(
+      "mInternalCookie", "Ljava/lang/Object;");
+  // TODO Add check that mCookie is either null or same as mInternalCookie
+  CHECK(internal_cookie_field != nullptr);
+  art::Handle<art::mirror::LongArray> cookie(
+      hs.NewHandle(internal_cookie_field->GetObject(java_dex_file_obj.Get())->AsLongArray()));
+  // TODO Maybe make these non-fatal.
+  CHECK(cookie.Get() != nullptr);
+  CHECK_GE(cookie->GetLength(), 1);
+  art::Handle<art::mirror::LongArray> new_cookie(
+      hs.NewHandle(art::mirror::LongArray::Alloc(self_, cookie->GetLength() + 1)));
+  if (new_cookie.Get() == nullptr) {
+    self_->AssertPendingOOMException();
+    return nullptr;
+  }
+  // Copy the oat-dex field at the start.
+  // TODO Should I clear this field?
+  // TODO This is a really crappy thing here with the first element being different.
+  new_cookie->SetWithoutChecks<false>(0, cookie->GetWithoutChecks(0));
+  new_cookie->SetWithoutChecks<false>(
+      1, static_cast<int64_t>(reinterpret_cast<intptr_t>(dex_file_.get())));
+  new_cookie->Memcpy(2, cookie.Get(), 1, cookie->GetLength() - 1);
+  return new_cookie.Get();
+}
+
+void Redefiner::RecordFailure(jvmtiError result, const std::string& error_msg) {
+  *error_msg_ = art::StringPrintf("Unable to perform redefinition of '%s': %s",
+                                  class_sig_,
+                                  error_msg.c_str());
+  result_ = result;
+}
+
+bool Redefiner::FinishRemainingAllocations(
+    /*out*/art::MutableHandle<art::mirror::ClassLoader>* source_class_loader,
+    /*out*/art::MutableHandle<art::mirror::Object>* java_dex_file_obj,
+    /*out*/art::MutableHandle<art::mirror::LongArray>* new_dex_file_cookie,
+    /*out*/art::MutableHandle<art::mirror::DexCache>* new_dex_cache) {
+  art::StackHandleScope<4> hs(self_);
+  // This shouldn't allocate
+  art::Handle<art::mirror::ClassLoader> loader(hs.NewHandle(GetClassLoader()));
+  if (loader.Get() == nullptr) {
+    // TODO Better error msg.
+    RecordFailure(ERR(INTERNAL), "Unable to find class loader!");
+    return false;
+  }
+  art::Handle<art::mirror::Object> dex_file_obj(hs.NewHandle(FindSourceDexFileObject(loader)));
+  if (dex_file_obj.Get() == nullptr) {
+    // TODO Better error msg.
+    RecordFailure(ERR(INTERNAL), "Unable to find class loader!");
+    return false;
+  }
+  art::Handle<art::mirror::LongArray> new_cookie(hs.NewHandle(AllocateDexFileCookie(dex_file_obj)));
+  if (new_cookie.Get() == nullptr) {
+    self_->AssertPendingOOMException();
+    self_->ClearException();
+    RecordFailure(ERR(OUT_OF_MEMORY), "Unable to allocate dex file array for class loader");
+    return false;
+  }
+  art::Handle<art::mirror::DexCache> dex_cache(hs.NewHandle(CreateNewDexCache(loader)));
+  if (dex_cache.Get() == nullptr) {
+    self_->AssertPendingOOMException();
+    self_->ClearException();
+    RecordFailure(ERR(OUT_OF_MEMORY), "Unable to allocate DexCache");
+    return false;
+  }
+  source_class_loader->Assign(loader.Get());
+  java_dex_file_obj->Assign(dex_file_obj.Get());
+  new_dex_file_cookie->Assign(new_cookie.Get());
+  new_dex_cache->Assign(dex_cache.Get());
+  return true;
+}
+
+jvmtiError Redefiner::Run() {
+  art::StackHandleScope<5> hs(self_);
+  // TODO We might want to have a global lock (or one based on the class being redefined at least)
+  // in order to make cleanup easier. Not a huge deal though.
+  //
+  // First we just allocate the ClassExt and its fields that we need. These can be updated
+  // atomically without any issues (since we allocate the map arrays as empty) so we don't bother
+  // doing a try loop. The other allocations we need to ensure that nothing has changed in the time
+  // between allocating them and pausing all threads before we can update them so we need to do a
+  // try loop.
+  if (!EnsureRedefinitionIsValid() || !EnsureClassAllocationsFinished()) {
+    return result_;
+  }
+  art::MutableHandle<art::mirror::ClassLoader> source_class_loader(
+      hs.NewHandle<art::mirror::ClassLoader>(nullptr));
+  art::MutableHandle<art::mirror::Object> java_dex_file(
+      hs.NewHandle<art::mirror::Object>(nullptr));
+  art::MutableHandle<art::mirror::LongArray> new_dex_file_cookie(
+      hs.NewHandle<art::mirror::LongArray>(nullptr));
+  art::MutableHandle<art::mirror::DexCache> new_dex_cache(
+      hs.NewHandle<art::mirror::DexCache>(nullptr));
+  if (!FinishRemainingAllocations(&source_class_loader,
+                                  &java_dex_file,
+                                  &new_dex_file_cookie,
+                                  &new_dex_cache)) {
+    // TODO Null out the ClassExt fields we allocated (if possible, might be racing with another
+    // redefineclass call which made it even bigger. Leak shouldn't be huge (2x array of size
+    // declared_methods_.length) but would be good to get rid of.
+    // new_dex_file_cookie & new_dex_cache should be cleaned up by the GC.
+    return result_;
+  }
+  // Get the mirror class now that we aren't allocating anymore.
+  art::Handle<art::mirror::Class> art_class(hs.NewHandle(GetMirrorClass()));
+  // Enable assertion that this thread isn't interrupted during this installation.
+  // After this we will need to do real cleanup in case of failure. Prior to this we could simply
+  // return and would let everything get cleaned up or harmlessly leaked.
+  // Do transition to final suspension
+  // TODO We might want to give this its own suspended state!
+  // TODO This isn't right. We need to change state without any chance of suspend ideally!
+  self_->TransitionFromRunnableToSuspended(art::ThreadState::kNative);
+  runtime_->GetThreadList()->SuspendAll(
+      "Final installation of redefined Class!", /*long_suspend*/true);
+  // TODO Might want to move this into a different type.
+  // Now we reach the part where we must do active cleanup if something fails.
+  // TODO We should really Retry if this fails instead of simply aborting.
+  // Set the new DexFileCookie returns the original so we can fix it back up if redefinition fails
+  art::ObjPtr<art::mirror::LongArray> original_dex_file_cookie(nullptr);
+  if (!UpdateJavaDexFile(java_dex_file.Get(),
+                         new_dex_file_cookie.Get(),
+                         &original_dex_file_cookie)) {
+    // Release suspendAll
+    runtime_->GetThreadList()->ResumeAll();
+    // Get back shared mutator lock as expected for return.
+    self_->TransitionFromSuspendedToRunnable();
+    return result_;
+  }
+  if (!UpdateClass(art_class.Get(), new_dex_cache.Get())) {
+    // TODO Should have some form of scope to do this.
+    RestoreJavaDexFile(java_dex_file.Get(), original_dex_file_cookie);
+    // Release suspendAll
+    runtime_->GetThreadList()->ResumeAll();
+    // Get back shared mutator lock as expected for return.
+    self_->TransitionFromSuspendedToRunnable();
+    return result_;
+  }
+  // Update the ClassObjects Keep the old DexCache (and other stuff) around so we can restore
+  // functions/fields.
+  // Verify the new Class.
+  //   Failure then undo updates to class
+  // Do stack walks and allocate obsolete methods
+  // Shrink the obsolete method maps if possible?
+  // TODO find appropriate class loader. Allocate new dex files array. Pause all java treads.
+  // Replace dex files array. Do stack scan + allocate obsoletes. Remove array if possible.
+  // TODO We might want to ensure that all threads are stopped for this!
+  // AddDexToClassPath();
+  // TODO
+  // Release suspendAll
+  // TODO Put this into a scoped thing.
+  runtime_->GetThreadList()->ResumeAll();
+  // Get back shared mutator lock as expected for return.
+  self_->TransitionFromSuspendedToRunnable();
+  // TODO Do this at a more reasonable place.
+  dex_file_.release();
+  return OK;
+}
+
+void Redefiner::RestoreJavaDexFile(art::ObjPtr<art::mirror::Object> java_dex_file,
+                                   art::ObjPtr<art::mirror::LongArray> orig_cookie) {
+  art::ArtField* internal_cookie_field = java_dex_file->GetClass()->FindDeclaredInstanceField(
+      "mInternalCookie", "Ljava/lang/Object;");
+  art::ArtField* cookie_field = java_dex_file->GetClass()->FindDeclaredInstanceField(
+      "mCookie", "Ljava/lang/Object;");
+  art::ObjPtr<art::mirror::LongArray> new_cookie(
+      cookie_field->GetObject(java_dex_file)->AsLongArray());
+  internal_cookie_field->SetObject<false>(java_dex_file, orig_cookie);
+  if (!new_cookie.IsNull()) {
+    cookie_field->SetObject<false>(java_dex_file, orig_cookie);
+  }
+}
+
+// Performs updates to class that will allow us to verify it.
+bool Redefiner::UpdateClass(art::ObjPtr<art::mirror::Class> mclass,
+                            art::ObjPtr<art::mirror::DexCache> new_dex_cache) {
+  art::ClassLinker* linker = runtime_->GetClassLinker();
+  art::PointerSize image_pointer_size = linker->GetImagePointerSize();
+  const art::DexFile::ClassDef* class_def = art::OatFile::OatDexFile::FindClassDef(
+      *dex_file_, class_sig_, art::ComputeModifiedUtf8Hash(class_sig_));
+  if (class_def == nullptr) {
+    RecordFailure(ERR(INVALID_CLASS_FORMAT), "Unable to find ClassDef!");
+    return false;
+  }
+  const art::DexFile::TypeId& declaring_class_id = dex_file_->GetTypeId(class_def->class_idx_);
+  const art::DexFile& old_dex_file = mclass->GetDexFile();
+  for (art::ArtMethod& method : mclass->GetMethods(image_pointer_size)) {
+    const art::DexFile::StringId* new_name_id = dex_file_->FindStringId(method.GetName());
+    art::dex::TypeIndex method_return_idx =
+        dex_file_->GetIndexForTypeId(*dex_file_->FindTypeId(method.GetReturnTypeDescriptor()));
+    const auto* old_type_list = method.GetParameterTypeList();
+    std::vector<art::dex::TypeIndex> new_type_list;
+    for (uint32_t i = 0; old_type_list != nullptr && i < old_type_list->Size(); i++) {
+      new_type_list.push_back(
+          dex_file_->GetIndexForTypeId(
+              *dex_file_->FindTypeId(
+                  old_dex_file.GetTypeDescriptor(
+                      old_dex_file.GetTypeId(
+                          old_type_list->GetTypeItem(i).type_idx_)))));
+    }
+    const art::DexFile::ProtoId* proto_id = dex_file_->FindProtoId(method_return_idx,
+                                                                   new_type_list);
+    CHECK(proto_id != nullptr || old_type_list == nullptr);
+    // TODO Return false, cleanup.
+    const art::DexFile::MethodId* method_id = dex_file_->FindMethodId(declaring_class_id,
+                                                                      *new_name_id,
+                                                                      *proto_id);
+    CHECK(method_id != nullptr);
+    // TODO Return false, cleanup.
+    uint32_t dex_method_idx = dex_file_->GetIndexForMethodId(*method_id);
+    method.SetDexMethodIndex(dex_method_idx);
+    linker->SetEntryPointsToInterpreter(&method);
+    method.SetCodeItemOffset(dex_file_->FindCodeItemOffset(*class_def, dex_method_idx));
+    method.SetDexCacheResolvedMethods(new_dex_cache->GetResolvedMethods(), image_pointer_size);
+    method.SetDexCacheResolvedTypes(new_dex_cache->GetResolvedTypes(), image_pointer_size);
+  }
+  // Update the class fields.
+  // Need to update class last since the ArtMethod gets its DexFile from the class (which is needed
+  // to call GetReturnTypeDescriptor and GetParameterTypeList above).
+  mclass->SetDexCache(new_dex_cache.Ptr());
+  mclass->SetDexCacheStrings(new_dex_cache->GetStrings());
+  mclass->SetDexClassDefIndex(dex_file_->GetIndexForClassDef(*class_def));
+  mclass->SetDexTypeIndex(dex_file_->GetIndexForTypeId(*dex_file_->FindTypeId(class_sig_)));
+  return true;
+}
+
+bool Redefiner::UpdateJavaDexFile(art::ObjPtr<art::mirror::Object> java_dex_file,
+                                  art::ObjPtr<art::mirror::LongArray> new_cookie,
+                                  /*out*/art::ObjPtr<art::mirror::LongArray>* original_cookie) {
+  art::ArtField* internal_cookie_field = java_dex_file->GetClass()->FindDeclaredInstanceField(
+      "mInternalCookie", "Ljava/lang/Object;");
+  art::ArtField* cookie_field = java_dex_file->GetClass()->FindDeclaredInstanceField(
+      "mCookie", "Ljava/lang/Object;");
+  CHECK(internal_cookie_field != nullptr);
+  art::ObjPtr<art::mirror::LongArray> orig_internal_cookie(
+      internal_cookie_field->GetObject(java_dex_file)->AsLongArray());
+  art::ObjPtr<art::mirror::LongArray> orig_cookie(
+      cookie_field->GetObject(java_dex_file)->AsLongArray());
+  internal_cookie_field->SetObject<false>(java_dex_file, new_cookie);
+  *original_cookie = orig_internal_cookie;
+  if (!orig_cookie.IsNull()) {
+    cookie_field->SetObject<false>(java_dex_file, new_cookie);
+  }
+  return true;
+}
+
+// This function does all (java) allocations we need to do for the Class being redefined.
+// TODO Change this name maybe?
+bool Redefiner::EnsureClassAllocationsFinished() {
+  art::StackHandleScope<2> hs(self_);
+  art::Handle<art::mirror::Class> klass(hs.NewHandle(self_->DecodeJObject(klass_)->AsClass()));
+  if (klass.Get() == nullptr) {
+    RecordFailure(ERR(INVALID_CLASS), "Unable to decode class argument!");
+    return false;
+  }
+  // Allocate the classExt
+  art::Handle<art::mirror::ClassExt> ext(hs.NewHandle(klass->EnsureExtDataPresent(self_)));
+  if (ext.Get() == nullptr) {
+    // No memory. Clear exception (it's not useful) and return error.
+    // TODO This doesn't need to be fatal. We could just not support obsolete methods after hitting
+    // this case.
+    self_->AssertPendingOOMException();
+    self_->ClearException();
+    RecordFailure(ERR(OUT_OF_MEMORY), "Could not allocate ClassExt");
+    return false;
+  }
+  // Allocate the 2 arrays that make up the obsolete methods map.  Since the contents of the arrays
+  // are only modified when all threads (other than the modifying one) are suspended we don't need
+  // to worry about missing the unsyncronized writes to the array. We do synchronize when setting it
+  // however, since that can happen at any time.
+  // TODO Clear these after we walk the stacks in order to free them in the (likely?) event there
+  // are no obsolete methods.
+  {
+    art::ObjectLock<art::mirror::ClassExt> lock(self_, ext);
+    if (!ext->ExtendObsoleteArrays(
+          self_, klass->GetDeclaredMethodsSlice(art::kRuntimePointerSize).size())) {
+      // OOM. Clear exception and return error.
+      self_->AssertPendingOOMException();
+      self_->ClearException();
+      RecordFailure(ERR(OUT_OF_MEMORY), "Unable to allocate/extend obsolete methods map");
+      return false;
+    }
+  }
+  return true;
+}
+
+}  // namespace openjdkjvmti
diff --git a/runtime/openjdkjvmti/ti_redefine.h b/runtime/openjdkjvmti/ti_redefine.h
new file mode 100644
index 0000000..f3a5834
--- /dev/null
+++ b/runtime/openjdkjvmti/ti_redefine.h
@@ -0,0 +1,168 @@
+/* Copyright (C) 2016 The Android Open Source Project
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This file implements interfaces from the file jvmti.h. This implementation
+ * is licensed under the same terms as the file jvmti.h.  The
+ * copyright and license information for the file jvmti.h follows.
+ *
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef ART_RUNTIME_OPENJDKJVMTI_TI_REDEFINE_H_
+#define ART_RUNTIME_OPENJDKJVMTI_TI_REDEFINE_H_
+
+#include <string>
+
+#include <jni.h>
+
+#include "art_jvmti.h"
+#include "art_method.h"
+#include "class_linker.h"
+#include "dex_file.h"
+#include "gc_root-inl.h"
+#include "globals.h"
+#include "jni_env_ext-inl.h"
+#include "jvmti.h"
+#include "linear_alloc.h"
+#include "mem_map.h"
+#include "mirror/array-inl.h"
+#include "mirror/array.h"
+#include "mirror/class-inl.h"
+#include "mirror/class.h"
+#include "mirror/class_loader-inl.h"
+#include "mirror/string-inl.h"
+#include "oat_file.h"
+#include "obj_ptr.h"
+#include "scoped_thread_state_change-inl.h"
+#include "stack.h"
+#include "thread_list.h"
+#include "transform.h"
+#include "utf.h"
+#include "utils/dex_cache_arrays_layout-inl.h"
+
+namespace openjdkjvmti {
+
+// Class that can redefine a single class's methods.
+class Redefiner {
+ public:
+  // Redefine the given class with the given dex data. Note this function does not take ownership of
+  // the dex_data pointer. It is not used after this call however and may be freed if desired.
+  // The caller is responsible for freeing it. The runtime makes it's own copy of the data.
+  static jvmtiError RedefineClass(ArtJvmTiEnv* env,
+                                  art::Runtime* runtime,
+                                  art::Thread* self,
+                                  jclass klass,
+                                  const std::string& original_dex_location,
+                                  jint data_len,
+                                  unsigned char* dex_data,
+                                  std::string* error_msg);
+
+ private:
+  jvmtiError result_;
+  art::Runtime* runtime_;
+  art::Thread* self_;
+  // Kept as a jclass since we have weird run-state changes that make keeping it around as a
+  // mirror::Class difficult and confusing.
+  jclass klass_;
+  std::unique_ptr<const art::DexFile> dex_file_;
+  std::string* error_msg_;
+  char* class_sig_;
+
+  // TODO Maybe change jclass to a mirror::Class
+  Redefiner(art::Runtime* runtime,
+            art::Thread* self,
+            jclass klass,
+            char* class_sig,
+            std::unique_ptr<const art::DexFile>& redefined_dex_file,
+            std::string* error_msg)
+      : result_(ERR(INTERNAL)),
+        runtime_(runtime),
+        self_(self),
+        klass_(klass),
+        dex_file_(std::move(redefined_dex_file)),
+        error_msg_(error_msg),
+        class_sig_(class_sig) { }
+
+  static std::unique_ptr<art::MemMap> MoveDataToMemMap(const std::string& original_location,
+                                                       jint data_len,
+                                                       unsigned char* dex_data,
+                                                       std::string* error_msg);
+
+  // TODO Put on all the lock qualifiers.
+  jvmtiError Run() REQUIRES_SHARED(art::Locks::mutator_lock_);
+
+  bool FinishRemainingAllocations(
+        /*out*/art::MutableHandle<art::mirror::ClassLoader>* source_class_loader,
+        /*out*/art::MutableHandle<art::mirror::Object>* source_dex_file_obj,
+        /*out*/art::MutableHandle<art::mirror::LongArray>* new_dex_file_cookie,
+        /*out*/art::MutableHandle<art::mirror::DexCache>* new_dex_cache)
+      REQUIRES_SHARED(art::Locks::mutator_lock_);
+
+  // Preallocates all needed allocations in klass so that we can pause execution safely.
+  // TODO We should be able to free the arrays if they end up not being used. Investigate doing this
+  // in the future. For now we will just take the memory hit.
+  bool EnsureClassAllocationsFinished() REQUIRES_SHARED(art::Locks::mutator_lock_);
+
+  art::mirror::ClassLoader* GetClassLoader() REQUIRES_SHARED(art::Locks::mutator_lock_);
+
+  // This finds the java.lang.DexFile we will add the native DexFile to as part of the classpath.
+  // TODO Make sure the DexFile object returned is the one that the klass_ actually comes from.
+  art::mirror::Object* FindSourceDexFileObject(art::Handle<art::mirror::ClassLoader> loader)
+      REQUIRES_SHARED(art::Locks::mutator_lock_);
+
+  art::mirror::Class* GetMirrorClass() REQUIRES_SHARED(art::Locks::mutator_lock_);
+
+  // Allocates and fills the new DexFileCookie
+  art::mirror::LongArray* AllocateDexFileCookie(art::Handle<art::mirror::Object> java_dex_file_obj)
+      REQUIRES_SHARED(art::Locks::mutator_lock_);
+
+  art::mirror::DexCache* CreateNewDexCache(art::Handle<art::mirror::ClassLoader> loader)
+      REQUIRES_SHARED(art::Locks::mutator_lock_);
+
+  void RecordFailure(jvmtiError result, const std::string& error_msg);
+
+  // TODO Actually write this.
+  // This will check that no constraints are violated (more than 1 class in dex file, any changes in
+  // number/declaration of methods & fields, changes in access flags, etc.)
+  bool EnsureRedefinitionIsValid() {
+    return true;
+  }
+
+  bool UpdateJavaDexFile(art::ObjPtr<art::mirror::Object> java_dex_file,
+                         art::ObjPtr<art::mirror::LongArray> new_cookie,
+                         /*out*/art::ObjPtr<art::mirror::LongArray>* original_cookie)
+      REQUIRES(art::Locks::mutator_lock_);
+
+  void RestoreJavaDexFile(art::ObjPtr<art::mirror::Object> java_dex_file,
+                          art::ObjPtr<art::mirror::LongArray> original_cookie)
+      REQUIRES(art::Locks::mutator_lock_);
+
+  bool UpdateClass(art::ObjPtr<art::mirror::Class> mclass,
+                   art::ObjPtr<art::mirror::DexCache> new_dex_cache)
+      REQUIRES(art::Locks::mutator_lock_);
+};
+
+}  // namespace openjdkjvmti
+
+#endif  // ART_RUNTIME_OPENJDKJVMTI_TI_REDEFINE_H_
diff --git a/runtime/openjdkjvmti/transform.cc b/runtime/openjdkjvmti/transform.cc
index 7bb5205..f7b8b92 100644
--- a/runtime/openjdkjvmti/transform.cc
+++ b/runtime/openjdkjvmti/transform.cc
@@ -29,8 +29,12 @@
  * questions.
  */
 
+#include <unordered_map>
+#include <unordered_set>
+
 #include "transform.h"
 
+#include "art_method.h"
 #include "class_linker.h"
 #include "dex_file.h"
 #include "dex_file_types.h"
@@ -46,6 +50,7 @@
 #include "mirror/string-inl.h"
 #include "oat_file.h"
 #include "scoped_thread_state_change-inl.h"
+#include "stack.h"
 #include "thread_list.h"
 #include "transform.h"
 #include "utf.h"
@@ -53,196 +58,7 @@
 
 namespace openjdkjvmti {
 
-static bool ReadChecksum(jint data_len, const unsigned char* dex, /*out*/uint32_t* res) {
-  if (data_len < static_cast<jint>(sizeof(art::DexFile::Header))) {
-    return false;
-  }
-  *res = reinterpret_cast<const art::DexFile::Header*>(dex)->checksum_;
-  return true;
-}
-
-static std::unique_ptr<art::MemMap> MoveDataToMemMap(const std::string& original_location,
-                                                      jint data_len,
-                                                      unsigned char* dex_data) {
-  std::string error_msg;
-  std::unique_ptr<art::MemMap> map(art::MemMap::MapAnonymous(
-      art::StringPrintf("%s-transformed", original_location.c_str()).c_str(),
-      nullptr,
-      data_len,
-      PROT_READ|PROT_WRITE,
-      /*low_4gb*/false,
-      /*reuse*/false,
-      &error_msg));
-  if (map == nullptr) {
-    return map;
-  }
-  memcpy(map->Begin(), dex_data, data_len);
-  map->Protect(PROT_READ);
-  return map;
-}
-
-static void InvalidateExistingMethods(art::Thread* self,
-                                      art::Handle<art::mirror::Class> klass,
-                                      art::Handle<art::mirror::DexCache> cache,
-                                      const art::DexFile* dex_file)
-    REQUIRES_SHARED(art::Locks::mutator_lock_) {
-  // Create new DexCache with new DexFile.
-  // reset dex_class_def_idx_
-  // for each method reset entry_point_from_quick_compiled_code_ to bridge
-  // for each method reset dex_code_item_offset_
-  // for each method reset dex_method_index_
-  // for each method set dex_cache_resolved_methods_ to new DexCache
-  // for each method set dex_cache_resolved_types_ to new DexCache
-  auto* runtime = art::Runtime::Current();
-  art::ClassLinker* linker = runtime->GetClassLinker();
-  art::PointerSize image_pointer_size = linker->GetImagePointerSize();
-  std::string descriptor_storage;
-  const char* descriptor = klass->GetDescriptor(&descriptor_storage);
-  // Get the new class def
-  const art::DexFile::ClassDef* class_def = art::OatFile::OatDexFile::FindClassDef(
-      *dex_file, descriptor, art::ComputeModifiedUtf8Hash(descriptor));
-  CHECK(class_def != nullptr);
-  const art::DexFile::TypeId& declaring_class_id = dex_file->GetTypeId(class_def->class_idx_);
-  art::StackHandleScope<6> hs(self);
-  const art::DexFile& old_dex_file = klass->GetDexFile();
-  for (art::ArtMethod& method : klass->GetMethods(image_pointer_size)) {
-    // Find the code_item for the method then find the dex_method_index and dex_code_item_offset to
-    // set.
-    const art::DexFile::StringId* new_name_id = dex_file->FindStringId(method.GetName());
-    art::dex::TypeIndex method_return_idx =
-        dex_file->GetIndexForTypeId(*dex_file->FindTypeId(method.GetReturnTypeDescriptor()));
-    const auto* old_type_list = method.GetParameterTypeList();
-    std::vector<art::dex::TypeIndex> new_type_list;
-    for (uint32_t i = 0; old_type_list != nullptr && i < old_type_list->Size(); i++) {
-      new_type_list.push_back(
-          dex_file->GetIndexForTypeId(
-              *dex_file->FindTypeId(
-                  old_dex_file.GetTypeDescriptor(
-                      old_dex_file.GetTypeId(
-                          old_type_list->GetTypeItem(i).type_idx_)))));
-    }
-    const art::DexFile::ProtoId* proto_id = dex_file->FindProtoId(method_return_idx,
-                                                                  new_type_list);
-    CHECK(proto_id != nullptr || old_type_list == nullptr);
-    const art::DexFile::MethodId* method_id = dex_file->FindMethodId(declaring_class_id,
-                                                                      *new_name_id,
-                                                                      *proto_id);
-    CHECK(method_id != nullptr);
-    uint32_t dex_method_idx = dex_file->GetIndexForMethodId(*method_id);
-    method.SetDexMethodIndex(dex_method_idx);
-    linker->SetEntryPointsToInterpreter(&method);
-    method.SetCodeItemOffset(dex_file->FindCodeItemOffset(*class_def, dex_method_idx));
-    method.SetDexCacheResolvedMethods(cache->GetResolvedMethods(), image_pointer_size);
-    method.SetDexCacheResolvedTypes(cache->GetResolvedTypes(), image_pointer_size);
-  }
-
-  // Update the class fields.
-  // Need to update class last since the ArtMethod gets its DexFile from the class (which is needed
-  // to call GetReturnTypeDescriptor and GetParameterTypeList above).
-  klass->SetDexCache(cache.Get());
-  klass->SetDexCacheStrings(cache->GetStrings());
-  klass->SetDexClassDefIndex(dex_file->GetIndexForClassDef(*class_def));
-  klass->SetDexTypeIndex(dex_file->GetIndexForTypeId(*dex_file->FindTypeId(descriptor)));
-}
-
-// Adds the dex file.
-static art::mirror::LongArray* InsertDexFileIntoArray(art::Thread* self,
-                                                      const art::DexFile* dex,
-                                                      art::Handle<art::mirror::LongArray>& orig)
-    REQUIRES_SHARED(art::Locks::mutator_lock_) {
-  art::StackHandleScope<1> hs(self);
-  CHECK_GE(orig->GetLength(), 1);
-  art::Handle<art::mirror::LongArray> ret(
-      hs.NewHandle(art::mirror::LongArray::Alloc(self, orig->GetLength() + 1)));
-  CHECK(ret.Get() != nullptr);
-  // Copy the oat-dex.
-  // TODO Should I clear the oatdex element?
-  ret->SetWithoutChecks<false>(0, orig->GetWithoutChecks(0));
-  ret->SetWithoutChecks<false>(1, static_cast<int64_t>(reinterpret_cast<intptr_t>(dex)));
-  ret->Memcpy(2, orig.Get(), 1, orig->GetLength() - 1);
-  return ret.Get();
-}
-
-// TODO Handle all types of class loaders.
-static bool FindDalvikSystemDexFileAndLoaderForClass(
-    art::Handle<art::mirror::Class> klass,
-    /*out*/art::mirror::Object** dex_file,
-    /*out*/art::mirror::ClassLoader** loader)
-      REQUIRES_SHARED(art::Locks::mutator_lock_) {
-  const char* dex_path_list_element_array_name = "[Ldalvik/system/DexPathList$Element;";
-  const char* dex_path_list_element_name = "Ldalvik/system/DexPathList$Element;";
-  const char* dex_file_name = "Ldalvik/system/DexFile;";
-  const char* dex_path_list_name = "Ldalvik/system/DexPathList;";
-  const char* dex_class_loader_name = "Ldalvik/system/BaseDexClassLoader;";
-
-  art::Thread* self = art::Thread::Current();
-  CHECK(!self->IsExceptionPending());
-  art::StackHandleScope<11> hs(self);
-  art::ClassLinker* class_linker = art::Runtime::Current()->GetClassLinker();
-
-  art::Handle<art::mirror::ClassLoader> null_loader(hs.NewHandle<art::mirror::ClassLoader>(
-      nullptr));
-  art::Handle<art::mirror::Class> base_dex_loader_class(hs.NewHandle(class_linker->FindClass(
-      self, dex_class_loader_name, null_loader)));
-
-  art::ArtField* path_list_field = base_dex_loader_class->FindDeclaredInstanceField(
-      "pathList", dex_path_list_name);
-  CHECK(path_list_field != nullptr);
-
-  art::ArtField* dex_path_list_element_field =
-      class_linker->FindClass(self, dex_path_list_name, null_loader)
-        ->FindDeclaredInstanceField("dexElements", dex_path_list_element_array_name);
-  CHECK(dex_path_list_element_field != nullptr);
-
-  art::ArtField* element_dex_file_field =
-      class_linker->FindClass(self, dex_path_list_element_name, null_loader)
-        ->FindDeclaredInstanceField("dexFile", dex_file_name);
-  CHECK(element_dex_file_field != nullptr);
-
-  art::Handle<art::mirror::ClassLoader> h_class_loader(hs.NewHandle(klass->GetClassLoader()));
-  art::Handle<art::mirror::Class> loader_class(hs.NewHandle(h_class_loader->GetClass()));
-  // Check if loader is a BaseDexClassLoader
-  if (!loader_class->IsSubClass(base_dex_loader_class.Get())) {
-    LOG(ERROR) << "The classloader is not a BaseDexClassLoader which is currently the only "
-               << "supported class loader type!";
-    return false;
-  }
-  art::Handle<art::mirror::Object> path_list(
-      hs.NewHandle(path_list_field->GetObject(h_class_loader.Get())));
-  CHECK(path_list.Get() != nullptr);
-  CHECK(!self->IsExceptionPending());
-  art::Handle<art::mirror::ObjectArray<art::mirror::Object>> dex_elements_list(hs.NewHandle(
-      dex_path_list_element_field->GetObject(path_list.Get())->
-      AsObjectArray<art::mirror::Object>()));
-  CHECK(!self->IsExceptionPending());
-  CHECK(dex_elements_list.Get() != nullptr);
-  size_t num_elements = dex_elements_list->GetLength();
-  art::MutableHandle<art::mirror::Object> current_element(
-      hs.NewHandle<art::mirror::Object>(nullptr));
-  art::MutableHandle<art::mirror::Object> first_dex_file(
-      hs.NewHandle<art::mirror::Object>(nullptr));
-  for (size_t i = 0; i < num_elements; i++) {
-    current_element.Assign(dex_elements_list->Get(i));
-    CHECK(current_element.Get() != nullptr);
-    CHECK(!self->IsExceptionPending());
-    CHECK(dex_elements_list.Get() != nullptr);
-    CHECK_EQ(current_element->GetClass(), class_linker->FindClass(self,
-                                                                  dex_path_list_element_name,
-                                                                  null_loader));
-    // TODO It would be cleaner to put the art::DexFile into the dalvik.system.DexFile the class
-    // comes from but it is more annoying because we would need to find this class. It is not
-    // necessary for proper function since we just need to be in front of the classes old dex file
-    // in the path.
-    first_dex_file.Assign(element_dex_file_field->GetObject(current_element.Get()));
-    if (first_dex_file.Get() != nullptr) {
-      *dex_file = first_dex_file.Get();
-      *loader = h_class_loader.Get();
-      return true;
-    }
-  }
-  return false;
-}
-
+// TODO Move this function somewhere more appropriate.
 // Gets the data surrounding the given class.
 jvmtiError GetTransformationData(ArtJvmTiEnv* env,
                                  jclass klass,
@@ -281,83 +97,4 @@
   return OK;
 }
 
-// Install the new dex file.
-// TODO do error checks for bad state (method in a stack, changes to number of methods/fields/etc).
-jvmtiError MoveTransformedFileIntoRuntime(jclass jklass,
-                                          const std::string& original_location,
-                                          jint data_len,
-                                          unsigned char* dex_data) {
-  const char* dex_file_name = "Ldalvik/system/DexFile;";
-  art::Thread* self = art::Thread::Current();
-  art::Runtime* runtime = art::Runtime::Current();
-  art::ThreadList* threads = runtime->GetThreadList();
-  art::ClassLinker* class_linker = runtime->GetClassLinker();
-  uint32_t checksum = 0;
-  if (!ReadChecksum(data_len, dex_data, &checksum)) {
-    return ERR(INVALID_CLASS_FORMAT);
-  }
-
-  std::unique_ptr<art::MemMap> map(MoveDataToMemMap(original_location, data_len, dex_data));
-  if (map.get() == nullptr) {
-    return ERR(INTERNAL);
-  }
-  std::string error_msg;
-  // Load the new dex_data in memory (mmap it, etc)
-  std::unique_ptr<const art::DexFile> new_dex_file = art::DexFile::Open(map->GetName(),
-                                                                        checksum,
-                                                                        std::move(map),
-                                                                        /*verify*/ true,
-                                                                        /*verify_checksum*/ true,
-                                                                        &error_msg);
-  CHECK(new_dex_file.get() != nullptr) << "Unable to load dex file! " << error_msg;
-
-  // Get mutator lock. We need the lifetimes of these variables (hs, the classes, etc.) to be longer
-  // then current lock (since there isn't upgrading of the lock) so we don't use soa.
-  art::ThreadState old_state = self->TransitionFromSuspendedToRunnable();
-  // This scope is needed to make sure that the HandleScope dies with mutator_lock_ since we need to
-  // upgrade the mutator_lock during the execution.
-  {
-    art::StackHandleScope<11> hs(self);
-    art::Handle<art::mirror::ClassLoader> null_loader(
-        hs.NewHandle<art::mirror::ClassLoader>(nullptr));
-    CHECK(null_loader.Get() == nullptr);
-    art::ArtField* dex_file_cookie_field = class_linker->
-        FindClass(self, dex_file_name, null_loader)->
-        FindDeclaredInstanceField("mCookie", "Ljava/lang/Object;");
-    art::ArtField* dex_file_internal_cookie_field =
-        class_linker->FindClass(self, dex_file_name, null_loader)
-          ->FindDeclaredInstanceField("mInternalCookie", "Ljava/lang/Object;");
-    CHECK(dex_file_cookie_field != nullptr);
-    art::Handle<art::mirror::Class> klass(hs.NewHandle(self->DecodeJObject(jklass)->AsClass()));
-    art::mirror::Object* dex_file_ptr = nullptr;
-    art::mirror::ClassLoader* class_loader_ptr = nullptr;
-    // Find dalvik.system.DexFile that represents the dex file we are changing.
-    if (!FindDalvikSystemDexFileAndLoaderForClass(klass, &dex_file_ptr, &class_loader_ptr)) {
-      self->TransitionFromRunnableToSuspended(old_state);
-      LOG(ERROR) << "Could not find DexFile.";
-      return ERR(INTERNAL);
-    }
-    art::Handle<art::mirror::Object> dex_file_obj(hs.NewHandle(dex_file_ptr));
-    art::Handle<art::mirror::ClassLoader> class_loader(hs.NewHandle(class_loader_ptr));
-    art::Handle<art::mirror::LongArray> art_dex_array(
-        hs.NewHandle<art::mirror::LongArray>(
-            dex_file_cookie_field->GetObject(dex_file_obj.Get())->AsLongArray()));
-    art::Handle<art::mirror::LongArray> new_art_dex_array(
-        hs.NewHandle<art::mirror::LongArray>(
-            InsertDexFileIntoArray(self, new_dex_file.get(), art_dex_array)));
-    art::Handle<art::mirror::DexCache> cache(
-        hs.NewHandle(class_linker->RegisterDexFile(*new_dex_file.get(), class_loader.Get())));
-    self->TransitionFromRunnableToSuspended(old_state);
-
-    threads->SuspendAll("moving dex file into runtime", /*long_suspend*/true);
-    // Change the mCookie field. Old value will be GC'd as normal.
-    dex_file_cookie_field->SetObject<false>(dex_file_obj.Get(), new_art_dex_array.Get());
-    dex_file_internal_cookie_field->SetObject<false>(dex_file_obj.Get(), new_art_dex_array.Get());
-    // Invalidate existing methods.
-    InvalidateExistingMethods(self, klass, cache, new_dex_file.release());
-  }
-  threads->ResumeAll();
-  return OK;
-}
-
 }  // namespace openjdkjvmti
diff --git a/runtime/openjdkjvmti/transform.h b/runtime/openjdkjvmti/transform.h
index a76ed93..35b990b 100644
--- a/runtime/openjdkjvmti/transform.h
+++ b/runtime/openjdkjvmti/transform.h
@@ -52,12 +52,6 @@
                                  /*out*/jint* data_len,
                                  /*out*/unsigned char** dex_data);
 
-// Install the new dex file.
-jvmtiError MoveTransformedFileIntoRuntime(jclass jklass,
-                                          const std::string& original_location,
-                                          jint data_len,
-                                          unsigned char* dex_data);
-
 }  // namespace openjdkjvmti
 
 #endif  // ART_RUNTIME_OPENJDKJVMTI_TRANSFORM_H_
