diff --git a/build/Android.common.mk b/build/Android.common.mk
index 9c7238a..c56bb0f 100644
--- a/build/Android.common.mk
+++ b/build/Android.common.mk
@@ -111,6 +111,7 @@
 	src/dalvik_system_VMRuntime.cc \
 	src/dalvik_system_VMStack.cc \
 	src/dalvik_system_Zygote.cc \
+	src/debugger.cc \
 	src/dex_cache.cc \
 	src/dex_file.cc \
 	src/dex_instruction.cc \
@@ -137,6 +138,12 @@
 	src/java_lang_reflect_Method.cc \
 	src/java_lang_reflect_Proxy.cc \
 	src/java_util_concurrent_atomic_AtomicLong.cc \
+	src/jdwp/jdwp_constants.cc \
+	src/jdwp/jdwp_event.cc \
+	src/jdwp/jdwp_expand_buf.cc \
+	src/jdwp/jdwp_handler.cc \
+	src/jdwp/jdwp_main.cc \
+	src/jdwp/jdwp_socket.cc \
 	src/jni_compiler.cc \
 	src/jni_internal.cc \
 	src/jni_internal_arm.cc \
@@ -179,6 +186,7 @@
 
 LIBART_TARGET_SRC_FILES := \
 	$(LIBART_COMMON_SRC_FILES) \
+	src/jdwp/jdwp_adb.cc \
 	src/logging_android.cc \
 	src/monitor_android.cc \
 	src/runtime_android.cc \
diff --git a/src/dalvik_system_VMDebug.cc b/src/dalvik_system_VMDebug.cc
index 0540631..4537a69 100644
--- a/src/dalvik_system_VMDebug.cc
+++ b/src/dalvik_system_VMDebug.cc
@@ -15,6 +15,7 @@
  */
 
 #include "class_linker.h"
+#include "debugger.h"
 #include "jni_internal.h"
 #include "ScopedUtfChars.h"
 #include "toStringArray.h"
