diff --git a/src/jni_internal.cc b/src/jni_internal.cc
index f28bff9..dbb2674 100644
--- a/src/jni_internal.cc
+++ b/src/jni_internal.cc
@@ -20,244 +20,123 @@
 
 namespace art {
 
-jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args);
-void CallNonvirtualVoidMethodV(JNIEnv* env, jobject obj, jclass clazz,
-                               jmethodID methodID, va_list args);
-void CallNonvirtualVoidMethodA(JNIEnv* env, jobject obj, jclass clazz,
-                               jmethodID methodID, jvalue* args);
+// This is private API, but with two different implementations: ARM and x86.
+void CreateInvokeStub(Assembler* assembler, Method* method);
 
-enum JNI_OnLoadState {
-  kPending = 0,     /* initial state, must be zero */
-  kFailed,
-  kOkay,
-};
+// TODO: this should be in our anonymous namespace, but is currently needed
+// for testing in "jni_internal_test.cc".
+bool EnsureInvokeStub(Method* method) {
+  if (method->GetInvokeStub() != NULL) {
+    return true;
+  }
+  // TODO: use signature to find a matching stub
+  // TODO: failed, acquire a lock on the stub table
+  Assembler assembler;
+  CreateInvokeStub(&assembler, method);
+  // TODO: store native_entry in the stub table
+  int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
+  size_t length = assembler.CodeSize();
+  void* addr = mmap(NULL, length, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  if (addr == MAP_FAILED) {
+    PLOG(FATAL) << "mmap failed";
+  }
+  MemoryRegion region(addr, length);
+  assembler.FinalizeInstructions(region);
+  method->SetInvokeStub(reinterpret_cast<Method::InvokeStub*>(region.pointer()));
+  return true;
+}
 
-struct SharedLibrary {
-  SharedLibrary() : jni_on_load_lock(Mutex::Create("JNI_OnLoad lock")) {
+// TODO: this can't be in our anonymous namespace because of the map in JavaVM.
+class SharedLibrary {
+public:
+  SharedLibrary(const std::string& path, void* handle, Object* class_loader)
+      : path_(path),
+        handle_(handle),
+        jni_on_load_lock_(Mutex::Create("JNI_OnLoad lock")),
+        jni_on_load_tid_(Thread::Current()->GetId()),
+        jni_on_load_result_(kPending) {
   }
 
   ~SharedLibrary() {
-    delete jni_on_load_lock;
+    delete jni_on_load_lock_;
   }
 
-  // Path to library "/system/lib/libjni.so".
-  std::string path;
-
-  // The void* returned by dlopen(3).
-  void* handle;
-
-  // The ClassLoader this library is associated with.
-  Object* class_loader;
-
-  // Guards remaining items.
-  Mutex* jni_on_load_lock;
-  // Wait for JNI_OnLoad in other thread.
-  pthread_cond_t  jni_on_load_cond;
-  // Recursive invocation guard.
-  uint32_t jni_on_load_tid;
-  // Result of earlier JNI_OnLoad call.
-  JNI_OnLoadState jni_on_load_result;
-};
-
-/*
- * Check the result of an earlier call to JNI_OnLoad on this library.  If
- * the call has not yet finished in another thread, wait for it.
- */
-bool CheckOnLoadResult(JavaVMExt* vm, SharedLibrary* library) {
-  Thread* self = Thread::Current();
-  if (library->jni_on_load_tid == self->GetId()) {
-    // Check this so we don't end up waiting for ourselves.  We need
-    // to return "true" so the caller can continue.
-    LOG(INFO) << *self << " recursive attempt to load library "
-              << "\"" << library->path << "\"";
-    return true;
+  Object* GetClassLoader() {
+    return class_loader_;
   }
 
-  UNIMPLEMENTED(ERROR) << "need to pthread_cond_wait!";
-  // MutexLock mu(library->jni_on_load_lock);
-  while (library->jni_on_load_result == kPending) {
-    if (vm->verbose_jni) {
-      LOG(INFO) << "[" << *self << " waiting for \"" << library->path << "\" "
-                << "JNI_OnLoad...]";
-    }
-    Thread::State old_state = self->GetState();
-    self->SetState(Thread::kWaiting); // TODO: VMWAIT
-    // pthread_cond_wait(&library->jni_on_load_cond, &library->jni_on_load_lock);
-    self->SetState(old_state);
-  }
-
-  bool okay = (library->jni_on_load_result == kOkay);
-  if (vm->verbose_jni) {
-    LOG(INFO) << "[Earlier JNI_OnLoad for \"" << library->path << "\" "
-              << (okay ? "succeeded" : "failed") << "]";
-  }
-  return okay;
-}
-
-typedef int (*JNI_OnLoadFn)(JavaVM*, void*);
-
-/*
- * Load native code from the specified absolute pathname.  Per the spec,
- * if we've already loaded a library with the specified pathname, we
- * return without doing anything.
- *
- * TODO? for better results we should absolutify the pathname.  For fully
- * correct results we should stat to get the inode and compare that.  The
- * existing implementation is fine so long as everybody is using
- * System.loadLibrary.
- *
- * The library will be associated with the specified class loader.  The JNI
- * spec says we can't load the same library into more than one class loader.
- *
- * Returns "true" on success. On failure, sets *detail to a
- * human-readable description of the error or NULL if no detail is
- * available; ownership of the string is transferred to the caller.
- */
-bool JavaVMExt::LoadNativeLibrary(const std::string& path, Object* class_loader, char** detail) {
-  *detail = NULL;
-
-  // See if we've already loaded this library.  If we have, and the class loader
-  // matches, return successfully without doing anything.
-  SharedLibrary* library = libraries[path];
-  if (library != NULL) {
-    if (library->class_loader != class_loader) {
-      LOG(WARNING) << "Shared library \"" << path << "\" already opened by "
-                   << "ClassLoader " << library->class_loader << "; "
-                   << "can't open in " << class_loader;
-      *detail = strdup("already opened by different ClassLoader");
-      return false;
-    }
-    if (verbose_jni) {
-      LOG(INFO) << "[Shared library \"" << path << "\" already loaded in "
-                << "ClassLoader " << class_loader << "]";
-    }
-    if (!CheckOnLoadResult(this, library)) {
-      *detail = strdup("JNI_OnLoad failed before");
-      return false;
-    }
-    return true;
-  }
-
-  // Open the shared library.  Because we're using a full path, the system
-  // doesn't have to search through LD_LIBRARY_PATH.  (It may do so to
-  // resolve this library's dependencies though.)
-
-  // Failures here are expected when java.library.path has several entries
-  // and we have to hunt for the lib.
-
-  // The current version of the dynamic linker prints detailed information
-  // about dlopen() failures.  Some things to check if the message is
-  // cryptic:
-  //   - make sure the library exists on the device
-  //   - verify that the right path is being opened (the debug log message
-  //     above can help with that)
-  //   - check to see if the library is valid (e.g. not zero bytes long)
-  //   - check config/prelink-linux-arm.map to ensure that the library
-  //     is listed and is not being overrun by the previous entry (if
-  //     loading suddenly stops working on a prelinked library, this is
-  //     a good one to check)
-  //   - write a trivial app that calls sleep() then dlopen(), attach
-  //     to it with "strace -p <pid>" while it sleeps, and watch for
-  //     attempts to open nonexistent dependent shared libs
-
-  // TODO: automate some of these checks!
-
-  // This can execute slowly for a large library on a busy system, so we
-  // want to switch from RUNNING to VMWAIT while it executes.  This allows
-  // the GC to ignore us.
-  Thread* self = Thread::Current();
-  Thread::State old_state = self->GetState();
-  self->SetState(Thread::kWaiting); // TODO: VMWAIT
-  void* handle = dlopen(path.c_str(), RTLD_LAZY);
-  self->SetState(old_state);
-
-  if (verbose_jni) {
-    LOG(INFO) << "[Call to dlopen(\"" << path << "\") returned " << handle << "]";
-  }
-
-  if (handle == NULL) {
-    *detail = strdup(dlerror());
-    return false;
-  }
-
-  // Create a new entry.
-  library = new SharedLibrary;
-  library->path = path;
-  library->handle = handle;
-  library->class_loader = class_loader;
-  UNIMPLEMENTED(ERROR) << "missing pthread_cond_init";
-  // pthread_cond_init(&library->onLoadCond, NULL);
-  library->jni_on_load_tid = self->GetId();
-
-  libraries[path] = library;
-
-//  if (pNewEntry != pActualEntry) {
-//    LOG(INFO) << "WOW: we lost a race to add a shared library (\"" << path << "\" ClassLoader=" << class_loader <<")";
-//    freeSharedLibEntry(pNewEntry);
-//    return CheckOnLoadResult(this, pActualEntry);
-//  } else
-  {
-    if (verbose_jni) {
-      LOG(INFO) << "[Added shared library \"" << path << "\" for ClassLoader " << class_loader << "]";
+  /*
+   * Check the result of an earlier call to JNI_OnLoad on this library.  If
+   * the call has not yet finished in another thread, wait for it.
+   */
+  bool CheckOnLoadResult(JavaVMExt* vm) {
+    Thread* self = Thread::Current();
+    if (jni_on_load_tid_ == self->GetId()) {
+      // Check this so we don't end up waiting for ourselves.  We need
+      // to return "true" so the caller can continue.
+      LOG(INFO) << *self << " recursive attempt to load library "
+                << "\"" << path_ << "\"";
+      return true;
     }
 
-    bool result = true;
-    void* sym = dlsym(handle, "JNI_OnLoad");
-    if (sym == NULL) {
-      if (verbose_jni) {
-        LOG(INFO) << "[No JNI_OnLoad found in \"" << path << "\"]";
+    UNIMPLEMENTED(ERROR) << "need to pthread_cond_wait!";
+    // MutexLock mu(jni_on_load_lock_);
+    while (jni_on_load_result_ == kPending) {
+      if (vm->verbose_jni) {
+        LOG(INFO) << "[" << *self << " waiting for \"" << path_ << "\" "
+                  << "JNI_OnLoad...]";
       }
-    } else {
-      // Call JNI_OnLoad.  We have to override the current class
-      // loader, which will always be "null" since the stuff at the
-      // top of the stack is around Runtime.loadLibrary().  (See
-      // the comments in the JNI FindClass function.)
-      UNIMPLEMENTED(WARNING) << "need to override current class loader";
-      JNI_OnLoadFn jni_on_load = reinterpret_cast<JNI_OnLoadFn>(sym);
-      //Object* prevOverride = self->classLoaderOverride;
-      //self->classLoaderOverride = classLoader;
-
-      old_state = self->GetState();
-      self->SetState(Thread::kNative);
-      if (verbose_jni) {
-        LOG(INFO) << "[Calling JNI_OnLoad in \"" << path << "\"]";
-      }
-      int version = (*jni_on_load)(reinterpret_cast<JavaVM*>(this), NULL);
+      Thread::State old_state = self->GetState();
+      self->SetState(Thread::kWaiting); // TODO: VMWAIT
+      // pthread_cond_wait(&jni_on_load_cond_, &jni_on_load_lock_);
       self->SetState(old_state);
-
-      UNIMPLEMENTED(WARNING) << "need to restore current class loader";
-      //self->classLoaderOverride = prevOverride;
-
-      if (version != JNI_VERSION_1_2 &&
-          version != JNI_VERSION_1_4 &&
-          version != JNI_VERSION_1_6) {
-        LOG(WARNING) << "JNI_OnLoad in \"" << path << "\" returned "
-                     << "bad version: " << version;
-        // It's unwise to call dlclose() here, but we can mark it
-        // as bad and ensure that future load attempts will fail.
-        // We don't know how far JNI_OnLoad got, so there could
-        // be some partially-initialized stuff accessible through
-        // newly-registered native method calls.  We could try to
-        // unregister them, but that doesn't seem worthwhile.
-        result = false;
-      } else {
-        if (verbose_jni) {
-          LOG(INFO) << "[Returned " << (result ? "successfully" : "failure")
-                    << " from JNI_OnLoad in \"" << path << "\"]";
-        }
-      }
     }
 
-    library->jni_on_load_result = result ? kOkay : kFailed;
-    library->jni_on_load_tid = 0;
+    bool okay = (jni_on_load_result_ == kOkay);
+    if (vm->verbose_jni) {
+      LOG(INFO) << "[Earlier JNI_OnLoad for \"" << path_ << "\" "
+                << (okay ? "succeeded" : "failed") << "]";
+    }
+    return okay;
+  }
+
+  void SetResult(bool result) {
+    jni_on_load_result_ = result ? kOkay : kFailed;
+    jni_on_load_tid_ = 0;
 
     // Broadcast a wakeup to anybody sleeping on the condition variable.
     UNIMPLEMENTED(ERROR) << "missing pthread_cond_broadcast";
-    // MutexLock mu(library->jni_on_load_lock);
-    // pthread_cond_broadcast(&library->jni_on_load_cond);
-    return result;
+    // MutexLock mu(library->jni_on_load_lock_);
+    // pthread_cond_broadcast(&library->jni_on_load_cond_);
   }
-}
+
+ private:
+  enum JNI_OnLoadState {
+    kPending,
+    kFailed,
+    kOkay,
+  };
+
+  // Path to library "/system/lib/libjni.so".
+  std::string path_;
+
+  // The void* returned by dlopen(3).
+  void* handle_;
+
+  // The ClassLoader this library is associated with.
+  Object* class_loader_;
+
+  // Guards remaining items.
+  Mutex* jni_on_load_lock_;
+  // Wait for JNI_OnLoad in other thread.
+  pthread_cond_t jni_on_load_cond_;
+  // Recursive invocation guard.
+  uint32_t jni_on_load_tid_;
+  // Result of earlier JNI_OnLoad call.
+  JNI_OnLoadState jni_on_load_result_;
+};
+
+namespace {
 
 // Entry/exit processing for all JNI calls.
 //
@@ -355,6 +234,17 @@
   return reinterpret_cast<T>(ref);
 }
 
+jweak AddWeakGlobalReference(ScopedJniThreadState& ts, Object* obj) {
+  if (obj == NULL) {
+    return NULL;
+  }
+  JavaVMExt* vm = Runtime::Current()->GetJavaVM();
+  IndirectReferenceTable& weak_globals = vm->weak_globals;
+  MutexLock mu(vm->weak_globals_lock);
+  IndirectRef ref = weak_globals.Add(IRT_FIRST_SEGMENT, obj);
+  return reinterpret_cast<jweak>(ref);
+}
+
 template<typename T>
 T Decode(ScopedJniThreadState& ts, jobject obj) {
   if (obj == NULL) {
@@ -408,27 +298,12 @@
   return reinterpret_cast<T>(result);
 }
 
-void CreateInvokeStub(Assembler* assembler, Method* method);
+Field* DecodeField(ScopedJniThreadState& ts, jfieldID fid) {
+  return Decode<Field*>(ts, reinterpret_cast<jweak>(fid));
+}
 
-bool EnsureInvokeStub(Method* method) {
-  if (method->GetInvokeStub() != NULL) {
-    return true;
-  }
-  // TODO: use signature to find a matching stub
-  // TODO: failed, acquire a lock on the stub table
-  Assembler assembler;
-  CreateInvokeStub(&assembler, method);
-  // TODO: store native_entry in the stub table
-  int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
-  size_t length = assembler.CodeSize();
-  void* addr = mmap(NULL, length, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-  if (addr == MAP_FAILED) {
-    PLOG(FATAL) << "mmap failed";
-  }
-  MemoryRegion region(addr, length);
-  assembler.FinalizeInstructions(region);
-  method->SetInvokeStub(reinterpret_cast<Method::InvokeStub*>(region.pointer()));
-  return true;
+Method* DecodeMethod(ScopedJniThreadState& ts, jmethodID mid) {
+  return Decode<Method*>(ts, reinterpret_cast<jweak>(mid));
 }
 
 byte* CreateArgArray(ScopedJniThreadState& ts, Method* method, va_list ap) {
@@ -506,9 +381,8 @@
 }
 
 JValue InvokeWithArgArray(ScopedJniThreadState& ts, jobject obj,
-                          jmethodID method_id, byte* args) {
-  // TODO: DecodeReference
-  Method* method = reinterpret_cast<Method*>(method_id);
+                          jmethodID mid, byte* args) {
+  Method* method = DecodeMethod(ts, mid);
   Object* rcvr = Decode<Object*>(ts, obj);
   Thread* self = ts.Self();
 
@@ -536,28 +410,17 @@
 }
 
 JValue InvokeWithJValues(ScopedJniThreadState& ts, jobject obj,
-                         jmethodID method_id, jvalue* args) {
-  Method* method = reinterpret_cast<Method*>(method_id);
+                         jmethodID mid, jvalue* args) {
+  Method* method = DecodeMethod(ts, mid);
   scoped_array<byte> arg_array(CreateArgArray(ts, method, args));
-  return InvokeWithArgArray(ts, obj, method_id, arg_array.get());
+  return InvokeWithArgArray(ts, obj, mid, arg_array.get());
 }
 
 JValue InvokeWithVarArgs(ScopedJniThreadState& ts, jobject obj,
-                         jmethodID method_id, va_list args) {
-  Method* method = reinterpret_cast<Method*>(method_id);
+                         jmethodID mid, va_list args) {
+  Method* method = DecodeMethod(ts, mid);
   scoped_array<byte> arg_array(CreateArgArray(ts, method, args));
-  return InvokeWithArgArray(ts, obj, method_id, arg_array.get());
-}
-
-jint GetVersion(JNIEnv* env) {
-  ScopedJniThreadState ts(env);
-  return JNI_VERSION_1_6;
-}
-
-jclass DefineClass(JNIEnv* env, const char*, jobject, const jbyte*, jsize) {
-  ScopedJniThreadState ts(env);
-  LOG(WARNING) << "JNI DefineClass is not supported";
-  return NULL;
+  return InvokeWithArgArray(ts, obj, mid, arg_array.get());
 }
 
 // Section 12.3.2 of the JNI spec describes JNI class descriptors. They're
@@ -584,1268 +447,68 @@
   return result;
 }
 
-jclass FindClass(JNIEnv* env, const char* name) {
-  ScopedJniThreadState ts(env);
-  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
-  std::string descriptor(NormalizeJniClassDescriptor(name));
-  // TODO: need to get the appropriate ClassLoader.
-  Class* c = class_linker->FindClass(descriptor, NULL);
-  return AddLocalReference<jclass>(ts, c);
-}
-
-jmethodID FromReflectedMethod(JNIEnv* env, jobject method) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-jfieldID FromReflectedField(JNIEnv* env, jobject field) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-jobject ToReflectedMethod(JNIEnv* env, jclass cls,
-    jmethodID methodID, jboolean isStatic) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-jclass GetSuperclass(JNIEnv* env, jclass sub) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-jboolean IsAssignableFrom(JNIEnv* env, jclass sub, jclass sup) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return JNI_FALSE;
-}
-
-jobject ToReflectedField(JNIEnv* env, jclass cls,
-    jfieldID fieldID, jboolean isStatic) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-jint Throw(JNIEnv* env, jthrowable obj) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jint ThrowNew(JNIEnv* env, jclass clazz, const char* msg) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jthrowable ExceptionOccurred(JNIEnv* env) {
-  ScopedJniThreadState ts(env);
-  Object* exception = ts.Self()->GetException();
-  if (exception == NULL) {
-    return NULL;
-  } else {
-    // TODO: if adding a local reference failing causes the VM to abort
-    // then the following check will never occur.
-    jthrowable localException = AddLocalReference<jthrowable>(ts, exception);
-    if (localException == NULL) {
-      // We were unable to add a new local reference, and threw a new
-      // exception.  We can't return "exception", because it's not a
-      // local reference.  So we have to return NULL, indicating that
-      // there was no exception, even though it's pretty much raining
-      // exceptions in here.
-      LOG(WARNING) << "JNI WARNING: addLocal/exception combo";
-    }
-    return localException;
-  }
-}
-
-void ExceptionDescribe(JNIEnv* env) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void ExceptionClear(JNIEnv* env) {
-  ScopedJniThreadState ts(env);
-  ts.Self()->ClearException();
-}
-
-void FatalError(JNIEnv* env, const char* msg) {
-  ScopedJniThreadState ts(env);
-  LOG(FATAL) << "JNI FatalError called: " << msg;
-}
-
-jint PushLocalFrame(JNIEnv* env, jint cap) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(WARNING) << "ignoring PushLocalFrame(" << cap << ")";
-  return JNI_OK;
-}
-
-jobject PopLocalFrame(JNIEnv* env, jobject res) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(WARNING) << "ignoring PopLocalFrame " << res;
-  return res;
-}
-
-jobject NewGlobalRef(JNIEnv* env, jobject obj) {
-  ScopedJniThreadState ts(env);
-  if (obj == NULL) {
-    return NULL;
-  }
-
-  JavaVMExt* vm = Runtime::Current()->GetJavaVM();
-  IndirectReferenceTable& globals = vm->globals;
-  MutexLock mu(vm->globals_lock);
-  IndirectRef ref = globals.Add(IRT_FIRST_SEGMENT, Decode<Object*>(ts, obj));
-  return reinterpret_cast<jobject>(ref);
-}
-
-void DeleteGlobalRef(JNIEnv* env, jobject obj) {
-  ScopedJniThreadState ts(env);
-  if (obj == NULL) {
-    return;
-  }
-
-  JavaVMExt* vm = Runtime::Current()->GetJavaVM();
-  IndirectReferenceTable& globals = vm->globals;
-  MutexLock mu(vm->globals_lock);
-
-  if (!globals.Remove(IRT_FIRST_SEGMENT, obj)) {
-    LOG(WARNING) << "JNI WARNING: DeleteGlobalRef(" << obj << ") "
-                 << "failed to find entry";
-  }
-}
-
-jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
-  ScopedJniThreadState ts(env);
-  if (obj == NULL) {
-    return NULL;
-  }
-
-  JavaVMExt* vm = Runtime::Current()->GetJavaVM();
-  IndirectReferenceTable& weak_globals = vm->weak_globals;
-  MutexLock mu(vm->weak_globals_lock);
-  IndirectRef ref = weak_globals.Add(IRT_FIRST_SEGMENT, Decode<Object*>(ts, obj));
-  return reinterpret_cast<jobject>(ref);
-}
-
-void DeleteWeakGlobalRef(JNIEnv* env, jweak obj) {
-  ScopedJniThreadState ts(env);
-  if (obj == NULL) {
-    return;
-  }
-
-  JavaVMExt* vm = Runtime::Current()->GetJavaVM();
-  IndirectReferenceTable& weak_globals = vm->weak_globals;
-  MutexLock mu(vm->weak_globals_lock);
-
-  if (!weak_globals.Remove(IRT_FIRST_SEGMENT, obj)) {
-    LOG(WARNING) << "JNI WARNING: DeleteWeakGlobalRef(" << obj << ") "
-                 << "failed to find entry";
-  }
-}
-
-jobject NewLocalRef(JNIEnv* env, jobject obj) {
-  ScopedJniThreadState ts(env);
-  if (obj == NULL) {
-    return NULL;
-  }
-
-  IndirectReferenceTable& locals = ts.Env()->locals;
-
-  uint32_t cookie = IRT_FIRST_SEGMENT; // TODO
-  IndirectRef ref = locals.Add(cookie, Decode<Object*>(ts, obj));
-  return reinterpret_cast<jobject>(ref);
-}
-
-void DeleteLocalRef(JNIEnv* env, jobject obj) {
-  ScopedJniThreadState ts(env);
-  if (obj == NULL) {
-    return;
-  }
-
-  IndirectReferenceTable& locals = ts.Env()->locals;
-
-  uint32_t cookie = IRT_FIRST_SEGMENT; // TODO
-  if (!locals.Remove(cookie, obj)) {
-    // Attempting to delete a local reference that is not in the
-    // topmost local reference frame is a no-op.  DeleteLocalRef returns
-    // void and doesn't throw any exceptions, but we should probably
-    // complain about it so the user will notice that things aren't
-    // going quite the way they expect.
-    LOG(WARNING) << "JNI WARNING: DeleteLocalRef(" << obj << ") "
-                 << "failed to find entry";
-  }
-}
-
-jboolean IsSameObject(JNIEnv* env, jobject obj1, jobject obj2) {
-  ScopedJniThreadState ts(env);
-  return (Decode<Object*>(ts, obj1) == Decode<Object*>(ts, obj2))
-         ? JNI_TRUE : JNI_FALSE;
-}
-
-jint EnsureLocalCapacity(JNIEnv* env, jint) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jobject AllocObject(JNIEnv* env, jclass clazz) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-jobject NewObject(JNIEnv* env, jclass clazz, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  va_list args;
-  va_start(args, methodID);
-  jobject result = NewObjectV(env, clazz, methodID, args);
-  va_end(args);
-  return result;
-}
-
-jobject NewObjectV(JNIEnv* env,
-    jclass clazz, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  Class* klass = Decode<Class*>(ts, clazz);
-  Object* result = klass->NewInstance();
-  jobject local_result = AddLocalReference<jobject>(ts, result);
-  CallNonvirtualVoidMethodV(env, local_result, clazz, methodID, args);
-  return local_result;
-}
-
-jobject NewObjectA(JNIEnv* env,
-    jclass clazz, jmethodID methodID, jvalue* args) {
-  ScopedJniThreadState ts(env);
-  Class* klass = Decode<Class*>(ts, clazz);
-  Object* result = klass->NewInstance();
-  jobject local_result = AddLocalReference<jobjectArray>(ts, result);
-  CallNonvirtualVoidMethodA(env, local_result, clazz, methodID, args);
-  return local_result;
-}
-
-jclass GetObjectClass(JNIEnv* env, jobject obj) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass clazz) {
-  ScopedJniThreadState ts(env);
-  CHECK_NE(static_cast<jclass>(NULL), clazz);
-  if (jobj == NULL) {
-    // NB. JNI is different from regular Java instanceof in this respect
-    return JNI_TRUE;
-  } else {
-    Object* obj = Decode<Object*>(ts, jobj);
-    Class* klass = Decode<Class*>(ts, clazz);
-    return Object::InstanceOf(obj, klass) ? JNI_TRUE : JNI_FALSE;
-  }
-}
-
-jmethodID GetMethodID(JNIEnv* env,
-    jclass clazz, const char* name, const char* sig) {
-  ScopedJniThreadState ts(env);
-  Class* klass = Decode<Class*>(ts, clazz);
-  if (!klass->IsInitialized()) {
+jmethodID FindMethodID(ScopedJniThreadState& ts, jclass jni_class, const char* name, const char* sig, bool is_static) {
+  Class* c = Decode<Class*>(ts, jni_class);
+  if (!c->IsInitialized()) {
     // TODO: initialize the class
   }
-  Method* method = klass->FindVirtualMethod(name, sig);
-  if (method == NULL) {
-    // No virtual method matching the signature.  Search declared
-    // private methods and constructors.
-    method = klass->FindDeclaredDirectMethod(name, sig);
-  }
-  if (method == NULL) {
-    Thread* self = Thread::Current();
-    std::string class_name = klass->GetDescriptor().ToString();
-    // TODO: pretty print method names through a single routine
-    self->ThrowNewException("Ljava/lang/NoSuchMethodError;",
-                            "no method \"%s.%s%s\"",
-                            class_name.c_str(), name, sig);
-    return NULL;
-  } else if (method->IsStatic()) {
-    Thread* self = Thread::Current();
-    std::string class_name = klass->GetDescriptor().ToString();
-    // TODO: pretty print method names through a single routine
-    self->ThrowNewException("Ljava/lang/NoSuchMethodError;",
-                            "method \"%s.%s%s\" is static",
-                            class_name.c_str(), name, sig);
-    return NULL;
+
+  Method* method = NULL;
+  if (is_static) {
+    method = c->FindDirectMethod(name, sig);
   } else {
-    // TODO: create a JNI weak global reference for method
-    bool success = EnsureInvokeStub(method);
-    if (!success) {
-      // TODO: throw OutOfMemoryException
-      return NULL;
+    method = c->FindVirtualMethod(name, sig);
+    if (method == NULL) {
+      // No virtual method matching the signature.  Search declared
+      // private methods and constructors.
+      method = c->FindDeclaredDirectMethod(name, sig);
     }
-    return reinterpret_cast<jmethodID>(method);
   }
-}
 
-jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
+  if (method == NULL || method->IsStatic() != is_static) {
+    Thread* self = Thread::Current();
+    std::string class_name(c->GetDescriptor().ToString());
+    // TODO: try searching for the opposite kind of method from is_static
+    // for better diagnostics?
+    self->ThrowNewException("Ljava/lang/NoSuchMethodError;",
+        "no %s method \"%s.%s%s\"", is_static ? "static" : "non-static",
+        class_name.c_str(), name, sig);
+    return NULL;
+  }
 
-jobject CallObjectMethodV(JNIEnv* env,
-    jobject obj, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
+  bool success = EnsureInvokeStub(method);
+  if (!success) {
+    // TODO: throw OutOfMemoryException
+    return NULL;
+  }
 
-jobject CallObjectMethodA(JNIEnv* env,
-    jobject obj, jmethodID methodID, jvalue*  args) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
+  return reinterpret_cast<jmethodID>(AddWeakGlobalReference(ts, method));
 }
 
-jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return JNI_FALSE;
-}
-
-jboolean CallBooleanMethodV(JNIEnv* env,
-    jobject obj, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return JNI_FALSE;
-}
-
-jboolean CallBooleanMethodA(JNIEnv* env,
-    jobject obj, jmethodID methodID, jvalue*  args) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return JNI_FALSE;
-}
-
-jbyte CallByteMethod(JNIEnv* env, jobject obj, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jbyte CallByteMethodV(JNIEnv* env,
-    jobject obj, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jbyte CallByteMethodA(JNIEnv* env,
-    jobject obj, jmethodID methodID, jvalue* args) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jchar CallCharMethod(JNIEnv* env, jobject obj, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jchar CallCharMethodV(JNIEnv* env,
-    jobject obj, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jchar CallCharMethodA(JNIEnv* env,
-    jobject obj, jmethodID methodID, jvalue* args) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jshort CallShortMethod(JNIEnv* env, jobject obj, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jshort CallShortMethodV(JNIEnv* env,
-    jobject obj, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jshort CallShortMethodA(JNIEnv* env,
-    jobject obj, jmethodID methodID, jvalue* args) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jint CallIntMethod(JNIEnv* env, jobject obj, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jint CallIntMethodV(JNIEnv* env,
-    jobject obj, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jint CallIntMethodA(JNIEnv* env,
-    jobject obj, jmethodID methodID, jvalue* args) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jlong CallLongMethod(JNIEnv* env, jobject obj, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jlong CallLongMethodV(JNIEnv* env,
-    jobject obj, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jlong CallLongMethodA(JNIEnv* env,
-    jobject obj, jmethodID methodID, jvalue* args) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jfloat CallFloatMethodV(JNIEnv* env,
-    jobject obj, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jfloat CallFloatMethodA(JNIEnv* env,
-    jobject obj, jmethodID methodID, jvalue* args) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jdouble CallDoubleMethod(JNIEnv* env, jobject obj, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jdouble CallDoubleMethodV(JNIEnv* env,
-    jobject obj, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jdouble CallDoubleMethodA(JNIEnv* env,
-    jobject obj, jmethodID methodID, jvalue* args) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void CallVoidMethodV(JNIEnv* env, jobject obj,
-    jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void CallVoidMethodA(JNIEnv* env, jobject obj,
-    jmethodID methodID, jvalue*  args) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-jobject CallNonvirtualObjectMethod(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  va_list ap;
-  va_start(ap, methodID);
-  JValue result = InvokeWithVarArgs(ts, obj, methodID, ap);
-  jobject local_result = AddLocalReference<jobject>(ts, result.l);
-  va_end(ap);
-  return local_result;
-}
-
-jobject CallNonvirtualObjectMethodV(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  JValue result = InvokeWithVarArgs(ts, obj, methodID, args);
-  return AddLocalReference<jobject>(ts, result.l);
-}
-
-jobject CallNonvirtualObjectMethodA(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, jvalue*  args) {
-  ScopedJniThreadState ts(env);
-  JValue result = InvokeWithJValues(ts, obj, methodID, args);
-  return AddLocalReference<jobject>(ts, result.l);
-}
-
-jboolean CallNonvirtualBooleanMethod(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  va_list ap;
-  va_start(ap, methodID);
-  JValue result = InvokeWithVarArgs(ts, obj, methodID, ap);
-  va_end(ap);
-  return result.z;
-}
-
-jboolean CallNonvirtualBooleanMethodV(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithVarArgs(ts, obj, methodID, args).z;
-}
-
-jboolean CallNonvirtualBooleanMethodA(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, jvalue*  args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithJValues(ts, obj, methodID, args).z;
-}
-
-jbyte CallNonvirtualByteMethod(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  va_list ap;
-  va_start(ap, methodID);
-  JValue result = InvokeWithVarArgs(ts, obj, methodID, ap);
-  va_end(ap);
-  return result.b;
-}
-
-jbyte CallNonvirtualByteMethodV(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithVarArgs(ts, obj, methodID, args).b;
-}
-
-jbyte CallNonvirtualByteMethodA(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, jvalue* args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithJValues(ts, obj, methodID, args).b;
-}
-
-jchar CallNonvirtualCharMethod(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  va_list ap;
-  va_start(ap, methodID);
-  JValue result = InvokeWithVarArgs(ts, obj, methodID, ap);
-  va_end(ap);
-  return result.c;
-}
-
-jchar CallNonvirtualCharMethodV(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithVarArgs(ts, obj, methodID, args).c;
-}
-
-jchar CallNonvirtualCharMethodA(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, jvalue* args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithJValues(ts, obj, methodID, args).c;
-}
-
-jshort CallNonvirtualShortMethod(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  va_list ap;
-  va_start(ap, methodID);
-  JValue result = InvokeWithVarArgs(ts, obj, methodID, ap);
-  va_end(ap);
-  return result.s;
-}
-
-jshort CallNonvirtualShortMethodV(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithVarArgs(ts, obj, methodID, args).s;
-}
-
-jshort CallNonvirtualShortMethodA(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, jvalue* args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithJValues(ts, obj, methodID, args).s;
-}
-
-jint CallNonvirtualIntMethod(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  va_list ap;
-  va_start(ap, methodID);
-  JValue result = InvokeWithVarArgs(ts, obj, methodID, ap);
-  va_end(ap);
-  return result.i;
-}
-
-jint CallNonvirtualIntMethodV(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithVarArgs(ts, obj, methodID, args).i;
-}
-
-jint CallNonvirtualIntMethodA(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, jvalue* args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithJValues(ts, obj, methodID, args).i;
-}
-
-jlong CallNonvirtualLongMethod(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  va_list ap;
-  va_start(ap, methodID);
-  JValue result = InvokeWithVarArgs(ts, obj, methodID, ap);
-  va_end(ap);
-  return result.j;
-}
-
-jlong CallNonvirtualLongMethodV(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithVarArgs(ts, obj, methodID, args).j;
-}
-
-jlong CallNonvirtualLongMethodA(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, jvalue* args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithJValues(ts, obj, methodID, args).j;
-}
-
-jfloat CallNonvirtualFloatMethod(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  va_list ap;
-  va_start(ap, methodID);
-  JValue result = InvokeWithVarArgs(ts, obj, methodID, ap);
-  va_end(ap);
-  return result.f;
-}
-
-jfloat CallNonvirtualFloatMethodV(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithVarArgs(ts, obj, methodID, args).f;
-}
-
-jfloat CallNonvirtualFloatMethodA(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, jvalue* args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithJValues(ts, obj, methodID, args).f;
-}
-
-jdouble CallNonvirtualDoubleMethod(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  va_list ap;
-  va_start(ap, methodID);
-  JValue result = InvokeWithVarArgs(ts, obj, methodID, ap);
-  va_end(ap);
-  return result.d;
-}
-
-jdouble CallNonvirtualDoubleMethodV(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithVarArgs(ts, obj, methodID, args).d;
-}
-
-jdouble CallNonvirtualDoubleMethodA(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, jvalue* args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithJValues(ts, obj, methodID, args).d;
-}
-
-void CallNonvirtualVoidMethod(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  va_list ap;
-  va_start(ap, methodID);
-  InvokeWithVarArgs(ts, obj, methodID, ap);
-  va_end(ap);
-}
-
-void CallNonvirtualVoidMethodV(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  InvokeWithVarArgs(ts, obj, methodID, args);
-}
-
-void CallNonvirtualVoidMethodA(JNIEnv* env,
-    jobject obj, jclass clazz, jmethodID methodID, jvalue*  args) {
-  ScopedJniThreadState ts(env);
-  InvokeWithJValues(ts, obj, methodID, args);
-}
-
-jfieldID GetFieldID(JNIEnv* env,
-    jclass clazz, const char* name, const char* sig) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fieldID) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fieldID) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return JNI_FALSE;
-}
-
-jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fieldID) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fieldID) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fieldID) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jint GetIntField(JNIEnv* env, jobject obj, jfieldID fieldID) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fieldID) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fieldID) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fieldID) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-void SetObjectField(JNIEnv* env, jobject obj, jfieldID fieldID, jobject val) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fieldID, jboolean val) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void SetByteField(JNIEnv* env, jobject obj, jfieldID fieldID, jbyte val) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void SetCharField(JNIEnv* env, jobject obj, jfieldID fieldID, jchar val) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void SetShortField(JNIEnv* env, jobject obj, jfieldID fieldID, jshort val) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void SetIntField(JNIEnv* env, jobject obj, jfieldID fieldID, jint val) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void SetLongField(JNIEnv* env, jobject obj, jfieldID fieldID, jlong val) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void SetFloatField(JNIEnv* env, jobject obj, jfieldID fieldID, jfloat val) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fieldID, jdouble val) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-jmethodID GetStaticMethodID(JNIEnv* env,
-    jclass clazz, const char* name, const char* sig) {
-  ScopedJniThreadState ts(env);
-  Class* klass = Decode<Class*>(ts, clazz);
-  if (!klass->IsInitialized()) {
+jfieldID FindFieldID(ScopedJniThreadState& ts, jclass jni_class, const char* name, const char* sig, bool is_static) {
+  Class* c = Decode<Class*>(ts, jni_class);
+  if (!c->IsInitialized()) {
     // TODO: initialize the class
   }
-  Method* method = klass->FindDirectMethod(name, sig);
-  if (method == NULL) {
-    Thread* self = Thread::Current();
-    std::string class_name = klass->GetDescriptor().ToString();
-    // TODO: pretty print method names through a single routine
-    // TODO: may want to FindVirtualMethod to give more informative error
-    // message here
-    self->ThrowNewException("Ljava/lang/NoSuchMethodError;",
-                            "no method \"%s.%s%s\"",
-                            class_name.c_str(), name, sig);
-    return NULL;
-  } else if (!method->IsStatic()) {
-    Thread* self = Thread::Current();
-    std::string class_name = klass->GetDescriptor().ToString();
-    // TODO: pretty print method names through a single routine
-    self->ThrowNewException("Ljava/lang/NoSuchMethodError;",
-                            "method \"%s.%s%s\" is not static",
-                            class_name.c_str(), name, sig);
-    return NULL;
+
+  Field* field = NULL;
+  if (is_static) {
+    field = c->FindStaticField(name, sig);
   } else {
-    // TODO: create a JNI weak global reference for method
-    bool success = EnsureInvokeStub(method);
-    if (!success) {
-      // TODO: throw OutOfMemoryException
-      return NULL;
-    }
-    return reinterpret_cast<jmethodID>(method);
+    field = c->FindInstanceField(name, sig);
   }
-}
 
-jobject CallStaticObjectMethod(JNIEnv* env,
-    jclass clazz, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  va_list ap;
-  va_start(ap, methodID);
-  JValue result = InvokeWithVarArgs(ts, NULL, methodID, ap);
-  jobject local_result = AddLocalReference<jobject>(ts, result.l);
-  va_end(ap);
-  return local_result;
-}
-
-jobject CallStaticObjectMethodV(JNIEnv* env,
-    jclass clazz, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  JValue result = InvokeWithVarArgs(ts, NULL, methodID, args);
-  return AddLocalReference<jobject>(ts, result.l);
-}
-
-jobject CallStaticObjectMethodA(JNIEnv* env,
-    jclass clazz, jmethodID methodID, jvalue* args) {
-  ScopedJniThreadState ts(env);
-  JValue result = InvokeWithJValues(ts, NULL, methodID, args);
-  return AddLocalReference<jobject>(ts, result.l);
-}
-
-jboolean CallStaticBooleanMethod(JNIEnv* env,
-    jclass clazz, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  va_list ap;
-  va_start(ap, methodID);
-  JValue result = InvokeWithVarArgs(ts, NULL, methodID, ap);
-  va_end(ap);
-  return result.z;
-}
-
-jboolean CallStaticBooleanMethodV(JNIEnv* env,
-    jclass clazz, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithVarArgs(ts, NULL, methodID, args).z;
-}
-
-jboolean CallStaticBooleanMethodA(JNIEnv* env,
-    jclass clazz, jmethodID methodID, jvalue* args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithJValues(ts, NULL, methodID, args).z;
-}
-
-jbyte CallStaticByteMethod(JNIEnv* env, jclass clazz, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  va_list ap;
-  va_start(ap, methodID);
-  JValue result = InvokeWithVarArgs(ts, NULL, methodID, ap);
-  va_end(ap);
-  return result.b;
-}
-
-jbyte CallStaticByteMethodV(JNIEnv* env,
-    jclass clazz, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithVarArgs(ts, NULL, methodID, args).b;
-}
-
-jbyte CallStaticByteMethodA(JNIEnv* env,
-    jclass clazz, jmethodID methodID, jvalue* args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithJValues(ts, NULL, methodID, args).b;
-}
-
-jchar CallStaticCharMethod(JNIEnv* env, jclass clazz, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  va_list ap;
-  va_start(ap, methodID);
-  JValue result = InvokeWithVarArgs(ts, NULL, methodID, ap);
-  va_end(ap);
-  return result.c;
-}
-
-jchar CallStaticCharMethodV(JNIEnv* env,
-    jclass clazz, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithVarArgs(ts, NULL, methodID, args).c;
-}
-
-jchar CallStaticCharMethodA(JNIEnv* env,
-    jclass clazz, jmethodID methodID, jvalue* args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithJValues(ts, NULL, methodID, args).c;
-}
-
-jshort CallStaticShortMethod(JNIEnv* env, jclass clazz, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  va_list ap;
-  va_start(ap, methodID);
-  JValue result = InvokeWithVarArgs(ts, NULL, methodID, ap);
-  va_end(ap);
-  return result.s;
-}
-
-jshort CallStaticShortMethodV(JNIEnv* env,
-    jclass clazz, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithVarArgs(ts, NULL, methodID, args).s;
-}
-
-jshort CallStaticShortMethodA(JNIEnv* env,
-    jclass clazz, jmethodID methodID, jvalue* args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithJValues(ts, NULL, methodID, args).s;
-}
-
-jint CallStaticIntMethod(JNIEnv* env, jclass clazz, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  va_list ap;
-  va_start(ap, methodID);
-  JValue result = InvokeWithVarArgs(ts, NULL, methodID, ap);
-  va_end(ap);
-  return result.i;
-}
-
-jint CallStaticIntMethodV(JNIEnv* env,
-    jclass clazz, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithVarArgs(ts, NULL, methodID, args).i;
-}
-
-jint CallStaticIntMethodA(JNIEnv* env,
-    jclass clazz, jmethodID methodID, jvalue* args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithJValues(ts, NULL, methodID, args).i;
-}
-
-jlong CallStaticLongMethod(JNIEnv* env, jclass clazz, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  va_list ap;
-  va_start(ap, methodID);
-  JValue result = InvokeWithVarArgs(ts, NULL, methodID, ap);
-  va_end(ap);
-  return result.j;
-}
-
-jlong CallStaticLongMethodV(JNIEnv* env,
-    jclass clazz, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithVarArgs(ts, NULL, methodID, args).j;
-}
-
-jlong CallStaticLongMethodA(JNIEnv* env,
-    jclass clazz, jmethodID methodID, jvalue* args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithJValues(ts, NULL, methodID, args).j;
-}
-
-jfloat CallStaticFloatMethod(JNIEnv* env, jclass cls, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  va_list ap;
-  va_start(ap, methodID);
-  JValue result = InvokeWithVarArgs(ts, NULL, methodID, ap);
-  va_end(ap);
-  return result.f;
-}
-
-jfloat CallStaticFloatMethodV(JNIEnv* env,
-    jclass clazz, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithVarArgs(ts, NULL, methodID, args).f;
-}
-
-jfloat CallStaticFloatMethodA(JNIEnv* env,
-    jclass clazz, jmethodID methodID, jvalue* args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithJValues(ts, NULL, methodID, args).f;
-}
-
-jdouble CallStaticDoubleMethod(JNIEnv* env, jclass cls, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  va_list ap;
-  va_start(ap, methodID);
-  JValue result = InvokeWithVarArgs(ts, NULL, methodID, ap);
-  va_end(ap);
-  return result.d;
-}
-
-jdouble CallStaticDoubleMethodV(JNIEnv* env,
-    jclass clazz, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithVarArgs(ts, NULL, methodID, args).d;
-}
-
-jdouble CallStaticDoubleMethodA(JNIEnv* env,
-    jclass clazz, jmethodID methodID, jvalue* args) {
-  ScopedJniThreadState ts(env);
-  return InvokeWithJValues(ts, NULL, methodID, args).d;
-}
-
-void CallStaticVoidMethod(JNIEnv* env, jclass cls, jmethodID methodID, ...) {
-  ScopedJniThreadState ts(env);
-  va_list ap;
-  va_start(ap, methodID);
-  InvokeWithVarArgs(ts, NULL, methodID, ap);
-  va_end(ap);
-}
-
-void CallStaticVoidMethodV(JNIEnv* env,
-    jclass cls, jmethodID methodID, va_list args) {
-  ScopedJniThreadState ts(env);
-  InvokeWithVarArgs(ts, NULL, methodID, args);
-}
-
-void CallStaticVoidMethodA(JNIEnv* env,
-    jclass cls, jmethodID methodID, jvalue* args) {
-  ScopedJniThreadState ts(env);
-  InvokeWithJValues(ts, NULL, methodID, args);
-}
-
-jfieldID GetStaticFieldID(JNIEnv* env,
-    jclass clazz, const char* name, const char* sig) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jobject GetStaticObjectField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-jboolean GetStaticBooleanField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return JNI_FALSE;
-}
-
-jbyte GetStaticByteField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jchar GetStaticCharField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jshort GetStaticShortField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jint GetStaticIntField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jlong GetStaticLongField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jfloat GetStaticFloatField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jdouble GetStaticDoubleField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-void SetStaticObjectField(JNIEnv* env,
-    jclass clazz, jfieldID fieldID, jobject value) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void SetStaticBooleanField(JNIEnv* env,
-    jclass clazz, jfieldID fieldID, jboolean value) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void SetStaticByteField(JNIEnv* env,
-    jclass clazz, jfieldID fieldID, jbyte value) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void SetStaticCharField(JNIEnv* env,
-    jclass clazz, jfieldID fieldID, jchar value) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void SetStaticShortField(JNIEnv* env,
-    jclass clazz, jfieldID fieldID, jshort value) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void SetStaticIntField(JNIEnv* env,
-    jclass clazz, jfieldID fieldID, jint value) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void SetStaticLongField(JNIEnv* env,
-    jclass clazz, jfieldID fieldID, jlong value) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void SetStaticFloatField(JNIEnv* env,
-    jclass clazz, jfieldID fieldID, jfloat value) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void SetStaticDoubleField(JNIEnv* env,
-    jclass clazz, jfieldID fieldID, jdouble value) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-jstring NewString(JNIEnv* env, const jchar* unicode, jsize len) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-jsize GetStringLength(JNIEnv* env, jstring str) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-const jchar* GetStringChars(JNIEnv* env, jstring str, jboolean* isCopy) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-void ReleaseStringChars(JNIEnv* env, jstring str, const jchar* chars) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-jstring NewStringUTF(JNIEnv* env, const char* utf) {
-  ScopedJniThreadState ts(env);
-  if (utf == NULL) {
+  if (field == NULL) {
+    Thread* self = Thread::Current();
+    std::string class_name(c->GetDescriptor().ToString());
+    self->ThrowNewException("Ljava/lang/NoSuchFieldError;",
+        "no \"%s\" field \"%s\" in class \"%s\" or its superclasses", sig,
+        name, class_name.c_str());
     return NULL;
   }
-  String* result = String::AllocFromModifiedUtf8(utf);
-  return AddLocalReference<jstring>(ts, result);
-}
 
-jsize GetStringUTFLength(JNIEnv* env, jstring str) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-const char* GetStringUTFChars(JNIEnv* env, jstring str, jboolean* isCopy) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-void ReleaseStringUTFChars(JNIEnv* env, jstring str, const char* chars) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-jsize GetArrayLength(JNIEnv* env, jarray array) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jobject GetObjectArrayElement(JNIEnv* env, jobjectArray array, jsize index) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-void SetObjectArrayElement(JNIEnv* env,
-    jobjectArray java_array, jsize index, jobject java_value) {
-  ScopedJniThreadState ts(env);
-  ObjectArray<Object>* array = Decode<ObjectArray<Object>*>(ts, java_array);
-  Object* value = Decode<Object*>(ts, java_value);
-  array->Set(index, value);
+  jweak fid = AddWeakGlobalReference(ts, field);
+  return reinterpret_cast<jfieldID>(fid);
 }
 
 template<typename JniT, typename ArtT>
@@ -1855,633 +518,1835 @@
   return AddLocalReference<JniT>(ts, result);
 }
 
-jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) {
-  ScopedJniThreadState ts(env);
-  return NewPrimitiveArray<jbooleanArray, BooleanArray>(ts, length);
-}
+}  // namespace
 
-jbyteArray NewByteArray(JNIEnv* env, jsize length) {
-  ScopedJniThreadState ts(env);
-  return NewPrimitiveArray<jbyteArray, ByteArray>(ts, length);
-}
+class JNI {
+ public:
 
-jcharArray NewCharArray(JNIEnv* env, jsize length) {
-  ScopedJniThreadState ts(env);
-  return NewPrimitiveArray<jcharArray, CharArray>(ts, length);
-}
+  static jint GetVersion(JNIEnv* env) {
+    ScopedJniThreadState ts(env);
+    return JNI_VERSION_1_6;
+  }
 
-jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) {
-  ScopedJniThreadState ts(env);
-  return NewPrimitiveArray<jdoubleArray, DoubleArray>(ts, length);
-}
-
-jfloatArray NewFloatArray(JNIEnv* env, jsize length) {
-  ScopedJniThreadState ts(env);
-  return NewPrimitiveArray<jfloatArray, FloatArray>(ts, length);
-}
-
-jintArray NewIntArray(JNIEnv* env, jsize length) {
-  ScopedJniThreadState ts(env);
-  return NewPrimitiveArray<jintArray, IntArray>(ts, length);
-}
-
-jlongArray NewLongArray(JNIEnv* env, jsize length) {
-  ScopedJniThreadState ts(env);
-  return NewPrimitiveArray<jlongArray, LongArray>(ts, length);
-}
-
-jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_jclass, jobject initial_element) {
-  ScopedJniThreadState ts(env);
-  CHECK_GE(length, 0); // TODO: ReportJniError
-
-  // Compute the array class corresponding to the given element class.
-  Class* element_class = Decode<Class*>(ts, element_jclass);
-  std::string descriptor;
-  descriptor += "[";
-  descriptor += element_class->GetDescriptor().ToString();
-
-  // Find the class.
-  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
-  // TODO: need to get the appropriate ClassLoader.
-  Class* array_class = class_linker->FindClass(descriptor, NULL);
-  if (array_class == NULL) {
+  static jclass DefineClass(JNIEnv* env, const char*, jobject, const jbyte*, jsize) {
+    ScopedJniThreadState ts(env);
+    LOG(WARNING) << "JNI DefineClass is not supported";
     return NULL;
   }
 
-  ObjectArray<Object>* result = ObjectArray<Object>::Alloc(array_class, length);
-  CHECK(initial_element == NULL);  // TODO: support initial_element
-  return AddLocalReference<jobjectArray>(ts, result);
-}
-
-jshortArray NewShortArray(JNIEnv* env, jsize length) {
-  ScopedJniThreadState ts(env);
-  return NewPrimitiveArray<jshortArray, ShortArray>(ts, length);
-}
-
-jboolean* GetBooleanArrayElements(JNIEnv* env,
-    jbooleanArray array, jboolean* isCopy) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* isCopy) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* isCopy) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-jshort* GetShortArrayElements(JNIEnv* env,
-    jshortArray array, jboolean* isCopy) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* isCopy) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* isCopy) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-jfloat* GetFloatArrayElements(JNIEnv* env,
-    jfloatArray array, jboolean* isCopy) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-jdouble* GetDoubleArrayElements(JNIEnv* env,
-    jdoubleArray array, jboolean* isCopy) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-void ReleaseBooleanArrayElements(JNIEnv* env,
-    jbooleanArray array, jboolean* elems, jint mode) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void ReleaseByteArrayElements(JNIEnv* env,
-    jbyteArray array, jbyte* elems, jint mode) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void ReleaseCharArrayElements(JNIEnv* env,
-    jcharArray array, jchar* elems, jint mode) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void ReleaseShortArrayElements(JNIEnv* env,
-    jshortArray array, jshort* elems, jint mode) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void ReleaseIntArrayElements(JNIEnv* env,
-    jintArray array, jint* elems, jint mode) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void ReleaseLongArrayElements(JNIEnv* env,
-    jlongArray array, jlong* elems, jint mode) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void ReleaseFloatArrayElements(JNIEnv* env,
-    jfloatArray array, jfloat* elems, jint mode) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void ReleaseDoubleArrayElements(JNIEnv* env,
-    jdoubleArray array, jdouble* elems, jint mode) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void GetBooleanArrayRegion(JNIEnv* env,
-    jbooleanArray array, jsize start, jsize l, jboolean* buf) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void GetByteArrayRegion(JNIEnv* env,
-    jbyteArray array, jsize start, jsize len, jbyte* buf) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void GetCharArrayRegion(JNIEnv* env,
-    jcharArray array, jsize start, jsize len, jchar* buf) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void GetShortArrayRegion(JNIEnv* env,
-    jshortArray array, jsize start, jsize len, jshort* buf) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void GetIntArrayRegion(JNIEnv* env,
-    jintArray array, jsize start, jsize len, jint* buf) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void GetLongArrayRegion(JNIEnv* env,
-    jlongArray array, jsize start, jsize len, jlong* buf) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void GetFloatArrayRegion(JNIEnv* env,
-    jfloatArray array, jsize start, jsize len, jfloat* buf) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void GetDoubleArrayRegion(JNIEnv* env,
-    jdoubleArray array, jsize start, jsize len, jdouble* buf) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void SetBooleanArrayRegion(JNIEnv* env,
-    jbooleanArray array, jsize start, jsize l, const jboolean* buf) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void SetByteArrayRegion(JNIEnv* env,
-    jbyteArray array, jsize start, jsize len, const jbyte* buf) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void SetCharArrayRegion(JNIEnv* env,
-    jcharArray array, jsize start, jsize len, const jchar* buf) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void SetShortArrayRegion(JNIEnv* env,
-    jshortArray array, jsize start, jsize len, const jshort* buf) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void SetIntArrayRegion(JNIEnv* env,
-    jintArray array, jsize start, jsize len, const jint* buf) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void SetLongArrayRegion(JNIEnv* env,
-    jlongArray array, jsize start, jsize len, const jlong* buf) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void SetFloatArrayRegion(JNIEnv* env,
-    jfloatArray array, jsize start, jsize len, const jfloat* buf) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-void SetDoubleArrayRegion(JNIEnv* env,
-    jdoubleArray array, jsize start, jsize len, const jdouble* buf) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
-
-jint RegisterNatives(JNIEnv* env,
-    jclass clazz, const JNINativeMethod* methods, jint nMethods) {
-  ScopedJniThreadState ts(env);
-  Class* klass = Decode<Class*>(ts, clazz);
-  for(int i = 0; i < nMethods; i++) {
-    const char* name = methods[i].name;
-    const char* sig = methods[i].signature;
-
-    if (*sig == '!') {
-      // TODO: fast jni. it's too noisy to log all these.
-      ++sig;
-    }
-
-    Method* method = klass->FindDirectMethod(name, sig);
-    if (method == NULL) {
-      method = klass->FindVirtualMethod(name, sig);
-    }
-    if (method == NULL) {
-      Thread* self = Thread::Current();
-      std::string class_name = klass->GetDescriptor().ToString();
-      // TODO: pretty print method names through a single routine
-      self->ThrowNewException("Ljava/lang/NoSuchMethodError;",
-                              "no method \"%s.%s%s\"",
-                              class_name.c_str(), name, sig);
-      return JNI_ERR;
-    } else if (!method->IsNative()) {
-      Thread* self = Thread::Current();
-      std::string class_name = klass->GetDescriptor().ToString();
-      // TODO: pretty print method names through a single routine
-      self->ThrowNewException("Ljava/lang/NoSuchMethodError;",
-                              "method \"%s.%s%s\" is not native",
-                              class_name.c_str(), name, sig);
-      return JNI_ERR;
-    }
-    method->RegisterNative(methods[i].fnPtr);
+  static jclass FindClass(JNIEnv* env, const char* name) {
+    ScopedJniThreadState ts(env);
+    ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+    std::string descriptor(NormalizeJniClassDescriptor(name));
+    // TODO: need to get the appropriate ClassLoader.
+    Class* c = class_linker->FindClass(descriptor, NULL);
+    return AddLocalReference<jclass>(ts, c);
   }
-  return JNI_OK;
-}
 
-jint UnregisterNatives(JNIEnv* env, jclass clazz) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
-
-jint MonitorEnter(JNIEnv* env, jobject obj) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(WARNING);
-  return 0;
-}
-
-jint MonitorExit(JNIEnv* env, jobject obj) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(WARNING);
-  return 0;
-}
-
-jint GetJavaVM(JNIEnv* env, JavaVM** vm) {
-  ScopedJniThreadState ts(env);
-  Runtime* runtime = Runtime::Current();
-  if (runtime != NULL) {
-    *vm = reinterpret_cast<JavaVM*>(runtime->GetJavaVM());
-  } else {
-    *vm = NULL;
+  static jmethodID FromReflectedMethod(JNIEnv* env, jobject java_method) {
+    ScopedJniThreadState ts(env);
+    Method* method = Decode<Method*>(ts, java_method);
+    return reinterpret_cast<jmethodID>(AddWeakGlobalReference(ts, method));
   }
-  return (*vm != NULL) ? JNI_OK : JNI_ERR;
-}
 
-void GetStringRegion(JNIEnv* env,
-    jstring str, jsize start, jsize len, jchar* buf) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
+  static jfieldID FromReflectedField(JNIEnv* env, jobject java_field) {
+    ScopedJniThreadState ts(env);
+    Field* field = Decode<Field*>(ts, java_field);
+    return reinterpret_cast<jfieldID>(AddWeakGlobalReference(ts, field));
+  }
 
-void GetStringUTFRegion(JNIEnv* env,
-    jstring str, jsize start, jsize len, char* buf) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
+  static jobject ToReflectedMethod(JNIEnv* env, jclass, jmethodID mid, jboolean) {
+    ScopedJniThreadState ts(env);
+    Method* method = DecodeMethod(ts, mid);
+    return AddLocalReference<jobject>(ts, method);
+  }
 
-void* GetPrimitiveArrayCritical(JNIEnv* env,
-    jarray array, jboolean* isCopy) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
+  static jobject ToReflectedField(JNIEnv* env, jclass, jfieldID fid, jboolean) {
+    ScopedJniThreadState ts(env);
+    Field* field = DecodeField(ts, fid);
+    return AddLocalReference<jobject>(ts, field);
+  }
 
-void ReleasePrimitiveArrayCritical(JNIEnv* env,
-    jarray array, void* carray, jint mode) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
+  static jclass GetSuperclass(JNIEnv* env, jclass sub) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return NULL;
+  }
 
-const jchar* GetStringCritical(JNIEnv* env, jstring s, jboolean* isCopy) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
+  static jboolean IsAssignableFrom(JNIEnv* env, jclass sub, jclass sup) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return JNI_FALSE;
+  }
 
-void ReleaseStringCritical(JNIEnv* env, jstring s, const jchar* cstr) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-}
+  static jint Throw(JNIEnv* env, jthrowable obj) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
 
-jboolean ExceptionCheck(JNIEnv* env) {
-  ScopedJniThreadState ts(env);
-  return ts.Self()->IsExceptionPending() ? JNI_TRUE : JNI_FALSE;
-}
+  static jint ThrowNew(JNIEnv* env, jclass clazz, const char* msg) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
 
-jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
+  static jthrowable ExceptionOccurred(JNIEnv* env) {
+    ScopedJniThreadState ts(env);
+    Object* exception = ts.Self()->GetException();
+    if (exception == NULL) {
+      return NULL;
+    } else {
+      // TODO: if adding a local reference failing causes the VM to abort
+      // then the following check will never occur.
+      jthrowable localException = AddLocalReference<jthrowable>(ts, exception);
+      if (localException == NULL) {
+        // We were unable to add a new local reference, and threw a new
+        // exception.  We can't return "exception", because it's not a
+        // local reference.  So we have to return NULL, indicating that
+        // there was no exception, even though it's pretty much raining
+        // exceptions in here.
+        LOG(WARNING) << "JNI WARNING: addLocal/exception combo";
+      }
+      return localException;
+    }
+  }
+
+  static void ExceptionDescribe(JNIEnv* env) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void ExceptionClear(JNIEnv* env) {
+    ScopedJniThreadState ts(env);
+    ts.Self()->ClearException();
+  }
+
+  static void FatalError(JNIEnv* env, const char* msg) {
+    ScopedJniThreadState ts(env);
+    LOG(FATAL) << "JNI FatalError called: " << msg;
+  }
+
+  static jint PushLocalFrame(JNIEnv* env, jint cap) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(WARNING) << "ignoring PushLocalFrame(" << cap << ")";
+    return JNI_OK;
+  }
+
+  static jobject PopLocalFrame(JNIEnv* env, jobject res) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(WARNING) << "ignoring PopLocalFrame " << res;
+    return res;
+  }
+
+  static jobject NewGlobalRef(JNIEnv* env, jobject obj) {
+    ScopedJniThreadState ts(env);
+    if (obj == NULL) {
+      return NULL;
+    }
+
+    JavaVMExt* vm = Runtime::Current()->GetJavaVM();
+    IndirectReferenceTable& globals = vm->globals;
+    MutexLock mu(vm->globals_lock);
+    IndirectRef ref = globals.Add(IRT_FIRST_SEGMENT, Decode<Object*>(ts, obj));
+    return reinterpret_cast<jobject>(ref);
+  }
+
+  static void DeleteGlobalRef(JNIEnv* env, jobject obj) {
+    ScopedJniThreadState ts(env);
+    if (obj == NULL) {
+      return;
+    }
+
+    JavaVMExt* vm = Runtime::Current()->GetJavaVM();
+    IndirectReferenceTable& globals = vm->globals;
+    MutexLock mu(vm->globals_lock);
+
+    if (!globals.Remove(IRT_FIRST_SEGMENT, obj)) {
+      LOG(WARNING) << "JNI WARNING: DeleteGlobalRef(" << obj << ") "
+                   << "failed to find entry";
+    }
+  }
+
+  static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
+    ScopedJniThreadState ts(env);
+    return AddWeakGlobalReference(ts, Decode<Object*>(ts, obj));
+  }
+
+  static void DeleteWeakGlobalRef(JNIEnv* env, jweak obj) {
+    ScopedJniThreadState ts(env);
+    if (obj == NULL) {
+      return;
+    }
+
+    JavaVMExt* vm = Runtime::Current()->GetJavaVM();
+    IndirectReferenceTable& weak_globals = vm->weak_globals;
+    MutexLock mu(vm->weak_globals_lock);
+
+    if (!weak_globals.Remove(IRT_FIRST_SEGMENT, obj)) {
+      LOG(WARNING) << "JNI WARNING: DeleteWeakGlobalRef(" << obj << ") "
+                   << "failed to find entry";
+    }
+  }
+
+  static jobject NewLocalRef(JNIEnv* env, jobject obj) {
+    ScopedJniThreadState ts(env);
+    if (obj == NULL) {
+      return NULL;
+    }
+
+    IndirectReferenceTable& locals = ts.Env()->locals;
+
+    uint32_t cookie = IRT_FIRST_SEGMENT; // TODO
+    IndirectRef ref = locals.Add(cookie, Decode<Object*>(ts, obj));
+    return reinterpret_cast<jobject>(ref);
+  }
+
+  static void DeleteLocalRef(JNIEnv* env, jobject obj) {
+    ScopedJniThreadState ts(env);
+    if (obj == NULL) {
+      return;
+    }
+
+    IndirectReferenceTable& locals = ts.Env()->locals;
+
+    uint32_t cookie = IRT_FIRST_SEGMENT; // TODO
+    if (!locals.Remove(cookie, obj)) {
+      // Attempting to delete a local reference that is not in the
+      // topmost local reference frame is a no-op.  DeleteLocalRef returns
+      // void and doesn't throw any exceptions, but we should probably
+      // complain about it so the user will notice that things aren't
+      // going quite the way they expect.
+      LOG(WARNING) << "JNI WARNING: DeleteLocalRef(" << obj << ") "
+                   << "failed to find entry";
+    }
+  }
+
+  static jboolean IsSameObject(JNIEnv* env, jobject obj1, jobject obj2) {
+    ScopedJniThreadState ts(env);
+    return (Decode<Object*>(ts, obj1) == Decode<Object*>(ts, obj2))
+        ? JNI_TRUE : JNI_FALSE;
+  }
+
+  static jint EnsureLocalCapacity(JNIEnv* env, jint) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jobject AllocObject(JNIEnv* env, jclass clazz) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return NULL;
+  }
+
+  static jobject NewObject(JNIEnv* env, jclass clazz, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    va_list args;
+    va_start(args, methodID);
+    jobject result = NewObjectV(env, clazz, methodID, args);
+    va_end(args);
+    return result;
+  }
+
+  static jobject NewObjectV(JNIEnv* env,
+      jclass clazz, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    Class* klass = Decode<Class*>(ts, clazz);
+    Object* result = klass->NewInstance();
+    jobject local_result = AddLocalReference<jobject>(ts, result);
+    CallNonvirtualVoidMethodV(env, local_result, clazz, methodID, args);
+    return local_result;
+  }
+
+  static jobject NewObjectA(JNIEnv* env,
+      jclass clazz, jmethodID methodID, jvalue* args) {
+    ScopedJniThreadState ts(env);
+    Class* klass = Decode<Class*>(ts, clazz);
+    Object* result = klass->NewInstance();
+    jobject local_result = AddLocalReference<jobjectArray>(ts, result);
+    CallNonvirtualVoidMethodA(env, local_result, clazz, methodID, args);
+    return local_result;
+  }
+
+  static jclass GetObjectClass(JNIEnv* env, jobject obj) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return NULL;
+  }
+
+  static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass clazz) {
+    ScopedJniThreadState ts(env);
+    CHECK_NE(static_cast<jclass>(NULL), clazz);
+    if (jobj == NULL) {
+      // NB. JNI is different from regular Java instanceof in this respect
+      return JNI_TRUE;
+    } else {
+      Object* obj = Decode<Object*>(ts, jobj);
+      Class* klass = Decode<Class*>(ts, clazz);
+      return Object::InstanceOf(obj, klass) ? JNI_TRUE : JNI_FALSE;
+    }
+  }
+
+  static jmethodID GetMethodID(JNIEnv* env, jclass c, const char* name, const char* sig) {
+    ScopedJniThreadState ts(env);
+    return FindMethodID(ts, c, name, sig, false);
+  }
+
+  static jmethodID GetStaticMethodID(JNIEnv* env, jclass c, const char* name, const char* sig) {
+    ScopedJniThreadState ts(env);
+    return FindMethodID(ts, c, name, sig, true);
+  }
+
+  static jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return NULL;
+  }
+
+  static jobject CallObjectMethodV(JNIEnv* env,
+      jobject obj, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return NULL;
+  }
+
+  static jobject CallObjectMethodA(JNIEnv* env,
+      jobject obj, jmethodID methodID, jvalue*  args) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return NULL;
+  }
+
+  static jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return JNI_FALSE;
+  }
+
+  static jboolean CallBooleanMethodV(JNIEnv* env,
+      jobject obj, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return JNI_FALSE;
+  }
+
+  static jboolean CallBooleanMethodA(JNIEnv* env,
+      jobject obj, jmethodID methodID, jvalue*  args) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return JNI_FALSE;
+  }
+
+  static jbyte CallByteMethod(JNIEnv* env, jobject obj, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jbyte CallByteMethodV(JNIEnv* env,
+      jobject obj, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jbyte CallByteMethodA(JNIEnv* env,
+      jobject obj, jmethodID methodID, jvalue* args) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jchar CallCharMethod(JNIEnv* env, jobject obj, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jchar CallCharMethodV(JNIEnv* env,
+      jobject obj, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jchar CallCharMethodA(JNIEnv* env,
+      jobject obj, jmethodID methodID, jvalue* args) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jshort CallShortMethod(JNIEnv* env, jobject obj, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jshort CallShortMethodV(JNIEnv* env,
+      jobject obj, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jshort CallShortMethodA(JNIEnv* env,
+      jobject obj, jmethodID methodID, jvalue* args) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jint CallIntMethod(JNIEnv* env, jobject obj, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jint CallIntMethodV(JNIEnv* env,
+      jobject obj, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jint CallIntMethodA(JNIEnv* env,
+      jobject obj, jmethodID methodID, jvalue* args) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jlong CallLongMethod(JNIEnv* env, jobject obj, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jlong CallLongMethodV(JNIEnv* env,
+      jobject obj, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jlong CallLongMethodA(JNIEnv* env,
+      jobject obj, jmethodID methodID, jvalue* args) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jfloat CallFloatMethodV(JNIEnv* env,
+      jobject obj, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jfloat CallFloatMethodA(JNIEnv* env,
+      jobject obj, jmethodID methodID, jvalue* args) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jdouble CallDoubleMethod(JNIEnv* env, jobject obj, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jdouble CallDoubleMethodV(JNIEnv* env,
+      jobject obj, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jdouble CallDoubleMethodA(JNIEnv* env,
+      jobject obj, jmethodID methodID, jvalue* args) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void CallVoidMethodV(JNIEnv* env, jobject obj,
+      jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void CallVoidMethodA(JNIEnv* env, jobject obj,
+      jmethodID methodID, jvalue*  args) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static jobject CallNonvirtualObjectMethod(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    va_list ap;
+    va_start(ap, methodID);
+    JValue result = InvokeWithVarArgs(ts, obj, methodID, ap);
+    jobject local_result = AddLocalReference<jobject>(ts, result.l);
+    va_end(ap);
+    return local_result;
+  }
+
+  static jobject CallNonvirtualObjectMethodV(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    JValue result = InvokeWithVarArgs(ts, obj, methodID, args);
+    return AddLocalReference<jobject>(ts, result.l);
+  }
+
+  static jobject CallNonvirtualObjectMethodA(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, jvalue*  args) {
+    ScopedJniThreadState ts(env);
+    JValue result = InvokeWithJValues(ts, obj, methodID, args);
+    return AddLocalReference<jobject>(ts, result.l);
+  }
+
+  static jboolean CallNonvirtualBooleanMethod(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    va_list ap;
+    va_start(ap, methodID);
+    JValue result = InvokeWithVarArgs(ts, obj, methodID, ap);
+    va_end(ap);
+    return result.z;
+  }
+
+  static jboolean CallNonvirtualBooleanMethodV(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithVarArgs(ts, obj, methodID, args).z;
+  }
+
+  static jboolean CallNonvirtualBooleanMethodA(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, jvalue*  args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithJValues(ts, obj, methodID, args).z;
+  }
+
+  static jbyte CallNonvirtualByteMethod(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    va_list ap;
+    va_start(ap, methodID);
+    JValue result = InvokeWithVarArgs(ts, obj, methodID, ap);
+    va_end(ap);
+    return result.b;
+  }
+
+  static jbyte CallNonvirtualByteMethodV(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithVarArgs(ts, obj, methodID, args).b;
+  }
+
+  static jbyte CallNonvirtualByteMethodA(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, jvalue* args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithJValues(ts, obj, methodID, args).b;
+  }
+
+  static jchar CallNonvirtualCharMethod(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    va_list ap;
+    va_start(ap, methodID);
+    JValue result = InvokeWithVarArgs(ts, obj, methodID, ap);
+    va_end(ap);
+    return result.c;
+  }
+
+  static jchar CallNonvirtualCharMethodV(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithVarArgs(ts, obj, methodID, args).c;
+  }
+
+  static jchar CallNonvirtualCharMethodA(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, jvalue* args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithJValues(ts, obj, methodID, args).c;
+  }
+
+  static jshort CallNonvirtualShortMethod(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    va_list ap;
+    va_start(ap, methodID);
+    JValue result = InvokeWithVarArgs(ts, obj, methodID, ap);
+    va_end(ap);
+    return result.s;
+  }
+
+  static jshort CallNonvirtualShortMethodV(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithVarArgs(ts, obj, methodID, args).s;
+  }
+
+  static jshort CallNonvirtualShortMethodA(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, jvalue* args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithJValues(ts, obj, methodID, args).s;
+  }
+
+  static jint CallNonvirtualIntMethod(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    va_list ap;
+    va_start(ap, methodID);
+    JValue result = InvokeWithVarArgs(ts, obj, methodID, ap);
+    va_end(ap);
+    return result.i;
+  }
+
+  static jint CallNonvirtualIntMethodV(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithVarArgs(ts, obj, methodID, args).i;
+  }
+
+  static jint CallNonvirtualIntMethodA(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, jvalue* args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithJValues(ts, obj, methodID, args).i;
+  }
+
+  static jlong CallNonvirtualLongMethod(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    va_list ap;
+    va_start(ap, methodID);
+    JValue result = InvokeWithVarArgs(ts, obj, methodID, ap);
+    va_end(ap);
+    return result.j;
+  }
+
+  static jlong CallNonvirtualLongMethodV(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithVarArgs(ts, obj, methodID, args).j;
+  }
+
+  static jlong CallNonvirtualLongMethodA(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, jvalue* args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithJValues(ts, obj, methodID, args).j;
+  }
+
+  static jfloat CallNonvirtualFloatMethod(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    va_list ap;
+    va_start(ap, methodID);
+    JValue result = InvokeWithVarArgs(ts, obj, methodID, ap);
+    va_end(ap);
+    return result.f;
+  }
+
+  static jfloat CallNonvirtualFloatMethodV(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithVarArgs(ts, obj, methodID, args).f;
+  }
+
+  static jfloat CallNonvirtualFloatMethodA(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, jvalue* args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithJValues(ts, obj, methodID, args).f;
+  }
+
+  static jdouble CallNonvirtualDoubleMethod(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    va_list ap;
+    va_start(ap, methodID);
+    JValue result = InvokeWithVarArgs(ts, obj, methodID, ap);
+    va_end(ap);
+    return result.d;
+  }
+
+  static jdouble CallNonvirtualDoubleMethodV(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithVarArgs(ts, obj, methodID, args).d;
+  }
+
+  static jdouble CallNonvirtualDoubleMethodA(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, jvalue* args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithJValues(ts, obj, methodID, args).d;
+  }
+
+  static void CallNonvirtualVoidMethod(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    va_list ap;
+    va_start(ap, methodID);
+    InvokeWithVarArgs(ts, obj, methodID, ap);
+    va_end(ap);
+  }
+
+  static void CallNonvirtualVoidMethodV(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    InvokeWithVarArgs(ts, obj, methodID, args);
+  }
+
+  static void CallNonvirtualVoidMethodA(JNIEnv* env,
+      jobject obj, jclass clazz, jmethodID methodID, jvalue*  args) {
+    ScopedJniThreadState ts(env);
+    InvokeWithJValues(ts, obj, methodID, args);
+  }
+
+  static jfieldID GetFieldID(JNIEnv* env,
+      jclass c, const char* name, const char* sig) {
+    ScopedJniThreadState ts(env);
+    return FindFieldID(ts, c, name, sig, false);
+  }
 
 
-void* GetDirectBufferAddress(JNIEnv* env, jobject buf) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
+  static jfieldID GetStaticFieldID(JNIEnv* env,
+      jclass c, const char* name, const char* sig) {
+    ScopedJniThreadState ts(env);
+    return FindFieldID(ts, c, name, sig, true);
+  }
 
-jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return 0;
-}
+  static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fieldID) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return NULL;
+  }
 
-jobjectRefType GetObjectRefType(JNIEnv* env, jobject jobj) {
-  ScopedJniThreadState ts(env);
-  UNIMPLEMENTED(FATAL);
-  return JNIInvalidRefType;
-}
+  static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fieldID) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return JNI_FALSE;
+  }
+
+  static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fieldID) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fieldID) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fieldID) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fieldID) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fieldID) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fieldID) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fieldID) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static void SetObjectField(JNIEnv* env, jobject obj, jfieldID fieldID, jobject val) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fieldID, jboolean val) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void SetByteField(JNIEnv* env, jobject obj, jfieldID fieldID, jbyte val) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void SetCharField(JNIEnv* env, jobject obj, jfieldID fieldID, jchar val) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void SetShortField(JNIEnv* env, jobject obj, jfieldID fieldID, jshort val) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void SetIntField(JNIEnv* env, jobject obj, jfieldID fieldID, jint val) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void SetLongField(JNIEnv* env, jobject obj, jfieldID fieldID, jlong val) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fieldID, jfloat val) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fieldID, jdouble val) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static jobject CallStaticObjectMethod(JNIEnv* env,
+      jclass clazz, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    va_list ap;
+    va_start(ap, methodID);
+    JValue result = InvokeWithVarArgs(ts, NULL, methodID, ap);
+    jobject local_result = AddLocalReference<jobject>(ts, result.l);
+    va_end(ap);
+    return local_result;
+  }
+
+  static jobject CallStaticObjectMethodV(JNIEnv* env,
+      jclass clazz, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    JValue result = InvokeWithVarArgs(ts, NULL, methodID, args);
+    return AddLocalReference<jobject>(ts, result.l);
+  }
+
+  static jobject CallStaticObjectMethodA(JNIEnv* env,
+      jclass clazz, jmethodID methodID, jvalue* args) {
+    ScopedJniThreadState ts(env);
+    JValue result = InvokeWithJValues(ts, NULL, methodID, args);
+    return AddLocalReference<jobject>(ts, result.l);
+  }
+
+  static jboolean CallStaticBooleanMethod(JNIEnv* env,
+      jclass clazz, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    va_list ap;
+    va_start(ap, methodID);
+    JValue result = InvokeWithVarArgs(ts, NULL, methodID, ap);
+    va_end(ap);
+    return result.z;
+  }
+
+  static jboolean CallStaticBooleanMethodV(JNIEnv* env,
+      jclass clazz, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithVarArgs(ts, NULL, methodID, args).z;
+  }
+
+  static jboolean CallStaticBooleanMethodA(JNIEnv* env,
+      jclass clazz, jmethodID methodID, jvalue* args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithJValues(ts, NULL, methodID, args).z;
+  }
+
+  static jbyte CallStaticByteMethod(JNIEnv* env, jclass clazz, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    va_list ap;
+    va_start(ap, methodID);
+    JValue result = InvokeWithVarArgs(ts, NULL, methodID, ap);
+    va_end(ap);
+    return result.b;
+  }
+
+  static jbyte CallStaticByteMethodV(JNIEnv* env,
+      jclass clazz, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithVarArgs(ts, NULL, methodID, args).b;
+  }
+
+  static jbyte CallStaticByteMethodA(JNIEnv* env,
+      jclass clazz, jmethodID methodID, jvalue* args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithJValues(ts, NULL, methodID, args).b;
+  }
+
+  static jchar CallStaticCharMethod(JNIEnv* env, jclass clazz, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    va_list ap;
+    va_start(ap, methodID);
+    JValue result = InvokeWithVarArgs(ts, NULL, methodID, ap);
+    va_end(ap);
+    return result.c;
+  }
+
+  static jchar CallStaticCharMethodV(JNIEnv* env,
+      jclass clazz, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithVarArgs(ts, NULL, methodID, args).c;
+  }
+
+  static jchar CallStaticCharMethodA(JNIEnv* env,
+      jclass clazz, jmethodID methodID, jvalue* args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithJValues(ts, NULL, methodID, args).c;
+  }
+
+  static jshort CallStaticShortMethod(JNIEnv* env, jclass clazz, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    va_list ap;
+    va_start(ap, methodID);
+    JValue result = InvokeWithVarArgs(ts, NULL, methodID, ap);
+    va_end(ap);
+    return result.s;
+  }
+
+  static jshort CallStaticShortMethodV(JNIEnv* env,
+      jclass clazz, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithVarArgs(ts, NULL, methodID, args).s;
+  }
+
+  static jshort CallStaticShortMethodA(JNIEnv* env,
+      jclass clazz, jmethodID methodID, jvalue* args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithJValues(ts, NULL, methodID, args).s;
+  }
+
+  static jint CallStaticIntMethod(JNIEnv* env, jclass clazz, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    va_list ap;
+    va_start(ap, methodID);
+    JValue result = InvokeWithVarArgs(ts, NULL, methodID, ap);
+    va_end(ap);
+    return result.i;
+  }
+
+  static jint CallStaticIntMethodV(JNIEnv* env,
+      jclass clazz, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithVarArgs(ts, NULL, methodID, args).i;
+  }
+
+  static jint CallStaticIntMethodA(JNIEnv* env,
+      jclass clazz, jmethodID methodID, jvalue* args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithJValues(ts, NULL, methodID, args).i;
+  }
+
+  static jlong CallStaticLongMethod(JNIEnv* env, jclass clazz, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    va_list ap;
+    va_start(ap, methodID);
+    JValue result = InvokeWithVarArgs(ts, NULL, methodID, ap);
+    va_end(ap);
+    return result.j;
+  }
+
+  static jlong CallStaticLongMethodV(JNIEnv* env,
+      jclass clazz, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithVarArgs(ts, NULL, methodID, args).j;
+  }
+
+  static jlong CallStaticLongMethodA(JNIEnv* env,
+      jclass clazz, jmethodID methodID, jvalue* args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithJValues(ts, NULL, methodID, args).j;
+  }
+
+  static jfloat CallStaticFloatMethod(JNIEnv* env, jclass cls, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    va_list ap;
+    va_start(ap, methodID);
+    JValue result = InvokeWithVarArgs(ts, NULL, methodID, ap);
+    va_end(ap);
+    return result.f;
+  }
+
+  static jfloat CallStaticFloatMethodV(JNIEnv* env,
+      jclass clazz, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithVarArgs(ts, NULL, methodID, args).f;
+  }
+
+  static jfloat CallStaticFloatMethodA(JNIEnv* env,
+      jclass clazz, jmethodID methodID, jvalue* args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithJValues(ts, NULL, methodID, args).f;
+  }
+
+  static jdouble CallStaticDoubleMethod(JNIEnv* env, jclass cls, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    va_list ap;
+    va_start(ap, methodID);
+    JValue result = InvokeWithVarArgs(ts, NULL, methodID, ap);
+    va_end(ap);
+    return result.d;
+  }
+
+  static jdouble CallStaticDoubleMethodV(JNIEnv* env,
+      jclass clazz, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithVarArgs(ts, NULL, methodID, args).d;
+  }
+
+  static jdouble CallStaticDoubleMethodA(JNIEnv* env,
+      jclass clazz, jmethodID methodID, jvalue* args) {
+    ScopedJniThreadState ts(env);
+    return InvokeWithJValues(ts, NULL, methodID, args).d;
+  }
+
+  static void CallStaticVoidMethod(JNIEnv* env, jclass cls, jmethodID methodID, ...) {
+    ScopedJniThreadState ts(env);
+    va_list ap;
+    va_start(ap, methodID);
+    InvokeWithVarArgs(ts, NULL, methodID, ap);
+    va_end(ap);
+  }
+
+  static void CallStaticVoidMethodV(JNIEnv* env,
+      jclass cls, jmethodID methodID, va_list args) {
+    ScopedJniThreadState ts(env);
+    InvokeWithVarArgs(ts, NULL, methodID, args);
+  }
+
+  static void CallStaticVoidMethodA(JNIEnv* env,
+      jclass cls, jmethodID methodID, jvalue* args) {
+    ScopedJniThreadState ts(env);
+    InvokeWithJValues(ts, NULL, methodID, args);
+  }
+
+  static jobject GetStaticObjectField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return NULL;
+  }
+
+  static jboolean GetStaticBooleanField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return JNI_FALSE;
+  }
+
+  static jbyte GetStaticByteField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jchar GetStaticCharField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jshort GetStaticShortField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jint GetStaticIntField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jlong GetStaticLongField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jfloat GetStaticFloatField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jdouble GetStaticDoubleField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static void SetStaticObjectField(JNIEnv* env,
+      jclass clazz, jfieldID fieldID, jobject value) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void SetStaticBooleanField(JNIEnv* env,
+      jclass clazz, jfieldID fieldID, jboolean value) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void SetStaticByteField(JNIEnv* env,
+      jclass clazz, jfieldID fieldID, jbyte value) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void SetStaticCharField(JNIEnv* env,
+      jclass clazz, jfieldID fieldID, jchar value) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void SetStaticShortField(JNIEnv* env,
+      jclass clazz, jfieldID fieldID, jshort value) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void SetStaticIntField(JNIEnv* env,
+      jclass clazz, jfieldID fieldID, jint value) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void SetStaticLongField(JNIEnv* env,
+      jclass clazz, jfieldID fieldID, jlong value) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void SetStaticFloatField(JNIEnv* env,
+      jclass clazz, jfieldID fieldID, jfloat value) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void SetStaticDoubleField(JNIEnv* env,
+      jclass clazz, jfieldID fieldID, jdouble value) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static jstring NewString(JNIEnv* env, const jchar* unicode, jsize len) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return NULL;
+  }
+
+  static jsize GetStringLength(JNIEnv* env, jstring str) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static const jchar* GetStringChars(JNIEnv* env, jstring str, jboolean* isCopy) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return NULL;
+  }
+
+  static void ReleaseStringChars(JNIEnv* env, jstring str, const jchar* chars) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static jstring NewStringUTF(JNIEnv* env, const char* utf) {
+    ScopedJniThreadState ts(env);
+    if (utf == NULL) {
+      return NULL;
+    }
+    String* result = String::AllocFromModifiedUtf8(utf);
+    return AddLocalReference<jstring>(ts, result);
+  }
+
+  static jsize GetStringUTFLength(JNIEnv* env, jstring str) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static const char* GetStringUTFChars(JNIEnv* env, jstring str, jboolean* isCopy) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return NULL;
+  }
+
+  static void ReleaseStringUTFChars(JNIEnv* env, jstring str, const char* chars) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static jsize GetArrayLength(JNIEnv* env, jarray array) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray array, jsize index) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return NULL;
+  }
+
+  static void SetObjectArrayElement(JNIEnv* env,
+      jobjectArray java_array, jsize index, jobject java_value) {
+    ScopedJniThreadState ts(env);
+    ObjectArray<Object>* array = Decode<ObjectArray<Object>*>(ts, java_array);
+    Object* value = Decode<Object*>(ts, java_value);
+    array->Set(index, value);
+  }
+
+  static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) {
+    ScopedJniThreadState ts(env);
+    return NewPrimitiveArray<jbooleanArray, BooleanArray>(ts, length);
+  }
+
+  static jbyteArray NewByteArray(JNIEnv* env, jsize length) {
+    ScopedJniThreadState ts(env);
+    return NewPrimitiveArray<jbyteArray, ByteArray>(ts, length);
+  }
+
+  static jcharArray NewCharArray(JNIEnv* env, jsize length) {
+    ScopedJniThreadState ts(env);
+    return NewPrimitiveArray<jcharArray, CharArray>(ts, length);
+  }
+
+  static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) {
+    ScopedJniThreadState ts(env);
+    return NewPrimitiveArray<jdoubleArray, DoubleArray>(ts, length);
+  }
+
+  static jfloatArray NewFloatArray(JNIEnv* env, jsize length) {
+    ScopedJniThreadState ts(env);
+    return NewPrimitiveArray<jfloatArray, FloatArray>(ts, length);
+  }
+
+  static jintArray NewIntArray(JNIEnv* env, jsize length) {
+    ScopedJniThreadState ts(env);
+    return NewPrimitiveArray<jintArray, IntArray>(ts, length);
+  }
+
+  static jlongArray NewLongArray(JNIEnv* env, jsize length) {
+    ScopedJniThreadState ts(env);
+    return NewPrimitiveArray<jlongArray, LongArray>(ts, length);
+  }
+
+  static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_jclass, jobject initial_element) {
+    ScopedJniThreadState ts(env);
+    CHECK_GE(length, 0); // TODO: ReportJniError
+
+    // Compute the array class corresponding to the given element class.
+    Class* element_class = Decode<Class*>(ts, element_jclass);
+    std::string descriptor;
+    descriptor += "[";
+    descriptor += element_class->GetDescriptor().ToString();
+
+    // Find the class.
+    ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+    // TODO: need to get the appropriate ClassLoader.
+    Class* array_class = class_linker->FindClass(descriptor, NULL);
+    if (array_class == NULL) {
+      return NULL;
+    }
+
+    ObjectArray<Object>* result = ObjectArray<Object>::Alloc(array_class, length);
+    CHECK(initial_element == NULL);  // TODO: support initial_element
+    return AddLocalReference<jobjectArray>(ts, result);
+  }
+
+  static jshortArray NewShortArray(JNIEnv* env, jsize length) {
+    ScopedJniThreadState ts(env);
+    return NewPrimitiveArray<jshortArray, ShortArray>(ts, length);
+  }
+
+  static jboolean* GetBooleanArrayElements(JNIEnv* env,
+      jbooleanArray array, jboolean* isCopy) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return NULL;
+  }
+
+  static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* isCopy) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return NULL;
+  }
+
+  static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* isCopy) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return NULL;
+  }
+
+  static jshort* GetShortArrayElements(JNIEnv* env,
+      jshortArray array, jboolean* isCopy) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return NULL;
+  }
+
+  static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* isCopy) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return NULL;
+  }
+
+  static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* isCopy) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return NULL;
+  }
+
+  static jfloat* GetFloatArrayElements(JNIEnv* env,
+      jfloatArray array, jboolean* isCopy) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return NULL;
+  }
+
+  static jdouble* GetDoubleArrayElements(JNIEnv* env,
+      jdoubleArray array, jboolean* isCopy) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return NULL;
+  }
+
+  static void ReleaseBooleanArrayElements(JNIEnv* env,
+      jbooleanArray array, jboolean* elems, jint mode) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void ReleaseByteArrayElements(JNIEnv* env,
+      jbyteArray array, jbyte* elems, jint mode) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void ReleaseCharArrayElements(JNIEnv* env,
+      jcharArray array, jchar* elems, jint mode) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void ReleaseShortArrayElements(JNIEnv* env,
+      jshortArray array, jshort* elems, jint mode) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void ReleaseIntArrayElements(JNIEnv* env,
+      jintArray array, jint* elems, jint mode) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void ReleaseLongArrayElements(JNIEnv* env,
+      jlongArray array, jlong* elems, jint mode) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void ReleaseFloatArrayElements(JNIEnv* env,
+      jfloatArray array, jfloat* elems, jint mode) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void ReleaseDoubleArrayElements(JNIEnv* env,
+      jdoubleArray array, jdouble* elems, jint mode) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void GetBooleanArrayRegion(JNIEnv* env,
+      jbooleanArray array, jsize start, jsize l, jboolean* buf) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void GetByteArrayRegion(JNIEnv* env,
+      jbyteArray array, jsize start, jsize len, jbyte* buf) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void GetCharArrayRegion(JNIEnv* env,
+      jcharArray array, jsize start, jsize len, jchar* buf) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void GetShortArrayRegion(JNIEnv* env,
+      jshortArray array, jsize start, jsize len, jshort* buf) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void GetIntArrayRegion(JNIEnv* env,
+      jintArray array, jsize start, jsize len, jint* buf) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void GetLongArrayRegion(JNIEnv* env,
+      jlongArray array, jsize start, jsize len, jlong* buf) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void GetFloatArrayRegion(JNIEnv* env,
+      jfloatArray array, jsize start, jsize len, jfloat* buf) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void GetDoubleArrayRegion(JNIEnv* env,
+      jdoubleArray array, jsize start, jsize len, jdouble* buf) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void SetBooleanArrayRegion(JNIEnv* env,
+      jbooleanArray array, jsize start, jsize l, const jboolean* buf) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void SetByteArrayRegion(JNIEnv* env,
+      jbyteArray array, jsize start, jsize len, const jbyte* buf) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void SetCharArrayRegion(JNIEnv* env,
+      jcharArray array, jsize start, jsize len, const jchar* buf) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void SetShortArrayRegion(JNIEnv* env,
+      jshortArray array, jsize start, jsize len, const jshort* buf) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void SetIntArrayRegion(JNIEnv* env,
+      jintArray array, jsize start, jsize len, const jint* buf) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void SetLongArrayRegion(JNIEnv* env,
+      jlongArray array, jsize start, jsize len, const jlong* buf) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void SetFloatArrayRegion(JNIEnv* env,
+      jfloatArray array, jsize start, jsize len, const jfloat* buf) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void SetDoubleArrayRegion(JNIEnv* env,
+      jdoubleArray array, jsize start, jsize len, const jdouble* buf) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static jint RegisterNatives(JNIEnv* env,
+      jclass clazz, const JNINativeMethod* methods, jint nMethods) {
+    ScopedJniThreadState ts(env);
+    Class* klass = Decode<Class*>(ts, clazz);
+    for(int i = 0; i < nMethods; i++) {
+      const char* name = methods[i].name;
+      const char* sig = methods[i].signature;
+
+      if (*sig == '!') {
+        // TODO: fast jni. it's too noisy to log all these.
+        ++sig;
+      }
+
+      Method* method = klass->FindDirectMethod(name, sig);
+      if (method == NULL) {
+        method = klass->FindVirtualMethod(name, sig);
+      }
+      if (method == NULL) {
+        Thread* self = Thread::Current();
+        std::string class_name = klass->GetDescriptor().ToString();
+        // TODO: pretty print method names through a single routine
+        self->ThrowNewException("Ljava/lang/NoSuchMethodError;",
+            "no method \"%s.%s%s\"",
+            class_name.c_str(), name, sig);
+        return JNI_ERR;
+      } else if (!method->IsNative()) {
+        Thread* self = Thread::Current();
+        std::string class_name = klass->GetDescriptor().ToString();
+        // TODO: pretty print method names through a single routine
+        self->ThrowNewException("Ljava/lang/NoSuchMethodError;",
+            "method \"%s.%s%s\" is not native",
+            class_name.c_str(), name, sig);
+        return JNI_ERR;
+      }
+      method->RegisterNative(methods[i].fnPtr);
+    }
+    return JNI_OK;
+  }
+
+  static jint UnregisterNatives(JNIEnv* env, jclass clazz) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jint MonitorEnter(JNIEnv* env, jobject obj) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(WARNING);
+    return 0;
+  }
+
+  static jint MonitorExit(JNIEnv* env, jobject obj) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(WARNING);
+    return 0;
+  }
+
+  static jint GetJavaVM(JNIEnv* env, JavaVM** vm) {
+    ScopedJniThreadState ts(env);
+    Runtime* runtime = Runtime::Current();
+    if (runtime != NULL) {
+      *vm = reinterpret_cast<JavaVM*>(runtime->GetJavaVM());
+    } else {
+      *vm = NULL;
+    }
+    return (*vm != NULL) ? JNI_OK : JNI_ERR;
+  }
+
+  static void GetStringRegion(JNIEnv* env,
+      jstring str, jsize start, jsize len, jchar* buf) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void GetStringUTFRegion(JNIEnv* env,
+      jstring str, jsize start, jsize len, char* buf) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static void* GetPrimitiveArrayCritical(JNIEnv* env,
+      jarray array, jboolean* isCopy) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return NULL;
+  }
+
+  static void ReleasePrimitiveArrayCritical(JNIEnv* env,
+      jarray array, void* carray, jint mode) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static const jchar* GetStringCritical(JNIEnv* env, jstring s, jboolean* isCopy) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return NULL;
+  }
+
+  static void ReleaseStringCritical(JNIEnv* env, jstring s, const jchar* cstr) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+  }
+
+  static jboolean ExceptionCheck(JNIEnv* env) {
+    ScopedJniThreadState ts(env);
+    return ts.Self()->IsExceptionPending() ? JNI_TRUE : JNI_FALSE;
+  }
+
+  static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return NULL;
+  }
+
+  static void* GetDirectBufferAddress(JNIEnv* env, jobject buf) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return NULL;
+  }
+
+  static jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return 0;
+  }
+
+  static jobjectRefType GetObjectRefType(JNIEnv* env, jobject jobj) {
+    ScopedJniThreadState ts(env);
+    UNIMPLEMENTED(FATAL);
+    return JNIInvalidRefType;
+  }
+};
 
 static const struct JNINativeInterface gNativeInterface = {
   NULL,  // reserved0.
   NULL,  // reserved1.
   NULL,  // reserved2.
   NULL,  // reserved3.
-  GetVersion,
-  DefineClass,
-  FindClass,
-  FromReflectedMethod,
-  FromReflectedField,
-  ToReflectedMethod,
-  GetSuperclass,
-  IsAssignableFrom,
-  ToReflectedField,
-  Throw,
-  ThrowNew,
-  ExceptionOccurred,
-  ExceptionDescribe,
-  ExceptionClear,
-  FatalError,
-  PushLocalFrame,
-  PopLocalFrame,
-  NewGlobalRef,
-  DeleteGlobalRef,
-  DeleteLocalRef,
-  IsSameObject,
-  NewLocalRef,
-  EnsureLocalCapacity,
-  AllocObject,
-  NewObject,
-  NewObjectV,
-  NewObjectA,
-  GetObjectClass,
-  IsInstanceOf,
-  GetMethodID,
-  CallObjectMethod,
-  CallObjectMethodV,
-  CallObjectMethodA,
-  CallBooleanMethod,
-  CallBooleanMethodV,
-  CallBooleanMethodA,
-  CallByteMethod,
-  CallByteMethodV,
-  CallByteMethodA,
-  CallCharMethod,
-  CallCharMethodV,
-  CallCharMethodA,
-  CallShortMethod,
-  CallShortMethodV,
-  CallShortMethodA,
-  CallIntMethod,
-  CallIntMethodV,
-  CallIntMethodA,
-  CallLongMethod,
-  CallLongMethodV,
-  CallLongMethodA,
-  CallFloatMethod,
-  CallFloatMethodV,
-  CallFloatMethodA,
-  CallDoubleMethod,
-  CallDoubleMethodV,
-  CallDoubleMethodA,
-  CallVoidMethod,
-  CallVoidMethodV,
-  CallVoidMethodA,
-  CallNonvirtualObjectMethod,
-  CallNonvirtualObjectMethodV,
-  CallNonvirtualObjectMethodA,
-  CallNonvirtualBooleanMethod,
-  CallNonvirtualBooleanMethodV,
-  CallNonvirtualBooleanMethodA,
-  CallNonvirtualByteMethod,
-  CallNonvirtualByteMethodV,
-  CallNonvirtualByteMethodA,
-  CallNonvirtualCharMethod,
-  CallNonvirtualCharMethodV,
-  CallNonvirtualCharMethodA,
-  CallNonvirtualShortMethod,
-  CallNonvirtualShortMethodV,
-  CallNonvirtualShortMethodA,
-  CallNonvirtualIntMethod,
-  CallNonvirtualIntMethodV,
-  CallNonvirtualIntMethodA,
-  CallNonvirtualLongMethod,
-  CallNonvirtualLongMethodV,
-  CallNonvirtualLongMethodA,
-  CallNonvirtualFloatMethod,
-  CallNonvirtualFloatMethodV,
-  CallNonvirtualFloatMethodA,
-  CallNonvirtualDoubleMethod,
-  CallNonvirtualDoubleMethodV,
-  CallNonvirtualDoubleMethodA,
-  CallNonvirtualVoidMethod,
-  CallNonvirtualVoidMethodV,
-  CallNonvirtualVoidMethodA,
-  GetFieldID,
-  GetObjectField,
-  GetBooleanField,
-  GetByteField,
-  GetCharField,
-  GetShortField,
-  GetIntField,
-  GetLongField,
-  GetFloatField,
-  GetDoubleField,
-  SetObjectField,
-  SetBooleanField,
-  SetByteField,
-  SetCharField,
-  SetShortField,
-  SetIntField,
-  SetLongField,
-  SetFloatField,
-  SetDoubleField,
-  GetStaticMethodID,
-  CallStaticObjectMethod,
-  CallStaticObjectMethodV,
-  CallStaticObjectMethodA,
-  CallStaticBooleanMethod,
-  CallStaticBooleanMethodV,
-  CallStaticBooleanMethodA,
-  CallStaticByteMethod,
-  CallStaticByteMethodV,
-  CallStaticByteMethodA,
-  CallStaticCharMethod,
-  CallStaticCharMethodV,
-  CallStaticCharMethodA,
-  CallStaticShortMethod,
-  CallStaticShortMethodV,
-  CallStaticShortMethodA,
-  CallStaticIntMethod,
-  CallStaticIntMethodV,
-  CallStaticIntMethodA,
-  CallStaticLongMethod,
-  CallStaticLongMethodV,
-  CallStaticLongMethodA,
-  CallStaticFloatMethod,
-  CallStaticFloatMethodV,
-  CallStaticFloatMethodA,
-  CallStaticDoubleMethod,
-  CallStaticDoubleMethodV,
-  CallStaticDoubleMethodA,
-  CallStaticVoidMethod,
-  CallStaticVoidMethodV,
-  CallStaticVoidMethodA,
-  GetStaticFieldID,
-  GetStaticObjectField,
-  GetStaticBooleanField,
-  GetStaticByteField,
-  GetStaticCharField,
-  GetStaticShortField,
-  GetStaticIntField,
-  GetStaticLongField,
-  GetStaticFloatField,
-  GetStaticDoubleField,
-  SetStaticObjectField,
-  SetStaticBooleanField,
-  SetStaticByteField,
-  SetStaticCharField,
-  SetStaticShortField,
-  SetStaticIntField,
-  SetStaticLongField,
-  SetStaticFloatField,
-  SetStaticDoubleField,
-  NewString,
-  GetStringLength,
-  GetStringChars,
-  ReleaseStringChars,
-  NewStringUTF,
-  GetStringUTFLength,
-  GetStringUTFChars,
-  ReleaseStringUTFChars,
-  GetArrayLength,
-  NewObjectArray,
-  GetObjectArrayElement,
-  SetObjectArrayElement,
-  NewBooleanArray,
-  NewByteArray,
-  NewCharArray,
-  NewShortArray,
-  NewIntArray,
-  NewLongArray,
-  NewFloatArray,
-  NewDoubleArray,
-  GetBooleanArrayElements,
-  GetByteArrayElements,
-  GetCharArrayElements,
-  GetShortArrayElements,
-  GetIntArrayElements,
-  GetLongArrayElements,
-  GetFloatArrayElements,
-  GetDoubleArrayElements,
-  ReleaseBooleanArrayElements,
-  ReleaseByteArrayElements,
-  ReleaseCharArrayElements,
-  ReleaseShortArrayElements,
-  ReleaseIntArrayElements,
-  ReleaseLongArrayElements,
-  ReleaseFloatArrayElements,
-  ReleaseDoubleArrayElements,
-  GetBooleanArrayRegion,
-  GetByteArrayRegion,
-  GetCharArrayRegion,
-  GetShortArrayRegion,
-  GetIntArrayRegion,
-  GetLongArrayRegion,
-  GetFloatArrayRegion,
-  GetDoubleArrayRegion,
-  SetBooleanArrayRegion,
-  SetByteArrayRegion,
-  SetCharArrayRegion,
-  SetShortArrayRegion,
-  SetIntArrayRegion,
-  SetLongArrayRegion,
-  SetFloatArrayRegion,
-  SetDoubleArrayRegion,
-  RegisterNatives,
-  UnregisterNatives,
-  MonitorEnter,
-  MonitorExit,
-  GetJavaVM,
-  GetStringRegion,
-  GetStringUTFRegion,
-  GetPrimitiveArrayCritical,
-  ReleasePrimitiveArrayCritical,
-  GetStringCritical,
-  ReleaseStringCritical,
-  NewWeakGlobalRef,
-  DeleteWeakGlobalRef,
-  ExceptionCheck,
-  NewDirectByteBuffer,
-  GetDirectBufferAddress,
-  GetDirectBufferCapacity,
-  GetObjectRefType,
+  JNI::GetVersion,
+  JNI::DefineClass,
+  JNI::FindClass,
+  JNI::FromReflectedMethod,
+  JNI::FromReflectedField,
+  JNI::ToReflectedMethod,
+  JNI::GetSuperclass,
+  JNI::IsAssignableFrom,
+  JNI::ToReflectedField,
+  JNI::Throw,
+  JNI::ThrowNew,
+  JNI::ExceptionOccurred,
+  JNI::ExceptionDescribe,
+  JNI::ExceptionClear,
+  JNI::FatalError,
+  JNI::PushLocalFrame,
+  JNI::PopLocalFrame,
+  JNI::NewGlobalRef,
+  JNI::DeleteGlobalRef,
+  JNI::DeleteLocalRef,
+  JNI::IsSameObject,
+  JNI::NewLocalRef,
+  JNI::EnsureLocalCapacity,
+  JNI::AllocObject,
+  JNI::NewObject,
+  JNI::NewObjectV,
+  JNI::NewObjectA,
+  JNI::GetObjectClass,
+  JNI::IsInstanceOf,
+  JNI::GetMethodID,
+  JNI::CallObjectMethod,
+  JNI::CallObjectMethodV,
+  JNI::CallObjectMethodA,
+  JNI::CallBooleanMethod,
+  JNI::CallBooleanMethodV,
+  JNI::CallBooleanMethodA,
+  JNI::CallByteMethod,
+  JNI::CallByteMethodV,
+  JNI::CallByteMethodA,
+  JNI::CallCharMethod,
+  JNI::CallCharMethodV,
+  JNI::CallCharMethodA,
+  JNI::CallShortMethod,
+  JNI::CallShortMethodV,
+  JNI::CallShortMethodA,
+  JNI::CallIntMethod,
+  JNI::CallIntMethodV,
+  JNI::CallIntMethodA,
+  JNI::CallLongMethod,
+  JNI::CallLongMethodV,
+  JNI::CallLongMethodA,
+  JNI::CallFloatMethod,
+  JNI::CallFloatMethodV,
+  JNI::CallFloatMethodA,
+  JNI::CallDoubleMethod,
+  JNI::CallDoubleMethodV,
+  JNI::CallDoubleMethodA,
+  JNI::CallVoidMethod,
+  JNI::CallVoidMethodV,
+  JNI::CallVoidMethodA,
+  JNI::CallNonvirtualObjectMethod,
+  JNI::CallNonvirtualObjectMethodV,
+  JNI::CallNonvirtualObjectMethodA,
+  JNI::CallNonvirtualBooleanMethod,
+  JNI::CallNonvirtualBooleanMethodV,
+  JNI::CallNonvirtualBooleanMethodA,
+  JNI::CallNonvirtualByteMethod,
+  JNI::CallNonvirtualByteMethodV,
+  JNI::CallNonvirtualByteMethodA,
+  JNI::CallNonvirtualCharMethod,
+  JNI::CallNonvirtualCharMethodV,
+  JNI::CallNonvirtualCharMethodA,
+  JNI::CallNonvirtualShortMethod,
+  JNI::CallNonvirtualShortMethodV,
+  JNI::CallNonvirtualShortMethodA,
+  JNI::CallNonvirtualIntMethod,
+  JNI::CallNonvirtualIntMethodV,
+  JNI::CallNonvirtualIntMethodA,
+  JNI::CallNonvirtualLongMethod,
+  JNI::CallNonvirtualLongMethodV,
+  JNI::CallNonvirtualLongMethodA,
+  JNI::CallNonvirtualFloatMethod,
+  JNI::CallNonvirtualFloatMethodV,
+  JNI::CallNonvirtualFloatMethodA,
+  JNI::CallNonvirtualDoubleMethod,
+  JNI::CallNonvirtualDoubleMethodV,
+  JNI::CallNonvirtualDoubleMethodA,
+  JNI::CallNonvirtualVoidMethod,
+  JNI::CallNonvirtualVoidMethodV,
+  JNI::CallNonvirtualVoidMethodA,
+  JNI::GetFieldID,
+  JNI::GetObjectField,
+  JNI::GetBooleanField,
+  JNI::GetByteField,
+  JNI::GetCharField,
+  JNI::GetShortField,
+  JNI::GetIntField,
+  JNI::GetLongField,
+  JNI::GetFloatField,
+  JNI::GetDoubleField,
+  JNI::SetObjectField,
+  JNI::SetBooleanField,
+  JNI::SetByteField,
+  JNI::SetCharField,
+  JNI::SetShortField,
+  JNI::SetIntField,
+  JNI::SetLongField,
+  JNI::SetFloatField,
+  JNI::SetDoubleField,
+  JNI::GetStaticMethodID,
+  JNI::CallStaticObjectMethod,
+  JNI::CallStaticObjectMethodV,
+  JNI::CallStaticObjectMethodA,
+  JNI::CallStaticBooleanMethod,
+  JNI::CallStaticBooleanMethodV,
+  JNI::CallStaticBooleanMethodA,
+  JNI::CallStaticByteMethod,
+  JNI::CallStaticByteMethodV,
+  JNI::CallStaticByteMethodA,
+  JNI::CallStaticCharMethod,
+  JNI::CallStaticCharMethodV,
+  JNI::CallStaticCharMethodA,
+  JNI::CallStaticShortMethod,
+  JNI::CallStaticShortMethodV,
+  JNI::CallStaticShortMethodA,
+  JNI::CallStaticIntMethod,
+  JNI::CallStaticIntMethodV,
+  JNI::CallStaticIntMethodA,
+  JNI::CallStaticLongMethod,
+  JNI::CallStaticLongMethodV,
+  JNI::CallStaticLongMethodA,
+  JNI::CallStaticFloatMethod,
+  JNI::CallStaticFloatMethodV,
+  JNI::CallStaticFloatMethodA,
+  JNI::CallStaticDoubleMethod,
+  JNI::CallStaticDoubleMethodV,
+  JNI::CallStaticDoubleMethodA,
+  JNI::CallStaticVoidMethod,
+  JNI::CallStaticVoidMethodV,
+  JNI::CallStaticVoidMethodA,
+  JNI::GetStaticFieldID,
+  JNI::GetStaticObjectField,
+  JNI::GetStaticBooleanField,
+  JNI::GetStaticByteField,
+  JNI::GetStaticCharField,
+  JNI::GetStaticShortField,
+  JNI::GetStaticIntField,
+  JNI::GetStaticLongField,
+  JNI::GetStaticFloatField,
+  JNI::GetStaticDoubleField,
+  JNI::SetStaticObjectField,
+  JNI::SetStaticBooleanField,
+  JNI::SetStaticByteField,
+  JNI::SetStaticCharField,
+  JNI::SetStaticShortField,
+  JNI::SetStaticIntField,
+  JNI::SetStaticLongField,
+  JNI::SetStaticFloatField,
+  JNI::SetStaticDoubleField,
+  JNI::NewString,
+  JNI::GetStringLength,
+  JNI::GetStringChars,
+  JNI::ReleaseStringChars,
+  JNI::NewStringUTF,
+  JNI::GetStringUTFLength,
+  JNI::GetStringUTFChars,
+  JNI::ReleaseStringUTFChars,
+  JNI::GetArrayLength,
+  JNI::NewObjectArray,
+  JNI::GetObjectArrayElement,
+  JNI::SetObjectArrayElement,
+  JNI::NewBooleanArray,
+  JNI::NewByteArray,
+  JNI::NewCharArray,
+  JNI::NewShortArray,
+  JNI::NewIntArray,
+  JNI::NewLongArray,
+  JNI::NewFloatArray,
+  JNI::NewDoubleArray,
+  JNI::GetBooleanArrayElements,
+  JNI::GetByteArrayElements,
+  JNI::GetCharArrayElements,
+  JNI::GetShortArrayElements,
+  JNI::GetIntArrayElements,
+  JNI::GetLongArrayElements,
+  JNI::GetFloatArrayElements,
+  JNI::GetDoubleArrayElements,
+  JNI::ReleaseBooleanArrayElements,
+  JNI::ReleaseByteArrayElements,
+  JNI::ReleaseCharArrayElements,
+  JNI::ReleaseShortArrayElements,
+  JNI::ReleaseIntArrayElements,
+  JNI::ReleaseLongArrayElements,
+  JNI::ReleaseFloatArrayElements,
+  JNI::ReleaseDoubleArrayElements,
+  JNI::GetBooleanArrayRegion,
+  JNI::GetByteArrayRegion,
+  JNI::GetCharArrayRegion,
+  JNI::GetShortArrayRegion,
+  JNI::GetIntArrayRegion,
+  JNI::GetLongArrayRegion,
+  JNI::GetFloatArrayRegion,
+  JNI::GetDoubleArrayRegion,
+  JNI::SetBooleanArrayRegion,
+  JNI::SetByteArrayRegion,
+  JNI::SetCharArrayRegion,
+  JNI::SetShortArrayRegion,
+  JNI::SetIntArrayRegion,
+  JNI::SetLongArrayRegion,
+  JNI::SetFloatArrayRegion,
+  JNI::SetDoubleArrayRegion,
+  JNI::RegisterNatives,
+  JNI::UnregisterNatives,
+  JNI::MonitorEnter,
+  JNI::MonitorExit,
+  JNI::GetJavaVM,
+  JNI::GetStringRegion,
+  JNI::GetStringUTFRegion,
+  JNI::GetPrimitiveArrayCritical,
+  JNI::ReleasePrimitiveArrayCritical,
+  JNI::GetStringCritical,
+  JNI::ReleaseStringCritical,
+  JNI::NewWeakGlobalRef,
+  JNI::DeleteWeakGlobalRef,
+  JNI::ExceptionCheck,
+  JNI::NewDirectByteBuffer,
+  JNI::GetDirectBufferAddress,
+  JNI::GetDirectBufferCapacity,
+  JNI::GetObjectRefType,
 };
 
 static const size_t kMonitorsInitial = 32; // Arbitrary.
