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.