@@ -112,18 +113,15 @@
 }
 
 jboolean VMDebug_isDebuggerConnected(JNIEnv*, jclass) {
-  UNIMPLEMENTED(WARNING);
-  return JNI_FALSE; //dvmDbgIsDebuggerConnected();
+  return Dbg::IsDebuggerConnected();
 }
 
 jboolean VMDebug_isDebuggingEnabled(JNIEnv*, jclass) {
-  UNIMPLEMENTED(WARNING);
-  return JNI_FALSE; //return gDvm.jdwpConfigured;
+  return Dbg::IsDebuggingEnabled();
 }
 
 jlong VMDebug_lastDebuggerActivity(JNIEnv*, jclass) {
-  UNIMPLEMENTED(WARNING);
-  return 0; //dvmDbgLastDebuggerActivity();
+  return Dbg::LastDebuggerActivity();
 }
 
 void VMDebug_startInstructionCounting(JNIEnv* env, jclass) {
diff --git a/src/debugger.cc b/src/debugger.cc
new file mode 100644
index 0000000..46644e7
--- /dev/null
+++ b/src/debugger.cc
@@ -0,0 +1,442 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "debugger.h"
+
+namespace art {
+
+bool Dbg::DebuggerStartup() {
+  UNIMPLEMENTED(FATAL);
+  return false;
+}
+
+void Dbg::DebuggerShutdown() {
+  UNIMPLEMENTED(FATAL);
+}
+
+DebugInvokeReq* Dbg::GetInvokeReq() {
+  UNIMPLEMENTED(FATAL);
+  return NULL;
+}
+
+void Dbg::Connected() {
+  UNIMPLEMENTED(FATAL);
+}
+
+void Dbg::Active() {
+  UNIMPLEMENTED(FATAL);
+}
+
+void Dbg::Disconnected() {
+  UNIMPLEMENTED(FATAL);
+}
+
+bool Dbg::IsDebuggerConnected() {
+  UNIMPLEMENTED(WARNING);
+  return false;
+}
+
+bool Dbg::IsDebuggingEnabled() {
+  UNIMPLEMENTED(WARNING);
+  return false; //return gDvm.jdwpConfigured;
+}
+
+int64_t Dbg::LastDebuggerActivity() {
+  UNIMPLEMENTED(WARNING);
+  return -1;
+}
+
+int Dbg::ThreadRunning() {
+  UNIMPLEMENTED(FATAL);
+  return 0;
+}
+
+int Dbg::ThreadWaiting() {
+  UNIMPLEMENTED(FATAL);
+  return 0;
+}
+
+int Dbg::ThreadContinuing(int status) {
+  UNIMPLEMENTED(FATAL);
+  return 0;
+}
+
+void Dbg::UndoDebuggerSuspensions() {
+  UNIMPLEMENTED(FATAL);
+}
+
+void Dbg::Exit(int status) {
+  UNIMPLEMENTED(FATAL);
+}
+
+const char* Dbg::GetClassDescriptor(JDWP::RefTypeId id) {
+  UNIMPLEMENTED(FATAL);
+  return NULL;
+}
+
+JDWP::ObjectId Dbg::GetClassObject(JDWP::RefTypeId id) {
+  UNIMPLEMENTED(FATAL);
+  return 0;
+}
+
+JDWP::RefTypeId Dbg::GetSuperclass(JDWP::RefTypeId id) {
+  UNIMPLEMENTED(FATAL);
+  return 0;
+}
+
+JDWP::ObjectId Dbg::GetClassLoader(JDWP::RefTypeId id) {
+  UNIMPLEMENTED(FATAL);
+  return 0;
+}
+
+uint32_t Dbg::GetAccessFlags(JDWP::RefTypeId id) {
+  UNIMPLEMENTED(FATAL);
+  return 0;
+}
+
+bool Dbg::IsInterface(JDWP::RefTypeId id) {
+  UNIMPLEMENTED(FATAL);
+  return false;
+}
+
+void Dbg::GetClassList(uint32_t* pNumClasses, JDWP::RefTypeId** pClassRefBuf) {
+  UNIMPLEMENTED(FATAL);
+}
+
+void Dbg::GetVisibleClassList(JDWP::ObjectId classLoaderId, uint32_t* pNumClasses, JDWP::RefTypeId** pClassRefBuf) {
+  UNIMPLEMENTED(FATAL);
+}
+
+void Dbg::GetClassInfo(JDWP::RefTypeId classId, uint8_t* pTypeTag, uint32_t* pStatus, const char** pSignature) {
+  UNIMPLEMENTED(FATAL);
+}
+
+bool Dbg::FindLoadedClassBySignature(const char* classDescriptor, JDWP::RefTypeId* pRefTypeId) {
+  UNIMPLEMENTED(FATAL);
+  return false;
+}
+
+void Dbg::GetObjectType(JDWP::ObjectId objectId, uint8_t* pRefTypeTag, JDWP::RefTypeId* pRefTypeId) {
+  UNIMPLEMENTED(FATAL);
+}
+
+uint8_t Dbg::GetClassObjectType(JDWP::RefTypeId refTypeId) {
+  UNIMPLEMENTED(FATAL);
+  return 0;
+}
+
+const char* Dbg::GetSignature(JDWP::RefTypeId refTypeId) {
+  UNIMPLEMENTED(FATAL);
+  return NULL;
+}
+
+const char* Dbg::GetSourceFile(JDWP::RefTypeId refTypeId) {
+  UNIMPLEMENTED(FATAL);
+  return NULL;
+}
+
+const char* Dbg::GetObjectTypeName(JDWP::ObjectId objectId) {
+  UNIMPLEMENTED(FATAL);
+  return NULL;
+}
+
+uint8_t Dbg::GetObjectTag(JDWP::ObjectId objectId) {
+  UNIMPLEMENTED(FATAL);
+  return 0;
+}
+
+int Dbg::GetTagWidth(int tag) {
+  UNIMPLEMENTED(FATAL);
+  return 0;
+}
+
+int Dbg::GetArrayLength(JDWP::ObjectId arrayId) {
+  UNIMPLEMENTED(FATAL);
+  return 0;
+}
+
+uint8_t Dbg::GetArrayElementTag(JDWP::ObjectId arrayId) {
+  UNIMPLEMENTED(FATAL);
+  return 0;
+}
+
+bool Dbg::OutputArray(JDWP::ObjectId arrayId, int firstIndex, int count, JDWP::ExpandBuf* pReply) {
+  UNIMPLEMENTED(FATAL);
+  return false;
+}
+
+bool Dbg::SetArrayElements(JDWP::ObjectId arrayId, int firstIndex, int count, const uint8_t* buf) {
+  UNIMPLEMENTED(FATAL);
+  return false;
+}
+
+JDWP::ObjectId Dbg::CreateString(const char* str) {
+  UNIMPLEMENTED(FATAL);
+  return 0;
+}
+
+JDWP::ObjectId Dbg::CreateObject(JDWP::RefTypeId classId) {
+  UNIMPLEMENTED(FATAL);
+  return 0;
+}
+
+JDWP::ObjectId Dbg::CreateArrayObject(JDWP::RefTypeId arrayTypeId, uint32_t length) {
+  UNIMPLEMENTED(FATAL);
+  return 0;
+}
+
+bool Dbg::MatchType(JDWP::RefTypeId instClassId, JDWP::RefTypeId classId) {
+  UNIMPLEMENTED(FATAL);
+  return false;
+}
+
+const char* Dbg::GetMethodName(JDWP::RefTypeId refTypeId, JDWP::MethodId id) {
+  UNIMPLEMENTED(FATAL);
+  return NULL;
+}
+
+void Dbg::OutputAllFields(JDWP::RefTypeId refTypeId, bool withGeneric, JDWP::ExpandBuf* pReply) {
+  UNIMPLEMENTED(FATAL);
+}
+
+void Dbg::OutputAllMethods(JDWP::RefTypeId refTypeId, bool withGeneric, JDWP::ExpandBuf* pReply) {
+  UNIMPLEMENTED(FATAL);
+}
+
+void Dbg::OutputAllInterfaces(JDWP::RefTypeId refTypeId, JDWP::ExpandBuf* pReply) {
+  UNIMPLEMENTED(FATAL);
+}
+
+void Dbg::OutputLineTable(JDWP::RefTypeId refTypeId, JDWP::MethodId methodId, JDWP::ExpandBuf* pReply) {
+  UNIMPLEMENTED(FATAL);
+}
+
+void Dbg::OutputVariableTable(JDWP::RefTypeId refTypeId, JDWP::MethodId id, bool withGeneric, JDWP::ExpandBuf* pReply) {
+  UNIMPLEMENTED(FATAL);
+}
+
+uint8_t Dbg::GetFieldBasicTag(JDWP::ObjectId objId, JDWP::FieldId fieldId) {
+  UNIMPLEMENTED(FATAL);
+  return 0;
+}
+
+uint8_t Dbg::GetStaticFieldBasicTag(JDWP::RefTypeId refTypeId, JDWP::FieldId fieldId) {
+  UNIMPLEMENTED(FATAL);
+  return 0;
+}
+
+void Dbg::GetFieldValue(JDWP::ObjectId objectId, JDWP::FieldId fieldId, JDWP::ExpandBuf* pReply) {
+  UNIMPLEMENTED(FATAL);
+}
+
+void Dbg::SetFieldValue(JDWP::ObjectId objectId, JDWP::FieldId fieldId, uint64_t value, int width) {
+  UNIMPLEMENTED(FATAL);
+}
+
+void Dbg::GetStaticFieldValue(JDWP::RefTypeId refTypeId, JDWP::FieldId fieldId, JDWP::ExpandBuf* pReply) {
+  UNIMPLEMENTED(FATAL);
+}
+
+void Dbg::SetStaticFieldValue(JDWP::RefTypeId refTypeId, JDWP::FieldId fieldId, uint64_t rawValue, int width) {
+  UNIMPLEMENTED(FATAL);
+}
+
+char* Dbg::StringToUtf8(JDWP::ObjectId strId) {
+  UNIMPLEMENTED(FATAL);
+  return NULL;
+}
+
+char* Dbg::GetThreadName(JDWP::ObjectId threadId) {
+  UNIMPLEMENTED(FATAL);
+  return NULL;
+}
+
+JDWP::ObjectId Dbg::GetThreadGroup(JDWP::ObjectId threadId) {
+  UNIMPLEMENTED(FATAL);
+  return 0;
+}
+
+char* Dbg::GetThreadGroupName(JDWP::ObjectId threadGroupId) {
+  UNIMPLEMENTED(FATAL);
+  return NULL;
+}
+
+JDWP::ObjectId Dbg::GetThreadGroupParent(JDWP::ObjectId threadGroupId) {
+  UNIMPLEMENTED(FATAL);
+  return 0;
+}
+
+JDWP::ObjectId Dbg::GetSystemThreadGroupId() {
+  UNIMPLEMENTED(FATAL);
+  return 0;
+}
+
+JDWP::ObjectId Dbg::GetMainThreadGroupId() {
+  UNIMPLEMENTED(FATAL);
+  return 0;
+}
+
+bool Dbg::GetThreadStatus(JDWP::ObjectId threadId, uint32_t* threadStatus, uint32_t* suspendStatus) {
+  UNIMPLEMENTED(FATAL);
+  return false;
+}
+
+uint32_t Dbg::GetThreadSuspendCount(JDWP::ObjectId threadId) {
+  UNIMPLEMENTED(FATAL);
+  return 0;
+}
+
+bool Dbg::ThreadExists(JDWP::ObjectId threadId) {
+  UNIMPLEMENTED(FATAL);
+  return false;
+}
+
+bool Dbg::IsSuspended(JDWP::ObjectId threadId) {
+  UNIMPLEMENTED(FATAL);
+  return false;
+}
+
+//void Dbg::WaitForSuspend(JDWP::ObjectId threadId);
+
+void Dbg::GetThreadGroupThreads(JDWP::ObjectId threadGroupId, JDWP::ObjectId** ppThreadIds, uint32_t* pThreadCount) {
+  UNIMPLEMENTED(FATAL);
+}
+
+void Dbg::GetAllThreads(JDWP::ObjectId** ppThreadIds, uint32_t* pThreadCount) {
+  UNIMPLEMENTED(FATAL);
+}
+
+int Dbg::GetThreadFrameCount(JDWP::ObjectId threadId) {
+  UNIMPLEMENTED(FATAL);
+  return 0;
+}
+
+bool Dbg::GetThreadFrame(JDWP::ObjectId threadId, int num, JDWP::FrameId* pFrameId, JDWP::JdwpLocation* pLoc) {
+  UNIMPLEMENTED(FATAL);
+  return false;
+}
+
+JDWP::ObjectId Dbg::GetThreadSelfId() {
+  UNIMPLEMENTED(FATAL);
+  return 0;
+}
+
+void Dbg::SuspendVM(bool isEvent) {
+  UNIMPLEMENTED(FATAL);
+}
+
+void Dbg::ResumeVM() {
+  UNIMPLEMENTED(FATAL);
+}
+
+void Dbg::SuspendThread(JDWP::ObjectId threadId) {
+  UNIMPLEMENTED(FATAL);
+}
+
+void Dbg::ResumeThread(JDWP::ObjectId threadId) {
+  UNIMPLEMENTED(FATAL);
+}
+
+void Dbg::SuspendSelf() {
+  UNIMPLEMENTED(FATAL);
+}
+
+bool Dbg::GetThisObject(JDWP::ObjectId threadId, JDWP::FrameId frameId, JDWP::ObjectId* pThisId) {
+  UNIMPLEMENTED(FATAL);
+  return false;
+}
+
+void Dbg::GetLocalValue(JDWP::ObjectId threadId, JDWP::FrameId frameId, int slot, uint8_t tag, uint8_t* buf, int expectedLen) {
+  UNIMPLEMENTED(FATAL);
+}
+
+void Dbg::SetLocalValue(JDWP::ObjectId threadId, JDWP::FrameId frameId, int slot, uint8_t tag, uint64_t value, int width) {
+  UNIMPLEMENTED(FATAL);
+}
+
+void Dbg::PostLocationEvent(const Method* method, int pcOffset, Object* thisPtr, int eventFlags) {
+  UNIMPLEMENTED(FATAL);
+}
+
+void Dbg::PostException(void* throwFp, int throwRelPc, void* catchFp, int catchRelPc, Object* exception) {
+  UNIMPLEMENTED(FATAL);
+}
+
+void Dbg::PostThreadStart(Thread* t) {
+  UNIMPLEMENTED(WARNING);
+}
+
+void Dbg::PostThreadDeath(Thread* t) {
+  UNIMPLEMENTED(WARNING);
+}
+
+void Dbg::PostClassPrepare(Class* c) {
+  UNIMPLEMENTED(FATAL);
+}
+
+bool Dbg::WatchLocation(const JDWP::JdwpLocation* pLoc) {
+  UNIMPLEMENTED(FATAL);
+  return false;
+}
+
+void Dbg::UnwatchLocation(const JDWP::JdwpLocation* pLoc) {
+  UNIMPLEMENTED(FATAL);
+}
+
+bool Dbg::ConfigureStep(JDWP::ObjectId threadId, JDWP::JdwpStepSize size, JDWP::JdwpStepDepth depth) {
+  UNIMPLEMENTED(FATAL);
+  return false;
+}
+
+void Dbg::UnconfigureStep(JDWP::ObjectId threadId) {
+  UNIMPLEMENTED(FATAL);
+}
+
+JDWP::JdwpError Dbg::InvokeMethod(JDWP::ObjectId threadId, JDWP::ObjectId objectId, JDWP::RefTypeId classId, JDWP::MethodId methodId, uint32_t numArgs, uint64_t* argArray, uint32_t options, uint8_t* pResultTag, uint64_t* pResultValue, JDWP::ObjectId* pExceptObj) {
+  UNIMPLEMENTED(FATAL);
+  return JDWP::ERR_NONE;
+}
+
+void Dbg::ExecuteMethod(DebugInvokeReq* pReq) {
+  UNIMPLEMENTED(FATAL);
+}
+
+void Dbg::RegisterObjectId(JDWP::ObjectId id) {
+  UNIMPLEMENTED(FATAL);
+}
+
+bool Dbg::DdmHandlePacket(const uint8_t* buf, int dataLen, uint8_t** pReplyBuf, int* pReplyLen) {
+  UNIMPLEMENTED(FATAL);
+  return false;
+}
+
+void Dbg::DdmConnected() {
+  UNIMPLEMENTED(FATAL);
+}
+
+void Dbg::DdmDisconnected() {
+  UNIMPLEMENTED(FATAL);
+}
+
+void Dbg::DdmSendChunk(int type, size_t length, const uint8_t* buf) {
+  UNIMPLEMENTED(WARNING) << "DdmSendChunk(" << type << ", " << length << ", " << (void*) buf << ");";
+}
+
+void Dbg::DdmSendChunkV(int type, const struct iovec* iov, int iovcnt) {
+  UNIMPLEMENTED(FATAL);
+}
+
+}  // namespace art
diff --git a/src/debugger.h b/src/debugger.h
new file mode 100644
index 0000000..b66fd11
--- /dev/null
+++ b/src/debugger.h
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Dalvik-specific side of debugger support.  (The JDWP code is intended to
+ * be relatively generic.)
+ */
+#ifndef ART_DEBUGGER_H_
+#define ART_DEBUGGER_H_
+
+#include <pthread.h>
+
+#include "object.h"
+#include "jdwp/jdwp.h"
+
+namespace art {
+
+struct Thread;
+
+/*
+ * Invoke-during-breakpoint support.
+ */
+struct DebugInvokeReq {
+  /* boolean; only set when we're in the tail end of an event handler */
+  bool ready;
+
+  /* boolean; set if the JDWP thread wants this thread to do work */
+  bool invokeNeeded;
+
+  /* request */
+  Object* obj;        /* not used for ClassType.InvokeMethod */
+  Object* thread;
+  Class* class_;
+  Method* method;
+  uint32_t numArgs;
+  uint64_t* argArray;   /* will be NULL if numArgs==0 */
+  uint32_t options;
+
+  /* result */
+  JDWP::JdwpError err;
+  uint8_t resultTag;
+  JValue resultValue;
+  JDWP::ObjectId exceptObj;
+
+  /* condition variable to wait on while the method executes */
+  Mutex lock_;
+  ConditionVariable cond_;
+};
+
+class Dbg {
+public:
+  static bool DebuggerStartup();
+  static void DebuggerShutdown();
+
+  // Return the DebugInvokeReq for the current thread.
+  static DebugInvokeReq* GetInvokeReq();
+
+  /*
+   * Enable/disable breakpoints and step modes.  Used to provide a heads-up
+   * when the debugger attaches.
+   */
+  static void Connected();
+  static void Active();
+  static void Disconnected();
+
+  /*
+   * Returns "true" if a debugger is connected.  Returns "false" if it's
+   * just DDM.
+   */
+  static bool IsDebuggerConnected();
+
+  static bool IsDebuggingEnabled();
+
+  /*
+   * Time, in milliseconds, since the last debugger activity.  Does not
+   * include DDMS activity.  Returns -1 if there has been no activity.
+   * Returns 0 if we're in the middle of handling a debugger request.
+   */
+  static int64_t LastDebuggerActivity();
+
+  /*
+   * Block/allow GC depending on what we're doing.  These return the old
+   * status, which can be fed to ThreadContinuing() to restore the previous
+   * mode.
+   */
+  static int ThreadRunning();
+  static int ThreadWaiting();
+  static int ThreadContinuing(int status);
+
+  static void UndoDebuggerSuspensions();
+
+  // The debugger wants the VM to exit.
+  static void Exit(int status);
+
+  /*
+   * Class, Object, Array
+   */
+  static const char* GetClassDescriptor(JDWP::RefTypeId id);
+  static JDWP::ObjectId GetClassObject(JDWP::RefTypeId id);
+  static JDWP::RefTypeId GetSuperclass(JDWP::RefTypeId id);
+  static JDWP::ObjectId GetClassLoader(JDWP::RefTypeId id);
+  static uint32_t GetAccessFlags(JDWP::RefTypeId id);
+  static bool IsInterface(JDWP::RefTypeId id);
+  static void GetClassList(uint32_t* pNumClasses, JDWP::RefTypeId** pClassRefBuf);
+  static void GetVisibleClassList(JDWP::ObjectId classLoaderId, uint32_t* pNumClasses, JDWP::RefTypeId** pClassRefBuf);
+  static void GetClassInfo(JDWP::RefTypeId classId, uint8_t* pTypeTag, uint32_t* pStatus, const char** pSignature);
+  static bool FindLoadedClassBySignature(const char* classDescriptor, JDWP::RefTypeId* pRefTypeId);
+  static void GetObjectType(JDWP::ObjectId objectId, uint8_t* pRefTypeTag, JDWP::RefTypeId* pRefTypeId);
+  static uint8_t GetClassObjectType(JDWP::RefTypeId refTypeId);
+  static const char* GetSignature(JDWP::RefTypeId refTypeId);
+  static const char* GetSourceFile(JDWP::RefTypeId refTypeId);
+  static const char* GetObjectTypeName(JDWP::ObjectId objectId);
+  static uint8_t GetObjectTag(JDWP::ObjectId objectId);
+  static int GetTagWidth(int tag);
+
+  static int GetArrayLength(JDWP::ObjectId arrayId);
+  static uint8_t GetArrayElementTag(JDWP::ObjectId arrayId);
+  static bool OutputArray(JDWP::ObjectId arrayId, int firstIndex, int count, JDWP::ExpandBuf* pReply);
+  static bool SetArrayElements(JDWP::ObjectId arrayId, int firstIndex, int count, const uint8_t* buf);
+
+  static JDWP::ObjectId CreateString(const char* str);
+  static JDWP::ObjectId CreateObject(JDWP::RefTypeId classId);
+  static JDWP::ObjectId CreateArrayObject(JDWP::RefTypeId arrayTypeId, uint32_t length);
+
+  static bool MatchType(JDWP::RefTypeId instClassId, JDWP::RefTypeId classId);
+
+  /*
+   * Method and Field
+   */
+  static const char* GetMethodName(JDWP::RefTypeId refTypeId, JDWP::MethodId id);
+  static void OutputAllFields(JDWP::RefTypeId refTypeId, bool withGeneric, JDWP::ExpandBuf* pReply);
+  static void OutputAllMethods(JDWP::RefTypeId refTypeId, bool withGeneric, JDWP::ExpandBuf* pReply);
+  static void OutputAllInterfaces(JDWP::RefTypeId refTypeId, JDWP::ExpandBuf* pReply);
+  static void OutputLineTable(JDWP::RefTypeId refTypeId, JDWP::MethodId methodId, JDWP::ExpandBuf* pReply);
+  static void OutputVariableTable(JDWP::RefTypeId refTypeId, JDWP::MethodId id, bool withGeneric, JDWP::ExpandBuf* pReply);
+
+  static uint8_t GetFieldBasicTag(JDWP::ObjectId objId, JDWP::FieldId fieldId);
+  static uint8_t GetStaticFieldBasicTag(JDWP::RefTypeId refTypeId, JDWP::FieldId fieldId);
+  static void GetFieldValue(JDWP::ObjectId objectId, JDWP::FieldId fieldId, JDWP::ExpandBuf* pReply);
+  static void SetFieldValue(JDWP::ObjectId objectId, JDWP::FieldId fieldId, uint64_t value, int width);
+  static void GetStaticFieldValue(JDWP::RefTypeId refTypeId, JDWP::FieldId fieldId, JDWP::ExpandBuf* pReply);
+  static void SetStaticFieldValue(JDWP::RefTypeId refTypeId, JDWP::FieldId fieldId, uint64_t rawValue, int width);
+
+  static char* StringToUtf8(JDWP::ObjectId strId);
+
+  /*
+   * Thread, ThreadGroup, Frame
+   */
+  static char* GetThreadName(JDWP::ObjectId threadId);
+  static JDWP::ObjectId GetThreadGroup(JDWP::ObjectId threadId);
+  static char* GetThreadGroupName(JDWP::ObjectId threadGroupId);
+  static JDWP::ObjectId GetThreadGroupParent(JDWP::ObjectId threadGroupId);
+  static JDWP::ObjectId GetSystemThreadGroupId();
+  static JDWP::ObjectId GetMainThreadGroupId();
+
+  static bool GetThreadStatus(JDWP::ObjectId threadId, uint32_t* threadStatus, uint32_t* suspendStatus);
+  static uint32_t GetThreadSuspendCount(JDWP::ObjectId threadId);
+  static bool ThreadExists(JDWP::ObjectId threadId);
+  static bool IsSuspended(JDWP::ObjectId threadId);
+  //static void WaitForSuspend(JDWP::ObjectId threadId);
+  static void GetThreadGroupThreads(JDWP::ObjectId threadGroupId, JDWP::ObjectId** ppThreadIds, uint32_t* pThreadCount);
+  static void GetAllThreads(JDWP::ObjectId** ppThreadIds, uint32_t* pThreadCount);
+  static int GetThreadFrameCount(JDWP::ObjectId threadId);
+  static bool GetThreadFrame(JDWP::ObjectId threadId, int num, JDWP::FrameId* pFrameId, JDWP::JdwpLocation* pLoc);
+
+  static JDWP::ObjectId GetThreadSelfId();
+  static void SuspendVM(bool isEvent);
+  static void ResumeVM();
+  static void SuspendThread(JDWP::ObjectId threadId);
+  static void ResumeThread(JDWP::ObjectId threadId);
+  static void SuspendSelf();
+
+  static bool GetThisObject(JDWP::ObjectId threadId, JDWP::FrameId frameId, JDWP::ObjectId* pThisId);
+  static void GetLocalValue(JDWP::ObjectId threadId, JDWP::FrameId frameId, int slot, uint8_t tag, uint8_t* buf, int expectedLen);
+  static void SetLocalValue(JDWP::ObjectId threadId, JDWP::FrameId frameId, int slot, uint8_t tag, uint64_t value, int width);
+
+  /*
+   * Debugger notification
+   */
+  enum {
+    kBreakPoint     = 0x01,
+    kSingleStep     = 0x02,
+    kMethodEntry    = 0x04,
+    kMethodExit     = 0x08,
+  };
+  static void PostLocationEvent(const Method* method, int pcOffset, Object* thisPtr, int eventFlags);
+  static void PostException(void* throwFp, int throwRelPc, void* catchFp, int catchRelPc, Object* exception);
+  static void PostThreadStart(Thread* t);
+  static void PostThreadDeath(Thread* t);
+  static void PostClassPrepare(Class* c);
+
+  static bool WatchLocation(const JDWP::JdwpLocation* pLoc);
+  static void UnwatchLocation(const JDWP::JdwpLocation* pLoc);
+  static bool ConfigureStep(JDWP::ObjectId threadId, JDWP::JdwpStepSize size, JDWP::JdwpStepDepth depth);
+  static void UnconfigureStep(JDWP::ObjectId threadId);
+
+  static JDWP::JdwpError InvokeMethod(JDWP::ObjectId threadId, JDWP::ObjectId objectId, JDWP::RefTypeId classId, JDWP::MethodId methodId, uint32_t numArgs, uint64_t* argArray, uint32_t options, uint8_t* pResultTag, uint64_t* pResultValue, JDWP::ObjectId* pExceptObj);
+  static void ExecuteMethod(DebugInvokeReq* pReq);
+
+  /* perform "late registration" of an object ID */
+  static void RegisterObjectId(JDWP::ObjectId id);
+
+  /*
+   * DDM support.
+   */
+  static bool DdmHandlePacket(const uint8_t* buf, int dataLen, uint8_t** pReplyBuf, int* pReplyLen);
+  static void DdmConnected();
+  static void DdmDisconnected();
+  static void DdmSendChunk(int type, size_t len, const uint8_t* buf);
+  static void DdmSendChunkV(int type, const struct iovec* iov, int iovcnt);
+};
+
+#define CHUNK_TYPE(_name) \
+    ((_name)[0] << 24 | (_name)[1] << 16 | (_name)[2] << 8 | (_name)[3])
+
+}  // namespace art
+
+#endif  // ART_DEBUGGER_H_
diff --git a/src/jdwp/README.txt b/src/jdwp/README.txt
new file mode 100644
index 0000000..da25fb1
--- /dev/null
+++ b/src/jdwp/README.txt
@@ -0,0 +1,11 @@
+Java Debug Wire Protocol support
+
+This is a reasonably complete implementation, but only messages that are
+actually generated by debuggers have been implemented.  The reasoning
+behind this is that it's better to leave a call unimplemented than have
+something that appears implemented but has never been tested.
+
+An attempt has been made to keep the JDWP implementation distinct from the
+runtime, so that the code might be useful in other projects. Once you get
+multiple simultaneous events and debugger requests with thread suspension
+bouncing around, though, it's difficult to keep things "generic".
diff --git a/src/jdwp/jdwp.h b/src/jdwp/jdwp.h
new file mode 100644
index 0000000..1c205bc
--- /dev/null
+++ b/src/jdwp/jdwp.h
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_JDWP_JDWP_H_
+#define ART_JDWP_JDWP_H_
+
+#include "jdwp/jdwp_bits.h"
+#include "jdwp/jdwp_constants.h"
+#include "jdwp/jdwp_expand_buf.h"
+
+#include <pthread.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+struct iovec;
+
+namespace art {
+
+namespace JDWP {
+
+struct JdwpState;       /* opaque */
+
+/*
+ * Fundamental types.
+ *
+ * ObjectId and RefTypeId must be the same size.
+ */
+typedef uint32_t FieldId;     /* static or instance field */
+typedef uint32_t MethodId;    /* any kind of method, including constructors */
+typedef uint64_t ObjectId;    /* any object (threadID, stringID, arrayID, etc) */
+typedef uint64_t RefTypeId;   /* like ObjectID, but unique for Class objects */
+typedef uint64_t FrameId;     /* short-lived stack frame ID */
+
+/*
+ * Match these with the type sizes.  This way we don't have to pass
+ * a value and a length.
+ */
+static inline FieldId ReadFieldId(const uint8_t** pBuf) { return read4BE(pBuf); }
+static inline MethodId ReadMethodId(const uint8_t** pBuf) { return read4BE(pBuf); }
+static inline ObjectId ReadObjectId(const uint8_t** pBuf) { return read8BE(pBuf); }
+static inline RefTypeId ReadRefTypeId(const uint8_t** pBuf) { return read8BE(pBuf); }
+static inline FrameId ReadFrameId(const uint8_t** pBuf) { return read8BE(pBuf); }
+static inline void SetFieldId(uint8_t* buf, FieldId val) { return set4BE(buf, val); }
+static inline void SetMethodId(uint8_t* buf, MethodId val) { return set4BE(buf, val); }
+static inline void SetObjectId(uint8_t* buf, ObjectId val) { return set8BE(buf, val); }
+static inline void SetRefTypeId(uint8_t* buf, RefTypeId val) { return set8BE(buf, val); }
+static inline void SetFrameId(uint8_t* buf, FrameId val) { return set8BE(buf, val); }
+static inline void expandBufAddFieldId(ExpandBuf* pReply, FieldId id) { expandBufAdd4BE(pReply, id); }
+static inline void expandBufAddMethodId(ExpandBuf* pReply, MethodId id) { expandBufAdd4BE(pReply, id); }
+static inline void expandBufAddObjectId(ExpandBuf* pReply, ObjectId id) { expandBufAdd8BE(pReply, id); }
+static inline void expandBufAddRefTypeId(ExpandBuf* pReply, RefTypeId id) { expandBufAdd8BE(pReply, id); }
+static inline void expandBufAddFrameId(ExpandBuf* pReply, FrameId id) { expandBufAdd8BE(pReply, id); }
+
+
+/*
+ * Holds a JDWP "location".
+ */
+struct JdwpLocation {
+  uint8_t typeTag;        /* class or interface? */
+  RefTypeId classId;        /* method->clazz */
+  MethodId methodId;       /* method in which "idx" resides */
+  uint64_t idx;            /* relative index into code block */
+};
+
+/*
+ * How we talk to the debugger.
+ */
+enum JdwpTransportType {
+  kJdwpTransportUnknown = 0,
+  kJdwpTransportSocket,       /* transport=dt_socket */
+  kJdwpTransportAndroidAdb,   /* transport=dt_android_adb */
+};
+std::ostream& operator<<(std::ostream& os, const JdwpTransportType& rhs);
+
+/*
+ * Holds collection of JDWP initialization parameters.
+ */
+struct JdwpStartupParams {
+  JdwpTransportType transport;
+  bool server;
+  bool suspend;
+  char host[64];
+  short port;
+  /* more will be here someday */
+};
+
+/*
+ * Perform one-time initialization.
+ *
+ * Among other things, this binds to a port to listen for a connection from
+ * the debugger.
+ *
+ * Returns a newly-allocated JdwpState struct on success, or NULL on failure.
+ */
+JdwpState* JdwpStartup(const JdwpStartupParams* params);
+
+/*
+ * Shut everything down.
+ */
+void JdwpShutdown(JdwpState* state);
+
+/*
+ * Returns "true" if a debugger or DDM is connected.
+ */
+bool JdwpIsActive(JdwpState* state);
+
+/*
+ * Return the debugger thread's handle, or 0 if the debugger thread isn't
+ * running.
+ */
+pthread_t GetDebugThread(JdwpState* state);
+
+/*
+ * Get time, in milliseconds, since the last debugger activity.
+ */
+int64_t LastDebuggerActivity(JdwpState* state);
+
+/*
+ * When we hit a debugger event that requires suspension, it's important
+ * that we wait for the thread to suspend itself before processing any
+ * additional requests.  (Otherwise, if the debugger immediately sends a
+ * "resume thread" command, the resume might arrive before the thread has
+ * suspended itself.)
+ *
+ * The thread should call the "set" function before sending the event to
+ * the debugger.  The main JDWP handler loop calls "get" before processing
+ * an event, and will wait for thread suspension if it's set.  Once the
+ * thread has suspended itself, the JDWP handler calls "clear" and
+ * continues processing the current event.  This works in the suspend-all
+ * case because the event thread doesn't suspend itself until everything
+ * else has suspended.
+ *
+ * It's possible that multiple threads could encounter thread-suspending
+ * events at the same time, so we grab a mutex in the "set" call, and
+ * release it in the "clear" call.
+ */
+//ObjectId GetWaitForEventThread(JdwpState* state);
+void SetWaitForEventThread(JdwpState* state, ObjectId threadId);
+void ClearWaitForEventThread(JdwpState* state);
+
+/*
+ * These notify the debug code that something interesting has happened.  This
+ * could be a thread starting or ending, an exception, or an opportunity
+ * for a breakpoint.  These calls do not mean that an event the debugger
+ * is interested has happened, just that something has happened that the
+ * debugger *might* be interested in.
+ *
+ * The item of interest may trigger multiple events, some or all of which
+ * are grouped together in a single response.
+ *
+ * The event may cause the current thread or all threads (except the
+ * JDWP support thread) to be suspended.
+ */
+
+/*
+ * The VM has finished initializing.  Only called when the debugger is
+ * connected at the time initialization completes.
+ */
+bool PostVMStart(JdwpState* state, bool suspend);
+
+/*
+ * A location of interest has been reached.  This is used for breakpoints,
+ * single-stepping, and method entry/exit.  (JDWP requires that these four
+ * events are grouped together in a single response.)
+ *
+ * In some cases "*pLoc" will just have a method and class name, e.g. when
+ * issuing a MethodEntry on a native method.
+ *
+ * "eventFlags" indicates the types of events that have occurred.
+ */
+bool PostLocationEvent(JdwpState* state, const JdwpLocation* pLoc, ObjectId thisPtr, int eventFlags);
+
+/*
+ * An exception has been thrown.
+ *
+ * Pass in a zeroed-out "*pCatchLoc" if the exception wasn't caught.
+ */
+bool PostException(JdwpState* state, const JdwpLocation* pThrowLoc,
+    ObjectId excepId, RefTypeId excepClassId, const JdwpLocation* pCatchLoc,
+    ObjectId thisPtr);
+
+/*
+ * A thread has started or stopped.
+ */
+bool PostThreadChange(JdwpState* state, ObjectId threadId, bool start);
+
+/*
+ * Class has been prepared.
+ */
+bool PostClassPrepare(JdwpState* state, int tag, RefTypeId refTypeId,
+    const char* signature, int status);
+
+/*
+ * The VM is about to stop.
+ */
+bool PostVMDeath(JdwpState* state);
+
+/*
+ * Send up a chunk of DDM data.
+ */
+void DdmSendChunkV(JdwpState* state, int type, const iovec* iov, int iovcnt);
+
+}  // namespace JDWP
+
+}  // namespace art
+
+#endif  // ART_JDWP_JDWP_H_
diff --git a/src/jdwp/jdwp_adb.cc b/src/jdwp/jdwp_adb.cc
new file mode 100644
index 0000000..3a89f34
--- /dev/null
+++ b/src/jdwp/jdwp_adb.cc
@@ -0,0 +1,723 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "logging.h"
+#include "jdwp/jdwp_priv.h"
+#include "jdwp/jdwp_handler.h"
+#include "stringprintf.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#ifdef HAVE_ANDROID_OS
+#include "cutils/sockets.h"
+#endif
+
+/*
+ * The JDWP <-> ADB transport protocol is explained in detail
+ * in system/core/adb/jdwp_service.c. Here's a summary.
+ *
+ * 1/ when the JDWP thread starts, it tries to connect to a Unix
+ *    domain stream socket (@jdwp-control) that is opened by the
+ *    ADB daemon.
+ *
+ * 2/ it then sends the current process PID as a string of 4 hexadecimal
+ *    chars (no terminating zero)
+ *
+ * 3/ then, it uses recvmsg to receive file descriptors from the
+ *    daemon. each incoming file descriptor is a pass-through to
+ *    a given JDWP debugger, that can be used to read the usual
+ *    JDWP-handshake, etc...
+ */
+
+#define kInputBufferSize    8192
+
+#define kMagicHandshake     "JDWP-Handshake"
+#define kMagicHandshakeLen  (sizeof(kMagicHandshake)-1)
+
+#define kJdwpControlName    "\0jdwp-control"
+#define kJdwpControlNameLen (sizeof(kJdwpControlName)-1)
+
+namespace art {
+
+namespace JDWP {
+
+struct JdwpNetState : public JdwpNetStateBase {
+  int                 controlSock;
+  bool                awaitingHandshake;
+  bool                shuttingDown;
+  int                 wakeFds[2];
+
+  int                 inputCount;
+  unsigned char       inputBuffer[kInputBufferSize];
+
+  socklen_t           controlAddrLen;
+  union {
+    struct sockaddr_un  controlAddrUn;
+    struct sockaddr     controlAddrPlain;
+  } controlAddr;
+
+  JdwpNetState() {
+    controlSock = -1;
+    awaitingHandshake = false;
+    shuttingDown = false;
+    wakeFds[0] = -1;
+    wakeFds[1] = -1;
+
+    inputCount = 0;
+
+    controlAddr.controlAddrUn.sun_family = AF_UNIX;
+    controlAddrLen = sizeof(controlAddr.controlAddrUn.sun_family) + kJdwpControlNameLen;
+    memcpy(controlAddr.controlAddrUn.sun_path, kJdwpControlName, kJdwpControlNameLen);
+  }
+};
+
+static void adbStateFree(JdwpNetState* netState) {
+  if (netState == NULL) {
+    return;
+  }
+
+  if (netState->clientSock >= 0) {
+    shutdown(netState->clientSock, SHUT_RDWR);
+    close(netState->clientSock);
+  }
+  if (netState->controlSock >= 0) {
+    shutdown(netState->controlSock, SHUT_RDWR);
+    close(netState->controlSock);
+  }
+  if (netState->wakeFds[0] >= 0) {
+    close(netState->wakeFds[0]);
+    netState->wakeFds[0] = -1;
+  }
+  if (netState->wakeFds[1] >= 0) {
+    close(netState->wakeFds[1]);
+    netState->wakeFds[1] = -1;
+  }
+
+  delete netState;
+}
+
+/*
+ * Do initial prep work, e.g. binding to ports and opening files.  This
+ * runs in the main thread, before the JDWP thread starts, so it shouldn't
+ * do anything that might block forever.
+ */
+static bool startup(JdwpState* state, const JdwpStartupParams* pParams) {
+  JdwpNetState*  netState;
+
+  LOG(VERBOSE) << "ADB transport startup";
+
+  state->netState = netState = new JdwpNetState;
+  if (netState == NULL) {
+    return false;
+  }
+  return true;
+}
+
+/*
+ * Receive a file descriptor from ADB.  The fd can be used to communicate
+ * directly with a debugger or DDMS.
+ *
+ * Returns the file descriptor on success.  On failure, returns -1 and
+ * closes netState->controlSock.
+ */
+static int  receiveClientFd(JdwpNetState*  netState) {
+  struct msghdr    msg;
+  struct cmsghdr*  cmsg;
+  iovec     iov;
+  char             dummy = '!';
+  union {
+    struct cmsghdr cm;
+    char buffer[CMSG_SPACE(sizeof(int))];
+  } cm_un;
+  int              ret;
+
+  iov.iov_base       = &dummy;
+  iov.iov_len        = 1;
+  msg.msg_name       = NULL;
+  msg.msg_namelen    = 0;
+  msg.msg_iov        = &iov;
+  msg.msg_iovlen     = 1;
+  msg.msg_flags      = 0;
+  msg.msg_control    = cm_un.buffer;
+  msg.msg_controllen = sizeof(cm_un.buffer);
+
+  cmsg = CMSG_FIRSTHDR(&msg);
+  cmsg->cmsg_len   = msg.msg_controllen;
+  cmsg->cmsg_level = SOL_SOCKET;
+  cmsg->cmsg_type  = SCM_RIGHTS;
+  ((int*)(void*)CMSG_DATA(cmsg))[0] = -1;
+
+  do {
+    ret = recvmsg(netState->controlSock, &msg, 0);
+  } while (ret < 0 && errno == EINTR);
+
+  if (ret <= 0) {
+    if (ret < 0) {
+      PLOG(WARNING) << "receiving file descriptor from ADB failed (socket " << netState->controlSock << ")";
+    }
+    close(netState->controlSock);
+    netState->controlSock = -1;
+    return -1;
+  }
+
+  return ((int*)(void*)CMSG_DATA(cmsg))[0];
+}
+
+/*
+ * Block forever, waiting for a debugger to connect to us.  Called from the
+ * JDWP thread.
+ *
+ * This needs to un-block and return "false" if the VM is shutting down.  It
+ * should return "true" when it successfully accepts a connection.
+ */
+static bool acceptConnection(JdwpState* state) {
+  JdwpNetState*  netState = state->netState;
+  int retryCount = 0;
+
+  /* first, ensure that we get a connection to the ADB daemon */
+
+retry:
+  if (netState->shuttingDown) {
+    return false;
+  }
+
+  if (netState->controlSock < 0) {
+    int        sleep_ms     = 500;
+    const int  sleep_max_ms = 2*1000;
+    char       buff[5];
+
+    netState->controlSock = socket(PF_UNIX, SOCK_STREAM, 0);
+    if (netState->controlSock < 0) {
+      PLOG(ERROR) << "Could not create ADB control socket";
+      return false;
+    }
+
+    if (pipe(netState->wakeFds) < 0) {
+      PLOG(ERROR) << "pipe failed";
+      return false;
+    }
+
+    snprintf(buff, sizeof(buff), "%04x", getpid());
+    buff[4] = 0;
+
+    for (;;) {
+      /*
+       * If adbd isn't running, because USB debugging was disabled or
+       * perhaps the system is restarting it for "adb root", the
+       * connect() will fail.  We loop here forever waiting for it
+       * to come back.
+       *
+       * Waking up and polling every couple of seconds is generally a
+       * bad thing to do, but we only do this if the application is
+       * debuggable *and* adbd isn't running.  Still, for the sake
+       * of battery life, we should consider timing out and giving
+       * up after a few minutes in case somebody ships an app with
+       * the debuggable flag set.
+       */
+      int  ret = connect(netState->controlSock, &netState->controlAddr.controlAddrPlain, netState->controlAddrLen);
+      if (!ret) {
+#ifdef HAVE_ANDROID_OS
+        if (!socket_peer_is_trusted(netState->controlSock)) {
+          if (shutdown(netState->controlSock, SHUT_RDWR)) {
+            PLOG(ERROR) << "trouble shutting down socket";
+          }
+          return false;
+        }
+#endif
+
+        /* now try to send our pid to the ADB daemon */
+        do {
+          ret = send( netState->controlSock, buff, 4, 0 );
+        } while (ret < 0 && errno == EINTR);
+
+        if (ret >= 0) {
+          LOG(VERBOSE) << StringPrintf("PID sent as '%.*s' to ADB", 4, buff);
+          break;
+        }
+
+        PLOG(ERROR) << "Weird, can't send JDWP process pid to ADB";
+        return false;
+      }
+      PLOG(VERBOSE) << "Can't connect to ADB control socket";
+
+      usleep( sleep_ms*1000 );
+
+      sleep_ms += (sleep_ms >> 1);
+      if (sleep_ms > sleep_max_ms) {
+        sleep_ms = sleep_max_ms;
+      }
+      if (netState->shuttingDown) {
+        return false;
+      }
+    }
+  }
+
+  LOG(VERBOSE) << "trying to receive file descriptor from ADB";
+  /* now we can receive a client file descriptor */
+  netState->clientSock = receiveClientFd(netState);
+  if (netState->shuttingDown) {
+    return false;       // suppress logs and additional activity
+  }
+  if (netState->clientSock < 0) {
+    if (++retryCount > 5) {
+      LOG(ERROR) << "adb connection max retries exceeded";
+      return false;
+    }
+    goto retry;
+  } else {
+    LOG(VERBOSE) << "received file descriptor " << netState->clientSock << " from ADB";
+    netState->awaitingHandshake = 1;
+    netState->inputCount = 0;
+    return true;
+  }
+}
+
+/*
+ * Connect out to a debugger (for server=n).  Not required.
+ */
+static bool establishConnection(JdwpState* state) {
+  return false;
+}
+
+/*
+ * Close a connection from a debugger (which may have already dropped us).
+ * Only called from the JDWP thread.
+ */
+static void closeConnection(JdwpState* state) {
+  CHECK(state != NULL && state->netState != NULL);
+
+  JdwpNetState* netState = state->netState;
+  if (netState->clientSock < 0) {
+    return;
+  }
+
+  LOG(VERBOSE) << "+++ closed JDWP <-> ADB connection";
+
+  close(netState->clientSock);
+  netState->clientSock = -1;
+}
+
+/*
+ * Close all network stuff, including the socket we use to listen for
+ * new connections.
+ *
+ * May be called from a non-JDWP thread, e.g. when the VM is shutting down.
+ */
+static void adbStateShutdown(JdwpNetState* netState) {
+  int  controlSock;
+  int  clientSock;
+
+  if (netState == NULL) {
+    return;
+  }
+
+  netState->shuttingDown = true;
+
+  clientSock = netState->clientSock;
+  if (clientSock >= 0) {
+    shutdown(clientSock, SHUT_RDWR);
+    netState->clientSock = -1;
+  }
+
+  controlSock = netState->controlSock;
+  if (controlSock >= 0) {
+    shutdown(controlSock, SHUT_RDWR);
+    netState->controlSock = -1;
+  }
+
+  if (netState->wakeFds[1] >= 0) {
+    LOG(VERBOSE) << "+++ writing to wakePipe";
+    write(netState->wakeFds[1], "", 1);
+  }
+}
+
+static void netShutdown(JdwpState* state) {
+  adbStateShutdown(state->netState);
+}
+
+/*
+ * Free up anything we put in state->netState.  This is called after
+ * "netShutdown", after the JDWP thread has stopped.
+ */
+static void netFree(JdwpState* state) {
+  JdwpNetState*  netState = state->netState;
+  adbStateFree(netState);
+}
+
+/*
+ * Is a debugger connected to us?
+ */
+static bool isConnected(JdwpState* state) {
+  return (state->netState != NULL && state->netState->clientSock >= 0);
+}
+
+/*
+ * Are we still waiting for the JDWP handshake?
+ */
+static bool awaitingHandshake(JdwpState* state) {
+  return state->netState->awaitingHandshake;
+}
+
+/*
+ * Figure out if we have a full packet in the buffer.
+ */
+static bool haveFullPacket(JdwpNetState* netState) {
+  if (netState->awaitingHandshake) {
+    return (netState->inputCount >= (int) kMagicHandshakeLen);
+  }
+  if (netState->inputCount < 4) {
+    return false;
+  }
+  long length = get4BE(netState->inputBuffer);
+  return (netState->inputCount >= length);
+}
+
+/*
+ * Consume bytes from the buffer.
+ *
+ * This would be more efficient with a circular buffer.  However, we're
+ * usually only going to find one packet, which is trivial to handle.
+ */
+static void consumeBytes(JdwpNetState* netState, int count) {
+  CHECK_GT(count, 0);
+  CHECK_LE(count, netState->inputCount);
+
+  if (count == netState->inputCount) {
+    netState->inputCount = 0;
+    return;
+  }
+
+  memmove(netState->inputBuffer, netState->inputBuffer + count, netState->inputCount - count);
+  netState->inputCount -= count;
+}
+
+/*
+ * Handle a packet.  Returns "false" if we encounter a connection-fatal error.
+ */
+static bool handlePacket(JdwpState* state) {
+  JdwpNetState* netState = state->netState;
+  const unsigned char* buf = netState->inputBuffer;
+  JdwpReqHeader hdr;
+  uint32_t length, id;
+  uint8_t flags, cmdSet, cmd;
+  uint16_t error;
+  bool reply;
+  int dataLen;
+
+  cmd = cmdSet = 0;       // shut up gcc
+
+  length = read4BE(&buf);
+  id = read4BE(&buf);
+  flags = read1(&buf);
+  if ((flags & kJDWPFlagReply) != 0) {
+    reply = true;
+    error = read2BE(&buf);
+  } else {
+    reply = false;
+    cmdSet = read1(&buf);
+    cmd = read1(&buf);
+  }
+
+  CHECK_LE((int) length, netState->inputCount);
+  dataLen = length - (buf - netState->inputBuffer);
+
+  if (!reply) {
+    ExpandBuf* pReply = expandBufAlloc();
+
+    hdr.length = length;
+    hdr.id = id;
+    hdr.cmdSet = cmdSet;
+    hdr.cmd = cmd;
+    ProcessRequest(state, &hdr, buf, dataLen, pReply);
+    if (expandBufGetLength(pReply) > 0) {
+      ssize_t cc = netState->writePacket(pReply);
+
+      if (cc != (ssize_t) expandBufGetLength(pReply)) {
+        PLOG(ERROR) << "Failed sending reply to debugger";
+        expandBufFree(pReply);
+        return false;
+      }
+    } else {
+      LOG(WARNING) << "No reply created for set=" << cmdSet << " cmd=" << cmd;
+    }
+    expandBufFree(pReply);
+  } else {
+    LOG(FATAL) << "reply?!";
+  }
+
+  LOG(VERBOSE) << "----------";
+
+  consumeBytes(netState, length);
+  return true;
+}
+
+/*
+ * Process incoming data.  If no data is available, this will block until
+ * some arrives.
+ *
+ * If we get a full packet, handle it.
+ *
+ * To take some of the mystery out of life, we want to reject incoming
+ * connections if we already have a debugger attached.  If we don't, the
+ * debugger will just mysteriously hang until it times out.  We could just
+ * close the listen socket, but there's a good chance we won't be able to
+ * bind to the same port again, which would confuse utilities.
+ *
+ * Returns "false" on error (indicating that the connection has been severed),
+ * "true" if things are still okay.
+ */
+static bool processIncoming(JdwpState* state) {
+  JdwpNetState* netState = state->netState;
+  int readCount;
+
+  CHECK_GE(netState->clientSock, 0);
+
+  if (!haveFullPacket(netState)) {
+    /* read some more, looping until we have data */
+    errno = 0;
+    while (1) {
+      int selCount;
+      fd_set readfds;
+      int maxfd = -1;
+      int fd;
+
+      FD_ZERO(&readfds);
+
+      /* configure fds; note these may get zapped by another thread */
+      fd = netState->controlSock;
+      if (fd >= 0) {
+        FD_SET(fd, &readfds);
+        if (maxfd < fd) {
+          maxfd = fd;
+        }
+      }
+      fd = netState->clientSock;
+      if (fd >= 0) {
+        FD_SET(fd, &readfds);
+        if (maxfd < fd) {
+          maxfd = fd;
+        }
+      }
+      fd = netState->wakeFds[0];
+      if (fd >= 0) {
+        FD_SET(fd, &readfds);
+        if (maxfd < fd) {
+          maxfd = fd;
+        }
+      } else {
+        LOG(INFO) << "NOTE: entering select w/o wakepipe";
+      }
+
+      if (maxfd < 0) {
+        LOG(VERBOSE) << "+++ all fds are closed";
+        return false;
+      }
+
+      /*
+       * Select blocks until it sees activity on the file descriptors.
+       * Closing the local file descriptor does not count as activity,
+       * so we can't rely on that to wake us up (it works for read()
+       * and accept(), but not select()).
+       *
+       * We can do one of three things: (1) send a signal and catch
+       * EINTR, (2) open an additional fd ("wakePipe") and write to
+       * it when it's time to exit, or (3) time out periodically and
+       * re-issue the select.  We're currently using #2, as it's more
+       * reliable than #1 and generally better than #3.  Wastes two fds.
+       */
+      selCount = select(maxfd+1, &readfds, NULL, NULL, NULL);
+      if (selCount < 0) {
+        if (errno == EINTR) {
+          continue;
+        }
+        PLOG(ERROR) << "select failed";
+        goto fail;
+      }
+
+      if (netState->wakeFds[0] >= 0 && FD_ISSET(netState->wakeFds[0], &readfds)) {
+        LOG(DEBUG) << "Got wake-up signal, bailing out of select";
+        goto fail;
+      }
+      if (netState->controlSock >= 0 && FD_ISSET(netState->controlSock, &readfds)) {
+        int  sock = receiveClientFd(netState);
+        if (sock >= 0) {
+          LOG(INFO) << "Ignoring second debugger -- accepting and dropping";
+          close(sock);
+        } else {
+          CHECK_LT(netState->controlSock, 0);
+          /*
+           * Remote side most likely went away, so our next read
+           * on netState->clientSock will fail and throw us out
+           * of the loop.
+           */
+        }
+      }
+      if (netState->clientSock >= 0 && FD_ISSET(netState->clientSock, &readfds)) {
+        readCount = read(netState->clientSock, netState->inputBuffer + netState->inputCount, sizeof(netState->inputBuffer) - netState->inputCount);
+        if (readCount < 0) {
+          /* read failed */
+          if (errno != EINTR) {
+            goto fail;
+          }
+          LOG(DEBUG) << "+++ EINTR hit";
+          return true;
+        } else if (readCount == 0) {
+          /* EOF hit -- far end went away */
+          LOG(VERBOSE) << "+++ peer disconnected";
+          goto fail;
+        } else {
+          break;
+        }
+      }
+    }
+
+    netState->inputCount += readCount;
+    if (!haveFullPacket(netState)) {
+      return true;        /* still not there yet */
+    }
+  }
+
+  /*
+   * Special-case the initial handshake.  For some bizarre reason we're
+   * expected to emulate bad tty settings by echoing the request back
+   * exactly as it was sent.  Note the handshake is always initiated by
+   * the debugger, no matter who connects to whom.
+   *
+   * Other than this one case, the protocol [claims to be] stateless.
+   */
+  if (netState->awaitingHandshake) {
+    int cc;
+
+    if (memcmp(netState->inputBuffer, kMagicHandshake, kMagicHandshakeLen) != 0) {
+      LOG(ERROR) << StringPrintf("ERROR: bad handshake '%.14s'", netState->inputBuffer);
+      goto fail;
+    }
+
+    errno = 0;
+    cc = write(netState->clientSock, netState->inputBuffer, kMagicHandshakeLen);
+    if (cc != kMagicHandshakeLen) {
+      PLOG(ERROR) << "Failed writing handshake bytes (" << cc << " of " << kMagicHandshakeLen << ")";
+      goto fail;
+    }
+
+    consumeBytes(netState, kMagicHandshakeLen);
+    netState->awaitingHandshake = false;
+    LOG(VERBOSE) << "+++ handshake complete";
+    return true;
+  }
+
+  /*
+   * Handle this packet.
+   */
+  return handlePacket(state);
+
+fail:
+  closeConnection(state);
+  return false;
+}
+
+/*
+ * Send a request.
+ *
+ * The entire packet must be sent with a single write() call to avoid
+ * threading issues.
+ *
+ * Returns "true" if it was sent successfully.
+ */
+static bool sendRequest(JdwpState* state, ExpandBuf* pReq) {
+  JdwpNetState* netState = state->netState;
+
+  if (netState->clientSock < 0) {
+    /* can happen with some DDMS events */
+    LOG(VERBOSE) << "NOT sending request -- no debugger is attached";
+    return false;
+  }
+
+  errno = 0;
+
+  ssize_t cc = netState->writePacket(pReq);
+
+  if (cc != (ssize_t) expandBufGetLength(pReq)) {
+    PLOG(ERROR) << "Failed sending req to debugger (" << cc << " of " << expandBufGetLength(pReq) << ")";
+    return false;
+  }
+
+  return true;
+}
+
+/*
+ * Send a request that was split into multiple buffers.
+ *
+ * The entire packet must be sent with a single writev() call to avoid
+ * threading issues.
+ *
+ * Returns "true" if it was sent successfully.
+ */
+static bool sendBufferedRequest(JdwpState* state, const iovec* iov, int iovcnt) {
+  JdwpNetState* netState = state->netState;
+
+  if (netState->clientSock < 0) {
+    /* can happen with some DDMS events */
+    LOG(VERBOSE) << "NOT sending request -- no debugger is attached";
+    return false;
+  }
+
+  size_t expected = 0;
+  int i;
+  for (i = 0; i < iovcnt; i++) {
+    expected += iov[i].iov_len;
+  }
+
+  ssize_t actual = netState->writeBufferedPacket(iov, iovcnt);
+  if ((size_t)actual != expected) {
+    PLOG(ERROR) << "Failed sending b-req to debugger (" << actual << " of " << expected << ")";
+    return false;
+  }
+
+  return true;
+}
+
+/*
+ * Our functions.
+ */
+static const JdwpTransport adbTransport = {
+  startup,
+  acceptConnection,
+  establishConnection,
+  closeConnection,
+  netShutdown,
+  netFree,
+  isConnected,
+  awaitingHandshake,
+  processIncoming,
+  sendRequest,
+  sendBufferedRequest
+};
+
+/*
+ * Return our set.
+ */
+const JdwpTransport* AndroidAdbTransport() {
+  return &adbTransport;
+}
+
+}  // namespace JDWP
+
+}  // namespace art
diff --git a/src/jdwp/jdwp_bits.h b/src/jdwp/jdwp_bits.h
new file mode 100644
index 0000000..b0041f1
--- /dev/null
+++ b/src/jdwp/jdwp_bits.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_JDWP_BITS_H_
+#define ART_JDWP_BITS_H_
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+namespace art {
+
+namespace JDWP {
+
+static inline uint32_t get4BE(unsigned char const* pSrc) {
+  return (pSrc[0] << 24) | (pSrc[1] << 16) | (pSrc[2] << 8) | pSrc[3];
+}
+
+static inline uint8_t read1(unsigned const char** ppSrc) {
+  return *(*ppSrc)++;
+}
+
+static inline uint16_t read2BE(unsigned char const** ppSrc) {
+  const unsigned char* pSrc = *ppSrc;
+  *ppSrc = pSrc + 2;
+  return pSrc[0] << 8 | pSrc[1];
+}
+
+static inline uint32_t read4BE(unsigned char const** ppSrc) {
+  const unsigned char* pSrc = *ppSrc;
+  uint32_t result = pSrc[0] << 24;
+  result |= pSrc[1] << 16;
+  result |= pSrc[2] << 8;
+  result |= pSrc[3];
+  *ppSrc = pSrc + 4;
+  return result;
+}
+
+static inline uint64_t read8BE(unsigned char const** ppSrc) {
+  const unsigned char* pSrc = *ppSrc;
+  uint32_t high = pSrc[0];
+  high = (high << 8) | pSrc[1];
+  high = (high << 8) | pSrc[2];
+  high = (high << 8) | pSrc[3];
+  uint32_t low = pSrc[4];
+  low = (low << 8) | pSrc[5];
+  low = (low << 8) | pSrc[6];
+  low = (low << 8) | pSrc[7];
+  *ppSrc = pSrc + 8;
+  return ((uint64_t) high << 32) | (uint64_t) low;
+}
+
+/*
+ * Read a UTF-8 string into newly-allocated storage, and null-terminate it.
+ *
+ * Returns the string and its length.  (The latter is probably unnecessary
+ * for the way we're using UTF8.)
+ */
+static inline char* readNewUtf8String(unsigned char const** ppSrc, size_t* pLength) {
+  uint32_t length = read4BE(ppSrc);
+  char* buf = (char*) malloc(length+1);
+  memcpy(buf, *ppSrc, length);
+  buf[length] = '\0';
+  (*ppSrc) += length;
+  *pLength = length;
+  return buf;
+}
+
+static inline void set1(uint8_t* buf, uint8_t val) {
+  *buf = (uint8_t)(val);
+}
+
+static inline void set2BE(uint8_t* buf, uint16_t val) {
+  *buf++ = (uint8_t)(val >> 8);
+  *buf = (uint8_t)(val);
+}
+
+static inline void set4BE(uint8_t* buf, uint32_t val) {
+  *buf++ = (uint8_t)(val >> 24);
+  *buf++ = (uint8_t)(val >> 16);
+  *buf++ = (uint8_t)(val >> 8);
+  *buf = (uint8_t)(val);
+}
+
+static inline void set8BE(uint8_t* buf, uint64_t val) {
+  *buf++ = (uint8_t)(val >> 56);
+  *buf++ = (uint8_t)(val >> 48);
+  *buf++ = (uint8_t)(val >> 40);
+  *buf++ = (uint8_t)(val >> 32);
+  *buf++ = (uint8_t)(val >> 24);
+  *buf++ = (uint8_t)(val >> 16);
+  *buf++ = (uint8_t)(val >> 8);
+  *buf = (uint8_t)(val);
+}
+
+/*
+ * Stuff a UTF-8 string into the buffer.
+ */
+static inline void setUtf8String(uint8_t* buf, const uint8_t* str) {
+  uint32_t strLen = strlen((const char*)str);
+  set4BE(buf, strLen);
+  memcpy(buf + sizeof(uint32_t), str, strLen);
+}
+
+}  // namespace JDWP
+
+}  // namespace art
+
+#endif  // ART_JDWP_BITS_H_
diff --git a/src/jdwp/jdwp_constants.cc b/src/jdwp/jdwp_constants.cc
new file mode 100644
index 0000000..7110eed
--- /dev/null
+++ b/src/jdwp/jdwp_constants.cc
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * String constants to go along with enumerated values.  (Pity we don't
+ * have enumerated constant reflection in C.)  These are only needed for
+ * making the output human-readable.
+ */
+#include "jdwp/jdwp_constants.h"
+
+#include <iostream>
+
+namespace art {
+
+namespace JDWP {
+
+const char* ErrorStr(JdwpError error) {
+  switch (error) {
+  case ERR_NONE:
+    return "NONE";
+  case ERR_INVALID_THREAD:
+    return "INVALID_THREAD";
+  case ERR_INVALID_THREAD_GROUP:
+    return "INVALID_THREAD_GROUP";
+  case ERR_INVALID_PRIORITY:
+    return "INVALID_PRIORITY";
+  case ERR_THREAD_NOT_SUSPENDED:
+    return "THREAD_NOT_SUSPENDED";
+  case ERR_THREAD_SUSPENDED:
+    return "THREAD_SUSPENDED";
+  case ERR_INVALID_OBJECT:
+    return "INVALID_OBJEC";
+  case ERR_INVALID_CLASS:
+    return "INVALID_CLASS";
+  case ERR_CLASS_NOT_PREPARED:
+    return "CLASS_NOT_PREPARED";
+  case ERR_INVALID_METHODID:
+    return "INVALID_METHODID";
+  case ERR_INVALID_LOCATION:
+    return "INVALID_LOCATION";
+  case ERR_INVALID_FIELDID:
+    return "INVALID_FIELDID";
+  case ERR_INVALID_FRAMEID:
+    return "INVALID_FRAMEID";
+  case ERR_NO_MORE_FRAMES:
+    return "NO_MORE_FRAMES";
+  case ERR_OPAQUE_FRAME:
+    return "OPAQUE_FRAME";
+  case ERR_NOT_CURRENT_FRAME:
+    return "NOT_CURRENT_FRAME";
+  case ERR_TYPE_MISMATCH:
+    return "TYPE_MISMATCH";
+  case ERR_INVALID_SLOT:
+    return "INVALID_SLOT";
+  case ERR_DUPLICATE:
+    return "DUPLICATE";
+  case ERR_NOT_FOUND:
+    return "NOT_FOUND";
+  case ERR_INVALID_MONITOR:
+    return "INVALID_MONITOR";
+  case ERR_NOT_MONITOR_OWNER:
+    return "NOT_MONITOR_OWNER";
+  case ERR_INTERRUPT:
+    return "INTERRUPT";
+  case ERR_INVALID_CLASS_FORMAT:
+    return "INVALID_CLASS_FORMAT";
+  case ERR_CIRCULAR_CLASS_DEFINITION:
+    return "CIRCULAR_CLASS_DEFINITION";
+  case ERR_FAILS_VERIFICATION:
+    return "FAILS_VERIFICATION";
+  case ERR_ADD_METHOD_NOT_IMPLEMENTED:
+    return "ADD_METHOD_NOT_IMPLEMENTED";
+  case ERR_SCHEMA_CHANGE_NOT_IMPLEMENTED:
+    return "SCHEMA_CHANGE_NOT_IMPLEMENTED";
+  case ERR_INVALID_TYPESTATE:
+    return "INVALID_TYPESTATE";
+  case ERR_HIERARCHY_CHANGE_NOT_IMPLEMENTED:
+    return "HIERARCHY_CHANGE_NOT_IMPLEMENTED";
+  case ERR_DELETE_METHOD_NOT_IMPLEMENTED:
+    return "DELETE_METHOD_NOT_IMPLEMENTED";
+  case ERR_UNSUPPORTED_VERSION:
+    return "UNSUPPORTED_VERSION";
+  case ERR_NAMES_DONT_MATCH:
+    return "NAMES_DONT_MATCH";
+  case ERR_CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED:
+    return "CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED";
+  case ERR_METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED:
+    return "METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED";
+  case ERR_NOT_IMPLEMENTED:
+    return "NOT_IMPLEMENTED";
+  case ERR_NULL_POINTER:
+    return "NULL_POINTER";
+  case ERR_ABSENT_INFORMATION:
+    return "ABSENT_INFORMATION";
+  case ERR_INVALID_EVENT_TYPE:
+    return "INVALID_EVENT_TYPE";
+  case ERR_ILLEGAL_ARGUMENT:
+    return "ILLEGAL_ARGUMENT";
+  case ERR_OUT_OF_MEMORY:
+    return "OUT_OF_MEMORY";
+  case ERR_ACCESS_DENIED:
+    return "ACCESS_DENIED";
+  case ERR_VM_DEAD:
+    return "VM_DEAD";
+  case ERR_INTERNAL:
+    return "INTERNAL";
+  case ERR_UNATTACHED_THREAD:
+    return "UNATTACHED_THREAD";
+  case ERR_INVALID_TAG:
+    return "INVALID_TAG";
+  case ERR_ALREADY_INVOKING:
+    return "ALREADY_INVOKING";
+  case ERR_INVALID_INDEX:
+    return "INVALID_INDEX";
+  case ERR_INVALID_LENGTH:
+    return "INVALID_LENGTH";
+  case ERR_INVALID_STRING:
+    return "INVALID_STRING";
+  case ERR_INVALID_CLASS_LOADER:
+    return "INVALID_CLASS_LOADER";
+  case ERR_INVALID_ARRAY:
+    return "INVALID_ARRAY";
+  case ERR_TRANSPORT_LOAD:
+    return "TRANSPORT_LOAD";
+  case ERR_TRANSPORT_INIT:
+    return "TRANSPORT_INIT";
+  case ERR_NATIVE_METHOD:
+    return "NATIVE_METHOD";
+  case ERR_INVALID_COUNT:
+    return "INVALID_COUNT";
+  default:
+    return "?UNKNOWN?";
+  }
+}
+std::ostream& operator<<(std::ostream& os, const JdwpError& value) {
+  os << ErrorStr(value);
+  return os;
+}
+
+const char* EventKindStr(JdwpEventKind kind) {
+  switch (kind) {
+  case EK_SINGLE_STEP:        return "SINGLE_STEP";
+  case EK_BREAKPOINT:         return "BREAKPOINT";
+  case EK_FRAME_POP:          return "FRAME_POP";
+  case EK_EXCEPTION:          return "EXCEPTION";
+  case EK_USER_DEFINED:       return "USER_DEFINED";
+  case EK_THREAD_START:       return "THREAD_START";
+  /*case EK_THREAD_END:         return "THREAD_END";*/
+  case EK_CLASS_PREPARE:      return "CLASS_PREPARE";
+  case EK_CLASS_UNLOAD:       return "CLASS_UNLOAD";
+  case EK_CLASS_LOAD:         return "CLASS_LOAD";
+  case EK_FIELD_ACCESS:       return "FIELD_ACCESS";
+  case EK_FIELD_MODIFICATION: return "FIELD_MODIFICATION";
+  case EK_EXCEPTION_CATCH:    return "EXCEPTION_CATCH";
+  case EK_METHOD_ENTRY:       return "METHOD_ENTRY";
+  case EK_METHOD_EXIT:        return "METHOD_EXIT";
+  case EK_VM_INIT:            return "VM_INIT";
+  case EK_VM_DEATH:           return "VM_DEATH";
+  case EK_VM_DISCONNECTED:    return "VM_DISCONNECTED";
+  /*case EK_VM_START:           return "VM_START";*/
+  case EK_THREAD_DEATH:       return "THREAD_DEATH";
+  default:                    return "?UNKNOWN?";
+  }
+}
+std::ostream& operator<<(std::ostream& os, const JdwpEventKind& value) {
+  os << EventKindStr(value);
+  return os;
+}
+
+const char* ModKindStr(JdwpModKind kind) {
+  switch (kind) {
+  case MK_COUNT:              return "COUNT";
+  case MK_CONDITIONAL:        return "CONDITIONAL";
+  case MK_THREAD_ONLY:        return "THREAD_ONLY";
+  case MK_CLASS_ONLY:         return "CLASS_ONLY";
+  case MK_CLASS_MATCH:        return "CLASS_MATCH";
+  case MK_CLASS_EXCLUDE:      return "CLASS_EXCLUDE";
+  case MK_LOCATION_ONLY:      return "LOCATION_ONLY";
+  case MK_EXCEPTION_ONLY:     return "EXCEPTION_ONLY";
+  case MK_FIELD_ONLY:         return "FIELD_ONLY";
+  case MK_STEP:               return "STEP";
+  case MK_INSTANCE_ONLY:      return "INSTANCE_ONLY";
+  default:                    return "?UNKNOWN?";
+  }
+}
+std::ostream& operator<<(std::ostream& os, const JdwpModKind& value) {
+  os << ModKindStr(value);
+  return os;
+}
+
+const char* StepDepthStr(JdwpStepDepth depth) {
+  switch (depth) {
+  case SD_INTO:               return "INTO";
+  case SD_OVER:               return "OVER";
+  case SD_OUT:                return "OUT";
+  default:                    return "?UNKNOWN?";
+  }
+}
+std::ostream& operator<<(std::ostream& os, const JdwpStepDepth& value) {
+  os << StepDepthStr(value);
+  return os;
+}
+
+const char* StepSizeStr(JdwpStepSize size) {
+  switch (size) {
+  case SS_MIN:                return "MIN";
+  case SS_LINE:               return "LINE";
+  default:                    return "?UNKNOWN?";
+  }
+}
+std::ostream& operator<<(std::ostream& os, const JdwpStepSize& value) {
+  os << StepSizeStr(value);
+  return os;
+}
+
+const char* SuspendPolicyStr(JdwpSuspendPolicy policy) {
+  switch (policy) {
+  case SP_NONE:               return "NONE";
+  case SP_EVENT_THREAD:       return "EVENT_THREAD";
+  case SP_ALL:                return "ALL";
+  default:                    return "?UNKNOWN?";
+  }
+}
+std::ostream& operator<<(std::ostream& os, const JdwpSuspendPolicy& value) {
+  os << SuspendPolicyStr(value);
+  return os;
+}
+
+const char* SuspendStatusStr(JdwpSuspendStatus status) {
+  switch (status) {
+  case SUSPEND_STATUS_NOT_SUSPENDED: return "Not SUSPENDED";
+  case SUSPEND_STATUS_SUSPENDED:     return "SUSPENDED";
+  default:                           return "?UNKNOWN?";
+  }
+}
+std::ostream& operator<<(std::ostream& os, const JdwpSuspendStatus& value) {
+  os << SuspendStatusStr(value);
+  return os;
+}
+
+const char* ThreadStatusStr(JdwpThreadStatus status) {
+  switch (status) {
+  case TS_ZOMBIE:             return "ZOMBIE";
+  case TS_RUNNING:            return "RUNNING";
+  case TS_SLEEPING:           return "SLEEPING";
+  case TS_MONITOR:            return "MONITOR";
+  case TS_WAIT:               return "WAIT";
+  default:                    return "?UNKNOWN?";
+  }
+};
+std::ostream& operator<<(std::ostream& os, const JdwpThreadStatus& value) {
+  os << ThreadStatusStr(value);
+  return os;
+}
+
+}  // namespace JDWP
+
+}  // namespace art
diff --git a/src/jdwp/jdwp_constants.h b/src/jdwp/jdwp_constants.h
new file mode 100644
index 0000000..dc6d1bc
--- /dev/null
+++ b/src/jdwp/jdwp_constants.h
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * These come out of the JDWP documentation.
+ */
+#ifndef ART_JDWP_JDWPCONSTANTS_H_
+#define ART_JDWP_JDWPCONSTANTS_H_
+
+#include <iosfwd>
+
+namespace art {
+
+namespace JDWP {
+
+/*
+ * Error constants.
+ */
+enum JdwpError {
+  ERR_NONE                                        = 0,
+  ERR_INVALID_THREAD                              = 10,
+  ERR_INVALID_THREAD_GROUP                        = 11,
+  ERR_INVALID_PRIORITY                            = 12,
+  ERR_THREAD_NOT_SUSPENDED                        = 13,
+  ERR_THREAD_SUSPENDED                            = 14,
+  ERR_INVALID_OBJECT                              = 20,
+  ERR_INVALID_CLASS                               = 21,
+  ERR_CLASS_NOT_PREPARED                          = 22,
+  ERR_INVALID_METHODID                            = 23,
+  ERR_INVALID_LOCATION                            = 24,
+  ERR_INVALID_FIELDID                             = 25,
+  ERR_INVALID_FRAMEID                             = 30,
+  ERR_NO_MORE_FRAMES                              = 31,
+  ERR_OPAQUE_FRAME                                = 32,
+  ERR_NOT_CURRENT_FRAME                           = 33,
+  ERR_TYPE_MISMATCH                               = 34,
+  ERR_INVALID_SLOT                                = 35,
+  ERR_DUPLICATE                                   = 40,
+  ERR_NOT_FOUND                                   = 41,
+  ERR_INVALID_MONITOR                             = 50,
+  ERR_NOT_MONITOR_OWNER                           = 51,
+  ERR_INTERRUPT                                   = 52,
+  ERR_INVALID_CLASS_FORMAT                        = 60,
+  ERR_CIRCULAR_CLASS_DEFINITION                   = 61,
+  ERR_FAILS_VERIFICATION                          = 62,
+  ERR_ADD_METHOD_NOT_IMPLEMENTED                  = 63,
+  ERR_SCHEMA_CHANGE_NOT_IMPLEMENTED               = 64,
+  ERR_INVALID_TYPESTATE                           = 65,
+  ERR_HIERARCHY_CHANGE_NOT_IMPLEMENTED            = 66,
+  ERR_DELETE_METHOD_NOT_IMPLEMENTED               = 67,
+  ERR_UNSUPPORTED_VERSION                         = 68,
+  ERR_NAMES_DONT_MATCH                            = 69,
+  ERR_CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED      = 70,
+  ERR_METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED     = 71,
+  ERR_NOT_IMPLEMENTED                             = 99,
+  ERR_NULL_POINTER                                = 100,
+  ERR_ABSENT_INFORMATION                          = 101,
+  ERR_INVALID_EVENT_TYPE                          = 102,
+  ERR_ILLEGAL_ARGUMENT                            = 103,
+  ERR_OUT_OF_MEMORY                               = 110,
+  ERR_ACCESS_DENIED                               = 111,
+  ERR_VM_DEAD                                     = 112,
+  ERR_INTERNAL                                    = 113,
+  ERR_UNATTACHED_THREAD                           = 115,
+  ERR_INVALID_TAG                                 = 500,
+  ERR_ALREADY_INVOKING                            = 502,
+  ERR_INVALID_INDEX                               = 503,
+  ERR_INVALID_LENGTH                              = 504,
+  ERR_INVALID_STRING                              = 506,
+  ERR_INVALID_CLASS_LOADER                        = 507,
+  ERR_INVALID_ARRAY                               = 508,
+  ERR_TRANSPORT_LOAD                              = 509,
+  ERR_TRANSPORT_INIT                              = 510,
+  ERR_NATIVE_METHOD                               = 511,
+  ERR_INVALID_COUNT                               = 512,
+};
+std::ostream& operator<<(std::ostream& os, const JdwpError& value);
+
+
+/*
+ * ClassStatus constants.  These are bit flags that can be ORed together.
+ */
+enum JdwpClassStatus {
+  CS_VERIFIED             = 0x01,
+  CS_PREPARED             = 0x02,
+  CS_INITIALIZED          = 0x04,
+  CS_ERROR                = 0x08,
+};
+std::ostream& operator<<(std::ostream& os, const JdwpClassStatus& value);
+
+/*
+ * EventKind constants.
+ */
+enum JdwpEventKind {
+  EK_SINGLE_STEP          = 1,
+  EK_BREAKPOINT           = 2,
+  EK_FRAME_POP            = 3,
+  EK_EXCEPTION            = 4,
+  EK_USER_DEFINED         = 5,
+  EK_THREAD_START         = 6,
+  EK_THREAD_END           = 7,
+  EK_CLASS_PREPARE        = 8,
+  EK_CLASS_UNLOAD         = 9,
+  EK_CLASS_LOAD           = 10,
+  EK_FIELD_ACCESS         = 20,
+  EK_FIELD_MODIFICATION   = 21,
+  EK_EXCEPTION_CATCH      = 30,
+  EK_METHOD_ENTRY         = 40,
+  EK_METHOD_EXIT          = 41,
+  EK_VM_INIT              = 90,
+  EK_VM_DEATH             = 99,
+  EK_VM_DISCONNECTED      = 100,  /* "Never sent across JDWP */
+  EK_VM_START             = EK_VM_INIT,
+  EK_THREAD_DEATH         = EK_THREAD_END,
+};
+std::ostream& operator<<(std::ostream& os, const JdwpEventKind& value);
+
+/*
+ * Values for "modKind" in EventRequest.Set.
+ */
+enum JdwpModKind {
+  MK_COUNT                = 1,
+  MK_CONDITIONAL          = 2,
+  MK_THREAD_ONLY          = 3,
+  MK_CLASS_ONLY           = 4,
+  MK_CLASS_MATCH          = 5,
+  MK_CLASS_EXCLUDE        = 6,
+  MK_LOCATION_ONLY        = 7,
+  MK_EXCEPTION_ONLY       = 8,
+  MK_FIELD_ONLY           = 9,
+  MK_STEP                 = 10,
+  MK_INSTANCE_ONLY        = 11,
+};
+std::ostream& operator<<(std::ostream& os, const JdwpModKind& value);
+
+/*
+ * InvokeOptions constants (bit flags).
+ */
+enum JdwpInvokeOptions {
+  INVOKE_SINGLE_THREADED  = 0x01,
+  INVOKE_NONVIRTUAL       = 0x02,
+};
+std::ostream& operator<<(std::ostream& os, const JdwpInvokeOptions& value);
+
+/*
+ * StepDepth constants.
+ */
+enum JdwpStepDepth {
+  SD_INTO                 = 0,    /* step into method calls */
+  SD_OVER                 = 1,    /* step over method calls */
+  SD_OUT                  = 2,    /* step out of current method */
+};
+std::ostream& operator<<(std::ostream& os, const JdwpStepDepth& value);
+
+/*
+ * StepSize constants.
+ */
+enum JdwpStepSize {
+  SS_MIN                  = 0,    /* step by minimum (e.g. 1 bytecode inst) */
+  SS_LINE                 = 1,    /* if possible, step to next line */
+};
+std::ostream& operator<<(std::ostream& os, const JdwpStepSize& value);
+
+/*
+ * SuspendPolicy constants.
+ */
+enum JdwpSuspendPolicy {
+  SP_NONE                 = 0,    /* suspend no threads */
+  SP_EVENT_THREAD         = 1,    /* suspend event thread */
+  SP_ALL                  = 2,    /* suspend all threads */
+};
+std::ostream& operator<<(std::ostream& os, const JdwpSuspendPolicy& value);
+
+/*
+ * SuspendStatus constants.
+ */
+enum JdwpSuspendStatus {
+  SUSPEND_STATUS_NOT_SUSPENDED = 0,
+  SUSPEND_STATUS_SUSPENDED     = 1,
+};
+std::ostream& operator<<(std::ostream& os, const JdwpSuspendStatus& value);
+
+/*
+ * ThreadStatus constants.
+ */
+enum JdwpThreadStatus {
+  TS_ZOMBIE               = 0,
+  TS_RUNNING              = 1,        // RUNNING
+  TS_SLEEPING             = 2,        // (in Thread.sleep())
+  TS_MONITOR              = 3,        // WAITING (monitor wait)
+  TS_WAIT                 = 4,        // (in Object.wait())
+};
+std::ostream& operator<<(std::ostream& os, const JdwpThreadStatus& value);
+
+/*
+ * TypeTag constants.
+ */
+enum JdwpTypeTag {
+  TT_CLASS                = 1,
+  TT_INTERFACE            = 2,
+  TT_ARRAY                = 3,
+};
+std::ostream& operator<<(std::ostream& os, const JdwpTypeTag& value);
+
+/*
+ * Tag constants.
+ */
+enum JdwpType {
+  JT_ARRAY                 = '[',
+  JT_BYTE                  = 'B',
+  JT_CHAR                  = 'C',
+  JT_OBJECT                = 'L',
+  JT_FLOAT                 = 'F',
+  JT_DOUBLE                = 'D',
+  JT_INT                   = 'I',
+  JT_LONG                  = 'J',
+  JT_SHORT                 = 'S',
+  JT_VOID                  = 'V',
+  JT_BOOLEAN               = 'Z',
+  JT_STRING                = 's',
+  JT_THREAD                = 't',
+  JT_THREAD_GROUP          = 'g',
+  JT_CLASS_LOADER          = 'l',
+  JT_CLASS_OBJECT          = 'c',
+};
+std::ostream& operator<<(std::ostream& os, const JdwpType& value);
+
+}  // namespace JDWP
+
+}  // namespace art
+
+#endif  // ART_JDWP_JDWPCONSTANTS_H_
diff --git a/src/jdwp/jdwp_event.cc b/src/jdwp/jdwp_event.cc
new file mode 100644
index 0000000..3a2d73e
--- /dev/null
+++ b/src/jdwp/jdwp_event.cc
@@ -0,0 +1,1211 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Send events to the debugger.
+ */
+#include "debugger.h"
+#include "jdwp/jdwp_priv.h"
+#include "jdwp/jdwp_constants.h"
+#include "jdwp/jdwp_handler.h"
+#include "jdwp/jdwp_event.h"
+#include "jdwp/jdwp_expand_buf.h"
+#include "logging.h"
+#include "stringprintf.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stddef.h>     /* for offsetof() */
+#include <unistd.h>
+
+/*
+General notes:
+
+The event add/remove stuff usually happens from the debugger thread,
+in response to requests from the debugger, but can also happen as the
+result of an event in an arbitrary thread (e.g. an event with a "count"
+mod expires).  It's important to keep the event list locked when processing
+events.
+
+Event posting can happen from any thread.  The JDWP thread will not usually
+post anything but VM start/death, but if a JDWP request causes a class
+to be loaded, the ClassPrepare event will come from the JDWP thread.
+
+
+We can have serialization issues when we post an event to the debugger.
+For example, a thread could send an "I hit a breakpoint and am suspending
+myself" message to the debugger.  Before it manages to suspend itself, the
+debugger's response ("not interested, resume thread") arrives and is
+processed.  We try to resume a thread that hasn't yet suspended.
+
+This means that, after posting an event to the debugger, we need to wait
+for the event thread to suspend itself (and, potentially, all other threads)
+before processing any additional requests from the debugger.  While doing
+so we need to be aware that multiple threads may be hitting breakpoints
+or other events simultaneously, so we either need to wait for all of them
+or serialize the events with each other.
+
+The current mechanism works like this:
+  Event thread:
+   - If I'm going to suspend, grab the "I am posting an event" token.  Wait
+     for it if it's not currently available.
+   - Post the event to the debugger.
+   - If appropriate, suspend others and then myself.  As part of suspending
+     myself, release the "I am posting" token.
+  JDWP thread:
+   - When an event arrives, see if somebody is posting an event.  If so,
+     sleep until we can acquire the "I am posting an event" token.  Release
+     it immediately and continue processing -- the event we have already
+     received should not interfere with other events that haven't yet
+     been posted.
+
+Some care must be taken to avoid deadlock:
+
+ - thread A and thread B exit near-simultaneously, and post thread-death
+   events with a "suspend all" clause
+ - thread A gets the event token, thread B sits and waits for it
+ - thread A wants to suspend all other threads, but thread B is waiting
+   for the token and can't be suspended
+
+So we need to mark thread B in such a way that thread A doesn't wait for it.
+
+If we just bracket the "grab event token" call with a change to VMWAIT
+before sleeping, the switch back to RUNNING state when we get the token
+will cause thread B to suspend (remember, thread A's global suspend is
+still in force, even after it releases the token).  Suspending while
+holding the event token is very bad, because it prevents the JDWP thread
+from processing incoming messages.
+
+We need to change to VMWAIT state at the *start* of posting an event,
+and stay there until we either finish posting the event or decide to
+put ourselves to sleep.  That way we don't interfere with anyone else and
+don't allow anyone else to interfere with us.
+*/
+
+
+#define kJdwpEventCommandSet    64
+#define kJdwpCompositeCommand   100
+
+namespace art {
+
+namespace JDWP {
+
+/*
+ * Stuff to compare against when deciding if a mod matches.  Only the
+ * values for mods valid for the event being evaluated will be filled in.
+ * The rest will be zeroed.
+ */
+struct ModBasket {
+  const JdwpLocation* pLoc;           /* LocationOnly */
+  const char*         className;      /* ClassMatch/ClassExclude */
+  ObjectId            threadId;       /* ThreadOnly */
+  RefTypeId           classId;        /* ClassOnly */
+  RefTypeId           excepClassId;   /* ExceptionOnly */
+  bool                caught;         /* ExceptionOnly */
+  FieldId             field;          /* FieldOnly */
+  ObjectId            thisPtr;        /* InstanceOnly */
+  /* nothing for StepOnly -- handled differently */
+};
+
+/*
+ * Get the next "request" serial number.  We use this when sending
+ * packets to the debugger.
+ */
+uint32_t NextRequestSerial(JdwpState* state) {
+  MutexLock mu(state->serial_lock_);
+  return state->requestSerial++;
+}
+
+/*
+ * Get the next "event" serial number.  We use this in the response to
+ * message type EventRequest.Set.
+ */
+uint32_t NextEventSerial(JdwpState* state) {
+  MutexLock mu(state->serial_lock_);
+  return state->eventSerial++;
+}
+
+/*
+ * Lock the "event" mutex, which guards the list of registered events.
+ */
+static void lockEventMutex(JdwpState* state) {
+  //Dbg::ThreadWaiting();
+  state->event_lock_.Lock();
+  //Dbg::ThreadRunning();
+}
+
+/*
+ * Unlock the "event" mutex.
+ */
+static void unlockEventMutex(JdwpState* state) {
+  state->event_lock_.Unlock();
+}
+
+/*
+ * Dump an event to the log file.
+ */
+static void dumpEvent(const JdwpEvent* pEvent) {
+  LOG(INFO) << StringPrintf("Event id=0x%4x %p (prev=%p next=%p):", pEvent->requestId, pEvent, pEvent->prev, pEvent->next);
+  LOG(INFO) << "  kind=" << pEvent->eventKind << " susp=" << pEvent->suspendPolicy << " modCount=" << pEvent->modCount;
+
+  for (int i = 0; i < pEvent->modCount; i++) {
+    const JdwpEventMod* pMod = &pEvent->mods[i];
+    LOG(INFO) << "  " << static_cast<JdwpModKind>(pMod->modKind);
+    /* TODO - show details */
+  }
+}
+
+/*
+ * Add an event to the list.  Ordering is not important.
+ *
+ * If something prevents the event from being registered, e.g. it's a
+ * single-step request on a thread that doesn't exist, the event will
+ * not be added to the list, and an appropriate error will be returned.
+ */
+JdwpError RegisterEvent(JdwpState* state, JdwpEvent* pEvent) {
+  lockEventMutex(state);
+
+  CHECK(state != NULL);
+  CHECK(pEvent != NULL);
+  CHECK(pEvent->prev == NULL);
+  CHECK(pEvent->next == NULL);
+
+  /*
+   * If one or more "break"-type mods are used, register them with
+   * the interpreter.
+   */
+  for (int i = 0; i < pEvent->modCount; i++) {
+    const JdwpEventMod* pMod = &pEvent->mods[i];
+    if (pMod->modKind == MK_LOCATION_ONLY) {
+      /* should only be for Breakpoint, Step, and Exception */
+      Dbg::WatchLocation(&pMod->locationOnly.loc);
+    } else if (pMod->modKind == MK_STEP) {
+      /* should only be for EK_SINGLE_STEP; should only be one */
+      JdwpStepSize size = static_cast<JdwpStepSize>(pMod->step.size);
+      JdwpStepDepth depth = static_cast<JdwpStepDepth>(pMod->step.depth);
+      Dbg::ConfigureStep(pMod->step.threadId, size, depth);
+    } else if (pMod->modKind == MK_FIELD_ONLY) {
+      /* should be for EK_FIELD_ACCESS or EK_FIELD_MODIFICATION */
+      dumpEvent(pEvent);  /* TODO - need for field watches */
+    }
+  }
+
+  /*
+   * Add to list.
+   */
+  if (state->eventList != NULL) {
+    pEvent->next = state->eventList;
+    state->eventList->prev = pEvent;
+  }
+  state->eventList = pEvent;
+  state->numEvents++;
+
+  unlockEventMutex(state);
+
+  return ERR_NONE;
+}
+
+/*
+ * Remove an event from the list.  This will also remove the event from
+ * any optimization tables, e.g. breakpoints.
+ *
+ * Does not free the JdwpEvent.
+ *
+ * Grab the eventLock before calling here.
+ */
+static void unregisterEvent(JdwpState* state, JdwpEvent* pEvent) {
+  if (pEvent->prev == NULL) {
+    /* head of the list */
+    CHECK(state->eventList == pEvent);
+
+    state->eventList = pEvent->next;
+  } else {
+    pEvent->prev->next = pEvent->next;
+  }
+
+  if (pEvent->next != NULL) {
+    pEvent->next->prev = pEvent->prev;
+    pEvent->next = NULL;
+  }
+  pEvent->prev = NULL;
+
+  /*
+   * Unhook us from the interpreter, if necessary.
+   */
+  for (int i = 0; i < pEvent->modCount; i++) {
+    JdwpEventMod* pMod = &pEvent->mods[i];
+    if (pMod->modKind == MK_LOCATION_ONLY) {
+      /* should only be for Breakpoint, Step, and Exception */
+      Dbg::UnwatchLocation(&pMod->locationOnly.loc);
+    }
+    if (pMod->modKind == MK_STEP) {
+      /* should only be for EK_SINGLE_STEP; should only be one */
+      Dbg::UnconfigureStep(pMod->step.threadId);
+    }
+  }
+
+  state->numEvents--;
+  CHECK(state->numEvents != 0 || state->eventList == NULL);
+}
+
+/*
+ * Remove the event with the given ID from the list.
+ *
+ * Failure to find the event isn't really an error, but it is a little
+ * weird.  (It looks like Eclipse will try to be extra careful and will
+ * explicitly remove one-off single-step events.)
+ */
+void UnregisterEventById(JdwpState* state, uint32_t requestId) {
+  lockEventMutex(state);
+
+  JdwpEvent* pEvent = state->eventList;
+  while (pEvent != NULL) {
+    if (pEvent->requestId == requestId) {
+      unregisterEvent(state, pEvent);
+      EventFree(pEvent);
+      goto done;      /* there can be only one with a given ID */
+    }
+
+    pEvent = pEvent->next;
+  }
+
+  //LOGD("Odd: no match when removing event reqId=0x%04x", requestId);
+
+done:
+  unlockEventMutex(state);
+}
+
+/*
+ * Remove all entries from the event list.
+ */
+void UnregisterAll(JdwpState* state) {
+  lockEventMutex(state);
+
+  JdwpEvent* pEvent = state->eventList;
+  while (pEvent != NULL) {
+    JdwpEvent* pNextEvent = pEvent->next;
+
+    unregisterEvent(state, pEvent);
+    EventFree(pEvent);
+    pEvent = pNextEvent;
+  }
+
+  state->eventList = NULL;
+
+  unlockEventMutex(state);
+}
+
+/*
+ * Allocate a JdwpEvent struct with enough space to hold the specified
+ * number of mod records.
+ */
+JdwpEvent* EventAlloc(int numMods) {
+  JdwpEvent* newEvent;
+  int allocSize = offsetof(JdwpEvent, mods) + numMods * sizeof(newEvent->mods[0]);
+  newEvent = reinterpret_cast<JdwpEvent*>(malloc(allocSize));
+  memset(newEvent, 0, allocSize);
+  return newEvent;
+}
+
+/*
+ * Free a JdwpEvent.
+ *
+ * Do not call this until the event has been removed from the list.
+ */
+void EventFree(JdwpEvent* pEvent) {
+  if (pEvent == NULL) {
+    return;
+  }
+
+  /* make sure it was removed from the list */
+  CHECK(pEvent->prev == NULL);
+  CHECK(pEvent->next == NULL);
+  /* want to check state->eventList != pEvent */
+
+  /*
+   * Free any hairy bits in the mods.
+   */
+  for (int i = 0; i < pEvent->modCount; i++) {
+    if (pEvent->mods[i].modKind == MK_CLASS_MATCH) {
+      free(pEvent->mods[i].classMatch.classPattern);
+      pEvent->mods[i].classMatch.classPattern = NULL;
+    }
+    if (pEvent->mods[i].modKind == MK_CLASS_EXCLUDE) {
+      free(pEvent->mods[i].classExclude.classPattern);
+      pEvent->mods[i].classExclude.classPattern = NULL;
+    }
+  }
+
+  free(pEvent);
+}
+
+/*
+ * Allocate storage for matching events.  To keep things simple we
+ * use an array with enough storage for the entire list.
+ *
+ * The state->eventLock should be held before calling.
+ */
+static JdwpEvent** allocMatchList(JdwpState* state) {
+  return (JdwpEvent**) malloc(sizeof(JdwpEvent*) * state->numEvents);
+}
+
+/*
+ * Run through the list and remove any entries with an expired "count" mod
+ * from the event list, then free the match list.
+ */
+static void cleanupMatchList(JdwpState* state, JdwpEvent** matchList, int matchCount) {
+  JdwpEvent** ppEvent = matchList;
+
+  while (matchCount--) {
+    JdwpEvent* pEvent = *ppEvent;
+
+    for (int i = 0; i < pEvent->modCount; i++) {
+      if (pEvent->mods[i].modKind == MK_COUNT && pEvent->mods[i].count.count == 0) {
+        LOG(VERBOSE) << "##### Removing expired event";
+        unregisterEvent(state, pEvent);
+        EventFree(pEvent);
+        break;
+      }
+    }
+
+    ppEvent++;
+  }
+
+  free(matchList);
+}
+
+/*
+ * Match a string against a "restricted regular expression", which is just
+ * a string that may start or end with '*' (e.g. "*.Foo" or "java.*").
+ *
+ * ("Restricted name globbing" might have been a better term.)
+ */
+static bool patternMatch(const char* pattern, const char* target) {
+  int patLen = strlen(pattern);
+
+  if (pattern[0] == '*') {
+    int targetLen = strlen(target);
+    patLen--;
+    // TODO: remove printf when we find a test case to verify this
+    LOG(ERROR) << ">>> comparing '" << (pattern + 1) << "' to '" << (target + (targetLen-patLen)) << "'";
+
+    if (targetLen < patLen) {
+      return false;
+    }
+    return strcmp(pattern+1, target + (targetLen-patLen)) == 0;
+  } else if (pattern[patLen-1] == '*') {
+    return strncmp(pattern, target, patLen-1) == 0;
+  } else {
+    return strcmp(pattern, target) == 0;
+  }
+}
+
+/*
+ * See if two locations are equal.
+ *
+ * It's tempting to do a bitwise compare ("struct ==" or memcmp), but if
+ * the storage wasn't zeroed out there could be undefined values in the
+ * padding.  Besides, the odds of "idx" being equal while the others aren't
+ * is very small, so this is usually just a simple integer comparison.
+ */
+static inline bool locationMatch(const JdwpLocation* pLoc1, const JdwpLocation* pLoc2) {
+  return pLoc1->idx == pLoc2->idx &&
+      pLoc1->methodId == pLoc2->methodId &&
+      pLoc1->classId == pLoc2->classId &&
+      pLoc1->typeTag == pLoc2->typeTag;
+}
+
+/*
+ * See if the event's mods match up with the contents of "basket".
+ *
+ * If we find a Count mod before rejecting an event, we decrement it.  We
+ * need to do this even if later mods cause us to ignore the event.
+ */
+static bool modsMatch(JdwpState* state, JdwpEvent* pEvent, ModBasket* basket) {
+  JdwpEventMod* pMod = pEvent->mods;
+
+  for (int i = pEvent->modCount; i > 0; i--, pMod++) {
+    switch (pMod->modKind) {
+    case MK_COUNT:
+      CHECK_GT(pMod->count.count, 0);
+      pMod->count.count--;
+      break;
+    case MK_CONDITIONAL:
+      CHECK(false);  // should not be getting these
+      break;
+    case MK_THREAD_ONLY:
+      if (pMod->threadOnly.threadId != basket->threadId) {
+        return false;
+      }
+      break;
+    case MK_CLASS_ONLY:
+      if (!Dbg::MatchType(basket->classId, pMod->classOnly.refTypeId)) {
+        return false;
+      }
+      break;
+    case MK_CLASS_MATCH:
+      if (!patternMatch(pMod->classMatch.classPattern, basket->className)) {
+        return false;
+      }
+      break;
+    case MK_CLASS_EXCLUDE:
+      if (patternMatch(pMod->classMatch.classPattern, basket->className)) {
+        return false;
+      }
+      break;
+    case MK_LOCATION_ONLY:
+      if (!locationMatch(&pMod->locationOnly.loc, basket->pLoc)) {
+        return false;
+      }
+      break;
+    case MK_EXCEPTION_ONLY:
+      if (pMod->exceptionOnly.refTypeId != 0 && !Dbg::MatchType(basket->excepClassId, pMod->exceptionOnly.refTypeId)) {
+        return false;
+      }
+      if ((basket->caught && !pMod->exceptionOnly.caught) || (!basket->caught && !pMod->exceptionOnly.uncaught)) {
+        return false;
+      }
+      break;
+    case MK_FIELD_ONLY:
+      if (!Dbg::MatchType(basket->classId, pMod->fieldOnly.refTypeId) || pMod->fieldOnly.fieldId != basket->field) {
+        return false;
+      }
+      break;
+    case MK_STEP:
+      if (pMod->step.threadId != basket->threadId) {
+        return false;
+      }
+      break;
+    case MK_INSTANCE_ONLY:
+      if (pMod->instanceOnly.objectId != basket->thisPtr) {
+        return false;
+      }
+      break;
+    default:
+      LOG(ERROR) << "unhandled mod kind " << pMod->modKind;
+      CHECK(false);
+      break;
+    }
+  }
+  return true;
+}
+
+/*
+ * Find all events of type "eventKind" with mods that match up with the
+ * rest of the arguments.
+ *
+ * Found events are appended to "matchList", and "*pMatchCount" is advanced,
+ * so this may be called multiple times for grouped events.
+ *
+ * DO NOT call this multiple times for the same eventKind, as Count mods are
+ * decremented during the scan.
+ */
+static void findMatchingEvents(JdwpState* state, JdwpEventKind eventKind,
+    ModBasket* basket, JdwpEvent** matchList, int* pMatchCount) {
+  /* start after the existing entries */
+  matchList += *pMatchCount;
+
+  JdwpEvent* pEvent = state->eventList;
+  while (pEvent != NULL) {
+    if (pEvent->eventKind == eventKind && modsMatch(state, pEvent, basket)) {
+      *matchList++ = pEvent;
+      (*pMatchCount)++;
+    }
+
+    pEvent = pEvent->next;
+  }
+}
+
+/*
+ * Scan through the list of matches and determine the most severe
+ * suspension policy.
+ */
+static JdwpSuspendPolicy scanSuspendPolicy(JdwpEvent** matchList, int matchCount) {
+  JdwpSuspendPolicy policy = SP_NONE;
+
+  while (matchCount--) {
+    if ((*matchList)->suspendPolicy > policy) {
+      policy = (*matchList)->suspendPolicy;
+    }
+    matchList++;
+  }
+
+  return policy;
+}
+
+/*
+ * Three possibilities:
+ *  SP_NONE - do nothing
+ *  SP_EVENT_THREAD - suspend ourselves
+ *  SP_ALL - suspend everybody except JDWP support thread
+ */
+static void suspendByPolicy(JdwpState* state, JdwpSuspendPolicy suspendPolicy) {
+  if (suspendPolicy == SP_NONE) {
+    return;
+  }
+
+  if (suspendPolicy == SP_ALL) {
+    Dbg::SuspendVM(true);
+  } else {
+    CHECK_EQ(suspendPolicy, SP_EVENT_THREAD);
+  }
+
+  /* this is rare but possible -- see CLASS_PREPARE handling */
+  if (Dbg::GetThreadSelfId() == state->debugThreadId) {
+    LOG(INFO) << "NOTE: suspendByPolicy not suspending JDWP thread";
+    return;
+  }
+
+  DebugInvokeReq* pReq = Dbg::GetInvokeReq();
+  while (true) {
+    pReq->ready = true;
+    Dbg::SuspendSelf();
+    pReq->ready = false;
+
+    /*
+     * The JDWP thread has told us (and possibly all other threads) to
+     * resume.  See if it has left anything in our DebugInvokeReq mailbox.
+     */
+    if (!pReq->invokeNeeded) {
+      /*LOGD("suspendByPolicy: no invoke needed");*/
+      break;
+    }
+
+    /* grab this before posting/suspending again */
+    SetWaitForEventThread(state, Dbg::GetThreadSelfId());
+
+    /* leave pReq->invokeNeeded raised so we can check reentrancy */
+    LOG(VERBOSE) << "invoking method...";
+    Dbg::ExecuteMethod(pReq);
+
+    pReq->err = ERR_NONE;
+
+    /* clear this before signaling */
+    pReq->invokeNeeded = false;
+
+    LOG(VERBOSE) << "invoke complete, signaling and self-suspending";
+    MutexLock mu(pReq->lock_);
+    pReq->cond_.Signal();
+  }
+}
+
+/*
+ * Determine if there is a method invocation in progress in the current
+ * thread.
+ *
+ * We look at the "invokeNeeded" flag in the per-thread DebugInvokeReq
+ * state.  If set, we're in the process of invoking a method.
+ */
+static bool invokeInProgress(JdwpState* state) {
+  DebugInvokeReq* pReq = Dbg::GetInvokeReq();
+  return pReq->invokeNeeded;
+}
+
+/*
+ * We need the JDWP thread to hold off on doing stuff while we post an
+ * event and then suspend ourselves.
+ *
+ * Call this with a threadId of zero if you just want to wait for the
+ * current thread operation to complete.
+ *
+ * This could go to sleep waiting for another thread, so it's important
+ * that the thread be marked as VMWAIT before calling here.
+ */
+void SetWaitForEventThread(JdwpState* state, ObjectId threadId) {
+  bool waited = false;
+
+  /* this is held for very brief periods; contention is unlikely */
+  MutexLock mu(state->event_thread_lock_);
+
+  /*
+   * If another thread is already doing stuff, wait for it.  This can
+   * go to sleep indefinitely.
+   */
+  while (state->eventThreadId != 0) {
+    LOG(VERBOSE) << StringPrintf("event in progress (0x%llx), 0x%llx sleeping", state->eventThreadId, threadId);
+    waited = true;
+    state->event_thread_cond_.Wait(state->event_thread_lock_);
+  }
+
+  if (waited || threadId != 0) {
+    LOG(VERBOSE) << StringPrintf("event token grabbed (0x%llx)", threadId);
+  }
+  if (threadId != 0) {
+    state->eventThreadId = threadId;
+  }
+}
+
+/*
+ * Clear the threadId and signal anybody waiting.
+ */
+void ClearWaitForEventThread(JdwpState* state) {
+  /*
+   * Grab the mutex.  Don't try to go in/out of VMWAIT mode, as this
+   * function is called by dvmSuspendSelf(), and the transition back
+   * to RUNNING would confuse it.
+   */
+  MutexLock mu(state->event_thread_lock_);
+
+  CHECK_NE(state->eventThreadId, 0U);
+  LOG(VERBOSE) << StringPrintf("cleared event token (0x%llx)", state->eventThreadId);
+
+  state->eventThreadId = 0;
+
+  state->event_thread_cond_.Signal();
+}
+
+
+/*
+ * Prep an event.  Allocates storage for the message and leaves space for
+ * the header.
+ */
+static ExpandBuf* eventPrep() {
+  ExpandBuf* pReq = expandBufAlloc();
+  expandBufAddSpace(pReq, kJDWPHeaderLen);
+  return pReq;
+}
+
+/*
+ * Write the header into the buffer and send the packet off to the debugger.
+ *
+ * Takes ownership of "pReq" (currently discards it).
+ */
+static void eventFinish(JdwpState* state, ExpandBuf* pReq) {
+  uint8_t* buf = expandBufGetBuffer(pReq);
+
+  set4BE(buf, expandBufGetLength(pReq));
+  set4BE(buf+4, NextRequestSerial(state));
+  set1(buf+8, 0);     /* flags */
+  set1(buf+9, kJdwpEventCommandSet);
+  set1(buf+10, kJdwpCompositeCommand);
+
+  SendRequest(state, pReq);
+
+  expandBufFree(pReq);
+}
+
+
+/*
+ * Tell the debugger that we have finished initializing.  This is always
+ * sent, even if the debugger hasn't requested it.
+ *
+ * This should be sent "before the main thread is started and before
+ * any application code has been executed".  The thread ID in the message
+ * must be for the main thread.
+ */
+bool PostVMStart(JdwpState* state, bool suspend) {
+  JdwpSuspendPolicy suspendPolicy;
+  ObjectId threadId = Dbg::GetThreadSelfId();
+
+  if (suspend) {
+    suspendPolicy = SP_ALL;
+  } else {
+    suspendPolicy = SP_NONE;
+  }
+
+  /* probably don't need this here */
+  lockEventMutex(state);
+
+  ExpandBuf* pReq = NULL;
+  if (true) {
+    LOG(VERBOSE) << "EVENT: " << EK_VM_START;
+    LOG(VERBOSE) << "  suspendPolicy=" << suspendPolicy;
+
+    pReq = eventPrep();
+    expandBufAdd1(pReq, suspendPolicy);
+    expandBufAdd4BE(pReq, 1);
+
+    expandBufAdd1(pReq, EK_VM_START);
+    expandBufAdd4BE(pReq, 0);       /* requestId */
+    expandBufAdd8BE(pReq, threadId);
+  }
+
+  unlockEventMutex(state);
+
+  /* send request and possibly suspend ourselves */
+  if (pReq != NULL) {
+    int oldStatus = Dbg::ThreadWaiting();
+    if (suspendPolicy != SP_NONE) {
+      SetWaitForEventThread(state, threadId);
+    }
+
+    eventFinish(state, pReq);
+
+    suspendByPolicy(state, suspendPolicy);
+    Dbg::ThreadContinuing(oldStatus);
+  }
+
+  return true;
+}
+
+// TODO: This doesn't behave like the real dvmDescriptorToName.
+// I'm hoping this isn't used to communicate with the debugger, and we can just use descriptors.
+char* dvmDescriptorToName(const char* descriptor) {
+  return strdup(descriptor);
+}
+
+/*
+ * A location of interest has been reached.  This handles:
+ *   Breakpoint
+ *   SingleStep
+ *   MethodEntry
+ *   MethodExit
+ * These four types must be grouped together in a single response.  The
+ * "eventFlags" indicates the type of event(s) that have happened.
+ *
+ * Valid mods:
+ *   Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, InstanceOnly
+ *   LocationOnly (for breakpoint/step only)
+ *   Step (for step only)
+ *
+ * Interesting test cases:
+ *  - Put a breakpoint on a native method.  Eclipse creates METHOD_ENTRY
+ *    and METHOD_EXIT events with a ClassOnly mod on the method's class.
+ *  - Use "run to line".  Eclipse creates a BREAKPOINT with Count=1.
+ *  - Single-step to a line with a breakpoint.  Should get a single
+ *    event message with both events in it.
+ */
+bool PostLocationEvent(JdwpState* state, const JdwpLocation* pLoc, ObjectId thisPtr, int eventFlags) {
+  ModBasket basket;
+  char* nameAlloc = NULL;
+
+  memset(&basket, 0, sizeof(basket));
+  basket.pLoc = pLoc;
+  basket.classId = pLoc->classId;
+  basket.thisPtr = thisPtr;
+  basket.threadId = Dbg::GetThreadSelfId();
+  basket.className = nameAlloc = dvmDescriptorToName(Dbg::GetClassDescriptor(pLoc->classId));
+
+  /*
+   * On rare occasions we may need to execute interpreted code in the VM
+   * while handling a request from the debugger.  Don't fire breakpoints
+   * while doing so.  (I don't think we currently do this at all, so
+   * this is mostly paranoia.)
+   */
+  if (basket.threadId == state->debugThreadId) {
+    LOG(VERBOSE) << "Ignoring location event in JDWP thread";
+    free(nameAlloc);
+    return false;
+  }
+
+  /*
+   * The debugger variable display tab may invoke the interpreter to format
+   * complex objects.  We want to ignore breakpoints and method entry/exit
+   * traps while working on behalf of the debugger.
+   *
+   * If we don't ignore them, the VM will get hung up, because we'll
+   * suspend on a breakpoint while the debugger is still waiting for its
+   * method invocation to complete.
+   */
+  if (invokeInProgress(state)) {
+    LOG(VERBOSE) << "Not checking breakpoints during invoke (" << basket.className << ")";
+    free(nameAlloc);
+    return false;
+  }
+
+  /* don't allow the list to be updated while we scan it */
+  lockEventMutex(state);
+
+  JdwpEvent** matchList = allocMatchList(state);
+  int matchCount = 0;
+
+  if ((eventFlags & Dbg::kBreakPoint) != 0) {
+    findMatchingEvents(state, EK_BREAKPOINT, &basket, matchList, &matchCount);
+  }
+  if ((eventFlags & Dbg::kSingleStep) != 0) {
+    findMatchingEvents(state, EK_SINGLE_STEP, &basket, matchList, &matchCount);
+  }
+  if ((eventFlags & Dbg::kMethodEntry) != 0) {
+    findMatchingEvents(state, EK_METHOD_ENTRY, &basket, matchList, &matchCount);
+  }
+  if ((eventFlags & Dbg::kMethodExit) != 0) {
+    findMatchingEvents(state, EK_METHOD_EXIT, &basket, matchList, &matchCount);
+  }
+
+  ExpandBuf* pReq = NULL;
+  JdwpSuspendPolicy suspendPolicy = SP_NONE;
+  if (matchCount != 0) {
+    LOG(VERBOSE) << "EVENT: " << matchList[0]->eventKind << "(" << matchCount << " total) "
+                 << basket.className << "." << Dbg::GetMethodName(pLoc->classId, pLoc->methodId)
+                 << " thread=" << (void*) basket.threadId << " code=" << (void*) pLoc->idx << ")";
+
+    suspendPolicy = scanSuspendPolicy(matchList, matchCount);
+    LOG(VERBOSE) << "  suspendPolicy=" << suspendPolicy;
+
+    pReq = eventPrep();
+    expandBufAdd1(pReq, suspendPolicy);
+    expandBufAdd4BE(pReq, matchCount);
+
+    for (int i = 0; i < matchCount; i++) {
+      expandBufAdd1(pReq, matchList[i]->eventKind);
+      expandBufAdd4BE(pReq, matchList[i]->requestId);
+      expandBufAdd8BE(pReq, basket.threadId);
+      AddLocation(pReq, pLoc);
+    }
+  }
+
+  cleanupMatchList(state, matchList, matchCount);
+  unlockEventMutex(state);
+
+  /* send request and possibly suspend ourselves */
+  if (pReq != NULL) {
+    int oldStatus = Dbg::ThreadWaiting();
+    if (suspendPolicy != SP_NONE) {
+      SetWaitForEventThread(state, basket.threadId);
+    }
+
+    eventFinish(state, pReq);
+
+    suspendByPolicy(state, suspendPolicy);
+    Dbg::ThreadContinuing(oldStatus);
+  }
+
+  free(nameAlloc);
+  return matchCount != 0;
+}
+
+/*
+ * A thread is starting or stopping.
+ *
+ * Valid mods:
+ *  Count, ThreadOnly
+ */
+bool PostThreadChange(JdwpState* state, ObjectId threadId, bool start) {
+  CHECK_EQ(threadId, Dbg::GetThreadSelfId());
+
+  /*
+   * I don't think this can happen.
+   */
+  if (invokeInProgress(state)) {
+    LOG(WARNING) << "Not posting thread change during invoke";
+    return false;
+  }
+
+  ModBasket basket;
+  memset(&basket, 0, sizeof(basket));
+  basket.threadId = threadId;
+
+  /* don't allow the list to be updated while we scan it */
+  lockEventMutex(state);
+
+  JdwpEvent** matchList = allocMatchList(state);
+  int matchCount = 0;
+
+  if (start) {
+    findMatchingEvents(state, EK_THREAD_START, &basket, matchList, &matchCount);
+  } else {
+    findMatchingEvents(state, EK_THREAD_DEATH, &basket, matchList, &matchCount);
+  }
+
+  ExpandBuf* pReq = NULL;
+  JdwpSuspendPolicy suspendPolicy = SP_NONE;
+  if (matchCount != 0) {
+    LOG(VERBOSE) << "EVENT: " << matchList[0]->eventKind << "(" << matchCount << " total) "
+                 << "thread=" << (void*) basket.threadId << ")";
+
+    suspendPolicy = scanSuspendPolicy(matchList, matchCount);
+    LOG(VERBOSE) << "  suspendPolicy=" << suspendPolicy;
+
+    pReq = eventPrep();
+    expandBufAdd1(pReq, suspendPolicy);
+    expandBufAdd4BE(pReq, matchCount);
+
+    for (int i = 0; i < matchCount; i++) {
+      expandBufAdd1(pReq, matchList[i]->eventKind);
+      expandBufAdd4BE(pReq, matchList[i]->requestId);
+      expandBufAdd8BE(pReq, basket.threadId);
+    }
+  }
+
+  cleanupMatchList(state, matchList, matchCount);
+  unlockEventMutex(state);
+
+  /* send request and possibly suspend ourselves */
+  if (pReq != NULL) {
+    int oldStatus = Dbg::ThreadWaiting();
+    if (suspendPolicy != SP_NONE) {
+      SetWaitForEventThread(state, basket.threadId);
+    }
+    eventFinish(state, pReq);
+
+    suspendByPolicy(state, suspendPolicy);
+    Dbg::ThreadContinuing(oldStatus);
+  }
+
+  return matchCount != 0;
+}
+
+/*
+ * Send a polite "VM is dying" message to the debugger.
+ *
+ * Skips the usual "event token" stuff.
+ */
+bool PostVMDeath(JdwpState* state) {
+  LOG(VERBOSE) << "EVENT: " << EK_VM_DEATH;
+
+  ExpandBuf* pReq = eventPrep();
+  expandBufAdd1(pReq, SP_NONE);
+  expandBufAdd4BE(pReq, 1);
+
+  expandBufAdd1(pReq, EK_VM_DEATH);
+  expandBufAdd4BE(pReq, 0);
+  eventFinish(state, pReq);
+  return true;
+}
+
+/*
+ * An exception has been thrown.  It may or may not have been caught.
+ *
+ * Valid mods:
+ *  Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, LocationOnly,
+ *    ExceptionOnly, InstanceOnly
+ *
+ * The "exceptionId" has not been added to the GC-visible object registry,
+ * because there's a pretty good chance that we're not going to send it
+ * up the debugger.
+ */
+bool PostException(JdwpState* state, const JdwpLocation* pThrowLoc,
+    ObjectId exceptionId, RefTypeId exceptionClassId,
+    const JdwpLocation* pCatchLoc, ObjectId thisPtr)
+{
+  ModBasket basket;
+  char* nameAlloc = NULL;
+
+  memset(&basket, 0, sizeof(basket));
+  basket.pLoc = pThrowLoc;
+  basket.classId = pThrowLoc->classId;
+  basket.threadId = Dbg::GetThreadSelfId();
+  basket.className = nameAlloc = dvmDescriptorToName(Dbg::GetClassDescriptor(basket.classId));
+  basket.excepClassId = exceptionClassId;
+  basket.caught = (pCatchLoc->classId != 0);
+  basket.thisPtr = thisPtr;
+
+  /* don't try to post an exception caused by the debugger */
+  if (invokeInProgress(state)) {
+    LOG(VERBOSE) << "Not posting exception hit during invoke (" << basket.className << ")";
+    free(nameAlloc);
+    return false;
+  }
+
+  /* don't allow the list to be updated while we scan it */
+  lockEventMutex(state);
+
+  JdwpEvent** matchList = allocMatchList(state);
+  int matchCount = 0;
+
+  findMatchingEvents(state, EK_EXCEPTION, &basket, matchList, &matchCount);
+
+  ExpandBuf* pReq = NULL;
+  JdwpSuspendPolicy suspendPolicy = SP_NONE;
+  if (matchCount != 0) {
+    LOG(VERBOSE) << "EVENT: " << matchList[0]->eventKind << "(" << matchCount << " total)"
+                 << " thread=" << (void*) basket.threadId
+                 << " exceptId=" << (void*) exceptionId
+                 << " caught=" << basket.caught << ")";
+    LOG(VERBOSE) << StringPrintf("  throw: %d %llx %x %lld (%s.%s)", pThrowLoc->typeTag,
+        pThrowLoc->classId, pThrowLoc->methodId, pThrowLoc->idx,
+        Dbg::GetClassDescriptor(pThrowLoc->classId),
+        Dbg::GetMethodName(pThrowLoc->classId, pThrowLoc->methodId));
+    if (pCatchLoc->classId == 0) {
+      LOG(VERBOSE) << "  catch: (not caught)";
+    } else {
+      LOG(VERBOSE) << StringPrintf("  catch: %d %llx %x %lld (%s.%s)", pCatchLoc->typeTag,
+          pCatchLoc->classId, pCatchLoc->methodId, pCatchLoc->idx,
+          Dbg::GetClassDescriptor(pCatchLoc->classId),
+          Dbg::GetMethodName(pCatchLoc->classId, pCatchLoc->methodId));
+    }
+
+    suspendPolicy = scanSuspendPolicy(matchList, matchCount);
+    LOG(VERBOSE) << "  suspendPolicy=" << suspendPolicy;
+
+    pReq = eventPrep();
+    expandBufAdd1(pReq, suspendPolicy);
+    expandBufAdd4BE(pReq, matchCount);
+
+    for (int i = 0; i < matchCount; i++) {
+      expandBufAdd1(pReq, matchList[i]->eventKind);
+      expandBufAdd4BE(pReq, matchList[i]->requestId);
+      expandBufAdd8BE(pReq, basket.threadId);
+
+      AddLocation(pReq, pThrowLoc);
+      expandBufAdd1(pReq, JT_OBJECT);
+      expandBufAdd8BE(pReq, exceptionId);
+      AddLocation(pReq, pCatchLoc);
+    }
+
+    /* don't let the GC discard it */
+    Dbg::RegisterObjectId(exceptionId);
+  }
+
+  cleanupMatchList(state, matchList, matchCount);
+  unlockEventMutex(state);
+
+  /* send request and possibly suspend ourselves */
+  if (pReq != NULL) {
+    int oldStatus = Dbg::ThreadWaiting();
+    if (suspendPolicy != SP_NONE) {
+      SetWaitForEventThread(state, basket.threadId);
+    }
+
+    eventFinish(state, pReq);
+
+    suspendByPolicy(state, suspendPolicy);
+    Dbg::ThreadContinuing(oldStatus);
+  }
+
+  free(nameAlloc);
+  return matchCount != 0;
+}
+
+/*
+ * Announce that a class has been loaded.
+ *
+ * Valid mods:
+ *  Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude
+ */
+bool PostClassPrepare(JdwpState* state, int tag, RefTypeId refTypeId, const char* signature, int status) {
+  ModBasket basket;
+  char* nameAlloc = NULL;
+
+  memset(&basket, 0, sizeof(basket));
+  basket.classId = refTypeId;
+  basket.threadId = Dbg::GetThreadSelfId();
+  basket.className = nameAlloc = dvmDescriptorToName(Dbg::GetClassDescriptor(basket.classId));
+
+  /* suppress class prep caused by debugger */
+  if (invokeInProgress(state)) {
+    LOG(VERBOSE) << "Not posting class prep caused by invoke (" << basket.className << ")";
+    free(nameAlloc);
+    return false;
+  }
+
+  /* don't allow the list to be updated while we scan it */
+  lockEventMutex(state);
+
+  JdwpEvent** matchList = allocMatchList(state);
+  int matchCount = 0;
+
+  findMatchingEvents(state, EK_CLASS_PREPARE, &basket, matchList, &matchCount);
+
+  ExpandBuf* pReq = NULL;
+  JdwpSuspendPolicy suspendPolicy = SP_NONE;
+  if (matchCount != 0) {
+    LOG(VERBOSE) << "EVENT: " << matchList[0]->eventKind << "(" << matchCount << " total) "
+                 << "thread=" << (void*) basket.threadId << ")";
+
+    suspendPolicy = scanSuspendPolicy(matchList, matchCount);
+    LOG(VERBOSE) << "  suspendPolicy=" << suspendPolicy;
+
+    if (basket.threadId == state->debugThreadId) {
+      /*
+       * JDWP says that, for a class prep in the debugger thread, we
+       * should set threadId to null and if any threads were supposed
+       * to be suspended then we suspend all other threads.
+       */
+      LOG(VERBOSE) << "  NOTE: class prepare in debugger thread!";
+      basket.threadId = 0;
+      if (suspendPolicy == SP_EVENT_THREAD) {
+        suspendPolicy = SP_ALL;
+      }
+    }
+
+    pReq = eventPrep();
+    expandBufAdd1(pReq, suspendPolicy);
+    expandBufAdd4BE(pReq, matchCount);
+
+    for (int i = 0; i < matchCount; i++) {
+      expandBufAdd1(pReq, matchList[i]->eventKind);
+      expandBufAdd4BE(pReq, matchList[i]->requestId);
+      expandBufAdd8BE(pReq, basket.threadId);
+
+      expandBufAdd1(pReq, tag);
+      expandBufAdd8BE(pReq, refTypeId);
+      expandBufAddUtf8String(pReq, (const uint8_t*) signature);
+      expandBufAdd4BE(pReq, status);
+    }
+  }
+
+  cleanupMatchList(state, matchList, matchCount);
+
+  unlockEventMutex(state);
+
+  /* send request and possibly suspend ourselves */
+  if (pReq != NULL) {
+    int oldStatus = Dbg::ThreadWaiting();
+    if (suspendPolicy != SP_NONE) {
+      SetWaitForEventThread(state, basket.threadId);
+    }
+    eventFinish(state, pReq);
+
+    suspendByPolicy(state, suspendPolicy);
+    Dbg::ThreadContinuing(oldStatus);
+  }
+
+  free(nameAlloc);
+  return matchCount != 0;
+}
+
+bool SendBufferedRequest(JdwpState* state, const iovec* iov, int iovcnt) {
+  return (*state->transport->sendBufferedRequest)(state, iov, iovcnt);
+}
+
+/*
+ * Send up a chunk of DDM data.
+ *
+ * While this takes the form of a JDWP "event", it doesn't interact with
+ * other debugger traffic, and can't suspend the VM, so we skip all of
+ * the fun event token gymnastics.
+ */
+void DdmSendChunkV(JdwpState* state, int type, const iovec* iov, int iovcnt) {
+  uint8_t header[kJDWPHeaderLen + 8];
+  size_t dataLen = 0;
+
+  CHECK(iov != NULL);
+  CHECK(iovcnt > 0 && iovcnt < 10);
+
+  /*
+   * "Wrap" the contents of the iovec with a JDWP/DDMS header.  We do
+   * this by creating a new copy of the vector with space for the header.
+   */
+  iovec wrapiov[iovcnt+1];
+  for (int i = 0; i < iovcnt; i++) {
+    wrapiov[i+1].iov_base = iov[i].iov_base;
+    wrapiov[i+1].iov_len = iov[i].iov_len;
+    dataLen += iov[i].iov_len;
+  }
+
+  /* form the header (JDWP plus DDMS) */
+  set4BE(header, sizeof(header) + dataLen);
+  set4BE(header+4, NextRequestSerial(state));
+  set1(header+8, 0);     /* flags */
+  set1(header+9, kJDWPDdmCmdSet);
+  set1(header+10, kJDWPDdmCmd);
+  set4BE(header+11, type);
+  set4BE(header+15, dataLen);
+
+  wrapiov[0].iov_base = header;
+  wrapiov[0].iov_len = sizeof(header);
+
+  /*
+   * Make sure we're in VMWAIT in case the write blocks.
+   */
+  int oldStatus = Dbg::ThreadWaiting();
+  SendBufferedRequest(state, wrapiov, iovcnt+1);
+  Dbg::ThreadContinuing(oldStatus);
+}
+
+}  // namespace JDWP
+
+}  // namespace art
diff --git a/src/jdwp/jdwp_event.h b/src/jdwp/jdwp_event.h
new file mode 100644
index 0000000..2b957fb
--- /dev/null
+++ b/src/jdwp/jdwp_event.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Handle registration of events, and debugger event notification.
+ */
+#ifndef ART_JDWP_JDWPEVENT_H_
+#define ART_JDWP_JDWPEVENT_H_
+
+#include "jdwp/jdwp_constants.h"
+#include "jdwp/jdwp_expand_buf.h"
+
+namespace art {
+
+namespace JDWP {
+
+/*
+ * Event modifiers.  A JdwpEvent may have zero or more of these.
+ */
+union JdwpEventMod {
+  uint8_t      modKind;                /* JdwpModKind */
+  struct {
+    uint8_t          modKind;
+    int         count;
+  } count;
+  struct {
+    uint8_t          modKind;
+    uint32_t          exprId;
+  } conditional;
+  struct {
+    uint8_t          modKind;
+    ObjectId    threadId;
+  } threadOnly;
+  struct {
+    uint8_t          modKind;
+    RefTypeId   refTypeId;
+  } classOnly;
+  struct {
+    uint8_t          modKind;
+    char*       classPattern;
+  } classMatch;
+  struct {
+    uint8_t          modKind;
+    char*       classPattern;
+  } classExclude;
+  struct {
+    uint8_t          modKind;
+    JdwpLocation loc;
+  } locationOnly;
+  struct {
+    uint8_t          modKind;
+    uint8_t          caught;
+    uint8_t          uncaught;
+    RefTypeId   refTypeId;
+  } exceptionOnly;
+  struct {
+    uint8_t          modKind;
+    RefTypeId   refTypeId;
+    FieldId     fieldId;
+  } fieldOnly;
+  struct {
+    uint8_t          modKind;
+    ObjectId    threadId;
+    int         size;           /* JdwpStepSize */
+    int         depth;          /* JdwpStepDepth */
+  } step;
+  struct {
+    uint8_t          modKind;
+    ObjectId    objectId;
+  } instanceOnly;
+};
+
+/*
+ * One of these for every registered event.
+ *
+ * We over-allocate the struct to hold the modifiers.
+ */
+struct JdwpEvent {
+  JdwpEvent* prev;           /* linked list */
+  JdwpEvent* next;
+
+  JdwpEventKind eventKind;      /* what kind of event is this? */
+  JdwpSuspendPolicy suspendPolicy;  /* suspend all, none, or self? */
+  int modCount;       /* #of entries in mods[] */
+  uint32_t requestId;      /* serial#, reported to debugger */
+
+  JdwpEventMod mods[1];        /* MUST be last field in struct */
+};
+
+/*
+ * Allocate an event structure with enough space.
+ */
+JdwpEvent* EventAlloc(int numMods);
+void EventFree(JdwpEvent* pEvent);
+
+/*
+ * Register an event by adding it to the event list.
+ *
+ * "*pEvent" must be storage allocated with jdwpEventAlloc().  The caller
+ * may discard its pointer after calling this.
+ */
+JdwpError RegisterEvent(JdwpState* state, JdwpEvent* pEvent);
+
+/*
+ * Unregister an event, given the requestId.
+ */
+void UnregisterEventById(JdwpState* state, uint32_t requestId);
+
+/*
+ * Unregister all events.
+ */
+void UnregisterAll(JdwpState* state);
+
+/*
+ * Send an event, formatted into "pReq", to the debugger.
+ *
+ * (Messages are sent asynchronously, and do not receive a reply.)
+ */
+bool SendRequest(JdwpState* state, ExpandBuf* pReq);
+
+}  // namespace JDWP
+
+}  // namespace art
+
+#endif  // ART_JDWP_JDWPEVENT_H_
diff --git a/src/jdwp/jdwp_expand_buf.cc b/src/jdwp/jdwp_expand_buf.cc
new file mode 100644
index 0000000..f1675fd
--- /dev/null
+++ b/src/jdwp/jdwp_expand_buf.cc
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Implementation of an expandable byte buffer.  Designed for serializing
+ * primitive values, e.g. JDWP replies.
+ */
+
+#include "jdwp/jdwp_bits.h"
+#include "jdwp/jdwp_expand_buf.h"
+#include "logging.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+namespace art {
+
+namespace JDWP {
+
+/*
+ * Data structure used to track buffer use.
+ */
+struct ExpandBuf {
+  uint8_t*     storage;
+  int     curLen;
+  int     maxLen;
+};
+
+#define kInitialStorage 64
+
+/*
+ * Allocate a JdwpBuf and some initial storage.
+ */
+ExpandBuf* expandBufAlloc() {
+  ExpandBuf* newBuf;
+
+  newBuf = (ExpandBuf*) malloc(sizeof(*newBuf));
+  newBuf->storage = (uint8_t*) malloc(kInitialStorage);
+  newBuf->curLen = 0;
+  newBuf->maxLen = kInitialStorage;
+
+  return newBuf;
+}
+
+/*
+ * Free a JdwpBuf and associated storage.
+ */
+void expandBufFree(ExpandBuf* pBuf) {
+  if (pBuf == NULL) {
+    return;
+  }
+
+  free(pBuf->storage);
+  free(pBuf);
+}
+
+/*
+ * Get a pointer to the start of the buffer.
+ */
+uint8_t* expandBufGetBuffer(ExpandBuf* pBuf) {
+  return pBuf->storage;
+}
+
+/*
+ * Get the amount of data currently in the buffer.
+ */
+size_t expandBufGetLength(ExpandBuf* pBuf) {
+  return pBuf->curLen;
+}
+
+
+/*
+ * Ensure that the buffer has enough space to hold incoming data.  If it
+ * doesn't, resize the buffer.
+ */
+static void ensureSpace(ExpandBuf* pBuf, int newCount) {
+  if (pBuf->curLen + newCount <= pBuf->maxLen) {
+    return;
+  }
+
+  while (pBuf->curLen + newCount > pBuf->maxLen) {
+    pBuf->maxLen *= 2;
+  }
+
+  uint8_t* newPtr = (uint8_t*) realloc(pBuf->storage, pBuf->maxLen);
+  if (newPtr == NULL) {
+    LOG(ERROR) << "realloc(" << pBuf->maxLen << ") failed";
+    abort();
+  }
+
+  pBuf->storage = newPtr;
+}
+
+/*
+ * Allocate some space in the buffer.
+ */
+uint8_t* expandBufAddSpace(ExpandBuf* pBuf, int gapSize) {
+  uint8_t* gapStart;
+
+  ensureSpace(pBuf, gapSize);
+  gapStart = pBuf->storage + pBuf->curLen;
+  /* do we want to garbage-fill the gap for debugging? */
+  pBuf->curLen += gapSize;
+
+  return gapStart;
+}
+
+/*
+ * Append a byte.
+ */
+void expandBufAdd1(ExpandBuf* pBuf, uint8_t val) {
+  ensureSpace(pBuf, sizeof(val));
+  *(pBuf->storage + pBuf->curLen) = val;
+  pBuf->curLen++;
+}
+
+/*
+ * Append two big-endian bytes.
+ */
+void expandBufAdd2BE(ExpandBuf* pBuf, uint16_t val) {
+  ensureSpace(pBuf, sizeof(val));
+  set2BE(pBuf->storage + pBuf->curLen, val);
+  pBuf->curLen += sizeof(val);
+}
+
+/*
+ * Append four big-endian bytes.
+ */
+void expandBufAdd4BE(ExpandBuf* pBuf, uint32_t val) {
+  ensureSpace(pBuf, sizeof(val));
+  set4BE(pBuf->storage + pBuf->curLen, val);
+  pBuf->curLen += sizeof(val);
+}
+
+/*
+ * Append eight big-endian bytes.
+ */
+void expandBufAdd8BE(ExpandBuf* pBuf, uint64_t val) {
+  ensureSpace(pBuf, sizeof(val));
+  set8BE(pBuf->storage + pBuf->curLen, val);
+  pBuf->curLen += sizeof(val);
+}
+
+/*
+ * Add a UTF8 string as a 4-byte length followed by a non-NULL-terminated
+ * string.
+ *
+ * Because these strings are coming out of the VM, it's safe to assume that
+ * they can be null-terminated (either they don't have null bytes or they
+ * have stored null bytes in a multi-byte encoding).
+ */
+void expandBufAddUtf8String(ExpandBuf* pBuf, const uint8_t* str) {
+  int strLen = strlen((const char*)str);
+
+  ensureSpace(pBuf, sizeof(uint32_t) + strLen);
+  setUtf8String(pBuf->storage + pBuf->curLen, str);
+  pBuf->curLen += sizeof(uint32_t) + strLen;
+}
+
+}  // namespace JDWP
+
+}  // namespace art
diff --git a/src/jdwp/jdwp_expand_buf.h b/src/jdwp/jdwp_expand_buf.h
new file mode 100644
index 0000000..2c19f54
--- /dev/null
+++ b/src/jdwp/jdwp_expand_buf.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Expanding byte buffer, with primitives for appending basic data types.
+ */
+#ifndef ART_JDWP_EXPANDBUF_H_
+#define ART_JDWP_EXPANDBUF_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace art {
+
+namespace JDWP {
+
+struct ExpandBuf;   /* private */
+
+/* create a new struct */
+ExpandBuf* expandBufAlloc();
+/* free storage */
+void expandBufFree(ExpandBuf* pBuf);
+
+/*
+ * Accessors.  The buffer pointer and length will only be valid until more
+ * data is added.
+ */
+uint8_t* expandBufGetBuffer(ExpandBuf* pBuf);
+size_t expandBufGetLength(ExpandBuf* pBuf);
+
+/*
+ * The "add" operations allocate additional storage and append the data.
+ *
+ * There are no "get" operations included with this "class", other than
+ * GetBuffer().  If you want to get or set data from a position other
+ * than the end, get a pointer to the buffer and use the inline functions
+ * defined elsewhere.
+ *
+ * expandBufAddSpace() returns a pointer to the *start* of the region
+ * added.
+ */
+uint8_t* expandBufAddSpace(ExpandBuf* pBuf, int gapSize);
+void expandBufAdd1(ExpandBuf* pBuf, uint8_t val);
+void expandBufAdd2BE(ExpandBuf* pBuf, uint16_t val);
+void expandBufAdd4BE(ExpandBuf* pBuf, uint32_t val);
+void expandBufAdd8BE(ExpandBuf* pBuf, uint64_t val);
+void expandBufAddUtf8String(ExpandBuf* pBuf, const uint8_t* str);
+
+}  // namespace JDWP
+
+}  // namespace art
+
+#endif  // ART_JDWP_EXPANDBUF_H_
diff --git a/src/jdwp/jdwp_handler.cc b/src/jdwp/jdwp_handler.cc
new file mode 100644
index 0000000..8fe3c3f
--- /dev/null
+++ b/src/jdwp/jdwp_handler.cc
@@ -0,0 +1,1818 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Handle messages from debugger.
+ *
+ * GENERAL NOTE: we're not currently testing the message length for
+ * correctness.  This is usually a bad idea, but here we can probably
+ * get away with it so long as the debugger isn't broken.  We can
+ * change the "read" macros to use "dataLen" to avoid wandering into
+ * bad territory, and have a single "is dataLen correct" check at the
+ * end of each function.  Not needed at this time.
+ */
+
+#include "atomic.h"
+#include "debugger.h"
+#include "jdwp/jdwp_priv.h"
+#include "jdwp/jdwp_handler.h"
+#include "jdwp/jdwp_event.h"
+#include "jdwp/jdwp_constants.h"
+#include "jdwp/jdwp_expand_buf.h"
+#include "logging.h"
+#include "macros.h"
+#include "stringprintf.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+namespace art {
+
+namespace JDWP {
+
+/*
+ * Helper function: read a "location" from an input buffer.
+ */
+static void jdwpReadLocation(const uint8_t** pBuf, JdwpLocation* pLoc) {
+  memset(pLoc, 0, sizeof(*pLoc));     /* allows memcmp() later */
+  pLoc->typeTag = read1(pBuf);
+  pLoc->classId = ReadObjectId(pBuf);
+  pLoc->methodId = ReadMethodId(pBuf);
+  pLoc->idx = read8BE(pBuf);
+}
+
+/*
+ * Helper function: write a "location" into the reply buffer.
+ */
+void AddLocation(ExpandBuf* pReply, const JdwpLocation* pLoc) {
+  expandBufAdd1(pReply, pLoc->typeTag);
+  expandBufAddObjectId(pReply, pLoc->classId);
+  expandBufAddMethodId(pReply, pLoc->methodId);
+  expandBufAdd8BE(pReply, pLoc->idx);
+}
+
+/*
+ * Helper function: read a variable-width value from the input buffer.
+ */
+static uint64_t jdwpReadValue(const uint8_t** pBuf, int width) {
+  uint64_t value = -1;
+  switch (width) {
+  case 1:     value = read1(pBuf); break;
+  case 2:     value = read2BE(pBuf); break;
+  case 4:     value = read4BE(pBuf); break;
+  case 8:     value = read8BE(pBuf); break;
+  default:    LOG(FATAL) << width; break;
+  }
+  return value;
+}
+
+/*
+ * Helper function: write a variable-width value into the output input buffer.
+ */
+static void jdwpWriteValue(ExpandBuf* pReply, int width, uint64_t value) {
+  switch (width) {
+  case 1:     expandBufAdd1(pReply, value); break;
+  case 2:     expandBufAdd2BE(pReply, value); break;
+  case 4:     expandBufAdd4BE(pReply, value); break;
+  case 8:     expandBufAdd8BE(pReply, value); break;
+  default:    LOG(FATAL) << width; break;
+  }
+}
+
+/*
+ * Common code for *_InvokeMethod requests.
+ *
+ * If "isConstructor" is set, this returns "objectId" rather than the
+ * expected-to-be-void return value of the called function.
+ */
+static JdwpError finishInvoke(JdwpState* state,
+    const uint8_t* buf, int dataLen, ExpandBuf* pReply,
+    ObjectId threadId, ObjectId objectId, RefTypeId classId, MethodId methodId,
+    bool isConstructor)
+{
+  CHECK(!isConstructor || objectId != 0);
+
+  uint32_t numArgs = read4BE(&buf);
+
+  LOG(VERBOSE) << StringPrintf("    --> threadId=%llx objectId=%llx", threadId, objectId);
+  LOG(VERBOSE) << StringPrintf("        classId=%llx methodId=%x %s.%s", classId, methodId, Dbg::GetClassDescriptor(classId), Dbg::GetMethodName(classId, methodId));
+  LOG(VERBOSE) << StringPrintf("        %d args:", numArgs);
+
+  uint64_t* argArray = NULL;
+  if (numArgs > 0) {
+    argArray = (ObjectId*) malloc(sizeof(ObjectId) * numArgs);
+  }
+
+  for (uint32_t i = 0; i < numArgs; i++) {
+    uint8_t typeTag = read1(&buf);
+    int width = Dbg::GetTagWidth(typeTag);
+    uint64_t value = jdwpReadValue(&buf, width);
+
+    LOG(VERBOSE) << StringPrintf("          '%c'(%d): 0x%llx", typeTag, width, value);
+    argArray[i] = value;
+  }
+
+  uint32_t options = read4BE(&buf);  /* enum InvokeOptions bit flags */
+  LOG(VERBOSE) << StringPrintf("        options=0x%04x%s%s", options, (options & INVOKE_SINGLE_THREADED) ? " (SINGLE_THREADED)" : "", (options & INVOKE_NONVIRTUAL) ? " (NONVIRTUAL)" : "");
+
+  uint8_t resultTag;
+  uint64_t resultValue;
+  ObjectId exceptObjId;
+  JdwpError err = Dbg::InvokeMethod(threadId, objectId, classId, methodId, numArgs, argArray, options, &resultTag, &resultValue, &exceptObjId);
+  if (err != ERR_NONE) {
+    goto bail;
+  }
+
+  if (err == ERR_NONE) {
+    if (isConstructor) {
+      expandBufAdd1(pReply, JT_OBJECT);
+      expandBufAddObjectId(pReply, objectId);
+    } else {
+      int width = Dbg::GetTagWidth(resultTag);
+
+      expandBufAdd1(pReply, resultTag);
+      if (width != 0) {
+        jdwpWriteValue(pReply, width, resultValue);
+      }
+    }
+    expandBufAdd1(pReply, JT_OBJECT);
+    expandBufAddObjectId(pReply, exceptObjId);
+
+    LOG(VERBOSE) << StringPrintf("  --> returned '%c' 0x%llx (except=%08llx)", resultTag, resultValue, exceptObjId);
+
+    /* show detailed debug output */
+    if (resultTag == JT_STRING && exceptObjId == 0) {
+      if (resultValue != 0) {
+        char* str = Dbg::StringToUtf8(resultValue);
+        LOG(VERBOSE) << StringPrintf("      string '%s'", str);
+        free(str);
+      } else {
+        LOG(VERBOSE) << "      string (null)";
+      }
+    }
+  }
+
+bail:
+  free(argArray);
+  return err;
+}
+
+
+/*
+ * Request for version info.
+ */
+static JdwpError handleVM_Version(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  /* text information on runtime version */
+  std::string version(StringPrintf("Android Runtime %s", Runtime::Current()->GetVersion()));
+  expandBufAddUtf8String(pReply, (const uint8_t*) version.c_str());
+  /* JDWP version numbers */
+  expandBufAdd4BE(pReply, 1);        // major
+  expandBufAdd4BE(pReply, 5);        // minor
+  /* VM JRE version */
+  expandBufAddUtf8String(pReply, (const uint8_t*) "1.6.0");  /* e.g. 1.6.0_22 */
+  /* target VM name */
+  expandBufAddUtf8String(pReply, (const uint8_t*) "DalvikVM");
+
+  return ERR_NONE;
+}
+
+/*
+ * Given a class JNI signature (e.g. "Ljava/lang/Error;"), return the
+ * referenceTypeID.  We need to send back more than one if the class has
+ * been loaded by multiple class loaders.
+ */
+static JdwpError handleVM_ClassesBySignature(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  size_t strLen;
+  char* classDescriptor = readNewUtf8String(&buf, &strLen);
+  LOG(VERBOSE) << "  Req for class by signature '" << classDescriptor << "'";
+
+  /*
+   * TODO: if a class with the same name has been loaded multiple times
+   * (by different class loaders), we're supposed to return each of them.
+   *
+   * NOTE: this may mangle "className".
+   */
+  uint32_t numClasses;
+  RefTypeId refTypeId;
+  if (!Dbg::FindLoadedClassBySignature(classDescriptor, &refTypeId)) {
+    /* not currently loaded */
+    LOG(VERBOSE) << "    --> no match!";
+    numClasses = 0;
+  } else {
+    /* just the one */
+    numClasses = 1;
+  }
+
+  expandBufAdd4BE(pReply, numClasses);
+
+  if (numClasses > 0) {
+    uint8_t typeTag;
+    uint32_t status;
+
+    /* get class vs. interface and status flags */
+    Dbg::GetClassInfo(refTypeId, &typeTag, &status, NULL);
+
+    expandBufAdd1(pReply, typeTag);
+    expandBufAddRefTypeId(pReply, refTypeId);
+    expandBufAdd4BE(pReply, status);
+  }
+
+  free(classDescriptor);
+
+  return ERR_NONE;
+}
+
+/*
+ * Handle request for the thread IDs of all running threads.
+ *
+ * We exclude ourselves from the list, because we don't allow ourselves
+ * to be suspended, and that violates some JDWP expectations.
+ */
+static JdwpError handleVM_AllThreads(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  ObjectId* pThreadIds;
+  uint32_t threadCount;
+  Dbg::GetAllThreads(&pThreadIds, &threadCount);
+
+  expandBufAdd4BE(pReply, threadCount);
+
+  ObjectId* walker = pThreadIds;
+  for (uint32_t i = 0; i < threadCount; i++) {
+    expandBufAddObjectId(pReply, *walker++);
+  }
+
+  free(pThreadIds);
+
+  return ERR_NONE;
+}
+
+/*
+ * List all thread groups that do not have a parent.
+ */
+static JdwpError handleVM_TopLevelThreadGroups(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  /*
+   * TODO: maintain a list of parentless thread groups in the VM.
+   *
+   * For now, just return "system".  Application threads are created
+   * in "main", which is a child of "system".
+   */
+  uint32_t groups = 1;
+  expandBufAdd4BE(pReply, groups);
+  //threadGroupId = debugGetMainThreadGroup();
+  //expandBufAdd8BE(pReply, threadGroupId);
+  ObjectId threadGroupId = Dbg::GetSystemThreadGroupId();
+  expandBufAddObjectId(pReply, threadGroupId);
+
+  return ERR_NONE;
+}
+
+/*
+ * Respond with the sizes of the basic debugger types.
+ *
+ * All IDs are 8 bytes.
+ */
+static JdwpError handleVM_IDSizes(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  expandBufAdd4BE(pReply, sizeof(FieldId));
+  expandBufAdd4BE(pReply, sizeof(MethodId));
+  expandBufAdd4BE(pReply, sizeof(ObjectId));
+  expandBufAdd4BE(pReply, sizeof(RefTypeId));
+  expandBufAdd4BE(pReply, sizeof(FrameId));
+  return ERR_NONE;
+}
+
+/*
+ * The debugger is politely asking to disconnect.  We're good with that.
+ *
+ * We could resume threads and clean up pinned references, but we can do
+ * that when the TCP connection drops.
+ */
+static JdwpError handleVM_Dispose(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  return ERR_NONE;
+}
+
+/*
+ * Suspend the execution of the application running in the VM (i.e. suspend
+ * all threads).
+ *
+ * This needs to increment the "suspend count" on all threads.
+ */
+static JdwpError handleVM_Suspend(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  Dbg::SuspendVM(false);
+  return ERR_NONE;
+}
+
+/*
+ * Resume execution.  Decrements the "suspend count" of all threads.
+ */
+static JdwpError handleVM_Resume(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  Dbg::ResumeVM();
+  return ERR_NONE;
+}
+
+/*
+ * The debugger wants the entire VM to exit.
+ */
+static JdwpError handleVM_Exit(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  uint32_t exitCode = get4BE(buf);
+
+  LOG(WARNING) << "Debugger is telling the VM to exit with code=" << exitCode;
+
+  Dbg::Exit(exitCode);
+  return ERR_NOT_IMPLEMENTED;     // shouldn't get here
+}
+
+/*
+ * Create a new string in the VM and return its ID.
+ *
+ * (Ctrl-Shift-I in Eclipse on an array of objects causes it to create the
+ * string "java.util.Arrays".)
+ */
+static JdwpError handleVM_CreateString(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  size_t strLen;
+  char* str = readNewUtf8String(&buf, &strLen);
+
+  LOG(VERBOSE) << "  Req to create string '" << str << "'";
+
+  ObjectId stringId = Dbg::CreateString(str);
+  if (stringId == 0) {
+    return ERR_OUT_OF_MEMORY;
+  }
+
+  expandBufAddObjectId(pReply, stringId);
+  return ERR_NONE;
+}
+
+/*
+ * Tell the debugger what we are capable of.
+ */
+static JdwpError handleVM_Capabilities(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  expandBufAdd1(pReply, false);   /* canWatchFieldModification */
+  expandBufAdd1(pReply, false);   /* canWatchFieldAccess */
+  expandBufAdd1(pReply, false);   /* canGetBytecodes */
+  expandBufAdd1(pReply, true);    /* canGetSyntheticAttribute */
+  expandBufAdd1(pReply, false);   /* canGetOwnedMonitorInfo */
+  expandBufAdd1(pReply, false);   /* canGetCurrentContendedMonitor */
+  expandBufAdd1(pReply, false);   /* canGetMonitorInfo */
+  return ERR_NONE;
+}
+
+/*
+ * Return classpath and bootclasspath.
+ */
+static JdwpError handleVM_ClassPaths(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  char baseDir[2] = "/";
+
+  /*
+   * TODO: make this real.  Not important for remote debugging, but
+   * might be useful for local debugging.
+   */
+  uint32_t classPaths = 1;
+  uint32_t bootClassPaths = 0;
+
+  expandBufAddUtf8String(pReply, (const uint8_t*) baseDir);
+  expandBufAdd4BE(pReply, classPaths);
+  for (uint32_t i = 0; i < classPaths; i++) {
+    expandBufAddUtf8String(pReply, (const uint8_t*) ".");
+  }
+
+  expandBufAdd4BE(pReply, bootClassPaths);
+  for (uint32_t i = 0; i < classPaths; i++) {
+    /* add bootclasspath components as strings */
+  }
+
+  return ERR_NONE;
+}
+
+/*
+ * Release a list of object IDs.  (Seen in jdb.)
+ *
+ * Currently does nothing.
+ */
+static JdwpError HandleVM_DisposeObjects(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  return ERR_NONE;
+}
+
+/*
+ * Tell the debugger what we are capable of.
+ */
+static JdwpError handleVM_CapabilitiesNew(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  expandBufAdd1(pReply, false);   /* canWatchFieldModification */
+  expandBufAdd1(pReply, false);   /* canWatchFieldAccess */
+  expandBufAdd1(pReply, false);   /* canGetBytecodes */
+  expandBufAdd1(pReply, true);    /* canGetSyntheticAttribute */
+  expandBufAdd1(pReply, false);   /* canGetOwnedMonitorInfo */
+  expandBufAdd1(pReply, false);   /* canGetCurrentContendedMonitor */
+  expandBufAdd1(pReply, false);   /* canGetMonitorInfo */
+  expandBufAdd1(pReply, false);   /* canRedefineClasses */
+  expandBufAdd1(pReply, false);   /* canAddMethod */
+  expandBufAdd1(pReply, false);   /* canUnrestrictedlyRedefineClasses */
+  expandBufAdd1(pReply, false);   /* canPopFrames */
+  expandBufAdd1(pReply, false);   /* canUseInstanceFilters */
+  expandBufAdd1(pReply, false);   /* canGetSourceDebugExtension */
+  expandBufAdd1(pReply, false);   /* canRequestVMDeathEvent */
+  expandBufAdd1(pReply, false);   /* canSetDefaultStratum */
+  expandBufAdd1(pReply, false);   /* 1.6: canGetInstanceInfo */
+  expandBufAdd1(pReply, false);   /* 1.6: canRequestMonitorEvents */
+  expandBufAdd1(pReply, false);   /* 1.6: canGetMonitorFrameInfo */
+  expandBufAdd1(pReply, false);   /* 1.6: canUseSourceNameFilters */
+  expandBufAdd1(pReply, false);   /* 1.6: canGetConstantPool */
+  expandBufAdd1(pReply, false);   /* 1.6: canForceEarlyReturn */
+
+  /* fill in reserved22 through reserved32; note count started at 1 */
+  for (int i = 22; i <= 32; i++) {
+    expandBufAdd1(pReply, false);   /* reservedN */
+  }
+  return ERR_NONE;
+}
+
+/*
+ * Cough up the complete list of classes.
+ */
+static JdwpError handleVM_AllClassesWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  uint32_t numClasses = 0;
+  RefTypeId* classRefBuf = NULL;
+
+  Dbg::GetClassList(&numClasses, &classRefBuf);
+
+  expandBufAdd4BE(pReply, numClasses);
+
+  for (uint32_t i = 0; i < numClasses; i++) {
+    static const uint8_t genericSignature[1] = "";
+    uint8_t refTypeTag;
+    const char* signature;
+    uint32_t status;
+
+    Dbg::GetClassInfo(classRefBuf[i], &refTypeTag, &status, &signature);
+
+    expandBufAdd1(pReply, refTypeTag);
+    expandBufAddRefTypeId(pReply, classRefBuf[i]);
+    expandBufAddUtf8String(pReply, (const uint8_t*) signature);
+    expandBufAddUtf8String(pReply, genericSignature);
+    expandBufAdd4BE(pReply, status);
+  }
+
+  free(classRefBuf);
+
+  return ERR_NONE;
+}
+
+/*
+ * Given a referenceTypeID, return a string with the JNI reference type
+ * signature (e.g. "Ljava/lang/Error;").
+ */
+static JdwpError handleRT_Signature(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  RefTypeId refTypeId = ReadRefTypeId(&buf);
+
+  LOG(VERBOSE) << StringPrintf("  Req for signature of refTypeId=0x%llx", refTypeId);
+  const char* signature = Dbg::GetSignature(refTypeId);
+  expandBufAddUtf8String(pReply, (const uint8_t*) signature);
+
+  return ERR_NONE;
+}
+
+/*
+ * Return the modifiers (a/k/a access flags) for a reference type.
+ */
+static JdwpError handleRT_Modifiers(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  RefTypeId refTypeId = ReadRefTypeId(&buf);
+  uint32_t modBits = Dbg::GetAccessFlags(refTypeId);
+  expandBufAdd4BE(pReply, modBits);
+  return ERR_NONE;
+}
+
+/*
+ * Get values from static fields in a reference type.
+ */
+static JdwpError handleRT_GetValues(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  RefTypeId refTypeId = ReadRefTypeId(&buf);
+  uint32_t numFields = read4BE(&buf);
+
+  LOG(VERBOSE) << "  RT_GetValues " << numFields << ":";
+
+  expandBufAdd4BE(pReply, numFields);
+  for (uint32_t i = 0; i < numFields; i++) {
+    FieldId fieldId = ReadFieldId(&buf);
+    Dbg::GetStaticFieldValue(refTypeId, fieldId, pReply);
+  }
+
+  return ERR_NONE;
+}
+
+/*
+ * Get the name of the source file in which a reference type was declared.
+ */
+static JdwpError handleRT_SourceFile(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  RefTypeId refTypeId = ReadRefTypeId(&buf);
+
+  const char* fileName = Dbg::GetSourceFile(refTypeId);
+  if (fileName != NULL) {
+    expandBufAddUtf8String(pReply, (const uint8_t*) fileName);
+    return ERR_NONE;
+  } else {
+    return ERR_ABSENT_INFORMATION;
+  }
+}
+
+/*
+ * Return the current status of the reference type.
+ */
+static JdwpError handleRT_Status(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  RefTypeId refTypeId = ReadRefTypeId(&buf);
+
+  /* get status flags */
+  uint8_t typeTag;
+  uint32_t status;
+  Dbg::GetClassInfo(refTypeId, &typeTag, &status, NULL);
+  expandBufAdd4BE(pReply, status);
+  return ERR_NONE;
+}
+
+/*
+ * Return interfaces implemented directly by this class.
+ */
+static JdwpError handleRT_Interfaces(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  RefTypeId refTypeId = ReadRefTypeId(&buf);
+
+  LOG(VERBOSE) << StringPrintf("  Req for interfaces in %llx (%s)", refTypeId,
+  Dbg::GetClassDescriptor(refTypeId));
+
+  Dbg::OutputAllInterfaces(refTypeId, pReply);
+
+  return ERR_NONE;
+}
+
+/*
+ * Return the class object corresponding to this type.
+ */
+static JdwpError handleRT_ClassObject(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  RefTypeId refTypeId = ReadRefTypeId(&buf);
+  ObjectId classObjId = Dbg::GetClassObject(refTypeId);
+
+  LOG(VERBOSE) << StringPrintf("  RefTypeId %llx -> ObjectId %llx", refTypeId, classObjId);
+
+  expandBufAddObjectId(pReply, classObjId);
+
+  return ERR_NONE;
+}
+
+/*
+ * Returns the value of the SourceDebugExtension attribute.
+ *
+ * JDB seems interested, but DEX files don't currently support this.
+ */
+static JdwpError handleRT_SourceDebugExtension(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  /* referenceTypeId in, string out */
+  return ERR_ABSENT_INFORMATION;
+}
+
+/*
+ * Like RT_Signature but with the possibility of a "generic signature".
+ */
+static JdwpError handleRT_SignatureWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  static const uint8_t genericSignature[1] = "";
+
+  RefTypeId refTypeId = ReadRefTypeId(&buf);
+
+  LOG(VERBOSE) << StringPrintf("  Req for signature of refTypeId=0x%llx", refTypeId);
+  const char* signature = Dbg::GetSignature(refTypeId);
+  if (signature != NULL) {
+    expandBufAddUtf8String(pReply, (const uint8_t*) signature);
+  } else {
+    LOG(WARNING) << StringPrintf("No signature for refTypeId=0x%llx", refTypeId);
+    expandBufAddUtf8String(pReply, (const uint8_t*) "Lunknown;");
+  }
+  expandBufAddUtf8String(pReply, genericSignature);
+
+  return ERR_NONE;
+}
+
+/*
+ * Return the instance of java.lang.ClassLoader that loaded the specified
+ * reference type, or null if it was loaded by the system loader.
+ */
+static JdwpError handleRT_ClassLoader(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  RefTypeId refTypeId = ReadRefTypeId(&buf);
+
+  expandBufAddObjectId(pReply, Dbg::GetClassLoader(refTypeId));
+
+  return ERR_NONE;
+}
+
+/*
+ * Given a referenceTypeId, return a block of stuff that describes the
+ * fields declared by a class.
+ */
+static JdwpError handleRT_FieldsWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  RefTypeId refTypeId = ReadRefTypeId(&buf);
+  LOG(VERBOSE) << StringPrintf("  Req for fields in refTypeId=0x%llx", refTypeId);
+  LOG(VERBOSE) << StringPrintf("  --> '%s'", Dbg::GetSignature(refTypeId));
+  Dbg::OutputAllFields(refTypeId, true, pReply);
+  return ERR_NONE;
+}
+
+/*
+ * Given a referenceTypeID, return a block of goodies describing the
+ * methods declared by a class.
+ */
+static JdwpError handleRT_MethodsWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  RefTypeId refTypeId = ReadRefTypeId(&buf);
+
+  LOG(VERBOSE) << StringPrintf("  Req for methods in refTypeId=0x%llx", refTypeId);
+  LOG(VERBOSE) << StringPrintf("  --> '%s'", Dbg::GetSignature(refTypeId));
+
+  Dbg::OutputAllMethods(refTypeId, true, pReply);
+
+  return ERR_NONE;
+}
+
+/*
+ * Return the immediate superclass of a class.
+ */
+static JdwpError handleCT_Superclass(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  RefTypeId classId = ReadRefTypeId(&buf);
+
+  RefTypeId superClassId = Dbg::GetSuperclass(classId);
+
+  expandBufAddRefTypeId(pReply, superClassId);
+
+  return ERR_NONE;
+}
+
+/*
+ * Set static class values.
+ */
+static JdwpError handleCT_SetValues(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  RefTypeId classId = ReadRefTypeId(&buf);
+  uint32_t values = read4BE(&buf);
+
+  LOG(VERBOSE) << StringPrintf("  Req to set %d values in classId=%llx", values, classId);
+
+  for (uint32_t i = 0; i < values; i++) {
+    FieldId fieldId = ReadFieldId(&buf);
+    uint8_t fieldTag = Dbg::GetStaticFieldBasicTag(classId, fieldId);
+    int width = Dbg::GetTagWidth(fieldTag);
+    uint64_t value = jdwpReadValue(&buf, width);
+
+    LOG(VERBOSE) << StringPrintf("    --> field=%x tag=%c -> %lld", fieldId, fieldTag, value);
+    Dbg::SetStaticFieldValue(classId, fieldId, value, width);
+  }
+
+  return ERR_NONE;
+}
+
+/*
+ * Invoke a static method.
+ *
+ * Example: Eclipse sometimes uses java/lang/Class.forName(String s) on
+ * values in the "variables" display.
+ */
+static JdwpError handleCT_InvokeMethod(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  RefTypeId classId = ReadRefTypeId(&buf);
+  ObjectId threadId = ReadObjectId(&buf);
+  MethodId methodId = ReadMethodId(&buf);
+
+  return finishInvoke(state, buf, dataLen, pReply, threadId, 0, classId, methodId, false);
+}
+
+/*
+ * Create a new object of the requested type, and invoke the specified
+ * constructor.
+ *
+ * Example: in IntelliJ, create a watch on "new String(myByteArray)" to
+ * see the contents of a byte[] as a string.
+ */
+static JdwpError handleCT_NewInstance(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  RefTypeId classId = ReadRefTypeId(&buf);
+  ObjectId threadId = ReadObjectId(&buf);
+  MethodId methodId = ReadMethodId(&buf);
+
+  LOG(VERBOSE) << "Creating instance of " << Dbg::GetClassDescriptor(classId);
+  ObjectId objectId = Dbg::CreateObject(classId);
+  if (objectId == 0) {
+    return ERR_OUT_OF_MEMORY;
+  }
+  return finishInvoke(state, buf, dataLen, pReply, threadId, objectId, classId, methodId, true);
+}
+
+/*
+ * Create a new array object of the requested type and length.
+ */
+static JdwpError handleAT_newInstance(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  RefTypeId arrayTypeId = ReadRefTypeId(&buf);
+  uint32_t length = read4BE(&buf);
+
+  LOG(VERBOSE) << StringPrintf("Creating array %s[%u]", Dbg::GetClassDescriptor(arrayTypeId), length);
+  ObjectId objectId = Dbg::CreateArrayObject(arrayTypeId, length);
+  if (objectId == 0) {
+    return ERR_OUT_OF_MEMORY;
+  }
+  expandBufAdd1(pReply, JT_ARRAY);
+  expandBufAddObjectId(pReply, objectId);
+  return ERR_NONE;
+}
+
+/*
+ * Return line number information for the method, if present.
+ */
+static JdwpError handleM_LineTable(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  RefTypeId refTypeId = ReadRefTypeId(&buf);
+  MethodId methodId = ReadMethodId(&buf);
+
+  LOG(VERBOSE) << StringPrintf("  Req for line table in %s.%s", Dbg::GetClassDescriptor(refTypeId), Dbg::GetMethodName(refTypeId,methodId));
+
+  Dbg::OutputLineTable(refTypeId, methodId, pReply);
+
+  return ERR_NONE;
+}
+
+/*
+ * Pull out the LocalVariableTable goodies.
+ */
+static JdwpError handleM_VariableTableWithGeneric(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  RefTypeId classId = ReadRefTypeId(&buf);
+  MethodId methodId = ReadMethodId(&buf);
+
+  LOG(VERBOSE) << StringPrintf("  Req for LocalVarTab in class=%s method=%s",
+  Dbg::GetClassDescriptor(classId),
+  Dbg::GetMethodName(classId, methodId));
+
+  /*
+   * We could return ERR_ABSENT_INFORMATION here if the DEX file was
+   * built without local variable information.  That will cause Eclipse
+   * to make a best-effort attempt at displaying local variables
+   * anonymously.  However, the attempt isn't very good, so we're probably
+   * better off just not showing anything.
+   */
+  Dbg::OutputVariableTable(classId, methodId, true, pReply);
+  return ERR_NONE;
+}
+
+/*
+ * Given an object reference, return the runtime type of the object
+ * (class or array).
+ *
+ * This can get called on different things, e.g. threadId gets
+ * passed in here.
+ */
+static JdwpError handleOR_ReferenceType(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  ObjectId objectId = ReadObjectId(&buf);
+  LOG(VERBOSE) << StringPrintf("  Req for type of objectId=0x%llx", objectId);
+
+  uint8_t refTypeTag;
+  RefTypeId typeId;
+  Dbg::GetObjectType(objectId, &refTypeTag, &typeId);
+
+  expandBufAdd1(pReply, refTypeTag);
+  expandBufAddRefTypeId(pReply, typeId);
+
+  return ERR_NONE;
+}
+
+/*
+ * Get values from the fields of an object.
+ */
+static JdwpError handleOR_GetValues(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  ObjectId objectId = ReadObjectId(&buf);
+  uint32_t numFields = read4BE(&buf);
+
+  LOG(VERBOSE) << StringPrintf("  Req for %d fields from objectId=0x%llx", numFields, objectId);
+
+  expandBufAdd4BE(pReply, numFields);
+
+  for (uint32_t i = 0; i < numFields; i++) {
+    FieldId fieldId = ReadFieldId(&buf);
+    Dbg::GetFieldValue(objectId, fieldId, pReply);
+  }
+
+  return ERR_NONE;
+}
+
+/*
+ * Set values in the fields of an object.
+ */
+static JdwpError handleOR_SetValues(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  ObjectId objectId = ReadObjectId(&buf);
+  uint32_t numFields = read4BE(&buf);
+
+  LOG(VERBOSE) << StringPrintf("  Req to set %d fields in objectId=0x%llx", numFields, objectId);
+
+  for (uint32_t i = 0; i < numFields; i++) {
+    FieldId fieldId = ReadFieldId(&buf);
+
+    uint8_t fieldTag = Dbg::GetFieldBasicTag(objectId, fieldId);
+    int width = Dbg::GetTagWidth(fieldTag);
+    uint64_t value = jdwpReadValue(&buf, width);
+
+    LOG(VERBOSE) << StringPrintf("    --> fieldId=%x tag='%c'(%d) value=%lld", fieldId, fieldTag, width, value);
+
+    Dbg::SetFieldValue(objectId, fieldId, value, width);
+  }
+
+  return ERR_NONE;
+}
+
+/*
+ * Invoke an instance method.  The invocation must occur in the specified
+ * thread, which must have been suspended by an event.
+ *
+ * The call is synchronous.  All threads in the VM are resumed, unless the
+ * SINGLE_THREADED flag is set.
+ *
+ * If you ask Eclipse to "inspect" an object (or ask JDB to "print" an
+ * object), it will try to invoke the object's toString() function.  This
+ * feature becomes crucial when examining ArrayLists with Eclipse.
+ */
+static JdwpError handleOR_InvokeMethod(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  ObjectId objectId = ReadObjectId(&buf);
+  ObjectId threadId = ReadObjectId(&buf);
+  RefTypeId classId = ReadRefTypeId(&buf);
+  MethodId methodId = ReadMethodId(&buf);
+
+  return finishInvoke(state, buf, dataLen, pReply, threadId, objectId, classId, methodId, false);
+}
+
+/*
+ * Disable garbage collection of the specified object.
+ */
+static JdwpError handleOR_DisableCollection(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  // this is currently a no-op
+  return ERR_NONE;
+}
+
+/*
+ * Enable garbage collection of the specified object.
+ */
+static JdwpError handleOR_EnableCollection(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  // this is currently a no-op
+  return ERR_NONE;
+}
+
+/*
+ * Determine whether an object has been garbage collected.
+ */
+static JdwpError handleOR_IsCollected(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  ObjectId objectId;
+
+  objectId = ReadObjectId(&buf);
+  LOG(VERBOSE) << StringPrintf("  Req IsCollected(0x%llx)", objectId);
+
+  // TODO: currently returning false; must integrate with GC
+  expandBufAdd1(pReply, 0);
+
+  return ERR_NONE;
+}
+
+/*
+ * Return the string value in a string object.
+ */
+static JdwpError handleSR_Value(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  ObjectId stringObject = ReadObjectId(&buf);
+  char* str = Dbg::StringToUtf8(stringObject);
+
+  LOG(VERBOSE) << StringPrintf("  Req for str %llx --> '%s'", stringObject, str);
+
+  expandBufAddUtf8String(pReply, (uint8_t*) str);
+  free(str);
+
+  return ERR_NONE;
+}
+
+/*
+ * Return a thread's name.
+ */
+static JdwpError handleTR_Name(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  ObjectId threadId = ReadObjectId(&buf);
+
+  LOG(VERBOSE) << StringPrintf("  Req for name of thread 0x%llx", threadId);
+  char* name = Dbg::GetThreadName(threadId);
+  if (name == NULL) {
+    return ERR_INVALID_THREAD;
+  }
+  expandBufAddUtf8String(pReply, (uint8_t*) name);
+  free(name);
+
+  return ERR_NONE;
+}
+
+/*
+ * Suspend the specified thread.
+ *
+ * It's supposed to remain suspended even if interpreted code wants to
+ * resume it; only the JDI is allowed to resume it.
+ */
+static JdwpError handleTR_Suspend(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  ObjectId threadId = ReadObjectId(&buf);
+
+  if (threadId == Dbg::GetThreadSelfId()) {
+    LOG(INFO) << "  Warning: ignoring request to suspend self";
+    return ERR_THREAD_NOT_SUSPENDED;
+  }
+  LOG(VERBOSE) << StringPrintf("  Req to suspend thread 0x%llx", threadId);
+  Dbg::SuspendThread(threadId);
+  return ERR_NONE;
+}
+
+/*
+ * Resume the specified thread.
+ */
+static JdwpError handleTR_Resume(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  ObjectId threadId = ReadObjectId(&buf);
+
+  if (threadId == Dbg::GetThreadSelfId()) {
+    LOG(INFO) << "  Warning: ignoring request to resume self";
+    return ERR_NONE;
+  }
+  LOG(VERBOSE) << StringPrintf("  Req to resume thread 0x%llx", threadId);
+  Dbg::ResumeThread(threadId);
+  return ERR_NONE;
+}
+
+/*
+ * Return status of specified thread.
+ */
+static JdwpError handleTR_Status(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  ObjectId threadId = ReadObjectId(&buf);
+
+  LOG(VERBOSE) << StringPrintf("  Req for status of thread 0x%llx", threadId);
+
+  uint32_t threadStatus;
+  uint32_t suspendStatus;
+  if (!Dbg::GetThreadStatus(threadId, &threadStatus, &suspendStatus)) {
+    return ERR_INVALID_THREAD;
+  }
+
+  LOG(VERBOSE) << "    --> " << JdwpThreadStatus(threadStatus) << ", " << JdwpSuspendStatus(suspendStatus);
+
+  expandBufAdd4BE(pReply, threadStatus);
+  expandBufAdd4BE(pReply, suspendStatus);
+
+  return ERR_NONE;
+}
+
+/*
+ * Return the thread group that the specified thread is a member of.
+ */
+static JdwpError handleTR_ThreadGroup(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  ObjectId threadId = ReadObjectId(&buf);
+
+  /* currently not handling these */
+  ObjectId threadGroupId = Dbg::GetThreadGroup(threadId);
+  expandBufAddObjectId(pReply, threadGroupId);
+
+  return ERR_NONE;
+}
+
+/*
+ * Return the current call stack of a suspended thread.
+ *
+ * If the thread isn't suspended, the error code isn't defined, but should
+ * be THREAD_NOT_SUSPENDED.
+ */
+static JdwpError handleTR_Frames(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  ObjectId threadId = ReadObjectId(&buf);
+  uint32_t startFrame = read4BE(&buf);
+  uint32_t length = read4BE(&buf);
+
+  if (!Dbg::ThreadExists(threadId)) {
+    return ERR_INVALID_THREAD;
+  }
+  if (!Dbg::IsSuspended(threadId)) {
+    LOG(VERBOSE) << StringPrintf("  Rejecting req for frames in running thread '%s' (%llx)", Dbg::GetThreadName(threadId), threadId);
+    return ERR_THREAD_NOT_SUSPENDED;
+  }
+
+  int frameCount = Dbg::GetThreadFrameCount(threadId);
+
+  LOG(VERBOSE) << StringPrintf("  Request for frames: threadId=%llx start=%d length=%d [count=%d]", threadId, startFrame, length, frameCount);
+  if (frameCount <= 0) {
+    return ERR_THREAD_NOT_SUSPENDED;    /* == 0 means 100% native */
+  }
+  if (length == (uint32_t) -1) {
+    length = frameCount;
+  }
+  CHECK((int) startFrame >= 0 && (int) startFrame < frameCount);
+  CHECK_LE((int) (startFrame + length), frameCount);
+
+  uint32_t frames = length;
+  expandBufAdd4BE(pReply, frames);
+  for (uint32_t i = startFrame; i < (startFrame+length); i++) {
+    FrameId frameId;
+    JdwpLocation loc;
+
+    Dbg::GetThreadFrame(threadId, i, &frameId, &loc);
+
+    expandBufAdd8BE(pReply, frameId);
+    AddLocation(pReply, &loc);
+
+    LOG(VERBOSE) << StringPrintf("    Frame %d: id=%llx loc={type=%d cls=%llx mth=%x loc=%llx}", i, frameId, loc.typeTag, loc.classId, loc.methodId, loc.idx);
+  }
+
+  return ERR_NONE;
+}
+
+/*
+ * Returns the #of frames on the specified thread, which must be suspended.
+ */
+static JdwpError handleTR_FrameCount(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  ObjectId threadId = ReadObjectId(&buf);
+
+  if (!Dbg::ThreadExists(threadId)) {
+    return ERR_INVALID_THREAD;
+  }
+  if (!Dbg::IsSuspended(threadId)) {
+    LOG(VERBOSE) << StringPrintf("  Rejecting req for frames in running thread '%s' (%llx)", Dbg::GetThreadName(threadId), threadId);
+    return ERR_THREAD_NOT_SUSPENDED;
+  }
+
+  int frameCount = Dbg::GetThreadFrameCount(threadId);
+  if (frameCount < 0) {
+    return ERR_INVALID_THREAD;
+  }
+  expandBufAdd4BE(pReply, (uint32_t)frameCount);
+
+  return ERR_NONE;
+}
+
+/*
+ * Get the monitor that the thread is waiting on.
+ */
+static JdwpError handleTR_CurrentContendedMonitor(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  ObjectId threadId;
+
+  threadId = ReadObjectId(&buf);
+
+  // TODO: create an Object to represent the monitor (we're currently
+  // just using a raw Monitor struct in the VM)
+
+  return ERR_NOT_IMPLEMENTED;
+}
+
+/*
+ * Return the suspend count for the specified thread.
+ *
+ * (The thread *might* still be running -- it might not have examined
+ * its suspend count recently.)
+ */
+static JdwpError handleTR_SuspendCount(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  ObjectId threadId = ReadObjectId(&buf);
+
+  uint32_t suspendCount = Dbg::GetThreadSuspendCount(threadId);
+  expandBufAdd4BE(pReply, suspendCount);
+
+  return ERR_NONE;
+}
+
+/*
+ * Return the name of a thread group.
+ *
+ * The Eclipse debugger recognizes "main" and "system" as special.
+ */
+static JdwpError handleTGR_Name(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  ObjectId threadGroupId = ReadObjectId(&buf);
+  LOG(VERBOSE) << StringPrintf("  Req for name of threadGroupId=0x%llx", threadGroupId);
+
+  char* name = Dbg::GetThreadGroupName(threadGroupId);
+  if (name != NULL) {
+    expandBufAddUtf8String(pReply, (uint8_t*) name);
+  } else {
+    expandBufAddUtf8String(pReply, (uint8_t*) "BAD-GROUP-ID");
+    LOG(VERBOSE) << StringPrintf("bad thread group ID");
+  }
+
+  free(name);
+
+  return ERR_NONE;
+}
+
+/*
+ * Returns the thread group -- if any -- that contains the specified
+ * thread group.
+ */
+static JdwpError handleTGR_Parent(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  ObjectId groupId = ReadObjectId(&buf);
+
+  ObjectId parentGroup = Dbg::GetThreadGroupParent(groupId);
+  expandBufAddObjectId(pReply, parentGroup);
+
+  return ERR_NONE;
+}
+
+/*
+ * Return the active threads and thread groups that are part of the
+ * specified thread group.
+ */
+static JdwpError handleTGR_Children(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  ObjectId threadGroupId = ReadObjectId(&buf);
+  LOG(VERBOSE) << StringPrintf("  Req for threads in threadGroupId=0x%llx", threadGroupId);
+
+  ObjectId* pThreadIds;
+  uint32_t threadCount;
+  Dbg::GetThreadGroupThreads(threadGroupId, &pThreadIds, &threadCount);
+
+  expandBufAdd4BE(pReply, threadCount);
+
+  for (uint32_t i = 0; i < threadCount; i++) {
+    expandBufAddObjectId(pReply, pThreadIds[i]);
+  }
+  free(pThreadIds);
+
+  /*
+   * TODO: finish support for child groups
+   *
+   * For now, just show that "main" is a child of "system".
+   */
+  if (threadGroupId == Dbg::GetSystemThreadGroupId()) {
+    expandBufAdd4BE(pReply, 1);
+    expandBufAddObjectId(pReply, Dbg::GetMainThreadGroupId());
+  } else {
+    expandBufAdd4BE(pReply, 0);
+  }
+
+  return ERR_NONE;
+}
+
+/*
+ * Return the #of components in the array.
+ */
+static JdwpError handleAR_Length(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  ObjectId arrayId = ReadObjectId(&buf);
+  LOG(VERBOSE) << StringPrintf("  Req for length of array 0x%llx", arrayId);
+
+  uint32_t arrayLength = Dbg::GetArrayLength(arrayId);
+
+  LOG(VERBOSE) << StringPrintf("    --> %d", arrayLength);
+
+  expandBufAdd4BE(pReply, arrayLength);
+
+  return ERR_NONE;
+}
+
+/*
+ * Return the values from an array.
+ */
+static JdwpError handleAR_GetValues(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  ObjectId arrayId = ReadObjectId(&buf);
+  uint32_t firstIndex = read4BE(&buf);
+  uint32_t length = read4BE(&buf);
+
+  uint8_t tag = Dbg::GetArrayElementTag(arrayId);
+  LOG(VERBOSE) << StringPrintf("  Req for array values 0x%llx first=%d len=%d (elem tag=%c)", arrayId, firstIndex, length, tag);
+
+  expandBufAdd1(pReply, tag);
+  expandBufAdd4BE(pReply, length);
+
+  if (!Dbg::OutputArray(arrayId, firstIndex, length, pReply)) {
+    return ERR_INVALID_LENGTH;
+  }
+
+  return ERR_NONE;
+}
+
+/*
+ * Set values in an array.
+ */
+static JdwpError handleAR_SetValues(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  ObjectId arrayId = ReadObjectId(&buf);
+  uint32_t firstIndex = read4BE(&buf);
+  uint32_t values = read4BE(&buf);
+
+  LOG(VERBOSE) << StringPrintf("  Req to set array values 0x%llx first=%d count=%d", arrayId, firstIndex, values);
+
+  if (!Dbg::SetArrayElements(arrayId, firstIndex, values, buf)) {
+    return ERR_INVALID_LENGTH;
+  }
+
+  return ERR_NONE;
+}
+
+/*
+ * Return the set of classes visible to a class loader.  All classes which
+ * have the class loader as a defining or initiating loader are returned.
+ */
+static JdwpError handleCLR_VisibleClasses(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  ObjectId classLoaderObject;
+  uint32_t numClasses = 0;
+  RefTypeId* classRefBuf = NULL;
+  int i;
+
+  classLoaderObject = ReadObjectId(&buf);
+
+  Dbg::GetVisibleClassList(classLoaderObject, &numClasses, &classRefBuf);
+
+  expandBufAdd4BE(pReply, numClasses);
+  for (i = 0; i < (int) numClasses; i++) {
+    uint8_t refTypeTag = Dbg::GetClassObjectType(classRefBuf[i]);
+
+    expandBufAdd1(pReply, refTypeTag);
+    expandBufAddRefTypeId(pReply, classRefBuf[i]);
+  }
+
+  return ERR_NONE;
+}
+
+/*
+ * Return a newly-allocated string in which all occurrences of '.' have
+ * been changed to '/'.  If we find a '/' in the original string, NULL
+ * is returned to avoid ambiguity.
+ */
+char* dvmDotToSlash(const char* str) {
+  char* newStr = strdup(str);
+  char* cp = newStr;
+
+  if (newStr == NULL) {
+    return NULL;
+  }
+
+  while (*cp != '\0') {
+    if (*cp == '/') {
+      CHECK(false);
+      return NULL;
+    }
+    if (*cp == '.') {
+      *cp = '/';
+    }
+    cp++;
+  }
+
+  return newStr;
+}
+
+/*
+ * Set an event trigger.
+ *
+ * Reply with a requestID.
+ */
+static JdwpError handleER_Set(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  const uint8_t* origBuf = buf;
+
+  uint8_t eventKind = read1(&buf);
+  uint8_t suspendPolicy = read1(&buf);
+  uint32_t modifierCount = read4BE(&buf);
+
+  LOG(VERBOSE) << "  Set(kind=" << JdwpEventKind(eventKind)
+               << " suspend=" << JdwpSuspendPolicy(suspendPolicy)
+               << " mods=" << modifierCount << ")";
+
+  CHECK_LT(modifierCount, 256U);    /* reasonableness check */
+
+  JdwpEvent* pEvent = EventAlloc(modifierCount);
+  pEvent->eventKind = static_cast<JdwpEventKind>(eventKind);
+  pEvent->suspendPolicy = static_cast<JdwpSuspendPolicy>(suspendPolicy);
+  pEvent->modCount = modifierCount;
+
+  /*
+   * Read modifiers.  Ordering may be significant (see explanation of Count
+   * mods in JDWP doc).
+   */
+  for (uint32_t idx = 0; idx < modifierCount; idx++) {
+    uint8_t modKind = read1(&buf);
+
+    pEvent->mods[idx].modKind = modKind;
+
+    switch (modKind) {
+    case MK_COUNT:          /* report once, when "--count" reaches 0 */
+      {
+        uint32_t count = read4BE(&buf);
+        LOG(VERBOSE) << "    Count: " << count;
+        if (count == 0) {
+          return ERR_INVALID_COUNT;
+        }
+        pEvent->mods[idx].count.count = count;
+      }
+      break;
+    case MK_CONDITIONAL:    /* conditional on expression) */
+      {
+        uint32_t exprId = read4BE(&buf);
+        LOG(VERBOSE) << "    Conditional: " << exprId;
+        pEvent->mods[idx].conditional.exprId = exprId;
+      }
+      break;
+    case MK_THREAD_ONLY:    /* only report events in specified thread */
+      {
+        ObjectId threadId = ReadObjectId(&buf);
+        LOG(VERBOSE) << StringPrintf("    ThreadOnly: %llx", threadId);
+        pEvent->mods[idx].threadOnly.threadId = threadId;
+      }
+      break;
+    case MK_CLASS_ONLY:     /* for ClassPrepare, MethodEntry */
+      {
+        RefTypeId clazzId = ReadRefTypeId(&buf);
+        LOG(VERBOSE) << StringPrintf("    ClassOnly: %llx (%s)", clazzId, Dbg::GetClassDescriptor(clazzId));
+        pEvent->mods[idx].classOnly.refTypeId = clazzId;
+      }
+      break;
+    case MK_CLASS_MATCH:    /* restrict events to matching classes */
+      {
+        char* pattern;
+        size_t strLen;
+
+        pattern = readNewUtf8String(&buf, &strLen);
+        LOG(VERBOSE) << StringPrintf("    ClassMatch: '%s'", pattern);
+        /* pattern is "java.foo.*", we want "java/foo/ *" */
+        pEvent->mods[idx].classMatch.classPattern = dvmDotToSlash(pattern);
+        free(pattern);
+      }
+      break;
+    case MK_CLASS_EXCLUDE:  /* restrict events to non-matching classes */
+      {
+        char* pattern;
+        size_t strLen;
+
+        pattern = readNewUtf8String(&buf, &strLen);
+        LOG(VERBOSE) << StringPrintf("    ClassExclude: '%s'", pattern);
+        pEvent->mods[idx].classExclude.classPattern = dvmDotToSlash(pattern);
+        free(pattern);
+      }
+      break;
+    case MK_LOCATION_ONLY:  /* restrict certain events based on loc */
+      {
+        JdwpLocation loc;
+
+        jdwpReadLocation(&buf, &loc);
+        LOG(VERBOSE) << StringPrintf("    LocationOnly: typeTag=%d classId=%llx methodId=%x idx=%llx",
+        loc.typeTag, loc.classId, loc.methodId, loc.idx);
+        pEvent->mods[idx].locationOnly.loc = loc;
+      }
+      break;
+    case MK_EXCEPTION_ONLY: /* modifies EK_EXCEPTION events */
+      {
+        RefTypeId exceptionOrNull;      /* null == all exceptions */
+        uint8_t caught, uncaught;
+
+        exceptionOrNull = ReadRefTypeId(&buf);
+        caught = read1(&buf);
+        uncaught = read1(&buf);
+        LOG(VERBOSE) << StringPrintf("    ExceptionOnly: type=%llx(%s) caught=%d uncaught=%d",
+            exceptionOrNull, (exceptionOrNull == 0) ? "null" : Dbg::GetClassDescriptor(exceptionOrNull), caught, uncaught);
+
+        pEvent->mods[idx].exceptionOnly.refTypeId = exceptionOrNull;
+        pEvent->mods[idx].exceptionOnly.caught = caught;
+        pEvent->mods[idx].exceptionOnly.uncaught = uncaught;
+      }
+      break;
+    case MK_FIELD_ONLY:     /* for field access/mod events */
+      {
+        RefTypeId declaring = ReadRefTypeId(&buf);
+        FieldId fieldId = ReadFieldId(&buf);
+        LOG(VERBOSE) << StringPrintf("    FieldOnly: %llx %x", declaring, fieldId);
+        pEvent->mods[idx].fieldOnly.refTypeId = declaring;
+        pEvent->mods[idx].fieldOnly.fieldId = fieldId;
+      }
+      break;
+    case MK_STEP:           /* for use with EK_SINGLE_STEP */
+      {
+        ObjectId threadId;
+        uint32_t size, depth;
+
+        threadId = ReadObjectId(&buf);
+        size = read4BE(&buf);
+        depth = read4BE(&buf);
+        LOG(VERBOSE) << StringPrintf("    Step: thread=%llx", threadId)
+                     << " size=" << JdwpStepSize(size) << " depth=" << JdwpStepDepth(depth);
+
+        pEvent->mods[idx].step.threadId = threadId;
+        pEvent->mods[idx].step.size = size;
+        pEvent->mods[idx].step.depth = depth;
+      }
+      break;
+    case MK_INSTANCE_ONLY:  /* report events related to a specific obj */
+      {
+        ObjectId instance = ReadObjectId(&buf);
+        LOG(VERBOSE) << StringPrintf("    InstanceOnly: %llx", instance);
+        pEvent->mods[idx].instanceOnly.objectId = instance;
+      }
+      break;
+    default:
+      LOG(WARNING) << "GLITCH: unsupported modKind=" << modKind;
+      break;
+    }
+  }
+
+  /*
+   * Make sure we consumed all data.  It is possible that the remote side
+   * has sent us bad stuff, but for now we blame ourselves.
+   */
+  if (buf != origBuf + dataLen) {
+    LOG(WARNING) << "GLITCH: dataLen is " << dataLen << ", we have consumed " << (buf - origBuf);
+  }
+
+  /*
+   * We reply with an integer "requestID".
+   */
+  uint32_t requestId = NextEventSerial(state);
+  expandBufAdd4BE(pReply, requestId);
+
+  pEvent->requestId = requestId;
+
+  LOG(VERBOSE) << StringPrintf("    --> event requestId=%#x", requestId);
+
+  /* add it to the list */
+  JdwpError err = RegisterEvent(state, pEvent);
+  if (err != ERR_NONE) {
+    /* registration failed, probably because event is bogus */
+    EventFree(pEvent);
+    LOG(WARNING) << "WARNING: event request rejected";
+  }
+  return err;
+}
+
+/*
+ * Clear an event.  Failure to find an event with a matching ID is a no-op
+ * and does not return an error.
+ */
+static JdwpError handleER_Clear(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  uint8_t eventKind;
+  eventKind = read1(&buf);
+  uint32_t requestId = read4BE(&buf);
+
+  LOG(VERBOSE) << StringPrintf("  Req to clear eventKind=%d requestId=%#x", eventKind, requestId);
+
+  UnregisterEventById(state, requestId);
+
+  return ERR_NONE;
+}
+
+/*
+ * Return the values of arguments and local variables.
+ */
+static JdwpError handleSF_GetValues(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  ObjectId threadId = ReadObjectId(&buf);
+  FrameId frameId = ReadFrameId(&buf);
+  uint32_t slots = read4BE(&buf);
+
+  LOG(VERBOSE) << StringPrintf("  Req for %d slots in threadId=%llx frameId=%llx", slots, threadId, frameId);
+
+  expandBufAdd4BE(pReply, slots);     /* "int values" */
+  for (uint32_t i = 0; i < slots; i++) {
+    uint32_t slot = read4BE(&buf);
+    uint8_t reqSigByte = read1(&buf);
+
+    LOG(VERBOSE) << StringPrintf("    --> slot %d '%c'", slot, reqSigByte);
+
+    int width = Dbg::GetTagWidth(reqSigByte);
+    uint8_t* ptr = expandBufAddSpace(pReply, width+1);
+    Dbg::GetLocalValue(threadId, frameId, slot, reqSigByte, ptr, width);
+  }
+
+  return ERR_NONE;
+}
+
+/*
+ * Set the values of arguments and local variables.
+ */
+static JdwpError handleSF_SetValues(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  ObjectId threadId = ReadObjectId(&buf);
+  FrameId frameId = ReadFrameId(&buf);
+  uint32_t slots = read4BE(&buf);
+
+  LOG(VERBOSE) << StringPrintf("  Req to set %d slots in threadId=%llx frameId=%llx", slots, threadId, frameId);
+
+  for (uint32_t i = 0; i < slots; i++) {
+    uint32_t slot = read4BE(&buf);
+    uint8_t sigByte = read1(&buf);
+    int width = Dbg::GetTagWidth(sigByte);
+    uint64_t value = jdwpReadValue(&buf, width);
+
+    LOG(VERBOSE) << StringPrintf("    --> slot %d '%c' %llx", slot, sigByte, value);
+    Dbg::SetLocalValue(threadId, frameId, slot, sigByte, value, width);
+  }
+
+  return ERR_NONE;
+}
+
+/*
+ * Returns the value of "this" for the specified frame.
+ */
+static JdwpError handleSF_ThisObject(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  ObjectId threadId = ReadObjectId(&buf);
+  FrameId frameId = ReadFrameId(&buf);
+
+  ObjectId objectId;
+  if (!Dbg::GetThisObject(threadId, frameId, &objectId)) {
+    return ERR_INVALID_FRAMEID;
+  }
+
+  uint8_t objectTag = Dbg::GetObjectTag(objectId);
+  LOG(VERBOSE) << StringPrintf("  Req for 'this' in thread=%llx frame=%llx --> %llx %s '%c'", threadId, frameId, objectId, Dbg::GetObjectTypeName(objectId), (char)objectTag);
+
+  expandBufAdd1(pReply, objectTag);
+  expandBufAddObjectId(pReply, objectId);
+
+  return ERR_NONE;
+}
+
+/*
+ * Return the reference type reflected by this class object.
+ *
+ * This appears to be required because ReferenceTypeId values are NEVER
+ * reused, whereas ClassIds can be recycled like any other object.  (Either
+ * that, or I have no idea what this is for.)
+ */
+static JdwpError handleCOR_ReflectedType(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  RefTypeId classObjectId = ReadRefTypeId(&buf);
+
+  LOG(VERBOSE) << StringPrintf("  Req for refTypeId for class=%llx (%s)", classObjectId, Dbg::GetClassDescriptor(classObjectId));
+
+  /* just hand the type back to them */
+  if (Dbg::IsInterface(classObjectId)) {
+    expandBufAdd1(pReply, TT_INTERFACE);
+  } else {
+    expandBufAdd1(pReply, TT_CLASS);
+  }
+  expandBufAddRefTypeId(pReply, classObjectId);
+
+  return ERR_NONE;
+}
+
+/*
+ * Handle a DDM packet with a single chunk in it.
+ */
+static JdwpError handleDDM_Chunk(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  uint8_t* replyBuf = NULL;
+  int replyLen = -1;
+
+  LOG(VERBOSE) << StringPrintf("  Handling DDM packet (%.4s)", buf);
+
+  /*
+   * On first DDM packet, notify all handlers that DDM is running.
+   */
+  if (!state->ddmActive) {
+    state->ddmActive = true;
+    Dbg::DdmConnected();
+  }
+
+  /*
+   * If they want to send something back, we copy it into the buffer.
+   * A no-copy approach would be nicer.
+   *
+   * TODO: consider altering the JDWP stuff to hold the packet header
+   * in a separate buffer.  That would allow us to writev() DDM traffic
+   * instead of copying it into the expanding buffer.  The reduction in
+   * heap requirements is probably more valuable than the efficiency.
+   */
+  if (Dbg::DdmHandlePacket(buf, dataLen, &replyBuf, &replyLen)) {
+    CHECK(replyLen > 0 && replyLen < 1*1024*1024);
+    memcpy(expandBufAddSpace(pReply, replyLen), replyBuf, replyLen);
+    free(replyBuf);
+  }
+  return ERR_NONE;
+}
+
+/*
+ * Handler map decl.
+ */
+typedef JdwpError (*JdwpRequestHandler)(JdwpState* state, const uint8_t* buf, int dataLen, ExpandBuf* reply);
+
+struct JdwpHandlerMap {
+  uint8_t  cmdSet;
+  uint8_t  cmd;
+  JdwpRequestHandler  func;
+  const char* descr;
+};
+
+/*
+ * Map commands to functions.
+ *
+ * Command sets 0-63 are incoming requests, 64-127 are outbound requests,
+ * and 128-256 are vendor-defined.
+ */
+static const JdwpHandlerMap gHandlerMap[] = {
+  /* VirtualMachine command set (1) */
+  { 1,    1,  handleVM_Version,       "VirtualMachine.Version" },
+  { 1,    2,  handleVM_ClassesBySignature, "VirtualMachine.ClassesBySignature" },
+  //1,    3,  VirtualMachine.AllClasses
+  { 1,    4,  handleVM_AllThreads,    "VirtualMachine.AllThreads" },
+  { 1,    5,  handleVM_TopLevelThreadGroups, "VirtualMachine.TopLevelThreadGroups" },
+  { 1,    6,  handleVM_Dispose,       "VirtualMachine.Dispose" },
+  { 1,    7,  handleVM_IDSizes,       "VirtualMachine.IDSizes" },
+  { 1,    8,  handleVM_Suspend,       "VirtualMachine.Suspend" },
+  { 1,    9,  handleVM_Resume,        "VirtualMachine.Resume" },
+  { 1,    10, handleVM_Exit,          "VirtualMachine.Exit" },
+  { 1,    11, handleVM_CreateString,  "VirtualMachine.CreateString" },
+  { 1,    12, handleVM_Capabilities,  "VirtualMachine.Capabilities" },
+  { 1,    13, handleVM_ClassPaths,    "VirtualMachine.ClassPaths" },
+  { 1,    14, HandleVM_DisposeObjects, "VirtualMachine.DisposeObjects" },
+  //1,    15, HoldEvents
+  //1,    16, ReleaseEvents
+  { 1,    17, handleVM_CapabilitiesNew, "VirtualMachine.CapabilitiesNew" },
+  //1,    18, RedefineClasses
+  //1,    19, SetDefaultStratum
+  { 1,    20, handleVM_AllClassesWithGeneric, "VirtualMachine.AllClassesWithGeneric"},
+  //1,    21, InstanceCounts
+
+  /* ReferenceType command set (2) */
+  { 2,    1,  handleRT_Signature,     "ReferenceType.Signature" },
+  { 2,    2,  handleRT_ClassLoader,   "ReferenceType.ClassLoader" },
+  { 2,    3,  handleRT_Modifiers,     "ReferenceType.Modifiers" },
+  //2,    4,  Fields
+  //2,    5,  Methods
+  { 2,    6,  handleRT_GetValues,     "ReferenceType.GetValues" },
+  { 2,    7,  handleRT_SourceFile,    "ReferenceType.SourceFile" },
+  //2,    8,  NestedTypes
+  { 2,    9,  handleRT_Status,        "ReferenceType.Status" },
+  { 2,    10, handleRT_Interfaces,    "ReferenceType.Interfaces" },
+  { 2,    11, handleRT_ClassObject,   "ReferenceType.ClassObject" },
+  { 2,    12, handleRT_SourceDebugExtension, "ReferenceType.SourceDebugExtension" },
+  { 2,    13, handleRT_SignatureWithGeneric, "ReferenceType.SignatureWithGeneric" },
+  { 2,    14, handleRT_FieldsWithGeneric, "ReferenceType.FieldsWithGeneric" },
+  { 2,    15, handleRT_MethodsWithGeneric, "ReferenceType.MethodsWithGeneric" },
+  //2,    16, Instances
+  //2,    17, ClassFileVersion
+  //2,    18, ConstantPool
+
+  /* ClassType command set (3) */
+  { 3,    1,  handleCT_Superclass,    "ClassType.Superclass" },
+  { 3,    2,  handleCT_SetValues,     "ClassType.SetValues" },
+  { 3,    3,  handleCT_InvokeMethod,  "ClassType.InvokeMethod" },
+  { 3,    4,  handleCT_NewInstance,   "ClassType.NewInstance" },
+
+  /* ArrayType command set (4) */
+  { 4,    1,  handleAT_newInstance,   "ArrayType.NewInstance" },
+
+  /* InterfaceType command set (5) */
+
+  /* Method command set (6) */
+  { 6,    1,  handleM_LineTable,      "Method.LineTable" },
+  //6,    2,  VariableTable
+  //6,    3,  Bytecodes
+  //6,    4,  IsObsolete
+  { 6,    5,  handleM_VariableTableWithGeneric, "Method.VariableTableWithGeneric" },
+
+  /* Field command set (8) */
+
+  /* ObjectReference command set (9) */
+  { 9,    1,  handleOR_ReferenceType, "ObjectReference.ReferenceType" },
+  { 9,    2,  handleOR_GetValues,     "ObjectReference.GetValues" },
+  { 9,    3,  handleOR_SetValues,     "ObjectReference.SetValues" },
+  //9,    4,  (not defined)
+  //9,    5,  MonitorInfo
+  { 9,    6,  handleOR_InvokeMethod,  "ObjectReference.InvokeMethod" },
+  { 9,    7,  handleOR_DisableCollection, "ObjectReference.DisableCollection" },
+  { 9,    8,  handleOR_EnableCollection, "ObjectReference.EnableCollection" },
+  { 9,    9,  handleOR_IsCollected,   "ObjectReference.IsCollected" },
+  //9,    10, ReferringObjects
+
+  /* StringReference command set (10) */
+  { 10,   1,  handleSR_Value,         "StringReference.Value" },
+
+  /* ThreadReference command set (11) */
+  { 11,   1,  handleTR_Name,          "ThreadReference.Name" },
+  { 11,   2,  handleTR_Suspend,       "ThreadReference.Suspend" },
+  { 11,   3,  handleTR_Resume,        "ThreadReference.Resume" },
+  { 11,   4,  handleTR_Status,        "ThreadReference.Status" },
+  { 11,   5,  handleTR_ThreadGroup,   "ThreadReference.ThreadGroup" },
+  { 11,   6,  handleTR_Frames,        "ThreadReference.Frames" },
+  { 11,   7,  handleTR_FrameCount,    "ThreadReference.FrameCount" },
+  //11,   8,  OwnedMonitors
+  { 11,   9,  handleTR_CurrentContendedMonitor, "ThreadReference.CurrentContendedMonitor" },
+  //11,   10, Stop
+  //11,   11, Interrupt
+  { 11,   12, handleTR_SuspendCount,  "ThreadReference.SuspendCount" },
+  //11,   13, OwnedMonitorsStackDepthInfo
+  //11,   14, ForceEarlyReturn
+
+  /* ThreadGroupReference command set (12) */
+  { 12,   1,  handleTGR_Name,         "ThreadGroupReference.Name" },
+  { 12,   2,  handleTGR_Parent,       "ThreadGroupReference.Parent" },
+  { 12,   3,  handleTGR_Children,     "ThreadGroupReference.Children" },
+
+  /* ArrayReference command set (13) */
+  { 13,   1,  handleAR_Length,        "ArrayReference.Length" },
+  { 13,   2,  handleAR_GetValues,     "ArrayReference.GetValues" },
+  { 13,   3,  handleAR_SetValues,     "ArrayReference.SetValues" },
+
+  /* ClassLoaderReference command set (14) */
+  { 14,   1,  handleCLR_VisibleClasses, "ClassLoaderReference.VisibleClasses" },
+
+  /* EventRequest command set (15) */
+  { 15,   1,  handleER_Set,           "EventRequest.Set" },
+  { 15,   2,  handleER_Clear,         "EventRequest.Clear" },
+  //15,   3,  ClearAllBreakpoints
+
+  /* StackFrame command set (16) */
+  { 16,   1,  handleSF_GetValues,     "StackFrame.GetValues" },
+  { 16,   2,  handleSF_SetValues,     "StackFrame.SetValues" },
+  { 16,   3,  handleSF_ThisObject,    "StackFrame.ThisObject" },
+  //16,   4,  PopFrames
+
+  /* ClassObjectReference command set (17) */
+  { 17,   1,  handleCOR_ReflectedType,"ClassObjectReference.ReflectedType" },
+
+  /* Event command set (64) */
+  //64,  100, Composite   <-- sent from VM to debugger, never received by VM
+
+  { 199,  1,  handleDDM_Chunk,        "DDM.Chunk" },
+};
+
+/*
+ * Process a request from the debugger.
+ *
+ * On entry, the JDWP thread is in VMWAIT.
+ */
+void ProcessRequest(JdwpState* state, const JdwpReqHeader* pHeader, const uint8_t* buf, int dataLen, ExpandBuf* pReply) {
+  JdwpError result = ERR_NONE;
+  int i, respLen;
+
+  if (pHeader->cmdSet != kJDWPDdmCmdSet) {
+    /*
+     * Activity from a debugger, not merely ddms.  Mark us as having an
+     * active debugger session, and zero out the last-activity timestamp
+     * so waitForDebugger() doesn't return if we stall for a bit here.
+     */
+    Dbg::Active();
+    QuasiAtomicSwap64(0, &state->lastActivityWhen);
+  }
+
+  /*
+   * If a debugger event has fired in another thread, wait until the
+   * initiating thread has suspended itself before processing messages
+   * from the debugger.  Otherwise we (the JDWP thread) could be told to
+   * resume the thread before it has suspended.
+   *
+   * We call with an argument of zero to wait for the current event
+   * thread to finish, and then clear the block.  Depending on the thread
+   * suspend policy, this may allow events in other threads to fire,
+   * but those events have no bearing on what the debugger has sent us
+   * in the current request.
+   *
+   * Note that we MUST clear the event token before waking the event
+   * thread up, or risk waiting for the thread to suspend after we've
+   * told it to resume.
+   */
+  SetWaitForEventThread(state, 0);
+
+  /*
+   * Tell the VM that we're running and shouldn't be interrupted by GC.
+   * Do this after anything that can stall indefinitely.
+   */
+  Dbg::ThreadRunning();
+
+  expandBufAddSpace(pReply, kJDWPHeaderLen);
+
+  for (i = 0; i < (int) arraysize(gHandlerMap); i++) {
+    if (gHandlerMap[i].cmdSet == pHeader->cmdSet && gHandlerMap[i].cmd == pHeader->cmd) {
+      LOG(VERBOSE) << StringPrintf("REQ: %s (cmd=%d/%d dataLen=%d id=0x%06x)", gHandlerMap[i].descr, pHeader->cmdSet, pHeader->cmd, dataLen, pHeader->id);
+      result = (*gHandlerMap[i].func)(state, buf, dataLen, pReply);
+      break;
+    }
+  }
+  if (i == arraysize(gHandlerMap)) {
+    LOG(ERROR) << StringPrintf("REQ: UNSUPPORTED (cmd=%d/%d dataLen=%d id=0x%06x)", pHeader->cmdSet, pHeader->cmd, dataLen, pHeader->id);
+    if (dataLen > 0) {
+      HexDump(buf, dataLen);
+    }
+    LOG(FATAL) << "command not implemented";      // make it *really* obvious
+    result = ERR_NOT_IMPLEMENTED;
+  }
+
+  /*
+   * Set up the reply header.
+   *
+   * If we encountered an error, only send the header back.
+   */
+  uint8_t* replyBuf = expandBufGetBuffer(pReply);
+  set4BE(replyBuf + 4, pHeader->id);
+  set1(replyBuf + 8, kJDWPFlagReply);
+  set2BE(replyBuf + 9, result);
+  if (result == ERR_NONE) {
+    set4BE(replyBuf + 0, expandBufGetLength(pReply));
+  } else {
+    set4BE(replyBuf + 0, kJDWPHeaderLen);
+  }
+
+  respLen = expandBufGetLength(pReply) - kJDWPHeaderLen;
+  if (false) {
+    LOG(INFO) << "reply: dataLen=" << respLen << " err=" << result << (result != ERR_NONE ? " **FAILED**" : "");
+    if (respLen > 0) {
+      HexDump(expandBufGetBuffer(pReply) + kJDWPHeaderLen, respLen);
+    }
+  }
+
+  /*
+   * Update last-activity timestamp.  We really only need this during
+   * the initial setup.  Only update if this is a non-DDMS packet.
+   */
+  if (pHeader->cmdSet != kJDWPDdmCmdSet) {
+    QuasiAtomicSwap64(GetNowMsec(), &state->lastActivityWhen);
+  }
+
+  /* tell the VM that GC is okay again */
+  Dbg::ThreadWaiting();
+}
+
+}  // namespace JDWP
+
+}  // namespace art
diff --git a/src/jdwp/jdwp_handler.h b/src/jdwp/jdwp_handler.h
new file mode 100644
index 0000000..6fa75d7
--- /dev/null
+++ b/src/jdwp/jdwp_handler.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Handle requests.
+ */
+#ifndef ART_JDWP_JDWPHANDLER_H_
+#define ART_JDWP_JDWPHANDLER_H_
+
+#include "jdwp_expand_buf.h"
+
+namespace art {
+
+namespace JDWP {
+
+/*
+ * JDWP message header for a request.
+ */
+struct JdwpReqHeader {
+  uint32_t length;
+  uint32_t id;
+  uint8_t cmdSet;
+  uint8_t cmd;
+};
+
+/*
+ * Process a request from the debugger.
+ *
+ * "buf" points past the header, to the content of the message.  "dataLen"
+ * can therefore be zero.
+ */
+void ProcessRequest(JdwpState* state, const JdwpReqHeader* pHeader,
+    const uint8_t* buf, int dataLen, ExpandBuf* pReply);
+
+/* helper function */
+void AddLocation(ExpandBuf* pReply, const JdwpLocation* pLoc);
+
+}  // namespace JDWP
+
+}  // namespace art
+
+#endif  // ART_JDWP_JDWPHANDLER_H_
diff --git a/src/jdwp/jdwp_main.cc b/src/jdwp/jdwp_main.cc
new file mode 100644
index 0000000..f2ff937
--- /dev/null
+++ b/src/jdwp/jdwp_main.cc
@@ -0,0 +1,508 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * JDWP initialization.
+ */
+
+#include "atomic.h"
+#include "debugger.h"
+#include "jdwp/jdwp_priv.h"
+#include "logging.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <time.h>
+#include <errno.h>
+
+namespace art {
+
+namespace JDWP {
+
+static void* jdwpThreadStart(void* arg);
+
+/*
+ * JdwpNetStateBase class implementation
+ */
+JdwpNetStateBase::JdwpNetStateBase() : socket_lock_("JdwpNetStateBase lock") {
+  clientSock = -1;
+}
+
+/*
+ * Write a packet. Grabs a mutex to assure atomicity.
+ */
+ssize_t JdwpNetStateBase::writePacket(ExpandBuf* pReply) {
+  MutexLock mu(socket_lock_);
+  return write(clientSock, expandBufGetBuffer(pReply), expandBufGetLength(pReply));
+}
+
+/*
+ * Write a buffered packet. Grabs a mutex to assure atomicity.
+ */
+ssize_t JdwpNetStateBase::writeBufferedPacket(const iovec* iov, int iovcnt) {
+  MutexLock mu(socket_lock_);
+  return writev(clientSock, iov, iovcnt);
+}
+
+bool NetStartup(JdwpState* state, const JdwpStartupParams* pParams) {
+  return (*state->transport->startup)(state, pParams);
+}
+
+bool AcceptConnection(JdwpState* state) {
+  return (*state->transport->accept)(state);
+}
+
+bool EstablishConnection(JdwpState* state) {
+  return (*state->transport->establish)(state);
+}
+
+void CloseConnection(JdwpState* state) {
+  (*state->transport->close)(state);
+}
+
+void NetShutdown(JdwpState* state) {
+  (*state->transport->shutdown)(state);
+}
+
+void NetFree(JdwpState* state) {
+  (*state->transport->free)(state);
+}
+
+bool IsTransportDefined(JdwpState* state) {
+  return state != NULL && state->transport != NULL;
+}
+
+bool JdwpIsConnected(JdwpState* state) {
+  return state != NULL && (*state->transport->isConnected)(state);
+}
+
+bool AwaitingHandshake(JdwpState* state) {
+  return (*state->transport->awaitingHandshake)(state);
+}
+
+bool ProcessIncoming(JdwpState* state) {
+  return (*state->transport->processIncoming)(state);
+}
+
+bool SendRequest(JdwpState* state, ExpandBuf* pReq) {
+  return (*state->transport->sendRequest)(state, pReq);
+}
+
+static void CreateJdwpThread(JdwpState* state) {
+  CHECK_PTHREAD_CALL(pthread_create, (&state->debugThreadHandle, NULL, jdwpThreadStart, state), "JDWP thread");
+}
+
+JdwpState::JdwpState()
+    : thread_start_lock_("JDWP thread start lock"),
+      thread_start_cond_("JDWP thread start condition variable"),
+      debug_thread_started_(false),
+      debugThreadId(0),
+      run(false),
+      transport(NULL),
+      netState(NULL),
+      attach_lock_("JDWP attach lock"),
+      attach_cond_("JDWP attach condition variable"),
+      lastActivityWhen(0),
+      requestSerial(0x10000000),
+      eventSerial(0x20000000),
+      serial_lock_("JDWP serial lock"),
+      numEvents(0),
+      eventList(NULL),
+      event_lock_("JDWP event lock"),
+      event_thread_lock_("JDWP event thread lock"),
+      event_thread_cond_("JDWP event thread condition variable"),
+      eventThreadId(0),
+      ddmActive(false) {
+}
+
+/*
+ * Initialize JDWP.
+ *
+ * Does not return until JDWP thread is running, but may return before
+ * the thread is accepting network connections.
+ */
+JdwpState* JdwpStartup(const JdwpStartupParams* pParams) {
+  /* comment this out when debugging JDWP itself */
+  //android_setMinPriority(LOG_TAG, ANDROID_LOG_DEBUG);
+
+  JdwpState* state = new JdwpState;
+
+  state->params = *pParams;
+
+  switch (pParams->transport) {
+  case kJdwpTransportSocket:
+    // LOGD("prepping for JDWP over TCP");
+    state->transport = SocketTransport();
+    break;
+#ifdef HAVE_ANDROID_OS
+  case kJdwpTransportAndroidAdb:
+    // LOGD("prepping for JDWP over ADB");
+    state->transport = AndroidAdbTransport();
+    break;
+#endif
+  default:
+    LOG(FATAL) << "Unknown transport: " << pParams->transport;
+  }
+
+  if (!NetStartup(state, pParams)) {
+    goto fail;
+  }
+
+  /*
+   * Grab a mutex or two before starting the thread.  This ensures they
+   * won't signal the cond var before we're waiting.
+   */
+  state->thread_start_lock_.Lock();
+  if (pParams->suspend) {
+    state->attach_lock_.Lock();
+  }
+
+  /*
+   * We have bound to a port, or are trying to connect outbound to a
+   * debugger.  Create the JDWP thread and let it continue the mission.
+   */
+  CreateJdwpThread(state);
+
+  /*
+   * Wait until the thread finishes basic initialization.
+   * TODO: cond vars should be waited upon in a loop
+   */
+  state->thread_start_cond_.Wait(state->thread_start_lock_);
+  state->thread_start_lock_.Unlock();
+
+  /*
+   * For suspend=y, wait for the debugger to connect to us or for us to
+   * connect to the debugger.
+   *
+   * The JDWP thread will signal us when it connects successfully or
+   * times out (for timeout=xxx), so we have to check to see what happened
+   * when we wake up.
+   */
+  if (pParams->suspend) {
+    {
+      ScopedThreadStateChange tsc(Thread::Current(), Thread::kVmWait);
+
+      state->attach_cond_.Wait(state->attach_lock_);
+      state->attach_lock_.Unlock();
+    }
+
+    if (!JdwpIsActive(state)) {
+      LOG(ERROR) << "JDWP connection failed";
+      goto fail;
+    }
+
+    LOG(INFO) << "JDWP connected";
+
+    /*
+     * Ordinarily we would pause briefly to allow the debugger to set
+     * breakpoints and so on, but for "suspend=y" the VM init code will
+     * pause the VM when it sends the VM_START message.
+     */
+  }
+
+  return state;
+
+fail:
+  JdwpShutdown(state);     // frees state
+  return NULL;
+}
+
+/*
+ * Reset all session-related state.  There should not be an active connection
+ * to the client at this point.  The rest of the VM still thinks there is
+ * a debugger attached.
+ *
+ * This includes freeing up the debugger event list.
+ */
+void ResetState(JdwpState* state) {
+  /* could reset the serial numbers, but no need to */
+
+  UnregisterAll(state);
+  CHECK(state->eventList == NULL);
+
+  /*
+   * Should not have one of these in progress.  If the debugger went away
+   * mid-request, though, we could see this.
+   */
+  if (state->eventThreadId != 0) {
+    LOG(WARNING) << "resetting state while event in progress";
+    DCHECK(false);
+  }
+}
+
+/*
+ * Tell the JDWP thread to shut down.  Frees "state".
+ */
+void JdwpShutdown(JdwpState* state) {
+  void* threadReturn;
+
+  if (state == NULL) {
+    return;
+  }
+
+  if (IsTransportDefined(state)) {
+    if (JdwpIsConnected(state)) {
+      PostVMDeath(state);
+    }
+
+    /*
+     * Close down the network to inspire the thread to halt.
+     */
+    LOG(DEBUG) << "JDWP shutting down net...";
+    NetShutdown(state);
+
+    if (state->debug_thread_started_) {
+      state->run = false;
+      if (pthread_join(state->debugThreadHandle, &threadReturn) != 0) {
+        LOG(WARNING) << "JDWP thread join failed";
+      }
+    }
+
+    LOG(DEBUG) << "JDWP freeing netstate...";
+    NetFree(state);
+    state->netState = NULL;
+  }
+  CHECK(state->netState == NULL);
+
+  ResetState(state);
+  free(state);
+}
+
+/*
+ * Are we talking to a debugger?
+ */
+bool JdwpIsActive(JdwpState* state) {
+  return JdwpIsConnected(state);
+}
+
+/*
+ * Entry point for JDWP thread.  The thread was created through the VM
+ * mechanisms, so there is a java/lang/Thread associated with us.
+ */
+static void* jdwpThreadStart(void* arg) {
+  JdwpState* state = reinterpret_cast<JdwpState*>(arg);
+  CHECK(state != NULL);
+
+  Runtime* runtime = Runtime::Current();
+  runtime->AttachCurrentThread("JDWP", true);
+
+  LOG(VERBOSE) << "JDWP: thread running";
+
+  /*
+   * Finish initializing "state", then notify the creating thread that
+   * we're running.
+   */
+  state->debugThreadHandle = pthread_self();
+  state->run = true;
+  android_atomic_release_store(true, &state->debug_thread_started_);
+
+  state->thread_start_lock_.Lock();
+  state->thread_start_cond_.Wait(state->thread_start_lock_);
+  state->thread_start_lock_.Unlock();
+
+  /* set the thread state to VMWAIT so GCs don't wait for us */
+  Dbg::ThreadWaiting();
+
+  /*
+   * Loop forever if we're in server mode, processing connections.  In
+   * non-server mode, we bail out of the thread when the debugger drops
+   * us.
+   *
+   * We broadcast a notification when a debugger attaches, after we
+   * successfully process the handshake.
+   */
+  while (state->run) {
+    bool first;
+
+    if (state->params.server) {
+      /*
+       * Block forever, waiting for a connection.  To support the
+       * "timeout=xxx" option we'll need to tweak this.
+       */
+      if (!AcceptConnection(state)) {
+        break;
+      }
+    } else {
+      /*
+       * If we're not acting as a server, we need to connect out to the
+       * debugger.  To support the "timeout=xxx" option we need to
+       * have a timeout if the handshake reply isn't received in a
+       * reasonable amount of time.
+       */
+      if (!EstablishConnection(state)) {
+        /* wake anybody who was waiting for us to succeed */
+        MutexLock mu(state->attach_lock_);
+        state->attach_cond_.Broadcast();
+        break;
+      }
+    }
+
+    /* prep debug code to handle the new connection */
+    Dbg::Connected();
+
+    /* process requests until the debugger drops */
+    first = true;
+    while (true) {
+      // sanity check -- shouldn't happen?
+      if (Thread::Current()->GetState() != Thread::kVmWait) {
+        LOG(ERROR) << "JDWP thread no longer in VMWAIT (now " << Thread::Current()->GetState() << "); resetting";
+        Dbg::ThreadWaiting();
+      }
+
+      if (!ProcessIncoming(state)) {
+        /* blocking read */
+        break;
+      }
+
+      if (first && !AwaitingHandshake(state)) {
+        /* handshake worked, tell the interpreter that we're active */
+        first = false;
+
+        /* set thread ID; requires object registry to be active */
+        state->debugThreadId = Dbg::GetThreadSelfId();
+
+        /* wake anybody who's waiting for us */
+        MutexLock mu(state->attach_lock_);
+        state->attach_cond_.Broadcast();
+      }
+    }
+
+    CloseConnection(state);
+
+    if (state->ddmActive) {
+      state->ddmActive = false;
+
+      /* broadcast the disconnect; must be in RUNNING state */
+      Dbg::ThreadRunning();
+      Dbg::DdmDisconnected();
+      Dbg::ThreadWaiting();
+    }
+
+    /* release session state, e.g. remove breakpoint instructions */
+    ResetState(state);
+
+    /* tell the interpreter that the debugger is no longer around */
+    Dbg::Disconnected();
+
+    /* if we had threads suspended, resume them now */
+    Dbg::UndoDebuggerSuspensions();
+
+    /* if we connected out, this was a one-shot deal */
+    if (!state->params.server) {
+      state->run = false;
+    }
+  }
+
+  /* back to running, for thread shutdown */
+  Dbg::ThreadRunning();
+
+  LOG(VERBOSE) << "JDWP: thread exiting";
+  return NULL;
+}
+
+
+/*
+ * Return the thread handle, or (pthread_t)0 if the debugger isn't running.
+ */
+pthread_t GetDebugThread(JdwpState* state) {
+  if (state == NULL) {
+    return 0;
+  }
+  return state->debugThreadHandle;
+}
+
+/*
+ * Support routines for waitForDebugger().
+ *
+ * We can't have a trivial "waitForDebugger" function that returns the
+ * instant the debugger connects, because we run the risk of executing code
+ * before the debugger has had a chance to configure breakpoints or issue
+ * suspend calls.  It would be nice to just sit in the suspended state, but
+ * most debuggers don't expect any threads to be suspended when they attach.
+ *
+ * There's no JDWP event we can post to tell the debugger, "we've stopped,
+ * and we like it that way".  We could send a fake breakpoint, which should
+ * cause the debugger to immediately send a resume, but the debugger might
+ * send the resume immediately or might throw an exception of its own upon
+ * receiving a breakpoint event that it didn't ask for.
+ *
+ * What we really want is a "wait until the debugger is done configuring
+ * stuff" event.  We can approximate this with a "wait until the debugger
+ * has been idle for a brief period".
+ */
+
+/*
+ * Get a notion of the current time, in milliseconds.
+ */
+int64_t GetNowMsec() {
+#ifdef HAVE_POSIX_CLOCKS
+  struct timespec now;
+  clock_gettime(CLOCK_MONOTONIC, &now);
+  return now.tv_sec * 1000LL + now.tv_nsec / 1000000LL;
+#else
+  struct timeval now;
+  gettimeofday(&now, NULL);
+  return now.tv_sec * 1000LL + now.tv_usec / 1000LL;
+#endif
+}
+
+/*
+ * Return the time, in milliseconds, since the last debugger activity.
+ *
+ * Returns -1 if no debugger is attached, or 0 if we're in the middle of
+ * processing a debugger request.
+ */
+int64_t LastDebuggerActivity(JdwpState* state) {
+  if (!Dbg::IsDebuggerConnected()) {
+    LOG(DEBUG) << "no active debugger";
+    return -1;
+  }
+
+  int64_t last = QuasiAtomicRead64(&state->lastActivityWhen);
+
+  /* initializing or in the middle of something? */
+  if (last == 0) {
+    LOG(VERBOSE) << "+++ last=busy";
+    return 0;
+  }
+
+  /* now get the current time */
+  int64_t now = GetNowMsec();
+  CHECK_GT(now, last);
+
+  LOG(VERBOSE) << "+++ debugger interval=" << (now - last);
+  return now - last;
+}
+
+static const char* kTransportNames[] = {
+  "Unknown",
+  "Socket",
+  "AndroidAdb",
+};
+std::ostream& operator<<(std::ostream& os, const JdwpTransportType& value) {
+  int32_t int_value = static_cast<int32_t>(value);
+  if (value >= kJdwpTransportUnknown && value <= kJdwpTransportAndroidAdb) {
+    os << kTransportNames[int_value];
+  } else {
+    os << "JdwpTransportType[" << int_value << "]";
+  }
+  return os;
+}
+
+}  // namespace JDWP
+
+}  // namespace art
diff --git a/src/jdwp/jdwp_priv.h b/src/jdwp/jdwp_priv.h
new file mode 100644
index 0000000..60169dd
--- /dev/null
+++ b/src/jdwp/jdwp_priv.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * JDWP internal interfaces.
+ */
+#ifndef ART_JDWP_JDWPPRIV_H_
+#define ART_JDWP_JDWPPRIV_H_
+
+#define LOG_TAG "jdwp"
+
+#include "debugger.h"
+#include "jdwp/jdwp.h"
+#include "jdwp/jdwp_event.h"
+#include "../mutex.h" // TODO: fix our include path!
+
+#include <pthread.h>
+#include <sys/uio.h>
+
+/*
+ * JDWP constants.
+ */
+#define kJDWPHeaderLen  11
+#define kJDWPFlagReply  0x80
+
+/* DDM support */
+#define kJDWPDdmCmdSet  199     /* 0xc7, or 'G'+128 */
+#define kJDWPDdmCmd     1
+
+namespace art {
+
+namespace JDWP {
+
+/*
+ * Transport-specific network status.
+ */
+struct JdwpNetState;
+struct JdwpState;
+
+/*
+ * Transport functions.
+ */
+struct JdwpTransport {
+  bool (*startup)(JdwpState* state, const JdwpStartupParams* pParams);
+  bool (*accept)(JdwpState* state);
+  bool (*establish)(JdwpState* state);
+  void (*close)(JdwpState* state);
+  void (*shutdown)(JdwpState* state);
+  void (*free)(JdwpState* state);
+  bool (*isConnected)(JdwpState* state);
+  bool (*awaitingHandshake)(JdwpState* state);
+  bool (*processIncoming)(JdwpState* state);
+  bool (*sendRequest)(JdwpState* state, ExpandBuf* pReq);
+  bool (*sendBufferedRequest)(JdwpState* state, const iovec* iov, int iovcnt);
+};
+
+const JdwpTransport* SocketTransport();
+const JdwpTransport* AndroidAdbTransport();
+
+
+/*
+ * State for JDWP functions.
+ */
+struct JdwpState {
+  JdwpState();
+
+  JdwpStartupParams params;
+
+  /* wait for creation of the JDWP thread */
+  Mutex thread_start_lock_;
+  ConditionVariable thread_start_cond_;
+
+  volatile int32_t debug_thread_started_;
+  pthread_t debugThreadHandle;
+  ObjectId debugThreadId;
+  bool run;
+
+  const JdwpTransport* transport;
+  JdwpNetState* netState;
+
+  /* for wait-for-debugger */
+  Mutex attach_lock_;
+  ConditionVariable attach_cond_;
+
+  /* time of last debugger activity, in milliseconds */
+  int64_t lastActivityWhen;
+
+  /* global counters and a mutex to protect them */
+  uint32_t requestSerial;
+  uint32_t eventSerial;
+  Mutex serial_lock_;
+
+  /*
+   * Events requested by the debugger (breakpoints, class prep, etc).
+   */
+  int numEvents;      /* #of elements in eventList */
+  JdwpEvent* eventList;      /* linked list of events */
+  Mutex event_lock_;      /* guards numEvents/eventList */
+
+  /*
+   * Synchronize suspension of event thread (to avoid receiving "resume"
+   * events before the thread has finished suspending itself).
+   */
+  Mutex event_thread_lock_;
+  ConditionVariable event_thread_cond_;
+  ObjectId eventThreadId;
+
+  /*
+   * DDM support.
+   */
+  bool ddmActive;
+};
+
+/*
+ * Base class for JdwpNetState
+ */
+class JdwpNetStateBase {
+public:
+  int clientSock;     /* active connection to debugger */
+
+  JdwpNetStateBase();
+  ssize_t writePacket(ExpandBuf* pReply);
+  ssize_t writeBufferedPacket(const iovec* iov, int iovcnt);
+
+private:
+  Mutex socket_lock_;
+};
+
+
+/* reset all session-specific data */
+void ResetState(JdwpState* state);
+
+/* atomic ops to get next serial number */
+uint32_t NextRequestSerial(JdwpState* state);
+uint32_t NextEventSerial(JdwpState* state);
+
+/* get current time, in msec */
+int64_t GetNowMsec();
+
+}  // namespace JDWP
+
+}  // namespace art
+
+#endif  // ART_JDWP_JDWPPRIV_H_
diff --git a/src/jdwp/jdwp_socket.cc b/src/jdwp/jdwp_socket.cc
new file mode 100644
index 0000000..b4062d0
--- /dev/null
+++ b/src/jdwp/jdwp_socket.cc
@@ -0,0 +1,883 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * JDWP TCP socket network code.
+ */
+#include "jdwp/jdwp_priv.h"
+#include "jdwp/jdwp_handler.h"
+#include "logging.h"
+#include "stringprintf.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#define kBasePort           8000
+#define kMaxPort            8040
+
+#define kInputBufferSize    8192
+
+#define kMagicHandshake     "JDWP-Handshake"
+#define kMagicHandshakeLen  (sizeof(kMagicHandshake)-1)
+
+namespace art {
+
+namespace JDWP {
+
+// fwd
+static void netShutdown(JdwpNetState* state);
+static void netFree(JdwpNetState* state);
+
+/*
+ * JDWP network state.
+ *
+ * We only talk to one debugger at a time.
+ */
+struct JdwpNetState : public JdwpNetStateBase {
+    short   listenPort;
+    int     listenSock;         /* listen for connection from debugger */
+    int     wakePipe[2];        /* break out of select */
+
+    struct in_addr remoteAddr;
+    unsigned short remotePort;
+
+    bool    awaitingHandshake;  /* waiting for "JDWP-Handshake" */
+
+    /* pending data from the network; would be more efficient as circular buf */
+    unsigned char  inputBuffer[kInputBufferSize];
+    int     inputCount;
+
+    JdwpNetState()
+    {
+        listenPort  = 0;
+        listenSock  = -1;
+        wakePipe[0] = -1;
+        wakePipe[1] = -1;
+
+        awaitingHandshake = false;
+
+        inputCount = 0;
+    }
+};
+
+static JdwpNetState* netStartup(short port);
+
+/*
+ * Set up some stuff for transport=dt_socket.
+ */
+static bool prepareSocket(JdwpState* state, const JdwpStartupParams* pParams) {
+  unsigned short port;
+
+  if (pParams->server) {
+    if (pParams->port != 0) {
+      /* try only the specified port */
+      port = pParams->port;
+      state->netState = netStartup(port);
+    } else {
+      /* scan through a range of ports, binding to the first available */
+      for (port = kBasePort; port <= kMaxPort; port++) {
+        state->netState = netStartup(port);
+        if (state->netState != NULL) {
+          break;
+        }
+      }
+    }
+    if (state->netState == NULL) {
+      LOG(ERROR) << "JDWP net startup failed (req port=" << pParams->port << ")";
+      return false;
+    }
+  } else {
+    port = pParams->port;   // used in a debug msg later
+    state->netState = netStartup(-1);
+  }
+
+  if (pParams->suspend) {
+    LOG(INFO) << "JDWP will wait for debugger on port " << port;
+  } else {
+    LOG(INFO) << "JDWP will " << (pParams->server ? "listen" : "connect") << " on port " << port;
+  }
+
+  return true;
+}
+
+/*
+ * Are we still waiting for the handshake string?
+ */
+static bool awaitingHandshake(JdwpState* state) {
+  return state->netState->awaitingHandshake;
+}
+
+/*
+ * Initialize JDWP stuff.
+ *
+ * Allocates a new state structure.  If "port" is non-negative, this also
+ * tries to bind to a listen port.  If "port" is less than zero, we assume
+ * we're preparing for an outbound connection, and return without binding
+ * to anything.
+ *
+ * This may be called several times if we're probing for a port.
+ *
+ * Returns 0 on success.
+ */
+static JdwpNetState* netStartup(short port) {
+  int one = 1;
+  JdwpNetState* netState = new JdwpNetState;
+
+  if (port < 0) {
+    return netState;
+  }
+
+  CHECK_NE(port, 0);
+
+  netState->listenSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+  if (netState->listenSock < 0) {
+    PLOG(ERROR) << "Socket create failed";
+    goto fail;
+  }
+
+  /* allow immediate re-use */
+  if (setsockopt(netState->listenSock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) {
+    PLOG(ERROR) << "setsockopt(SO_REUSEADDR) failed";
+    goto fail;
+  }
+
+  union {
+    struct sockaddr_in  addrInet;
+    struct sockaddr     addrPlain;
+  } addr;
+  addr.addrInet.sin_family = AF_INET;
+  addr.addrInet.sin_port = htons(port);
+  inet_aton("127.0.0.1", &addr.addrInet.sin_addr);
+
+  if (bind(netState->listenSock, &addr.addrPlain, sizeof(addr)) != 0) {
+    PLOG(VERBOSE) << "attempt to bind to port " << port << " failed";
+    goto fail;
+  }
+
+  netState->listenPort = port;
+  LOG(VERBOSE) << "+++ bound to port " << netState->listenPort;
+
+  if (listen(netState->listenSock, 5) != 0) {
+    PLOG(ERROR) << "Listen failed";
+    goto fail;
+  }
+
+  return netState;
+
+fail:
+  netShutdown(netState);
+  netFree(netState);
+  return NULL;
+}
+
+/*
+ * Shut down JDWP listener.  Don't free state.
+ *
+ * Note that "netState" may be partially initialized if "startup" failed.
+ *
+ * This may be called from a non-JDWP thread as part of shutting the
+ * JDWP thread down.
+ *
+ * (This is currently called several times during startup as we probe
+ * for an open port.)
+ */
+static void netShutdown(JdwpNetState* netState) {
+  if (netState == NULL) {
+    return;
+  }
+
+  int listenSock = netState->listenSock;
+  int clientSock = netState->clientSock;
+
+  /* clear these out so it doesn't wake up and try to reuse them */
+  netState->listenSock = netState->clientSock = -1;
+
+  /* "shutdown" dislodges blocking read() and accept() calls */
+  if (listenSock >= 0) {
+    shutdown(listenSock, SHUT_RDWR);
+    close(listenSock);
+  }
+  if (clientSock >= 0) {
+    shutdown(clientSock, SHUT_RDWR);
+    close(clientSock);
+  }
+
+  /* if we might be sitting in select, kick us loose */
+  if (netState->wakePipe[1] >= 0) {
+    LOG(VERBOSE) << "+++ writing to wakePipe";
+    (void) write(netState->wakePipe[1], "", 1);
+  }
+}
+
+static void netShutdownExtern(JdwpState* state) {
+  netShutdown(state->netState);
+}
+
+/*
+ * Free JDWP state.
+ *
+ * Call this after shutting the network down with netShutdown().
+ */
+static void netFree(JdwpNetState* netState) {
+  if (netState == NULL) {
+    return;
+  }
+  CHECK_EQ(netState->listenSock, -1);
+  CHECK_EQ(netState->clientSock, -1);
+
+  if (netState->wakePipe[0] >= 0) {
+    close(netState->wakePipe[0]);
+    netState->wakePipe[0] = -1;
+  }
+  if (netState->wakePipe[1] >= 0) {
+    close(netState->wakePipe[1]);
+    netState->wakePipe[1] = -1;
+  }
+
+  delete netState;
+}
+
+static void netFreeExtern(JdwpState* state) {
+  netFree(state->netState);
+}
+
+/*
+ * Returns "true" if we're connected to a debugger.
+ */
+static bool isConnected(JdwpState* state) {
+  return (state->netState != NULL && state->netState->clientSock >= 0);
+}
+
+/*
+ * Returns "true" if the fd is ready, "false" if not.
+ */
+#if 0
+static bool isFdReadable(int sock)
+{
+    fd_set readfds;
+    struct timeval tv;
+    int count;
+
+    FD_ZERO(&readfds);
+    FD_SET(sock, &readfds);
+
+    tv.tv_sec = 0;
+    tv.tv_usec = 0;
+    count = select(sock+1, &readfds, NULL, NULL, &tv);
+    if (count <= 0)
+        return false;
+
+    if (FD_ISSET(sock, &readfds))   /* make sure it's our fd */
+        return true;
+
+  LOG(ERROR) << "WEIRD: odd behavior in select (count=" << count << ")";
+  return false;
+}
+#endif
+
+#if 0
+/*
+ * Check to see if we have a pending connection from the debugger.
+ *
+ * Returns true on success (meaning a connection is available).
+ */
+static bool checkConnection(JdwpState* state) {
+    JdwpNetState* netState = state->netState;
+
+    CHECK_GE(netState->listenSock, 0);
+    /* not expecting to be called when debugger is actively connected */
+    CHECK_LT(netState->clientSock, 0);
+
+    if (!isFdReadable(netState->listenSock))
+        return false;
+    return true;
+}
+#endif
+
+/*
+ * Disable the TCP Nagle algorithm, which delays transmission of outbound
+ * packets until the previous transmissions have been acked.  JDWP does a
+ * lot of back-and-forth with small packets, so this may help.
+ */
+static int setNoDelay(int fd)
+{
+    int on = 1;
+    int cc = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
+    CHECK_EQ(cc, 0);
+    return cc;
+}
+
+/*
+ * Accept a connection.  This will block waiting for somebody to show up.
+ * If that's not desirable, use checkConnection() to make sure something
+ * is pending.
+ */
+static bool acceptConnection(JdwpState* state)
+{
+  JdwpNetState* netState = state->netState;
+  union {
+    struct sockaddr_in  addrInet;
+    struct sockaddr     addrPlain;
+  } addr;
+  socklen_t addrlen;
+  int sock;
+
+  if (netState->listenSock < 0) {
+    return false;       /* you're not listening! */
+  }
+
+  CHECK_LT(netState->clientSock, 0);      /* must not already be talking */
+
+  addrlen = sizeof(addr);
+  do {
+    sock = accept(netState->listenSock, &addr.addrPlain, &addrlen);
+    if (sock < 0 && errno != EINTR) {
+      // When we call shutdown() on the socket, accept() returns with
+      // EINVAL.  Don't gripe about it.
+      if (errno == EINVAL) {
+        PLOG(VERBOSE) << "accept failed";
+      } else {
+        PLOG(ERROR) << "accept failed";
+        return false;
+      }
+    }
+  } while (sock < 0);
+
+  netState->remoteAddr = addr.addrInet.sin_addr;
+  netState->remotePort = ntohs(addr.addrInet.sin_port);
+  LOG(VERBOSE) << "+++ accepted connection from " << inet_ntoa(netState->remoteAddr) << ":" << netState->remotePort;
+
+  netState->clientSock = sock;
+  netState->awaitingHandshake = true;
+  netState->inputCount = 0;
+
+  LOG(VERBOSE) << "Setting TCP_NODELAY on accepted socket";
+  setNoDelay(netState->clientSock);
+
+  if (pipe(netState->wakePipe) < 0) {
+    PLOG(ERROR) << "pipe failed";
+    return false;
+  }
+
+  return true;
+}
+
+/*
+ * Create a connection to a waiting debugger.
+ */
+static bool establishConnection(JdwpState* state) {
+  union {
+    struct sockaddr_in  addrInet;
+    struct sockaddr     addrPlain;
+  } addr;
+  struct hostent* pEntry;
+
+  CHECK(state != NULL && state->netState != NULL);
+  CHECK(!state->params.server);
+  CHECK_NE(state->params.host[0], '\0');
+  CHECK_NE(state->params.port, 0);
+
+  /*
+   * Start by resolving the host name.
+   */
+//#undef HAVE_GETHOSTBYNAME_R
+//#warning "forcing non-R"
+#ifdef HAVE_GETHOSTBYNAME_R
+  struct hostent he;
+  char auxBuf[128];
+  int error;
+  int cc = gethostbyname_r(state->params.host, &he, auxBuf, sizeof(auxBuf), &pEntry, &error);
+  if (cc != 0) {
+    LOG(WARNING) << "gethostbyname_r('" << state->params.host << "') failed: " << hstrerror(error);
+    return false;
+  }
+#else
+  h_errno = 0;
+  pEntry = gethostbyname(state->params.host);
+  if (pEntry == NULL) {
+    PLOG(WARNING) << "gethostbyname('" << state->params.host << "') failed";
+    return false;
+  }
+#endif
+
+  /* copy it out ASAP to minimize risk of multithreaded annoyances */
+  memcpy(&addr.addrInet.sin_addr, pEntry->h_addr, pEntry->h_length);
+  addr.addrInet.sin_family = pEntry->h_addrtype;
+
+  addr.addrInet.sin_port = htons(state->params.port);
+
+  LOG(INFO) << "Connecting out to " << inet_ntoa(addr.addrInet.sin_addr) << ":" << ntohs(addr.addrInet.sin_port);
+
+  /*
+   * Create a socket.
+   */
+  JdwpNetState* netState;
+  netState = state->netState;
+  netState->clientSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+  if (netState->clientSock < 0) {
+    PLOG(ERROR) << "Unable to create socket";
+    return false;
+  }
+
+  /*
+   * Try to connect.
+   */
+  if (connect(netState->clientSock, &addr.addrPlain, sizeof(addr)) != 0) {
+    PLOG(ERROR) << "Unable to connect to " << inet_ntoa(addr.addrInet.sin_addr) << ":" << ntohs(addr.addrInet.sin_port);
+    close(netState->clientSock);
+    netState->clientSock = -1;
+    return false;
+  }
+
+  LOG(INFO) << "Connection established to " << state->params.host << " (" << inet_ntoa(addr.addrInet.sin_addr) << ":" << ntohs(addr.addrInet.sin_port) << ")";
+  netState->awaitingHandshake = true;
+  netState->inputCount = 0;
+
+  setNoDelay(netState->clientSock);
+
+  if (pipe(netState->wakePipe) < 0) {
+    PLOG(ERROR) << "pipe failed";
+    return false;
+  }
+
+  return true;
+}
+
+/*
+ * Close the connection to the debugger.
+ *
+ * Reset the state so we're ready to receive a new connection.
+ */
+static void closeConnection(JdwpState* state) {
+  JdwpNetState* netState;
+
+  CHECK(state != NULL && state->netState != NULL);
+
+  netState = state->netState;
+  if (netState->clientSock < 0) {
+    return;
+  }
+
+  LOG(VERBOSE) << "+++ closed connection to " << inet_ntoa(netState->remoteAddr) << ":" << netState->remotePort;
+
+  close(netState->clientSock);
+  netState->clientSock = -1;
+}
+
+/*
+ * Figure out if we have a full packet in the buffer.
+ */
+static bool haveFullPacket(JdwpNetState* netState) {
+  if (netState->awaitingHandshake) {
+    return (netState->inputCount >= (int) kMagicHandshakeLen);
+  }
+  if (netState->inputCount < 4) {
+    return false;
+  }
+  long length = get4BE(netState->inputBuffer);
+  return (netState->inputCount >= length);
+}
+
+/*
+ * Consume bytes from the buffer.
+ *
+ * This would be more efficient with a circular buffer.  However, we're
+ * usually only going to find one packet, which is trivial to handle.
+ */
+static void consumeBytes(JdwpNetState* netState, int count) {
+  CHECK_GT(count, 0);
+  CHECK_LE(count, netState->inputCount);
+
+  if (count == netState->inputCount) {
+    netState->inputCount = 0;
+    return;
+  }
+
+  memmove(netState->inputBuffer, netState->inputBuffer + count, netState->inputCount - count);
+  netState->inputCount -= count;
+}
+
+/*
+ * Dump the contents of a packet to stdout.
+ */
+#if 0
+static void dumpPacket(const unsigned char* packetBuf)
+{
+    const unsigned char* buf = packetBuf;
+    uint32_t length, id;
+    uint8_t flags, cmdSet, cmd;
+    uint16_t error;
+    bool reply;
+    int dataLen;
+
+    cmd = cmdSet = 0xcc;
+
+    length = read4BE(&buf);
+    id = read4BE(&buf);
+    flags = read1(&buf);
+    if ((flags & kJDWPFlagReply) != 0) {
+        reply = true;
+        error = read2BE(&buf);
+    } else {
+        reply = false;
+        cmdSet = read1(&buf);
+        cmd = read1(&buf);
+    }
+
+    dataLen = length - (buf - packetBuf);
+
+    LOG(VERBOSE) << StringPrintf("--- %s: dataLen=%u id=0x%08x flags=0x%02x cmd=%d/%d",
+        reply ? "reply" : "req",
+        dataLen, id, flags, cmdSet, cmd);
+    if (dataLen > 0) {
+      HexDump(buf, dataLen);
+    }
+}
+#endif
+
+/*
+ * Handle a packet.  Returns "false" if we encounter a connection-fatal error.
+ */
+static bool handlePacket(JdwpState* state)
+{
+    JdwpNetState* netState = state->netState;
+    const unsigned char* buf = netState->inputBuffer;
+    JdwpReqHeader hdr;
+    uint32_t length, id;
+    uint8_t flags, cmdSet, cmd;
+    uint16_t error;
+    bool reply;
+    int dataLen;
+
+    cmd = cmdSet = 0;       // shut up gcc
+
+    /*dumpPacket(netState->inputBuffer);*/
+
+    length = read4BE(&buf);
+    id = read4BE(&buf);
+    flags = read1(&buf);
+    if ((flags & kJDWPFlagReply) != 0) {
+        reply = true;
+        error = read2BE(&buf);
+    } else {
+        reply = false;
+        cmdSet = read1(&buf);
+        cmd = read1(&buf);
+    }
+
+    CHECK_LE((int) length, netState->inputCount);
+    dataLen = length - (buf - netState->inputBuffer);
+
+    if (!reply) {
+        ExpandBuf* pReply = expandBufAlloc();
+
+        hdr.length = length;
+        hdr.id = id;
+        hdr.cmdSet = cmdSet;
+        hdr.cmd = cmd;
+        ProcessRequest(state, &hdr, buf, dataLen, pReply);
+        if (expandBufGetLength(pReply) > 0) {
+            ssize_t cc = netState->writePacket(pReply);
+
+            if (cc != (ssize_t) expandBufGetLength(pReply)) {
+              PLOG(ERROR) << "Failed sending reply to debugger";
+              expandBufFree(pReply);
+              return false;
+            }
+        } else {
+          LOG(WARNING) << "No reply created for set=" << cmdSet << " cmd=" << cmd;
+        }
+        expandBufFree(pReply);
+    } else {
+      LOG(ERROR) << "reply?!";
+      DCHECK(false);
+    }
+
+    LOG(VERBOSE) << "----------";
+
+    consumeBytes(netState, length);
+    return true;
+}
+
+/*
+ * Process incoming data.  If no data is available, this will block until
+ * some arrives.
+ *
+ * If we get a full packet, handle it.
+ *
+ * To take some of the mystery out of life, we want to reject incoming
+ * connections if we already have a debugger attached.  If we don't, the
+ * debugger will just mysteriously hang until it times out.  We could just
+ * close the listen socket, but there's a good chance we won't be able to
+ * bind to the same port again, which would confuse utilities.
+ *
+ * Returns "false" on error (indicating that the connection has been severed),
+ * "true" if things are still okay.
+ */
+static bool processIncoming(JdwpState* state) {
+  JdwpNetState* netState = state->netState;
+  int readCount;
+
+  CHECK_GE(netState->clientSock, 0);
+
+  if (!haveFullPacket(netState)) {
+    /* read some more, looping until we have data */
+    errno = 0;
+    while (1) {
+      int selCount;
+      fd_set readfds;
+      int maxfd;
+      int fd;
+
+      maxfd = netState->listenSock;
+      if (netState->clientSock > maxfd) {
+        maxfd = netState->clientSock;
+      }
+      if (netState->wakePipe[0] > maxfd) {
+        maxfd = netState->wakePipe[0];
+      }
+
+      if (maxfd < 0) {
+        LOG(VERBOSE) << "+++ all fds are closed";
+        return false;
+      }
+
+      FD_ZERO(&readfds);
+
+      /* configure fds; note these may get zapped by another thread */
+      fd = netState->listenSock;
+      if (fd >= 0) {
+        FD_SET(fd, &readfds);
+      }
+      fd = netState->clientSock;
+      if (fd >= 0) {
+        FD_SET(fd, &readfds);
+      }
+      fd = netState->wakePipe[0];
+      if (fd >= 0) {
+        FD_SET(fd, &readfds);
+      } else {
+        LOG(INFO) << "NOTE: entering select w/o wakepipe";
+      }
+
+      /*
+       * Select blocks until it sees activity on the file descriptors.
+       * Closing the local file descriptor does not count as activity,
+       * so we can't rely on that to wake us up (it works for read()
+       * and accept(), but not select()).
+       *
+       * We can do one of three things: (1) send a signal and catch
+       * EINTR, (2) open an additional fd ("wakePipe") and write to
+       * it when it's time to exit, or (3) time out periodically and
+       * re-issue the select.  We're currently using #2, as it's more
+       * reliable than #1 and generally better than #3.  Wastes two fds.
+       */
+      selCount = select(maxfd+1, &readfds, NULL, NULL, NULL);
+      if (selCount < 0) {
+        if (errno == EINTR) {
+          continue;
+        }
+        PLOG(ERROR) << "select failed";
+        goto fail;
+      }
+
+      if (netState->wakePipe[0] >= 0 && FD_ISSET(netState->wakePipe[0], &readfds)) {
+        if (netState->listenSock >= 0) {
+          LOG(ERROR) << "Exit wake set, but not exiting?";
+        } else {
+          LOG(DEBUG) << "Got wake-up signal, bailing out of select";
+        }
+        goto fail;
+      }
+      if (netState->listenSock >= 0 && FD_ISSET(netState->listenSock, &readfds)) {
+        LOG(INFO) << "Ignoring second debugger -- accepting and dropping";
+        union {
+          struct sockaddr_in   addrInet;
+          struct sockaddr      addrPlain;
+        } addr;
+        socklen_t addrlen;
+        int tmpSock;
+        tmpSock = accept(netState->listenSock, &addr.addrPlain, &addrlen);
+        if (tmpSock < 0) {
+          LOG(INFO) << "Weird -- accept failed";
+        } else {
+          close(tmpSock);
+        }
+      }
+      if (netState->clientSock >= 0 && FD_ISSET(netState->clientSock, &readfds)) {
+        readCount = read(netState->clientSock, netState->inputBuffer + netState->inputCount, sizeof(netState->inputBuffer) - netState->inputCount);
+        if (readCount < 0) {
+          /* read failed */
+          if (errno != EINTR) {
+            goto fail;
+          }
+          LOG(DEBUG) << "+++ EINTR hit";
+          return true;
+        } else if (readCount == 0) {
+          /* EOF hit -- far end went away */
+          LOG(DEBUG) << "+++ peer disconnected";
+          goto fail;
+        } else {
+          break;
+        }
+      }
+    }
+
+    netState->inputCount += readCount;
+    if (!haveFullPacket(netState)) {
+      return true;        /* still not there yet */
+    }
+  }
+
+  /*
+   * Special-case the initial handshake.  For some bizarre reason we're
+   * expected to emulate bad tty settings by echoing the request back
+   * exactly as it was sent.  Note the handshake is always initiated by
+   * the debugger, no matter who connects to whom.
+   *
+   * Other than this one case, the protocol [claims to be] stateless.
+   */
+  if (netState->awaitingHandshake) {
+    int cc;
+
+    if (memcmp(netState->inputBuffer, kMagicHandshake, kMagicHandshakeLen) != 0) {
+      LOG(ERROR) << StringPrintf("ERROR: bad handshake '%.14s'", netState->inputBuffer);
+      goto fail;
+    }
+
+    errno = 0;
+    cc = write(netState->clientSock, netState->inputBuffer, kMagicHandshakeLen);
+    if (cc != kMagicHandshakeLen) {
+      PLOG(ERROR) << "Failed writing handshake bytes (" << cc << " of " << kMagicHandshakeLen << ")";
+      goto fail;
+    }
+
+    consumeBytes(netState, kMagicHandshakeLen);
+    netState->awaitingHandshake = false;
+    LOG(VERBOSE) << "+++ handshake complete";
+    return true;
+  }
+
+  /*
+   * Handle this packet.
+   */
+  return handlePacket(state);
+
+fail:
+  closeConnection(state);
+  return false;
+}
+
+/*
+ * Send a request.
+ *
+ * The entire packet must be sent with a single write() call to avoid
+ * threading issues.
+ *
+ * Returns "true" if it was sent successfully.
+ */
+static bool sendRequest(JdwpState* state, ExpandBuf* pReq) {
+  JdwpNetState* netState = state->netState;
+
+  /*dumpPacket(expandBufGetBuffer(pReq));*/
+  if (netState->clientSock < 0) {
+    /* can happen with some DDMS events */
+    LOG(VERBOSE) << "NOT sending request -- no debugger is attached";
+    return false;
+  }
+
+  errno = 0;
+  ssize_t cc = netState->writePacket(pReq);
+
+  if (cc != (ssize_t) expandBufGetLength(pReq)) {
+    PLOG(ERROR) << "Failed sending req to debugger (" << cc << " of " << expandBufGetLength(pReq) << ")";
+    return false;
+  }
+
+  return true;
+}
+
+/*
+ * Send a request that was split into multiple buffers.
+ *
+ * The entire packet must be sent with a single writev() call to avoid
+ * threading issues.
+ *
+ * Returns "true" if it was sent successfully.
+ */
+static bool sendBufferedRequest(JdwpState* state, const iovec* iov, int iovcnt) {
+  JdwpNetState* netState = state->netState;
+
+  if (netState->clientSock < 0) {
+    /* can happen with some DDMS events */
+    LOG(VERBOSE) << "NOT sending request -- no debugger is attached";
+    return false;
+  }
+
+  size_t expected = 0;
+  for (int i = 0; i < iovcnt; i++) {
+    expected += iov[i].iov_len;
+  }
+
+  ssize_t actual = netState->writeBufferedPacket(iov, iovcnt);
+
+  if ((size_t)actual != expected) {
+    PLOG(ERROR) << "Failed sending b-req to debugger (" << actual << " of " << expected << ")";
+    return false;
+  }
+
+  return true;
+}
+
+/*
+ * Our functions.
+ *
+ * We can't generally share the implementations with other transports,
+ * even if they're also socket-based, because our JdwpNetState will be
+ * different from theirs.
+ */
+static const JdwpTransport socketTransport = {
+  prepareSocket,
+  acceptConnection,
+  establishConnection,
+  closeConnection,
+  netShutdownExtern,
+  netFreeExtern,
+  isConnected,
+  awaitingHandshake,
+  processIncoming,
+  sendRequest,
+  sendBufferedRequest,
+};
+
+/*
+ * Return our set.
+ */
+const JdwpTransport* SocketTransport() {
+  return &socketTransport;
+}
+
+}  // namespace JDWP
+
+}  // namespace art
diff --git a/src/logging.cc b/src/logging.cc
index bf6ab91..bb68442 100644
--- a/src/logging.cc
+++ b/src/logging.cc
@@ -63,4 +63,78 @@
   return data_->buffer;
 }
 