@@ -2539,92 +2404,95 @@
   return JNI_ERR;
 }
 
-jint DestroyJavaVM(JavaVM* vm) {
-  if (vm == NULL) {
-    return JNI_ERR;
-  } else {
-    JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
-    delete raw_vm->runtime;
-    return JNI_OK;
+class JII {
+ public:
+  static jint DestroyJavaVM(JavaVM* vm) {
+    if (vm == NULL) {
+      return JNI_ERR;
+    } else {
+      JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
+      delete raw_vm->runtime;
+      return JNI_OK;
+    }
   }
-}
 
-jint AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
-  if (vm == NULL || p_env == NULL) {
-    return JNI_ERR;
-  }
-  JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
-  Runtime* runtime = raw_vm->runtime;
-  const char* name = NULL;
-  if (thr_args != NULL) {
-    // TODO: check version
-    name = static_cast<JavaVMAttachArgs*>(thr_args)->name;
-    // TODO: thread group
-  }
-  bool success = runtime->AttachCurrentThread(name, p_env);
-  if (!success) {
-    return JNI_ERR;
-  } else {
-    return JNI_OK;
-  }
-}
-
-jint DetachCurrentThread(JavaVM* vm) {
-  if (vm == NULL) {
-    return JNI_ERR;
-  } else {
+  static jint AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
+    if (vm == NULL || p_env == NULL) {
+      return JNI_ERR;
+    }
     JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
     Runtime* runtime = raw_vm->runtime;
-    runtime->DetachCurrentThread();
+    const char* name = NULL;
+    if (thr_args != NULL) {
+      // TODO: check version
+      name = static_cast<JavaVMAttachArgs*>(thr_args)->name;
+      // TODO: thread group
+    }
+    bool success = runtime->AttachCurrentThread(name, p_env);
+    if (!success) {
+      return JNI_ERR;
+    } else {
+      return JNI_OK;
+    }
+  }
+
+  static jint AttachCurrentThreadAsDaemon(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
+    if (vm == NULL || p_env == NULL) {
+      return JNI_ERR;
+    }
+    JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
+    Runtime* runtime = raw_vm->runtime;
+    const char* name = NULL;
+    if (thr_args != NULL) {
+      // TODO: check version
+      name = static_cast<JavaVMAttachArgs*>(thr_args)->name;
+      // TODO: thread group
+    }
+    bool success = runtime->AttachCurrentThreadAsDaemon(name, p_env);
+    if (!success) {
+      return JNI_ERR;
+    } else {
+      return JNI_OK;
+    }
+  }
+
+  static jint DetachCurrentThread(JavaVM* vm) {
+    if (vm == NULL) {
+      return JNI_ERR;
+    } else {
+      JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
+      Runtime* runtime = raw_vm->runtime;
+      runtime->DetachCurrentThread();
+      return JNI_OK;
+    }
+  }
+
+  static jint GetEnv(JavaVM* vm, void** env, jint version) {
+    if (version < JNI_VERSION_1_1 || version > JNI_VERSION_1_6) {
+      return JNI_EVERSION;
+    }
+    if (vm == NULL || env == NULL) {
+      return JNI_ERR;
+    }
+    Thread* thread = Thread::Current();
+    if (thread == NULL) {
+      *env = NULL;
+      return JNI_EDETACHED;
+    }
+    *env = thread->GetJniEnv();
     return JNI_OK;
   }
-}
-
-jint GetEnv(JavaVM* vm, void** env, jint version) {
-  if (version < JNI_VERSION_1_1 || version > JNI_VERSION_1_6) {
-    return JNI_EVERSION;
-  }
-  if (vm == NULL || env == NULL) {
-    return JNI_ERR;
-  }
-  Thread* thread = Thread::Current();
-  if (thread == NULL) {
-    *env = NULL;
-    return JNI_EDETACHED;
-  }
-  *env = thread->GetJniEnv();
-  return JNI_OK;
-}
-
-jint AttachCurrentThreadAsDaemon(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
-  if (vm == NULL || p_env == NULL) {
-    return JNI_ERR;
-  }
-  JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
-  Runtime* runtime = raw_vm->runtime;
-  const char* name = NULL;
-  if (thr_args != NULL) {
-    // TODO: check version
-    name = static_cast<JavaVMAttachArgs*>(thr_args)->name;
-    // TODO: thread group
-  }
-  bool success = runtime->AttachCurrentThreadAsDaemon(name, p_env);
-  if (!success) {
-    return JNI_ERR;
-  } else {
-    return JNI_OK;
-  }
-}
+};
 
 struct JNIInvokeInterface gInvokeInterface = {
   NULL,  // reserved0
   NULL,  // reserved1
   NULL,  // reserved2
-  DestroyJavaVM,
-  AttachCurrentThread,
-  DetachCurrentThread,
-  GetEnv,
-  AttachCurrentThreadAsDaemon
+  JII::DestroyJavaVM,
+  JII::AttachCurrentThread,
+  JII::DetachCurrentThread,
+  JII::GetEnv,
+  JII::AttachCurrentThreadAsDaemon
 };
 
 static const size_t kPinTableInitialSize = 16;
