diff --git a/src/d8-debug.cc b/src/d8-debug.cc
new file mode 100644
index 0000000..4e0243a
--- /dev/null
+++ b/src/d8-debug.cc
@@ -0,0 +1,345 @@
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+#include "d8.h"
+#include "d8-debug.h"
+#include "platform.h"
+#include "debug-agent.h"
+
+
+namespace v8 {
+
+
+void HandleDebugEvent(DebugEvent event,
+                      Handle<Object> exec_state,
+                      Handle<Object> event_data,
+                      Handle<Value> data) {
+  HandleScope scope;
+
+  // Check for handled event.
+  if (event != Break && event != Exception && event != AfterCompile) {
+    return;
+  }
+
+  TryCatch try_catch;
+
+  // Get the toJSONProtocol function on the event and get the JSON format.
+  Local<String> to_json_fun_name = String::New("toJSONProtocol");
+  Local<Function> to_json_fun =
+      Function::Cast(*event_data->Get(to_json_fun_name));
+  Local<Value> event_json = to_json_fun->Call(event_data, 0, NULL);
+  if (try_catch.HasCaught()) {
+    Shell::ReportException(&try_catch);
+    return;
+  }
+
+  // Print the event details.
+  Handle<Object> details =
+      Shell::DebugMessageDetails(Handle<String>::Cast(event_json));
+  if (try_catch.HasCaught()) {
+    Shell::ReportException(&try_catch);
+    return;
+  }
+  String::Utf8Value str(details->Get(String::New("text")));
+  if (str.length() == 0) {
+    // Empty string is used to signal not to process this event.
+    return;
+  }
+  printf("%s\n", *str);
+
+  // Get the debug command processor.
+  Local<String> fun_name = String::New("debugCommandProcessor");
+  Local<Function> fun = Function::Cast(*exec_state->Get(fun_name));
+  Local<Object> cmd_processor =
+      Object::Cast(*fun->Call(exec_state, 0, NULL));
+  if (try_catch.HasCaught()) {
+    Shell::ReportException(&try_catch);
+    return;
+  }
+
+  static const int kBufferSize = 256;
+  bool running = false;
+  while (!running) {
+    char command[kBufferSize];
+    printf("dbg> ");
+    char* str = fgets(command, kBufferSize, stdin);
+    if (str == NULL) break;
+
+    // Ignore empty commands.
+    if (strlen(command) == 0) continue;
+
+    TryCatch try_catch;
+
+    // Convert the debugger command to a JSON debugger request.
+    Handle<Value> request =
+        Shell::DebugCommandToJSONRequest(String::New(command));
+    if (try_catch.HasCaught()) {
+      Shell::ReportException(&try_catch);
+      continue;
+    }
+
+    // If undefined is returned the command was handled internally and there is
+    // no JSON to send.
+    if (request->IsUndefined()) {
+      continue;
+    }
+
+    Handle<String> fun_name;
+    Handle<Function> fun;
+    // All the functions used below take one argument.
+    static const int kArgc = 1;
+    Handle<Value> args[kArgc];
+
+    // Invoke the JavaScript to convert the debug command line to a JSON
+    // request, invoke the JSON request and convert the JSON respose to a text
+    // representation.
+    fun_name = String::New("processDebugRequest");
+    fun = Handle<Function>::Cast(cmd_processor->Get(fun_name));
+    args[0] = request;
+    Handle<Value> response_val = fun->Call(cmd_processor, kArgc, args);
+    if (try_catch.HasCaught()) {
+      Shell::ReportException(&try_catch);
+      continue;
+    }
+    Handle<String> response = Handle<String>::Cast(response_val);
+
+    // Convert the debugger response into text details and the running state.
+    Handle<Object> response_details = Shell::DebugMessageDetails(response);
+    if (try_catch.HasCaught()) {
+      Shell::ReportException(&try_catch);
+      continue;
+    }
+    String::Utf8Value text_str(response_details->Get(String::New("text")));
+    if (text_str.length() > 0) {
+      printf("%s\n", *text_str);
+    }
+    running =
+        response_details->Get(String::New("running"))->ToBoolean()->Value();
+  }
+}
+
+
+void RunRemoteDebugger(int port) {
+  RemoteDebugger debugger(port);
+  debugger.Run();
+}
+
+
+void RemoteDebugger::Run() {
+  bool ok;
+
+  // Make sure that socket support is initialized.
+  ok = i::Socket::Setup();
+  if (!ok) {
+    printf("Unable to initialize socket support %d\n", i::Socket::LastError());
+    return;
+  }
+
+  // Connect to the debugger agent.
+  conn_ = i::OS::CreateSocket();
+  static const int kPortStrSize = 6;
+  char port_str[kPortStrSize];
+  i::OS::SNPrintF(i::Vector<char>(port_str, kPortStrSize), "%d", port_);
+  ok = conn_->Connect("localhost", port_str);
+  if (!ok) {
+    printf("Unable to connect to debug agent %d\n", i::Socket::LastError());
+    return;
+  }
+
+  // Start the receiver thread.
+  ReceiverThread receiver(this);
+  receiver.Start();
+
+  // Start the keyboard thread.
+  KeyboardThread keyboard(this);
+  keyboard.Start();
+
+  // Process events received from debugged VM and from the keyboard.
+  bool terminate = false;
+  while (!terminate) {
+    event_available_->Wait();
+    RemoteDebuggerEvent* event = GetEvent();
+    switch (event->type()) {
+      case RemoteDebuggerEvent::kMessage:
+        HandleMessageReceived(event->data());
+        break;
+      case RemoteDebuggerEvent::kKeyboard:
+        HandleKeyboardCommand(event->data());
+        break;
+      case RemoteDebuggerEvent::kDisconnect:
+        terminate = true;
+        break;
+
+      default:
+        UNREACHABLE();
+    }
+    delete event;
+  }
+
+  // Wait for the receiver thread to end.
+  receiver.Join();
+}
+
+
+void RemoteDebugger::MessageReceived(i::SmartPointer<char> message) {
+  RemoteDebuggerEvent* event =
+      new RemoteDebuggerEvent(RemoteDebuggerEvent::kMessage, message);
+  AddEvent(event);
+}
+
+
+void RemoteDebugger::KeyboardCommand(i::SmartPointer<char> command) {
+  RemoteDebuggerEvent* event =
+      new RemoteDebuggerEvent(RemoteDebuggerEvent::kKeyboard, command);
+  AddEvent(event);
+}
+
+
+void RemoteDebugger::ConnectionClosed() {
+  RemoteDebuggerEvent* event =
+      new RemoteDebuggerEvent(RemoteDebuggerEvent::kDisconnect,
+                              i::SmartPointer<char>());
+  AddEvent(event);
+}
+
+
+void RemoteDebugger::AddEvent(RemoteDebuggerEvent* event) {
+  i::ScopedLock lock(event_access_);
+  if (head_ == NULL) {
+    ASSERT(tail_ == NULL);
+    head_ = event;
+    tail_ = event;
+  } else {
+    ASSERT(tail_ != NULL);
+    tail_->set_next(event);
+    tail_ = event;
+  }
+  event_available_->Signal();
+}
+
+
+RemoteDebuggerEvent* RemoteDebugger::GetEvent() {
+  i::ScopedLock lock(event_access_);
+  ASSERT(head_ != NULL);
+  RemoteDebuggerEvent* result = head_;
+  head_ = head_->next();
+  if (head_ == NULL) {
+    ASSERT(tail_ == result);
+    tail_ = NULL;
+  }
+  return result;
+}
+
+
+void RemoteDebugger::HandleMessageReceived(char* message) {
+  HandleScope scope;
+
+  // Print the event details.
+  TryCatch try_catch;
+  Handle<Object> details =
+      Shell::DebugMessageDetails(Handle<String>::Cast(String::New(message)));
+  if (try_catch.HasCaught()) {
+      Shell::ReportException(&try_catch);
+    return;
+  }
+  String::Utf8Value str(details->Get(String::New("text")));
+  if (str.length() == 0) {
+    // Empty string is used to signal not to process this event.
+    return;
+  }
+  if (*str != NULL) {
+    printf("%s\n", *str);
+  } else {
+    printf("???\n");
+  }
+  printf("dbg> ");
+}
+
+
+void RemoteDebugger::HandleKeyboardCommand(char* command) {
+  HandleScope scope;
+
+  // Convert the debugger command to a JSON debugger request.
+  TryCatch try_catch;
+  Handle<Value> request =
+      Shell::DebugCommandToJSONRequest(String::New(command));
+  if (try_catch.HasCaught()) {
+    Shell::ReportException(&try_catch);
+    return;
+  }
+
+  // If undefined is returned the command was handled internally and there is
+  // no JSON to send.
+  if (request->IsUndefined()) {
+    return;
+  }
+
+  // Send the JSON debugger request.
+  i::DebuggerAgentUtil::SendMessage(conn_, Handle<String>::Cast(request));
+}
+
+
+void ReceiverThread::Run() {
+  // Receive the connect message (with empty body).
+  i::SmartPointer<char> message =
+    i::DebuggerAgentUtil::ReceiveMessage(remote_debugger_->conn());
+  ASSERT(*message == NULL);
+
+  while (true) {
+    // Receive a message.
+    i::SmartPointer<char> message =
+      i::DebuggerAgentUtil::ReceiveMessage(remote_debugger_->conn());
+    if (*message == NULL) {
+      remote_debugger_->ConnectionClosed();
+      return;
+    }
+
+    // Pass the message to the main thread.
+    remote_debugger_->MessageReceived(message);
+  }
+}
+
+
+void KeyboardThread::Run() {
+  static const int kBufferSize = 256;
+  while (true) {
+    // read keyboard input.
+    char command[kBufferSize];
+    char* str = fgets(command, kBufferSize, stdin);
+    if (str == NULL) {
+      break;
+    }
+
+    // Pass the keyboard command to the main thread.
+    remote_debugger_->KeyboardCommand(
+        i::SmartPointer<char>(i::StrDup(command)));
+  }
+}
+
+
+}  // namespace v8