+/*
+ * Print a hex dump in this format:
+ *
+ * 01234567: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff  0123456789abcdef\n
+ *
+ * Does not use printf() or other string-formatting calls.
+ */
+void HexDump(const void* address, size_t byte_count, bool show_actual_address) {
+  static const char gHexDigit[] = "0123456789abcdef";
+  const unsigned char* addr = reinterpret_cast<const unsigned char*>(address);
+  char out[77];           /* exact fit */
+  unsigned int offset;    /* offset to show while printing */
+
+  if (show_actual_address) {
+    offset = (int) addr;
+  } else {
+    offset = 0;
+  }
+  memset(out, ' ', sizeof(out)-1);
+  out[8] = ':';
+  out[sizeof(out)-2] = '\n';
+  out[sizeof(out)-1] = '\0';
+
+  int gap = (int) offset & 0x0f;
+  while (byte_count) {
+    unsigned int lineOffset = offset & ~0x0f;
+    int i, count;
+
+    char* hex = out;
+    char* asc = out + 59;
+
+    for (i = 0; i < 8; i++) {
+      *hex++ = gHexDigit[lineOffset >> 28];
+      lineOffset <<= 4;
+    }
+    hex++;
+    hex++;
+
+    count = ((int)byte_count > 16-gap) ? 16-gap : (int)byte_count; /* cap length */
+    CHECK_NE(count, 0);
+    CHECK_LE(count + gap, 16);
+
+    if (gap) {
+      /* only on first line */
+      hex += gap * 3;
+      asc += gap;
+    }
+
+    for (i = gap ; i < count+gap; i++) {
+      *hex++ = gHexDigit[*addr >> 4];
+      *hex++ = gHexDigit[*addr & 0x0f];
+      hex++;
+      if (*addr >= 0x20 && *addr < 0x7f /*isprint(*addr)*/)
+      *asc++ = *addr;
+      else
+      *asc++ = '.';
+      addr++;
+    }
+    for ( ; i < 16; i++) {
+      /* erase extra stuff; only happens on last line */
+      *hex++ = ' ';
+      *hex++ = ' ';
+      hex++;
+      *asc++ = ' ';
+    }
+
+    LOG(INFO) << out;
+
+    gap = 0;
+    byte_count -= count;
+    offset += count;
+  }
+}
+
 }  // namespace art