@@ -2653,4 +2521,158 @@
   delete weak_globals_lock;
 }
 
+/*
+ * Load native code from the specified absolute pathname.  Per the spec,
+ * if we've already loaded a library with the specified pathname, we
+ * return without doing anything.
+ *
+ * TODO? for better results we should absolutify the pathname.  For fully
+ * correct results we should stat to get the inode and compare that.  The
+ * existing implementation is fine so long as everybody is using
+ * System.loadLibrary.
+ *
+ * The library will be associated with the specified class loader.  The JNI
+ * spec says we can't load the same library into more than one class loader.
+ *
+ * Returns "true" on success. On failure, sets *detail to a
+ * human-readable description of the error or NULL if no detail is
+ * available; ownership of the string is transferred to the caller.
+ */
+bool JavaVMExt::LoadNativeLibrary(const std::string& path, Object* class_loader, char** detail) {
+  *detail = NULL;
+
+  // See if we've already loaded this library.  If we have, and the class loader
+  // matches, return successfully without doing anything.
+  SharedLibrary* library = libraries[path];
+  if (library != NULL) {
+    if (library->GetClassLoader() != class_loader) {
+      LOG(WARNING) << "Shared library \"" << path << "\" already opened by "
+                   << "ClassLoader " << library->GetClassLoader() << "; "
+                   << "can't open in " << class_loader;
+      *detail = strdup("already opened by different ClassLoader");
+      return false;
+    }
+    if (verbose_jni) {
+      LOG(INFO) << "[Shared library \"" << path << "\" already loaded in "
+                << "ClassLoader " << class_loader << "]";
+    }
+    if (!library->CheckOnLoadResult(this)) {
+      *detail = strdup("JNI_OnLoad failed before");
+      return false;
+    }
+    return true;
+  }
+
+  // Open the shared library.  Because we're using a full path, the system
+  // doesn't have to search through LD_LIBRARY_PATH.  (It may do so to
+  // resolve this library's dependencies though.)
+
+  // Failures here are expected when java.library.path has several entries
+  // and we have to hunt for the lib.
+
+  // The current version of the dynamic linker prints detailed information
+  // about dlopen() failures.  Some things to check if the message is
+  // cryptic:
+  //   - make sure the library exists on the device
+  //   - verify that the right path is being opened (the debug log message
+  //     above can help with that)
+  //   - check to see if the library is valid (e.g. not zero bytes long)
+  //   - check config/prelink-linux-arm.map to ensure that the library
+  //     is listed and is not being overrun by the previous entry (if
+  //     loading suddenly stops working on a prelinked library, this is
+  //     a good one to check)
+  //   - write a trivial app that calls sleep() then dlopen(), attach
+  //     to it with "strace -p <pid>" while it sleeps, and watch for
+  //     attempts to open nonexistent dependent shared libs
+
+  // TODO: automate some of these checks!
+
+  // This can execute slowly for a large library on a busy system, so we
+  // want to switch from RUNNING to VMWAIT while it executes.  This allows
+  // the GC to ignore us.
+  Thread* self = Thread::Current();
+  Thread::State old_state = self->GetState();
+  self->SetState(Thread::kWaiting); // TODO: VMWAIT
+  void* handle = dlopen(path.c_str(), RTLD_LAZY);
+  self->SetState(old_state);
+
+  if (verbose_jni) {
+    LOG(INFO) << "[Call to dlopen(\"" << path << "\") returned " << handle << "]";
+  }
+
+  if (handle == NULL) {
+    *detail = strdup(dlerror());
+    return false;
+  }
+
+  // Create a new entry.
+  library = new SharedLibrary(path, handle, class_loader);
+  UNIMPLEMENTED(ERROR) << "missing pthread_cond_init";
+  // pthread_cond_init(&library->onLoadCond, NULL);
+
+  libraries[path] = library;
+
+  //  if (pNewEntry != pActualEntry) {
+  //    LOG(INFO) << "WOW: we lost a race to add a shared library (\"" << path << "\" ClassLoader=" << class_loader <<")";
+  //    freeSharedLibEntry(pNewEntry);
+  //    return CheckOnLoadResult(this, pActualEntry);
+  //  } else
+  {
+    if (verbose_jni) {
+      LOG(INFO) << "[Added shared library \"" << path << "\" for ClassLoader " << class_loader << "]";
+    }
+
+    bool result = true;
+    void* sym = dlsym(handle, "JNI_OnLoad");
+    if (sym == NULL) {
+      if (verbose_jni) {
+        LOG(INFO) << "[No JNI_OnLoad found in \"" << path << "\"]";
+      }
+    } else {
+      // Call JNI_OnLoad.  We have to override the current class
+      // loader, which will always be "null" since the stuff at the
+      // top of the stack is around Runtime.loadLibrary().  (See
+      // the comments in the JNI FindClass function.)
+      UNIMPLEMENTED(WARNING) << "need to override current class loader";
+      typedef int (*JNI_OnLoadFn)(JavaVM*, void*);
+      JNI_OnLoadFn jni_on_load = reinterpret_cast<JNI_OnLoadFn>(sym);
+      //Object* prevOverride = self->classLoaderOverride;
+      //self->classLoaderOverride = classLoader;
+
+      old_state = self->GetState();
+      self->SetState(Thread::kNative);
+      if (verbose_jni) {
+        LOG(INFO) << "[Calling JNI_OnLoad in \"" << path << "\"]";
+      }
+      int version = (*jni_on_load)(reinterpret_cast<JavaVM*>(this), NULL);
+      self->SetState(old_state);
+
+      UNIMPLEMENTED(WARNING) << "need to restore current class loader";
+      //self->classLoaderOverride = prevOverride;
+
+      if (version != JNI_VERSION_1_2 &&
+      version != JNI_VERSION_1_4 &&
+      version != JNI_VERSION_1_6) {
+        LOG(WARNING) << "JNI_OnLoad in \"" << path << "\" returned "
+                     << "bad version: " << version;
+        // It's unwise to call dlclose() here, but we can mark it
+        // as bad and ensure that future load attempts will fail.
+        // We don't know how far JNI_OnLoad got, so there could
+        // be some partially-initialized stuff accessible through
+        // newly-registered native method calls.  We could try to
+        // unregister them, but that doesn't seem worthwhile.
+        result = false;
+      } else {
+        if (verbose_jni) {
+          LOG(INFO) << "[Returned " << (result ? "successfully" : "failure")
+                    << " from JNI_OnLoad in \"" << path << "\"]";
+        }
+      }
+    }
+
+    library->SetResult(result);
+    return result;
+  }
+}
+
 }  // namespace art