diff --git a/src/logging.h b/src/logging.h
index d3dbcd4..2e7856e 100644
--- a/src/logging.h
+++ b/src/logging.h
@@ -169,6 +169,8 @@
   DISALLOW_COPY_AND_ASSIGN(LogMessage);
 };
 
+void HexDump(const void* address, size_t byte_count, bool show_actual_address = false);
+
 }  // namespace art
 
 #endif  // ART_SRC_LOGGING_H_
diff --git a/src/org_apache_harmony_dalvik_ddmc_DdmServer.cc b/src/org_apache_harmony_dalvik_ddmc_DdmServer.cc
index 3392689..b0aba2f 100644
--- a/src/org_apache_harmony_dalvik_ddmc_DdmServer.cc
+++ b/src/org_apache_harmony_dalvik_ddmc_DdmServer.cc
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include "debugger.h"
 #include "logging.h"
 
 #include "JniConstants.h"  // Last to avoid problems with LOG redefinition.
@@ -28,7 +29,7 @@
 {
   ScopedByteArrayRO data(env, javaData);
   DCHECK_LE(offset + length, static_cast<int32_t>(data.size()));
-  UNIMPLEMENTED(WARNING) << "dvmDbgDdmSendChunk(type, length, data->get() + offset);";
+  Dbg::DdmSendChunk(type, length, reinterpret_cast<const uint8_t*>(&data[offset]));
 }
 
 static JNINativeMethod gMethods[] = {
diff --git a/src/thread.cc b/src/thread.cc
index 42d9f1a..1800834 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -26,6 +26,7 @@
 #include <iostream>
 #include <list>
 
+#include "debugger.h"
 #include "class_linker.h"
 #include "class_loader.h"
 #include "context.h"
@@ -165,10 +166,7 @@
   // in progress while we were starting up.)
   runtime->GetThreadList()->WaitForGo();
 
-  // TODO: say "hi" to the debugger.
-  //if (gDvm.debuggerConnected) {
-  //  dvmDbgPostThreadStart(self);
-  //}
+  Dbg::PostThreadStart(self);
 
   // Invoke the 'run' method of our java.lang.Thread.
   CHECK(self->peer_ != NULL);
@@ -767,10 +765,7 @@
     // this.vmData = 0;
     SetVmData(peer_, NULL);
 
-    // TODO: say "bye" to the debugger.
-    //if (gDvm.debuggerConnected) {
-    //  dvmDbgPostThreadDeath(self);
-    //}
+    Dbg::PostThreadDeath(this);
 
     // Thread.join() is implemented as an Object.wait() on the Thread.lock
     // object. Signal anyone who is waiting.