diff --git a/src/jni_internal_test.cc b/src/jni_internal_test.cc
index f51b6c9..6c5d6f2 100644
--- a/src/jni_internal_test.cc
+++ b/src/jni_internal_test.cc
@@ -57,23 +57,91 @@
   EXPECT_CLASS_NOT_FOUND("K");
 }
 
+#define EXPECT_EXCEPTION(exception_class) \
+  do { \
+    EXPECT_TRUE(env_->ExceptionCheck()); \
+    jthrowable exception = env_->ExceptionOccurred(); \
+    EXPECT_NE(static_cast<jthrowable>(NULL), exception); \
+    EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class)); \
+    env_->ExceptionClear(); \
+  } while (false)
+
+TEST_F(JniInternalTest, GetFieldID) {
+  jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
+  ASSERT_TRUE(jlnsfe != NULL);
+  jclass c = env_->FindClass("java/lang/String");
+  ASSERT_TRUE(c != NULL);
+
+  // Wrong type.
+  jfieldID fid = env_->GetFieldID(c, "count", "J");
+  EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
+  EXPECT_EXCEPTION(jlnsfe);
+
+  // Wrong name.
+  fid = env_->GetFieldID(c, "Count", "I");
+  EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
+  EXPECT_EXCEPTION(jlnsfe);
+
+  // Good declared field lookup.
+  fid = env_->GetFieldID(c, "count", "I");
+  EXPECT_NE(static_cast<jfieldID>(NULL), fid);
+  EXPECT_TRUE(fid != NULL);
+  EXPECT_FALSE(env_->ExceptionCheck());
+
+  // Good superclass field lookup.
+  c = env_->FindClass("java/lang/StringBuilder");
+  fid = env_->GetFieldID(c, "count", "I");
+  EXPECT_NE(static_cast<jfieldID>(NULL), fid);
+  EXPECT_TRUE(fid != NULL);
+  EXPECT_FALSE(env_->ExceptionCheck());
+
+  // Not instance.
+  fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
+  EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
+  EXPECT_EXCEPTION(jlnsfe);
+}
+
+TEST_F(JniInternalTest, GetStaticFieldID) {
+  jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError");
+  ASSERT_TRUE(jlnsfe != NULL);
+  jclass c = env_->FindClass("java/lang/String");
+  ASSERT_TRUE(c != NULL);
+
+  // Wrong type.
+  jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J");
+  EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
+  EXPECT_EXCEPTION(jlnsfe);
+
+  // Wrong name.
+  fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
+  EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
+  EXPECT_EXCEPTION(jlnsfe);
+
+  // Good declared field lookup.
+  fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
+  EXPECT_NE(static_cast<jfieldID>(NULL), fid);
+  EXPECT_TRUE(fid != NULL);
+  EXPECT_FALSE(env_->ExceptionCheck());
+
+  // Not static.
+  fid = env_->GetStaticFieldID(c, "count", "I");
+  EXPECT_EQ(static_cast<jfieldID>(NULL), fid);
+  EXPECT_EXCEPTION(jlnsfe);
+}
+
 TEST_F(JniInternalTest, GetMethodID) {
   jclass jlobject = env_->FindClass("java/lang/Object");
   jclass jlstring = env_->FindClass("java/lang/String");
   jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
 
   // Sanity check that no exceptions are pending
-  EXPECT_FALSE(env_->ExceptionCheck());
+  ASSERT_FALSE(env_->ExceptionCheck());
 
   // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
   // a pending exception
   jmethodID method = env_->GetMethodID(jlobject, "foo", "()V");
   EXPECT_EQ(static_cast<jmethodID>(NULL), method);
-  EXPECT_TRUE(env_->ExceptionCheck());
-  jthrowable exception = env_->ExceptionOccurred();
-  EXPECT_NE(static_cast<jthrowable>(NULL), exception);
-  EXPECT_TRUE(env_->IsInstanceOf(exception, jlnsme));
-  env_->ExceptionClear();
+  EXPECT_EXCEPTION(jlnsme);
 
   // Check that java.lang.Object.equals() does exist
   method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
@@ -84,11 +152,7 @@
   // method is static
   method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;");
   EXPECT_EQ(static_cast<jmethodID>(NULL), method);
-  EXPECT_TRUE(env_->ExceptionCheck());
-  exception = env_->ExceptionOccurred();
-  EXPECT_NE(static_cast<jthrowable>(NULL), exception);
-  EXPECT_TRUE(env_->IsInstanceOf(exception, jlnsme));
-  env_->ExceptionClear();
+  EXPECT_EXCEPTION(jlnsme);
 }
 
 TEST_F(JniInternalTest, GetStaticMethodID) {
@@ -96,27 +160,19 @@
   jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
 
   // Sanity check that no exceptions are pending
-  EXPECT_FALSE(env_->ExceptionCheck());
+  ASSERT_FALSE(env_->ExceptionCheck());
 
   // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is
   // a pending exception
   jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V");
   EXPECT_EQ(static_cast<jmethodID>(NULL), method);
-  EXPECT_TRUE(env_->ExceptionCheck());
-  jthrowable exception = env_->ExceptionOccurred();
-  EXPECT_NE(static_cast<jthrowable>(NULL), exception);
-  EXPECT_TRUE(env_->IsInstanceOf(exception, jlnsme));
-  env_->ExceptionClear();
+  EXPECT_EXCEPTION(jlnsme);
 
   // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as
   // the method is not static
   method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z");
   EXPECT_EQ(static_cast<jmethodID>(NULL), method);
-  EXPECT_TRUE(env_->ExceptionCheck());
-  exception = env_->ExceptionOccurred();
-  EXPECT_NE(static_cast<jthrowable>(NULL), exception);
-  EXPECT_TRUE(env_->IsInstanceOf(exception, jlnsme));
-  env_->ExceptionClear();
+  EXPECT_EXCEPTION(jlnsme);
 
   // Check that java.lang.String.valueOf(int) does exist
   jclass jlstring = env_->FindClass("java/lang/String");
@@ -126,12 +182,42 @@
   EXPECT_FALSE(env_->ExceptionCheck());
 }
 
+TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) {
+  jclass jlrField = env_->FindClass("java/lang/reflect/Field");
+  jclass c = env_->FindClass("java/lang/String");
+  ASSERT_TRUE(c != NULL);
+  jfieldID fid = env_->GetFieldID(c, "count", "I");
+  ASSERT_TRUE(fid != NULL);
+  // Turn the fid into a java.lang.reflect.Field...
+  jobject field = env_->ToReflectedField(c, fid, JNI_FALSE);
+  ASSERT_TRUE(c != NULL);
+  ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
+  // ...and back again.
+  jfieldID fid2 = env_->FromReflectedField(field);
+  ASSERT_TRUE(fid2 != NULL);
+}
+
+TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
+  jclass jlrMethod = env_->FindClass("java/lang/reflect/Method");
+  jclass c = env_->FindClass("java/lang/String");
+  ASSERT_TRUE(c != NULL);
+  jmethodID mid = env_->GetMethodID(c, "length", "()I");
+  ASSERT_TRUE(mid != NULL);
+  // Turn the mid into a java.lang.reflect.Method...
+  jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
+  ASSERT_TRUE(c != NULL);
+  ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod));
+  // ...and back again.
+  jmethodID mid2 = env_->FromReflectedMethod(method);
+  ASSERT_TRUE(mid2 != NULL);
+}
+
 TEST_F(JniInternalTest, RegisterNatives) {
   jclass jlobject = env_->FindClass("java/lang/Object");
   jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");
 
   // Sanity check that no exceptions are pending
-  EXPECT_FALSE(env_->ExceptionCheck());
+  ASSERT_FALSE(env_->ExceptionCheck());
 
   // Check that registering to a non-existent java.lang.Object.foo() causes a
   // NoSuchMethodError
@@ -139,22 +225,14 @@
     JNINativeMethod methods[] = {{"foo", "()V", NULL}};
     env_->RegisterNatives(jlobject, methods, 1);
   }
-  EXPECT_TRUE(env_->ExceptionCheck());
-  jthrowable exception = env_->ExceptionOccurred();
-  EXPECT_NE(static_cast<jthrowable>(NULL), exception);
-  EXPECT_TRUE(env_->IsInstanceOf(exception, jlnsme));
-  env_->ExceptionClear();
+  EXPECT_EXCEPTION(jlnsme);
 
   // Check that registering non-native methods causes a NoSuchMethodError
   {
     JNINativeMethod methods[] = {{"equals", "(Ljava/lang/Object;)Z", NULL}};
     env_->RegisterNatives(jlobject, methods, 1);
   }
-  EXPECT_TRUE(env_->ExceptionCheck());
-  exception = env_->ExceptionOccurred();
-  EXPECT_NE(static_cast<jthrowable>(NULL), exception);
-  EXPECT_TRUE(env_->IsInstanceOf(exception, jlnsme));
-  env_->ExceptionClear();
+  EXPECT_EXCEPTION(jlnsme);
 
   // Check that registering native methods is successful
   {
@@ -215,6 +293,7 @@
 }
 
 TEST_F(JniInternalTest, SetObjectArrayElement) {
+  jclass aioobe = env_->FindClass("java/lang/ArrayIndexOutOfBoundsException");
   jclass c = env_->FindClass("[Ljava/lang/Object;");
   ASSERT_TRUE(c != NULL);
 
@@ -224,16 +303,12 @@
   // TODO: check reading value back
 
   // ArrayIndexOutOfBounds for negative index.
-  // TODO: check exception type
   env_->SetObjectArrayElement(array, -1, c);
-  EXPECT_TRUE(env_->ExceptionCheck());
-  env_->ExceptionClear();
+  EXPECT_EXCEPTION(aioobe);
 
   // ArrayIndexOutOfBounds for too-large index.
-  // TODO: check exception type
   env_->SetObjectArrayElement(array, 1, c);
-  EXPECT_TRUE(env_->ExceptionCheck());
-  env_->ExceptionClear();
+  EXPECT_EXCEPTION(aioobe);
 
   // TODO: check ArrayStoreException thrown for bad types.
 }
diff --git a/src/object.cc b/src/object.cc
index 8af1778..b9324a6 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -442,6 +442,62 @@
   return NULL;
 }
 
+Field* Class::FindDeclaredInstanceField(const StringPiece& name, const StringPiece& descriptor) {
+  // Is the field in this class?
+  // Interfaces are not relevant because they can't contain instance fields.
+  for (size_t i = 0; i < NumInstanceFields(); ++i) {
+    Field* f = GetInstanceField(i);
+    if (f->GetName()->Equals(name) && f->GetDescriptor() == descriptor) {
+      return f;
+    }
+  }
+  return NULL;
+}
+
+Field* Class::FindInstanceField(const StringPiece& name, const StringPiece& descriptor) {
+  // Is the field in this class, or any of its superclasses?
+  // Interfaces are not relevant because they can't contain instance fields.
+  for (Class* c = this; c != NULL; c = c->GetSuperClass()) {
+    Field* f = c->FindDeclaredInstanceField(name, descriptor);
+    if (f != NULL) {
+      return f;
+    }
+  }
+  return NULL;
+}
+
+Field* Class::FindDeclaredStaticField(const StringPiece& name, const StringPiece& descriptor) {
+  for (size_t i = 0; i < NumStaticFields(); ++i) {
+    Field* f = GetStaticField(i);
+    if (f->GetName()->Equals(name) && f->GetDescriptor() == descriptor) {
+      return f;
+    }
+  }
+  return NULL;
+}
+
+Field* Class::FindStaticField(const StringPiece& name, const StringPiece& descriptor) {
+  // Is the field in this class (or its interfaces), or any of its
+  // superclasses (or their interfaces)?
+  for (Class* c = this; c != NULL; c = c->GetSuperClass()) {
+    // Is the field in this class?
+    Field* f = c->FindDeclaredStaticField(name, descriptor);
+    if (f != NULL) {
+      return f;
+    }
+
+    // Is this field in any of this class' interfaces?
+    for (size_t i = 0; i < c->NumInterfaces(); ++i) {
+      Class* interface = c->GetInterface(i);
+      f = interface->FindDeclaredStaticField(name, descriptor);
+      if (f != NULL) {
+        return f;
+      }
+    }
+  }
+  return NULL;
+}
+
 template<typename T>
 PrimitiveArray<T>* PrimitiveArray<T>::Alloc(size_t length) {
   Array* raw_array = Array::Alloc(array_class_, length, sizeof(T));
diff --git a/src/object.h b/src/object.h
index c78103b..2b5a054 100644
--- a/src/object.h
+++ b/src/object.h
@@ -979,6 +979,20 @@
     return num_reference_instance_fields_;
   }
 
+  // Finds the given instance field in this class or a superclass.
+  Field* FindInstanceField(const StringPiece& name,
+      const StringPiece& descriptor);
+
+  Field* FindDeclaredInstanceField(const StringPiece& name,
+      const StringPiece& descriptor);
+
+  // Finds the given static field in this class or a superclass.
+  Field* FindStaticField(const StringPiece& name,
+      const StringPiece& descriptor);
+
+  Field* FindDeclaredStaticField(const StringPiece& name,
+      const StringPiece& descriptor);
+
   Field* GetInstanceField(uint32_t i) const {  // TODO: uint16_t
     DCHECK_NE(NumInstanceFields(), 0U);
     return ifields_->Get(i);
diff --git a/src/object_test.cc b/src/object_test.cc
index 3f5333b..549544c 100644
--- a/src/object_test.cc
+++ b/src/object_test.cc
@@ -333,4 +333,62 @@
   EXPECT_TRUE(O->IsAssignableFrom(IA));
 }
 
+TEST_F(ObjectTest, FindInstanceField) {
+  String* s = String::AllocFromModifiedUtf8("ABC");
+  ASSERT_TRUE(s != NULL);
+  Class* c = s->GetClass();
+  ASSERT_TRUE(c != NULL);
+
+  // Wrong type.
+  EXPECT_TRUE(c->FindDeclaredInstanceField("count", "J") == NULL);
+  EXPECT_TRUE(c->FindInstanceField("count", "J") == NULL);
+
+  // Wrong name.
+  EXPECT_TRUE(c->FindDeclaredInstanceField("Count", "I") == NULL);
+  EXPECT_TRUE(c->FindInstanceField("Count", "I") == NULL);
+
+  // Right name and type.
+  Field* f1 = c->FindDeclaredInstanceField("count", "I");
+  Field* f2 = c->FindInstanceField("count", "I");
+  EXPECT_TRUE(f1 != NULL);
+  EXPECT_TRUE(f2 != NULL);
+  EXPECT_EQ(f1, f2);
+
+  // TODO: check that s.count == 3.
+
+  // Ensure that we handle superclass fields correctly...
+  c = class_linker_->FindSystemClass("Ljava/lang/StringBuilder;");
+  ASSERT_TRUE(c != NULL);
+  // No StringBuilder.count...
+  EXPECT_TRUE(c->FindDeclaredInstanceField("count", "I") == NULL);
+  // ...but there is an AbstractStringBuilder.count.
+  EXPECT_TRUE(c->FindInstanceField("count", "I") != NULL);
+}
+
+TEST_F(ObjectTest, FindStaticField) {
+  String* s = String::AllocFromModifiedUtf8("ABC");
+  ASSERT_TRUE(s != NULL);
+  Class* c = s->GetClass();
+  ASSERT_TRUE(c != NULL);
+
+  // Wrong type.
+  EXPECT_TRUE(c->FindDeclaredStaticField("CASE_INSENSITIVE_ORDER", "I") == NULL);
+  EXPECT_TRUE(c->FindStaticField("CASE_INSENSITIVE_ORDER", "I") == NULL);
+
+  // Wrong name.
+  EXPECT_TRUE(c->FindDeclaredStaticField("cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;") == NULL);
+  EXPECT_TRUE(c->FindStaticField("cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;") == NULL);
+
+  // Right name and type.
+  Field* f1 = c->FindDeclaredStaticField("CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
+  Field* f2 = c->FindStaticField("CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
+  EXPECT_TRUE(f1 != NULL);
+  EXPECT_TRUE(f2 != NULL);
+  EXPECT_EQ(f1, f2);
+
+  // TODO: test static fields via superclasses.
+  // TODO: test static fields via interfaces.
+  // TODO: test that interfaces trump superclasses.
+}
+
 }  // namespace art
